为什么长时程 Agent 的上下文问题,最终会变成执行问题
作者:cooleryu
一个 AI Agent 可以记得所有事实,仍然在错误的时刻执行一个“看起来完全正确”的动作。
想象这样一段轨迹:
- 10:02,Agent 读到当前环境是
staging,受保护配置允许修改; - 10:16,它拟定了一个修改
staging/config.json的计划,但任务被中断; - 10:40,环境已经切换到
production,超时值改变,受保护配置也不再允许修改; - 11:05,旧计划恢复执行。
这时,计划本身可能没有语法错误,路径也真实存在,甚至每一条旧事实都曾经是正确的。问题在于:支撑这个动作的世界已经不存在了。
这就是我在构建 ContextAdapt 时逐渐形成的判断:长时程 Agent 的上下文问题,不只是“模型忘了什么”,也不只是“怎样把更多内容塞进窗口”。它还有一个更靠近执行层的问题:
当 Agent 即将调用工具时,我们能否证明这个动作仍然由当前状态、当前指令和当前权限支持?
这篇文章结合相关研究与 ContextAdapt 的早期 Python 原型实验,讨论已有证据及其边界。引用这些论文,不表示复现或改进了它们。
01 / 上下文研究正在从“装得下”走向“管得住”
早期讨论很容易把长上下文简化为窗口大小:只要模型能读更多 token,长期任务就会更稳定。但近期研究展示的是一个更复杂的图景。
LOCA-bench 把环境增长本身作为可控制变量,研究 Agent 在动态长上下文中的表现。在其测得的模型与配置中,环境描述变长通常伴随性能下降;部分上下文管理策略可以改善结果。
ContextBench 则构建了覆盖 66 个代码仓库、8 种语言、1,136 个任务的基准。它提出了一个很关键的区分:Agent 探索过某段上下文,不等于将它纳入最终声明用于生成补丁的上下文。“访问”与“声明使用”之间仍有断层。
另一些工作开始让 Agent 主动编辑、外置或压缩自己的上下文。ACM 研究 Agent 控制的上下文编辑与外部记忆,CoMem 把记忆处理与主 Agent 解耦,Active Context Compression 让 Agent 通过工具主动发起压缩。这些方向都在回答同一类问题:有限的注意力应该怎样分配?
而 TRACE 把问题又推进了一步:重复压缩可能削弱近期交互,引发动作受阻、重复探索或后续不稳定。它采用从同一状态出发的成对闭环延续,并用验证器测量压缩后新增的动作受阻与重复探索。
把它们放在一起,可以看到研究重心正在移动:
| 方向 | 它主要解决什么 | 在执行前仍需回答什么 |
|---|---|---|
| 动态长上下文评测 | 上下文增长如何影响任务表现 | 当前动作到底依赖了哪一版状态 |
| 检索与利用分析 | Agent 找到了什么、真正用了什么 | 被使用的证据是否仍然有效 |
| 编辑、外置与压缩 | 如何降低注意力与延迟成本 | 压缩后是否保留了权限和时间关系 |
| 闭环成对验证 | 改写上下文是否改变后续行为 | 如何在真实工具调用前强制执行结论 |
这些工作与 ContextAdapt 不是相互替代的。它们更像是在上下文生命周期的不同位置上解决问题。
02 / 管理上下文,不等于授权一个动作
上下文可以被整理得很干净,却仍然包含一个已经失效的计划;摘要可以准确复述旧指令,却没有说明它后来被撤销;检索器可以找回正确文件,却把另一个实体的最新值绑定到当前任务。
所以我更关心一个窄一些的问题:
Context management 决定 Agent 看什么;execution authorization 决定 Agent 现在是否还能做。
两者需要连接,但不应被混为一谈。
ContextAdapt 的早期 Python 原型选择了“最后一个负责任的时刻”:计划已经形成、工具尚未执行。在这里,系统不再问“这段上下文总体上好不好”,而是要求一个动作给出最小来源说明:
based_on_event:这个动作依据哪一条状态或指令;permission_event:涉及受保护操作时,当前权限来自哪里;- 这些依据是否属于同一个实体;
- 它们是否已被更新事件取代;
- 当前状态是否仍然允许这次操作。
在受支持的动作契约内,证据不足会阻止执行,不会把“不知道”当作“安全”。
03 / 我们先否定了一个最容易讲的故事
“上下文太长,所以模型忘了。”这是一个很顺口的解释,也很适合做宣传。但我们的第一组实验并不支持这么简单的结论。
在一组显式标记、可精确检索的超长输入测试中,我们对 gpt-5.6-luna 做了 9 次真实调用,输入规模约为 198K、398K 和 898K token。三个档位中,27 个权威事实全部被正确提取,没有出现陈旧来源错误。这组数据来自项目内部实验记录,完整记录尚未随本文公开。
这项实验很窄:它不是现实 Agent 工作流,也没有复杂工具反馈。但它至少推翻了一个过度概括——长度本身并不必然让明确标记的事实丢失。
真正值得追问的于是变成:如果正确事实仍然在窗口里,Agent 为什么还会做错?
04 / 真正危险的不是“没看见”,而是“绑错了”
我们随后构造了一组乱序事件存储轨迹。正确事实始终可见,但同时存在多个实体、多次更新、失败读取与旧状态。Agent 必须判断哪条信息属于当前对象、哪次读取可信、哪个值已经被替代。
结果出现了明显分化:
| 输入条件 | 精确正确 | 未要求受保护修改 | 错误来源 |
|---|---|---|---|
| Raw 200K | 5/6 | 6/6 | 1/6 |
| Raw 400K | 2/6 | 2/6 | 4/6 |
| Raw 900K | 2/6 | 2/6 | 4/6 |
| 从 900K 轨迹提取的当前状态 | 6/6 | 6/6 | 0/6 |
表中 K 是原始轨迹的名义档位;规范化后输入已缩短,这里只评分动作 JSON,未执行写入。在相同状态哈希下,四个失败案例转为成功,没有反向退化。这组数据同样来自项目内部实验记录,完整轨迹与方法记录尚未随本文公开。
这不是简单的“记忆丢失”。更接近的描述是:正确事实仍在输入中,输出却采用了错误时间、实体或来源对应的值。
而且,单纯调整信息顺序也不够。在同一报告的等内容、仅顺序变化实验中,顺序改变了本次样本的错误计数和形态;但在 71 个有效实验单元里,六种看似合理的排列没有一种做到全对,每一种都至少出现过一次错误。排序是风险杠杆,不是安全机制。
05 / 从故障归因到同状态成对重放
如果一次失败真的是上下文造成的,那么修复上下文之后,从同一个环境状态继续,结果应该发生可重复的变化。否则,我们可能只是把工具故障、环境差异或随机波动错算成“上下文问题”。
因此,我们做了一组更接近诊断流程的受控实验:
- 从失败轨迹里定位一段高摩擦区间;
- 冻结环境状态与任务目标;
- 分别向 Agent 提供原始轨迹尾段、结构化近期状态、摘要加近期状态;
- 成对执行,并用独立结果判断上下文干预是否改变了行为;
- 加入工具故障对照,避免把不可用工具误判为上下文因果。
初始实验含 24 个不透明任务、8 个隐藏任务族;其中 8 任务保留集上,结构化近期状态的成功率为 87.5%,原始轨迹尾段为 25%。后续新建保留集的锚点精度为 4/4,剩余非锚点对照为 1/4。注入工具故障的对照在全部已测策略下均未通过任务验证,未被归因成上下文问题。这组数据来自项目内部实验记录,完整记录尚未随本文公开。
这些数字很有启发,但边界同样重要:它们来自受控配置编辑任务,不代表真实世界中上下文故障的普遍发生率,也不证明不同模型都具有相同幅度的收益。
06 / 最后一步:让验证结果真正拦住工具
诊断报告只有在接上执行边界之后,才会变成工程防线。
这个原型的最小路径是:
不可变事件记录
↓
重建当前状态,并区分可信读取与失败观察
↓
检查动作来源、实体范围、时间顺序与当前权限
↓
ALLOW 或 BLOCK
↓
受支持的工具调用只有 ALLOW 才继续
这份 Python 原型用以下命令演示这条路径:
python3 -m contextadapt demo
演示中的旧动作会被判为 BLOCK:一方面,当前权限不允许受保护修改;另一方面,它依赖的旧状态已经被后续事件取代。contextadapt check TRACE.jsonl 只有在证据充分且通过时才返回成功;BLOCK 或证据不足会以退出码 2 失败关闭。
执行器验证把预制、已接受的关系样例接入工具边界:当时 Codex 的 PreToolUse 在 apply_patch 前检查陈旧上下文,OMP 的 tool_call 覆盖写入、编辑及可识别的变更型 shell。成对案例中,陈旧路径被拦且文件未变,当前路径放行并写入;不透明脚本和未覆盖工具不在结论内。机器可读结果见执行器验证报告。项目的执行器集成文档可作为延伸阅读,但其中的当前实现说明不能直接代替这轮历史验证。
这轮 OMP 执行器验证使用了确定性 mock provider,报告记载远程 Qwen 后端当时离线。它证明的是执行拦截链条,不是在线 Qwen 的决策质量。
07 / 为什么还需要语义层,但不能偷偷把模型当安全证明
有些关系无法仅靠字段比较得出,例如两段自然语言是否描述同一实体、某个新事件是否真正推翻旧指令。这个原型的 hybrid 路径允许宿主提供两次分开运行的语义分析:一次提出关系,一次核对关系。
但确定性核心不会隐藏模型调用,也不会把缺失的语义分析当成安全证据。它会检查:
- 引用是否逐字来自原始事件;
- 时间顺序与实体范围是否一致;
- 结构化值是否有证据支持;
- 审查是否来自不同运行;
- 审查内容是否由 SHA-256 摘要绑定到原提案;
- 每个变化字段是否都被覆盖;
- 是否仍有未解决问题。
语义模型可以提出判断,机械检查与失败关闭由确定性核心执行;不同运行与哈希绑定本身不证明语义判断正确。当前项目的Hybrid 语义关系文档介绍了相关契约;它已随实现演进,不能逐字代表这份早期原型。
08 / ContextAdapt 现在还没有证明什么
我不想把一个 alpha 项目描述成通用安全层。这些实验的证据只支持一组具体能力:
- 发现动作依赖已经被取代的指令或状态;
- 发现受保护修改缺少当前权限;
- 在工具调用前以确定性规则执行
ALLOW/BLOCK; - 用同状态成对重放验证干预是否真的改变结果。
它还没有证明:
- 所有长时程 Agent 故障都来自陈旧上下文;
- 验证器能理解任意自然语言中的全部语义关系;
- 一条由恶意宿主伪造的事件轨迹可以被自动识破;
- 当前受控实验的收益能直接外推到所有模型、框架和生产任务;
- 只要装上 ContextAdapt,Agent 就会“安全”。
特别是,事件轨迹仍然是宿主提供的可信记录。验证器可以检查内部一致性,却不能凭空认证一个被伪造的历史。
09 / 一个更准确的问题
过去我们常问:Agent 还记得多少?
接下来也许应该多问一句:
在它真正动手之前,我们能否看见这个动作依据了什么,并确认那些依据此刻仍然成立?
长上下文、检索、摘要、外部记忆和压缩都很重要。它们帮助 Agent 形成更好的计划。但计划一旦跨越时间继续存活,就需要一个执行时的事实检查:世界有没有变,权限有没有变,旧证据有没有被替代。
The plan was valid. The world had changed.
ContextAdapt 想做的,就是在旧计划碰到真实世界之前,给系统最后一次说“不”的机会。
参考资料与实验记录
近期研究
- LOCA-bench: Benchmarking Language Agents Under Controllable and Extreme Context Growth
- ContextBench: A Benchmark for Context Retrieval in Coding Agents
- CoMem: Context Management with A Decoupled Long-Context Model
- ACM: Agentic Context Management for Long Horizon Tasks
- Active Context Compression: Autonomous Memory Management in LLM Agents
- Toward Reliable Context Compression for Long-Horizon Agents: An Empirical Study of Execution Instability
项目实验记录与实现文档
超长显式事实检索、隐藏时间与实体冲突、故障锚点与同状态成对重放这三组数据,来自 ContextAdapt 的内部实验记录。本文保留了结果与限制,但未提供完整记录的公开版本,读者目前无法仅凭本文独立检查这些实验。
以下链接固定到同一仓库提交,避免后续更新改变所引用内容。其中,执行器报告记录历史验证;其余文档描述该提交中的项目实现,不代表它们与早期 Python 原型完全相同。