ContextPilot 上手:腾讯开源的长上下文 Agent 管理框架
长上下文任务跑久了,上下文越滚越大,模型开始犯迷糊,该记的记不住,不该忘的反而卡在窗口里。腾讯刚开源的 ContextPilot 想做的是让 Agent 主动管理自己的上下文。项目地址:https://github.com/Tencent/ContextPilot,论文同步上了 arXiv。
这不是一个单纯扩大窗口的模型,而是一套教会模型自己决定什么时候该记住、什么时候该忘记、什么时候该整理的训练框架。
长上下文的问题不是窗口不够大
很多长上下文模型已经把窗口拉到 128K 甚至 1M token,但实际跑多轮检索、多步推理、跨文档问答这些任务时,问题往往不是窗口太小,而是塞进去的信息太杂。每轮都要塞新信息,同时保留之前的判断依据,窗口一大什么都往里扔,模型处理不过来;窗口一小,又只能被迫丢掉一些可能还有用的内容。
更麻烦的是,现在很多 Agent 框架的上下文管理工具就几样:搜索、删除、摘要。简单场景够用,长程任务就吃力了。
ContextPilot 的切入角度很直接:与其让模型在一个固定窗口里被动塞信息,不如教它主动整理自己的上下文。框架给 Agent 配了一套完整的整理工具,再用强化学习让模型自己学会什么该留、什么该扔、什么该存进长期记忆。
工具层:Agent 手里不只有锤子
ContextPilot 在常规的搜索和删除之外,扩展了三个核心工具。
规划工具:让模型在动手之前先列提纲,把任务拆成步骤,按顺序执行。规划结果作为上下文的一部分,供后续步骤随时参考。
长期记忆工具:把关键信息写进结构化的长期记忆里。和普通内存不同,这个记忆可以按需检索,模型后续能用查询语句主动调取。
软上下文卸载:暂时用不到但后面可能还得翻出来的内容,不直接删,归档到类似“抽屉”的地方。需要的时候再加载回来,不是真的丢掉。
这三样加在一起,Agent 的上下文不再是线性增长的文本流,更像一个可以随时整理的工作台。模型能主动决定哪些放桌面,哪些存档案,哪些写进待办清单。
训练层:只练关键动作,每个动作单独算账
工具配齐之后,难点变成了怎么教模型用。ContextPilot 的训练方法有三点设计和普通 RL 不太一样。
第一,只对关键编辑动作做深度探索。
模型尝试编辑上下文时,系统会判断哪些编辑操作对最终结果影响最大。比如删除一段看似无关但实际支撑后续推理的内容,或者把一条关键信息存进长期记忆的时机。这些影响大的动作,训练时让模型多试几次不同的选择,探索哪条路走得通。普通操作快速过,不浪费时间。
第二,每个编辑动作单独算账。
传统 RL 的做法是任务跑完了,成了就给整个轨迹打高分,败了就打低分。但一个长任务里有几十次上下文编辑,其中可能只有两三次是关键动作,其他都是常规操作。
ContextPilot 做了细粒度的信用分配:最终结果出来之后,倒推每一个中间编辑动作对后续所有分支轨迹的影响。真正帮上忙的编辑动作单独给奖励,拖后腿的单独扣分。这样模型才能学明白哪个动作对、哪个动作错。
第三,用上下文变化量和熵变识别关键节点。
系统怎么判断哪个编辑动作值得深度探索?看上下文变化量和模型输出熵的变化。如果一个操作让模型后续的推理路径发生剧烈变化,或者让模型从“犹豫不定”变成“确定”,系统认为这个节点值得多练几次。
上下文被大幅修改的地方,往往就是任务成败的关键转折点。把这些点拎出来单独训练,比在整个轨迹上均匀撒网高效得多。
效果:窗口缩小,性能反而提升了
腾讯基于 ContextPilot 训练了 Qwen3-14B。在 32K 上下文窗口下跑长程任务,性能超过了原生 128K 窗口的基座模型。窗口缩到原来的四分之一,任务完成得反而更好。同时,模型实际使用的 token 数被大幅压缩。
评估覆盖了四个任务:InfBench 的 longbook_choice_eng 分集、NovelQA、LongMemEval 和 BrowseComp+。这四个覆盖了长文档问答和深度搜索两种典型场景。具体跑分数据在论文里有详细说明。
上手路径
框架分推理和训练两块,都开源了。
安装推理环境
bash infer/scripts/setup_environment.sh
source infer/.venv/bin/activate
ContextPilot 的 searchEngine 工具依赖 Elasticsearch。项目的安装脚本会装一份本地 Elasticsearch 发行版。如果想单独跑服务:
bash infer/scripts/start_elasticsearch.sh
跑全量评估
四个任务全过一遍:
bash infer/scripts/run_full_pipeline.sh /path/to/checkpoint my-run
结果写到 infer/results/,包含预测结果、完整轨迹和评分。
单个任务也可以单独跑:
bash infer/scripts/eval_infbench.sh /path/to/checkpoint my-run
bash infer/scripts/eval_novelqa.sh /path/to/checkpoint my-run
bash infer/scripts/eval_longmemeval.sh /path/to/checkpoint my-run
bash infer/scripts/eval_browsecomp_plus.sh /path/to/checkpoint my-run
训练
训练部分基于 verl 实现,包含了上下文感知的部分展开和逐动作信用分配。入口在 train/ 目录下:
cd train
TRAIN_FILE=/path/to/train.parquet \
VAL_FILE=/path/to/validation.parquet \
MODEL_PATH=/path/to/qwen3-8b \
GPUS_PER_NODE=8 \
bash sh/run_qwen3-8b_longbenchv2.sh
Qwen3-14B 用 sh/run_qwen3-14b_longbenchv2.sh。
注意事项
数据文件:LongMemEval 和 BrowseComp+ 的数据文件用 Git LFS 管理。克隆仓库后跑:
git lfs install && git lfs pull
NovelQA 权限:NovelQA 的答案标注不能直接分发,需要去 NovelQA 数据集页面单独申请访问权限。
Judge 配置:LongMemEval 和 BrowseComp+ 的评分用到了 OpenAI 兼容的 Judge 服务,需要提前把 endpoint 配置写进 JSON 文件,然后设置环境变量:
export JUDGE_OPENAI_FILE=/path/to/judge-endpoint.json
具体配置格式在 infer/README.md 里可以找到。
操作清单
-
[ ] 克隆仓库: git clone https://github.com/Tencent/ContextPilot.git -
[ ] 安装 Git LFS 并拉取数据文件: git lfs install && git lfs pull -
[ ] 运行推理环境安装脚本: bash infer/scripts/setup_environment.sh -
[ ] 激活虚拟环境: source infer/.venv/bin/activate -
[ ] (如需 searchEngine 工具)启动 Elasticsearch: bash infer/scripts/start_elasticsearch.sh -
[ ] 配置 Judge endpoint 文件并设置 JUDGE_OPENAI_FILE环境变量 -
[ ] (如需 NovelQA)去数据集页面申请访问权限 -
[ ] 运行全量评估或单个任务评估脚本 -
[ ] (如需训练)进入 train 目录,配置训练数据路径和模型路径,运行对应训练脚本
FAQ
Q:ContextPilot 和直接扩大上下文窗口有什么区别?
A:扩大窗口是被动增加容量,ContextPilot 是教会模型主动管理和组织已有内容。实验结果是 32K 窗口加 ContextPilot 的表现超过原生 128K 窗口的基座模型。
Q:训练部分依赖什么框架?
A:训练基于 verl 实现。
Q:必须用 Elasticsearch 吗?
A:只有 searchEngine 工具需要 Elasticsearch。安装脚本会装本地发行版,也可以单独用 start_elasticsearch.sh 启动。
Q:Judge 服务一定要配置吗?
A:只有跑 LongMemEval 和 BrowseComp+ 评估时需要。InfBench 和 NovelQA 不需要 Judge 配置。
Q:NovelQA 的数据怎么拿?
A:去 Hugging Face 上 NovelQA 数据集页面申请全量访问权限,标注数据不能直接分发。
Q:支持哪些基座模型?
A:目前提供的训练脚本针对 Qwen3-8B 和 Qwen3-14B。
Q:评估结果输出在哪里?
A:统一写到 infer/results/ 目录,包含预测、轨迹和评分。

