Featured image of post 长程运行的Agent如何保证不会陷入思维死局

长程运行的Agent如何保证不会陷入思维死局

Anthropic 在研究自我复制能力的那篇报告里,顺手写了一个他们自己遇到的失败案例。一个 Qwen agent 花了几个小时在调包的版本问题,而实际的 bug 是它写的端点跟评测 API 不兼容。它反复在错误的地方找原因,从不回头。同一篇报告里写着这个模式的通用描述:agent 会对一个错误的想法产生执念(比如「这个 bug 为什么会出现」),然后一直追下去,而不是退回来重新判断。

这不是模型不够聪明。这是一种正在被单独命名、并且正在被一批人各自独立地对着修的失败模式。

它有个名字了:context inertia

2026 年 10 月 14 日,Drew Breunig 给它取了个名字,叫 context inertia(上下文惰性),定义是:模型在心里已经认定了一个假设、一个子任务或一个目标,然后在证据说明该停下来或该改方向之后,继续追着它跑。

他把这个失败模式看成两个老问题的叠加:一半是 context poisoning(一个错误进了上下文,然后被反复引用),一半是 context distraction(上下文长到模型过度关注上下文本身),再被一类模型特性放大,即前沿模型被训练得非常执着地去执行指令。他还专门解释了为什么大家是现在才集体撞上这件事:2025 年 6 月他写长上下文失效那篇时,能连续跑几十万 token 已经算运气好;今天是几天、几十亿 token 地跑。跑得足够久,惰性才有机会变成威胁。

还有一个更怪的数字来自他引用的另一项工作。Tan 的团队测量发现,随着会话变长,agent 不只是过度聚焦,它的推理量本身在缩水:每轮的思考 token 掉了 75%,改动也越改越小。上下文里堆积的东西不只降低了想法的多样性,它直接降低了推理的产出。

读到这个数字我才意识到,大家平时说的「上下文满了会变笨」,指的其实是一件比「变笨」更具体的事:模型变得不肯换路,而且越来越省着思考。

被训练得执着,同时也很容易被带偏

这两件事看起来矛盾,但它们是同一套训练的产物。

Breunig 说这批模型「很执着」,Simon Willison 形容某个模型时用的词更狠,叫 relentlessly proactive(不知疲倦地主动)。而执着正是厂商在追的一种品质,他给的说法是这既是优点也是双刃剑。同一个方向上还有一份研究值得提,Camassa 和 Derek Shiller 的论文《Do as I say, Not as I Do》测的是另一头:当上下文里反复出现跟指令矛盾的例子时,模型还能不能守住指令。Breunig 读那张矩阵图的结论是每个模型都受影响,规模小的模型在少数几个矛盾例子之后就有一半以上的时候跟着走,前沿模型需要多得多的例子,但最后也让步。

两件事拼起来才说得通。模型被训练得执着,所以它认准一个假设就一直追;同时它又对上下文里出现的信号高度敏感,所以矛盾的例子、跑偏的中间结论、堆了很久的假设,都能把它带走。执着决定了它不肯回头,敏感决定了它一开始就容易跑偏。惰性正好长在这两件事的交界处。

关键结论:压缩治不了它

大多数人遇到上下文问题,第一反应是用 compaction(把历史摘要成一段更短的文本,然后从摘要继续)。这是现在几乎所有 agent 框架的默认动作。

Breunig 的判断很直接:不管用。他引了 Fork-and-Flush 的实测结论,context inertia 在「周期性压缩对话历史」的条件下依然存在。

他给了一个机制解释,这是整篇文章里我认为最关键的一句:几乎所有的压缩方法,目标都是延长可用上下文,同时保住既定任务和当前正在进行的工作。而「当前正在进行的工作」恰恰就是驱动模型过度聚焦的那个东西。你把一段跑偏的过程压缩成一段更短的跑偏的过程,它还是那段跑偏的过程。

这个解释能站住,是因为它顺带解释了为什么压缩看起来有效但没解决问题:token 少了,成本降了,模型还在同一条路上。

四个系统,同时撞到同一堵墙

Breunig 列了四条各自独立走到同一个答案的工作,而且它们的模型覆盖面很杂,说明这不是某一家的毛病:

  • Fork-and-Flush 跑的是 GPT-5.5 和 5.6
  • SLA 跑的是 Codex 和 Claude Code
  • Tan 的 Forgetting 用的是 DeepSeek
  • Anthropic 的 Memento 驱动模型是 Qwen 和 GLM

Tan 那条给出了最硬的数字。他的做法是让 harness 会忘记:把状态清掉,只把当前最好的那个解作为文件留在环境里。结果是对那些卡住的自动研究任务,能忘记的运行在接下来 30 个提案上多拿了 4.5% 到 9.2%;不能忘记的运行只多拿了不到 2%,而且成本最多是前者的两倍。他还观察到一个细节:四个人并行的那一组,每次「忘记」之后,思考量和改动幅度都会跳回去一下。

所以「忘记」在这里不是省 token 的手段,它是一个能提升输出的动作。

官方解法长什么样:Memento

Anthropic 的 Memento 就是给这个失败模式做的。它建在一个叫 Pi 的开源编程 agent 之上,执行起来只有三步:

  1. 起一个 agent 实例,让它做到超时为止
  2. 这个实例自己做简短笔记,超时后把「试过哪些策略、遇到哪些失败、性能如何」总结成一个小文档
  3. 起一个新实例,它继承前一个的代码库和环境,外加上那份笔记

配置数字很朴素:每轮 1.5 小时,总共 6 小时,提示里只放大约 1k token 的信息(硬件规格加一个简单的采样分析脚本)。

Breunig 对它的描述是我见过最准的:每过一个半小时,agent 写下一段短笔记,然后上下文被清空;环境保留着,它做过的所有工作都还在;但那段正在进行的对话没了,它得从一个全新的视角重新开始。

值得留意的是 Anthropic 自己给这个 harness 加的注解:它不是一个普遍强效的 harness,他们预期小模型即使完全不靠 harness 也会随着能力提升而变强。这句话我在最后会回来讲。

官方答案的另一半:把状态从上下文里搬出去

Memento 解决的是「怎么打断执念」,还有另一半问题是「断掉之后靠什么恢复」。Anthropic 在讲长程 agent 的 harness 时给了这半边的答案。

他们的起点是一个比喻:长程 agent 就像分班干活的工程团队,每个新来的工程师对上一班发生了什么一无所知。他们的解法是两个角色配一套文件:第一个 session 用初始化的 prompt 搭好环境,产出 init.sh、一个 claude-progress.txt 进度日志、以及第一次 git 提交;之后每个 session 都只做增量,并且留下结构化的更新。让新 session 快速进入状态靠的是进度文件加 git 历史,agent 上来先读 git log 和进度文件,再挑一个最高优先级、还没做完的功能。

这里有两句值得抄下来的官方原话。第一句是结论:compaction 不够用。第二句是证据:即使是像 Opus 4.5 这样的前沿编码模型,在 Claude Agent SDK 上不加额外结构地跨多个上下文窗口循环跑,只给一句「做一个 claude.ai 的克隆」,也做不出生产质量的网站。失败形态有两种,其中一种特别典型:agent 想一把梭完,结果实现做到一半上下文耗尽,留给下一个 session 一个做了一半、还没有文档的功能,然后下一个 session 只能猜发生了什么,花大量时间把基础应用重新弄跑起来。

把 Memento 和这半边合起来看,原则是同一条:上下文是易失的工作区,环境才是持久的状态。 上层的功夫都在一件事上,就是怎么把工作区里的东西及时转移成环境里的东西。Anthropic 最近在讲托管 agent 时也把这条讲成了架构原则,他们的说法是「session 不是 Claude 的上下文窗口」,session 是一个活在上下文窗口外面的上下文对象,模型通过一个取事件流的接口去查询它想要的那一段。

平台层的三个机制也对应这三种转移方式。清工具结果最轻,默认在输入到 10 万 token 时触发,保留最近三组工具调用与结果,官方给的数字是在一个 100 轮的网页搜索评测里把 token 消耗砍掉 84%。记忆工具往 /memories 目录写文件,在客户端执行,官方文档里的说法是它做的方向和清理正好相反:在信息被删掉之前先把重要的挪出去。服务端压缩则是把整段对话换成一个签名过的压缩块。Anthropic 自己给压缩加的警告是,压得太狠会丢掉细微但关键的上下文。

六种修法,各自治什么

Breunig 在 AGNTCon 那场讲里把修法收成了六件事,值得单独列一张表,因为它们是判断「你该动哪一层」的索引:

修法 治什么 代价
上下文增补 该有的信息没进来 引入噪音,可能变成 confusion
工具装载 一次暴露给模型的工具/技能太多 需要提前判断哪些用得上
上下文隔离 历史本身已经带偏 子 agent 缺少主线判断
上下文裁剪 旧的不再需要 可能剪掉后面会用到的东西
上下文卸载 信息该住在环境里而不是窗口里 恢复时要重新读一遍
上下文摘要 窗口快满了 就是 compression,治不了惰性

表里的第三和第五行,才是对付惰性的正解。Breunig 给 harness 开发者的建议原文就是不只依赖 compaction,去看 context quarantine(让子 agent 带着空白历史进同一个环境)和 context offloading(把信息存到环境里,比如 Markdown 文件或数据库)。这个建议跟 Memento 的做法其实是同一件事:新实例加完整环境,本质上就是一次 quarantine,只不过切分点由时间触发。

工具装载那一行他给了一个很具体的例子。有个企业团队发现自己的 agent 突然表现极差,最后查明原因是他们的软件在启动时给每个工程师加载了 600 个技能。工具清单本身就占上下文,而且它跟正在做的事冲突时,就是另一类失败。这也解释了为什么「把能用的工具都接上」通常不是个好主意。

怎么判断它已经进了死局

有几个可以盯的信号,都是别人量出来过的,比「感觉它变笨了」可靠。

看每轮的思考 token。Tan 的团队量到的是 75% 的下降,而且它伴随改动幅度变小。一个健康的长程运行里,思考量会有起伏;持续单调下降基本说明它在缩圈。

看动作的重复性。Gemini 2.5 技术报告里描述的现象是 agent 开始重复自己历史里的动作,而不是合成新计划。判断方法是把最近若干轮的工具调用拿出来比对,如果是在同一批参数上反复试,那它已经在原地打转。

看它有没有回头。惰性的定义里最要紧的一半是「在证据说明该停下之后继续追」。所以一个可操作的判断是问它一句「你现在这条路如果错了,另一个可能是什么」,如果它给出的备选明显很差或者干脆给不出来,说明上下文里只剩一个假设了。

看上下文占用。Breunig 群里那句口头禅之所以好用,是因为它把抽象问题变成了一个可以直接读的数字。至于阈值,大模型的技术报告给了两个参照点,一个是 10 万 token 之后开始出现重复动作,一个是接近 20 万 token 时重置比较划算。

这几个信号的价值在于它们都可以自动采集。惰性这件事你现在还很难用一个 loss 或一个分数去监控,但上面四项里的前三项都是日志里现成的字段。

想自己动手,就照这个顺序

把上面这些收成一份能直接用的清单。它不是一个精确的调参方案,但顺序不该变。

第一刀落在重置点上。在长程任务里,一个便宜的动作是到大约 20 万 token 附近就重置一次,而不是等它撞上限。Breunig 说在他的群聊里这已经成了固定的口头禅,模型行为看起来不对时,先问一句「你的上下文多满了」。多数时候这就够用。

清空之前,笔记必须写。Memento 那份笔记的内容值得照抄:试过哪些策略、遇到了哪些失败、性能如何。要写策略和失败,不要写过程。过程是上下文里最占地方、也最先该被扔掉的部分。

清空之后,恢复要靠环境。这就是 Anthropic 那一套进度文件加 git 历史的价值,它的目标是让新实例用最短的时间搞清楚「现在做到哪了」。一个可执行的判断标准是:如果任务清单、代码、测试结果和进度日志都在环境里,那么新实例丢掉的只有「刚才在想什么」,这是可以重建的;如果这些只存在于上下文里,那清空就等于抹掉全部工作。

代价和陷阱

清空不是免费的,有几笔账要提前认。

压缩有安全代价。有一篇叫 Governance Decay 的工作(arXiv 2606.22528)专门研究这件事:上下文压缩会在你不知情的情况下把安全约束抹掉。这很好理解,如果压缩的默认目标是保住「正在进行的工作」,那护栏这种看起来不参与当前推进的信息,就是最先被丢掉的。重置同理,你把上下文扔了,附着在上下文上的规则也一起扔了。

上下文管理不能让你变强,它让你换一种方式失败。前面那篇系统评测(arXiv 2606.29718)的结论值得重复一遍:压缩、裁剪、隔离这三类七个方法都能降低 premature termination,但代价是更多未完成的轨迹。指标好看不等于任务做完。

摘要需要独立校验。Slipstream 那套异步压缩(arXiv 2605.08580)之所以有效,是因为它承认了「压缩后谁都不知道摘要对不对」这个前提。做法是让压缩器和 agent 继续在原上下文上跑同时进行,两边从同一份压缩前状态出发,于是 agent 继续做出来的推理就成了验证摘要的独立参照。结果是在 SWE-bench Verified 和 BrowseComp 上准确率最多提升 8.8 个百分点,端到端延迟最多降低 39.7%。如果你自己写压缩,最值得抄的就是这一点。

还有一组对照支持「直接清空」。Min 等人在做长程 agent 的上下文压缩时设了一组同前缀的对照,一边继续,一边重置会话和搜索状态、只保留最好的候选项和分数。三次重复都倾向重置,包括单 agent 的情况。

最后一笔账是隐性的,也是我认为最容易被低估的。重置这个动作,把失败成本从「模型跑偏了」转移到了「你的笔记写得好不好」上。笔记写得差,重置一次就丢一次进度,重置三次下来还不如让它继续跑偏。这属于记录纪律的范畴,而不是技术选型,它也没有标准答案。

三个判断

写到这里,我想把几个结论摆明确。

买更大的窗口不解决这个问题。 一个来自厂商自己技术报告的证据:Gemini 2.5 的技术报告附录里写着,上下文明显超过 10 万 token 之后,agent 开始重复它历史里的动作,而不再合成新计划。注意这是在厂商大力宣传百万级窗口、甚至预告两百万级窗口的同期报告里写下的。窗口从 10 万涨到 100 万,中间没有发生任何跟惰性有关的机制变化。

分界线是「工作区」和「状态」有没有分开。 分开之后,窗口多大都不太要紧,因为关键状态本来就不住在窗口里;没有分开,窗口越大,堆在里面的错误越多,而且堆得越久越难退出来。前面那些系统的做法本质上都是同一件事的不同实现:把该活的留在环境里,把该扔的扔在上下文里。

下一个真问题是「有计划的遗忘」。 Breunig 的预测是,个人 agent 会不断累积记忆和技能,最后自己长出互相冲突的指令,所以有计划的遗忘会成为一个关键未解问题。这个判断我很同意,而且它的方向跟过去两年整个行业是反着的:这两年所有人都在建记忆,记忆层、向量库、知识图谱,很少有人认真设计过「什么该被删掉、什么时候删」。遗忘需要被当成一个功能来设计,不是清缓存。这也跟我之前拆过的 Agent 记忆系统那篇正好接上:那篇讲怎么把记忆建起来,这篇讲为什么必须给记忆配一个垃圾桶。

最后一个观察,跟这一层为什么难做成生意有关。清空上下文、写一份短笔记、起一个新实例继承环境,这三个动作本身没有任何门槛,任何人今天下午就能实现。难的是决定什么必须被留下来、留下来多久、给谁看。这属于策略与责任,跟模型能力不是一个方向的东西。回到 Anthropic 那句注解,他们说预期小模型即使完全不用 harness 也会随着能力变强而变强,那意味着 harness 的价值会随模型一起被重估。能被重估的是机制,不能被重估的是「谁来决定留下什么」。

相关阅读:《Agent 记忆系统设计》、《94 位顶级工程师,只有 8 位还在逐行读 Agent 的代码》

By AI博士 万戈