ContextAdapt · Research note

计划没有错,世界已经变了

为什么长时程 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 200K5/66/61/6
Raw 400K2/62/64/6
Raw 900K2/62/64/6
从 900K 轨迹提取的当前状态6/66/60/6

表中 K 是原始轨迹的名义档位;规范化后输入已缩短,这里只评分动作 JSON,未执行写入。在相同状态哈希下,四个失败案例转为成功,没有反向退化。这组数据同样来自项目内部实验记录,完整轨迹与方法记录尚未随本文公开。

这不是简单的“记忆丢失”。更接近的描述是:正确事实仍在输入中,输出却采用了错误时间、实体或来源对应的值。

而且,单纯调整信息顺序也不够。在同一报告的等内容、仅顺序变化实验中,顺序改变了本次样本的错误计数和形态;但在 71 个有效实验单元里,六种看似合理的排列没有一种做到全对,每一种都至少出现过一次错误。排序是风险杠杆,不是安全机制。

05 / 从故障归因到同状态成对重放

如果一次失败真的是上下文造成的,那么修复上下文之后,从同一个环境状态继续,结果应该发生可重复的变化。否则,我们可能只是把工具故障、环境差异或随机波动错算成“上下文问题”。

因此,我们做了一组更接近诊断流程的受控实验:

  1. 从失败轨迹里定位一段高摩擦区间;
  2. 冻结环境状态与任务目标;
  3. 分别向 Agent 提供原始轨迹尾段、结构化近期状态、摘要加近期状态;
  4. 成对执行,并用独立结果判断上下文干预是否改变了行为;
  5. 加入工具故障对照,避免把不可用工具误判为上下文因果。

初始实验含 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 想做的,就是在旧计划碰到真实世界之前,给系统最后一次说“不”的机会。


参考资料与实验记录

近期研究

  1. LOCA-bench: Benchmarking Language Agents Under Controllable and Extreme Context Growth
  2. ContextBench: A Benchmark for Context Retrieval in Coding Agents
  3. CoMem: Context Management with A Decoupled Long-Context Model
  4. ACM: Agentic Context Management for Long Horizon Tasks
  5. Active Context Compression: Autonomous Memory Management in LLM Agents
  6. Toward Reliable Context Compression for Long-Horizon Agents: An Empirical Study of Execution Instability

项目实验记录与实现文档

超长显式事实检索、隐藏时间与实体冲突、故障锚点与同状态成对重放这三组数据,来自 ContextAdapt 的内部实验记录。本文保留了结果与限制,但未提供完整记录的公开版本,读者目前无法仅凭本文独立检查这些实验。

以下链接固定到同一仓库提交,避免后续更新改变所引用内容。其中,执行器报告记录历史验证;其余文档描述该提交中的项目实现,不代表它们与早期 Python 原型完全相同。