<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
    <channel>
        <title>Context Engineering on AI博士 万戈</title>
        <link>https://www.yesmiracle.net/tags/context-engineering/</link>
        <description>AI博士万戈的技术博客，聚焦 Agentic AI、AI Infra 与 Agent Security，分享 AI 基础设施与工程落地实践。</description>
        <generator>Hugo -- gohugo.io</generator>
        <language>zh-cn</language>
        <managingEditor>admin@yesmiracle.net (万戈)</managingEditor>
        <webMaster>admin@yesmiracle.net (万戈)</webMaster>
        <lastBuildDate>Fri, 30 Oct 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://www.yesmiracle.net/tags/context-engineering/index.xml" rel="self" type="application/rss+xml" /><item>
        <title>长程运行的Agent如何保证不会陷入思维死局</title>
        <link>https://www.yesmiracle.net/post/20261030-context-inertia-long-running-agents/</link>
        <pubDate>Fri, 30 Oct 2026 00:00:00 +0000</pubDate>
        <author>admin@yesmiracle.net (万戈)</author>
        <guid>https://www.yesmiracle.net/post/20261030-context-inertia-long-running-agents/</guid>
        <description>&lt;img src="https://www.yesmiracle.net/post/20261030-context-inertia-long-running-agents/cover.svg" alt="Featured image of post 长程运行的Agent如何保证不会陷入思维死局" /&gt;&lt;p&gt;Anthropic 在研究自我复制能力的那篇报告里，顺手写了一个他们自己遇到的失败案例。一个 Qwen agent 花了几个小时在调包的版本问题，而实际的 bug 是它写的端点跟评测 API 不兼容。它反复在错误的地方找原因，从不回头。同一篇报告里写着这个模式的通用描述：agent 会对一个错误的想法产生执念（比如「这个 bug 为什么会出现」），然后一直追下去，而不是退回来重新判断。&lt;/p&gt;
&lt;p&gt;这不是模型不够聪明。这是一种正在被单独命名、并且正在被一批人各自独立地对着修的失败模式。&lt;/p&gt;
&lt;h2 id=&#34;它有个名字了context-inertia&#34;&gt;它有个名字了：context inertia&lt;/h2&gt;
&lt;p&gt;2026 年 10 月 14 日，Drew Breunig 给它取了个名字，叫 &lt;strong&gt;context inertia（上下文惰性）&lt;/strong&gt;，定义是：模型在心里已经认定了一个假设、一个子任务或一个目标，然后在证据说明该停下来或该改方向之后，继续追着它跑。&lt;/p&gt;
&lt;p&gt;他把这个失败模式看成两个老问题的叠加：一半是 context poisoning（一个错误进了上下文，然后被反复引用），一半是 context distraction（上下文长到模型过度关注上下文本身），再被一类模型特性放大，即前沿模型被训练得非常执着地去执行指令。他还专门解释了为什么大家是现在才集体撞上这件事：2025 年 6 月他写长上下文失效那篇时，能连续跑几十万 token 已经算运气好；今天是几天、几十亿 token 地跑。跑得足够久，惰性才有机会变成威胁。&lt;/p&gt;
&lt;p&gt;还有一个更怪的数字来自他引用的另一项工作。Tan 的团队测量发现，随着会话变长，agent 不只是过度聚焦，它的推理量本身在缩水：每轮的思考 token 掉了 75%，改动也越改越小。上下文里堆积的东西不只降低了想法的多样性，它直接降低了推理的产出。&lt;/p&gt;
&lt;p&gt;读到这个数字我才意识到，大家平时说的「上下文满了会变笨」，指的其实是一件比「变笨」更具体的事：模型变得不肯换路，而且越来越省着思考。&lt;/p&gt;
&lt;h2 id=&#34;被训练得执着同时也很容易被带偏&#34;&gt;被训练得执着，同时也很容易被带偏&lt;/h2&gt;
&lt;p&gt;这两件事看起来矛盾，但它们是同一套训练的产物。&lt;/p&gt;
&lt;p&gt;Breunig 说这批模型「很执着」，Simon Willison 形容某个模型时用的词更狠，叫 relentlessly proactive（不知疲倦地主动）。而执着正是厂商在追的一种品质，他给的说法是这既是优点也是双刃剑。同一个方向上还有一份研究值得提，Camassa 和 Derek Shiller 的论文《Do as I say, Not as I Do》测的是另一头：当上下文里反复出现跟指令矛盾的例子时，模型还能不能守住指令。Breunig 读那张矩阵图的结论是每个模型都受影响，规模小的模型在少数几个矛盾例子之后就有一半以上的时候跟着走，前沿模型需要多得多的例子，但最后也让步。&lt;/p&gt;
&lt;p&gt;两件事拼起来才说得通。模型被训练得执着，所以它认准一个假设就一直追；同时它又对上下文里出现的信号高度敏感，所以矛盾的例子、跑偏的中间结论、堆了很久的假设，都能把它带走。执着决定了它不肯回头，敏感决定了它一开始就容易跑偏。惰性正好长在这两件事的交界处。&lt;/p&gt;
&lt;h2 id=&#34;关键结论压缩治不了它&#34;&gt;关键结论：压缩治不了它&lt;/h2&gt;
&lt;p&gt;大多数人遇到上下文问题，第一反应是用 compaction（把历史摘要成一段更短的文本，然后从摘要继续）。这是现在几乎所有 agent 框架的默认动作。&lt;/p&gt;
&lt;p&gt;Breunig 的判断很直接：不管用。他引了 Fork-and-Flush 的实测结论，context inertia 在「周期性压缩对话历史」的条件下依然存在。&lt;/p&gt;
&lt;p&gt;他给了一个机制解释，这是整篇文章里我认为最关键的一句：几乎所有的压缩方法，目标都是延长可用上下文，同时保住既定任务和当前正在进行的工作。而「当前正在进行的工作」恰恰就是驱动模型过度聚焦的那个东西。你把一段跑偏的过程压缩成一段更短的跑偏的过程，它还是那段跑偏的过程。&lt;/p&gt;
&lt;p&gt;这个解释能站住，是因为它顺带解释了为什么压缩看起来有效但没解决问题：token 少了，成本降了，模型还在同一条路上。&lt;/p&gt;
&lt;h2 id=&#34;四个系统同时撞到同一堵墙&#34;&gt;四个系统，同时撞到同一堵墙&lt;/h2&gt;
&lt;p&gt;Breunig 列了四条各自独立走到同一个答案的工作，而且它们的模型覆盖面很杂，说明这不是某一家的毛病：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fork-and-Flush 跑的是 GPT-5.5 和 5.6&lt;/li&gt;
&lt;li&gt;SLA 跑的是 Codex 和 Claude Code&lt;/li&gt;
&lt;li&gt;Tan 的 Forgetting 用的是 DeepSeek&lt;/li&gt;
&lt;li&gt;Anthropic 的 Memento 驱动模型是 Qwen 和 GLM&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Tan 那条给出了最硬的数字。他的做法是让 harness 会忘记：把状态清掉，只把当前最好的那个解作为文件留在环境里。结果是对那些卡住的自动研究任务，能忘记的运行在接下来 30 个提案上多拿了 4.5% 到 9.2%；不能忘记的运行只多拿了不到 2%，而且成本最多是前者的两倍。他还观察到一个细节：四个人并行的那一组，每次「忘记」之后，思考量和改动幅度都会跳回去一下。&lt;/p&gt;
&lt;p&gt;所以「忘记」在这里不是省 token 的手段，它是一个能提升输出的动作。&lt;/p&gt;
&lt;h2 id=&#34;官方解法长什么样memento&#34;&gt;官方解法长什么样：Memento&lt;/h2&gt;
&lt;p&gt;Anthropic 的 Memento 就是给这个失败模式做的。它建在一个叫 Pi 的开源编程 agent 之上，执行起来只有三步：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;起一个 agent 实例，让它做到超时为止&lt;/li&gt;
&lt;li&gt;这个实例自己做简短笔记，超时后把「试过哪些策略、遇到哪些失败、性能如何」总结成一个小文档&lt;/li&gt;
&lt;li&gt;起一个新实例，它继承前一个的代码库和环境，外加上那份笔记&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;配置数字很朴素：每轮 1.5 小时，总共 6 小时，提示里只放大约 1k token 的信息（硬件规格加一个简单的采样分析脚本）。&lt;/p&gt;
&lt;p&gt;Breunig 对它的描述是我见过最准的：每过一个半小时，agent 写下一段短笔记，然后上下文被清空；环境保留着，它做过的所有工作都还在；但那段正在进行的对话没了，它得从一个全新的视角重新开始。&lt;/p&gt;
&lt;p&gt;值得留意的是 Anthropic 自己给这个 harness 加的注解：它不是一个普遍强效的 harness，他们预期小模型即使完全不靠 harness 也会随着能力提升而变强。这句话我在最后会回来讲。&lt;/p&gt;
&lt;h2 id=&#34;官方答案的另一半把状态从上下文里搬出去&#34;&gt;官方答案的另一半：把状态从上下文里搬出去&lt;/h2&gt;
&lt;p&gt;Memento 解决的是「怎么打断执念」，还有另一半问题是「断掉之后靠什么恢复」。Anthropic 在讲长程 agent 的 harness 时给了这半边的答案。&lt;/p&gt;
&lt;p&gt;他们的起点是一个比喻：长程 agent 就像分班干活的工程团队，每个新来的工程师对上一班发生了什么一无所知。他们的解法是两个角色配一套文件：第一个 session 用初始化的 prompt 搭好环境，产出 &lt;code&gt;init.sh&lt;/code&gt;、一个 &lt;code&gt;claude-progress.txt&lt;/code&gt; 进度日志、以及第一次 git 提交；之后每个 session 都只做增量，并且留下结构化的更新。让新 session 快速进入状态靠的是进度文件加 git 历史，agent 上来先读 git log 和进度文件，再挑一个最高优先级、还没做完的功能。&lt;/p&gt;
&lt;p&gt;这里有两句值得抄下来的官方原话。第一句是结论：compaction 不够用。第二句是证据：即使是像 Opus 4.5 这样的前沿编码模型，在 Claude Agent SDK 上不加额外结构地跨多个上下文窗口循环跑，只给一句「做一个 claude.ai 的克隆」，也做不出生产质量的网站。失败形态有两种，其中一种特别典型：agent 想一把梭完，结果实现做到一半上下文耗尽，留给下一个 session 一个做了一半、还没有文档的功能，然后下一个 session 只能猜发生了什么，花大量时间把基础应用重新弄跑起来。&lt;/p&gt;
&lt;p&gt;把 Memento 和这半边合起来看，原则是同一条：&lt;strong&gt;上下文是易失的工作区，环境才是持久的状态。&lt;/strong&gt; 上层的功夫都在一件事上，就是怎么把工作区里的东西及时转移成环境里的东西。Anthropic 最近在讲托管 agent 时也把这条讲成了架构原则，他们的说法是「session 不是 Claude 的上下文窗口」，session 是一个活在上下文窗口外面的上下文对象，模型通过一个取事件流的接口去查询它想要的那一段。&lt;/p&gt;
&lt;p&gt;平台层的三个机制也对应这三种转移方式。清工具结果最轻，默认在输入到 10 万 token 时触发，保留最近三组工具调用与结果，官方给的数字是在一个 100 轮的网页搜索评测里把 token 消耗砍掉 84%。记忆工具往 &lt;code&gt;/memories&lt;/code&gt; 目录写文件，在客户端执行，官方文档里的说法是它做的方向和清理正好相反：在信息被删掉之前先把重要的挪出去。服务端压缩则是把整段对话换成一个签名过的压缩块。Anthropic 自己给压缩加的警告是，压得太狠会丢掉细微但关键的上下文。&lt;/p&gt;
&lt;h2 id=&#34;六种修法各自治什么&#34;&gt;六种修法，各自治什么&lt;/h2&gt;
&lt;p&gt;Breunig 在 AGNTCon 那场讲里把修法收成了六件事，值得单独列一张表，因为它们是判断「你该动哪一层」的索引：&lt;/p&gt;
&lt;table&gt;
  &lt;thead&gt;
      &lt;tr&gt;
          &lt;th&gt;修法&lt;/th&gt;
          &lt;th&gt;治什么&lt;/th&gt;
          &lt;th&gt;代价&lt;/th&gt;
      &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
      &lt;tr&gt;
          &lt;td&gt;上下文增补&lt;/td&gt;
          &lt;td&gt;该有的信息没进来&lt;/td&gt;
          &lt;td&gt;引入噪音，可能变成 confusion&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;工具装载&lt;/td&gt;
          &lt;td&gt;一次暴露给模型的工具/技能太多&lt;/td&gt;
          &lt;td&gt;需要提前判断哪些用得上&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;上下文隔离&lt;/td&gt;
          &lt;td&gt;历史本身已经带偏&lt;/td&gt;
          &lt;td&gt;子 agent 缺少主线判断&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;上下文裁剪&lt;/td&gt;
          &lt;td&gt;旧的不再需要&lt;/td&gt;
          &lt;td&gt;可能剪掉后面会用到的东西&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;上下文卸载&lt;/td&gt;
          &lt;td&gt;信息该住在环境里而不是窗口里&lt;/td&gt;
          &lt;td&gt;恢复时要重新读一遍&lt;/td&gt;
      &lt;/tr&gt;
      &lt;tr&gt;
          &lt;td&gt;上下文摘要&lt;/td&gt;
          &lt;td&gt;窗口快满了&lt;/td&gt;
          &lt;td&gt;就是 compression，治不了惰性&lt;/td&gt;
      &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;表里的第三和第五行，才是对付惰性的正解。Breunig 给 harness 开发者的建议原文就是不只依赖 compaction，去看 context quarantine（让子 agent 带着空白历史进同一个环境）和 context offloading（把信息存到环境里，比如 Markdown 文件或数据库）。这个建议跟 Memento 的做法其实是同一件事：新实例加完整环境，本质上就是一次 quarantine，只不过切分点由时间触发。&lt;/p&gt;
&lt;p&gt;工具装载那一行他给了一个很具体的例子。有个企业团队发现自己的 agent 突然表现极差，最后查明原因是他们的软件在启动时给每个工程师加载了 600 个技能。工具清单本身就占上下文，而且它跟正在做的事冲突时，就是另一类失败。这也解释了为什么「把能用的工具都接上」通常不是个好主意。&lt;/p&gt;
&lt;h2 id=&#34;怎么判断它已经进了死局&#34;&gt;怎么判断它已经进了死局&lt;/h2&gt;
&lt;p&gt;有几个可以盯的信号，都是别人量出来过的，比「感觉它变笨了」可靠。&lt;/p&gt;
&lt;p&gt;看每轮的思考 token。Tan 的团队量到的是 75% 的下降，而且它伴随改动幅度变小。一个健康的长程运行里，思考量会有起伏；持续单调下降基本说明它在缩圈。&lt;/p&gt;
&lt;p&gt;看动作的重复性。Gemini 2.5 技术报告里描述的现象是 agent 开始重复自己历史里的动作，而不是合成新计划。判断方法是把最近若干轮的工具调用拿出来比对，如果是在同一批参数上反复试，那它已经在原地打转。&lt;/p&gt;
&lt;p&gt;看它有没有回头。惰性的定义里最要紧的一半是「在证据说明该停下之后继续追」。所以一个可操作的判断是问它一句「你现在这条路如果错了，另一个可能是什么」，如果它给出的备选明显很差或者干脆给不出来，说明上下文里只剩一个假设了。&lt;/p&gt;
&lt;p&gt;看上下文占用。Breunig 群里那句口头禅之所以好用，是因为它把抽象问题变成了一个可以直接读的数字。至于阈值，大模型的技术报告给了两个参照点，一个是 10 万 token 之后开始出现重复动作，一个是接近 20 万 token 时重置比较划算。&lt;/p&gt;
&lt;p&gt;这几个信号的价值在于它们都可以自动采集。惰性这件事你现在还很难用一个 loss 或一个分数去监控，但上面四项里的前三项都是日志里现成的字段。&lt;/p&gt;
&lt;h2 id=&#34;想自己动手就照这个顺序&#34;&gt;想自己动手，就照这个顺序&lt;/h2&gt;
&lt;p&gt;把上面这些收成一份能直接用的清单。它不是一个精确的调参方案，但顺序不该变。&lt;/p&gt;
&lt;p&gt;第一刀落在重置点上。在长程任务里，一个便宜的动作是到大约 20 万 token 附近就重置一次，而不是等它撞上限。Breunig 说在他的群聊里这已经成了固定的口头禅，模型行为看起来不对时，先问一句「你的上下文多满了」。多数时候这就够用。&lt;/p&gt;
&lt;p&gt;清空之前，笔记必须写。Memento 那份笔记的内容值得照抄：试过哪些策略、遇到了哪些失败、性能如何。要写策略和失败，不要写过程。过程是上下文里最占地方、也最先该被扔掉的部分。&lt;/p&gt;
&lt;p&gt;清空之后，恢复要靠环境。这就是 Anthropic 那一套进度文件加 git 历史的价值，它的目标是让新实例用最短的时间搞清楚「现在做到哪了」。一个可执行的判断标准是：如果任务清单、代码、测试结果和进度日志都在环境里，那么新实例丢掉的只有「刚才在想什么」，这是可以重建的；如果这些只存在于上下文里，那清空就等于抹掉全部工作。&lt;/p&gt;
&lt;h2 id=&#34;代价和陷阱&#34;&gt;代价和陷阱&lt;/h2&gt;
&lt;p&gt;清空不是免费的，有几笔账要提前认。&lt;/p&gt;
&lt;p&gt;压缩有安全代价。有一篇叫 Governance Decay 的工作（arXiv 2606.22528）专门研究这件事：上下文压缩会在你不知情的情况下把安全约束抹掉。这很好理解，如果压缩的默认目标是保住「正在进行的工作」，那护栏这种看起来不参与当前推进的信息，就是最先被丢掉的。重置同理，你把上下文扔了，附着在上下文上的规则也一起扔了。&lt;/p&gt;
&lt;p&gt;上下文管理不能让你变强，它让你换一种方式失败。前面那篇系统评测（arXiv 2606.29718）的结论值得重复一遍：压缩、裁剪、隔离这三类七个方法都能降低 premature termination，但代价是更多未完成的轨迹。指标好看不等于任务做完。&lt;/p&gt;
&lt;p&gt;摘要需要独立校验。Slipstream 那套异步压缩（arXiv 2605.08580）之所以有效，是因为它承认了「压缩后谁都不知道摘要对不对」这个前提。做法是让压缩器和 agent 继续在原上下文上跑同时进行，两边从同一份压缩前状态出发，于是 agent 继续做出来的推理就成了验证摘要的独立参照。结果是在 SWE-bench Verified 和 BrowseComp 上准确率最多提升 8.8 个百分点，端到端延迟最多降低 39.7%。如果你自己写压缩，最值得抄的就是这一点。&lt;/p&gt;
&lt;p&gt;还有一组对照支持「直接清空」。Min 等人在做长程 agent 的上下文压缩时设了一组同前缀的对照，一边继续，一边重置会话和搜索状态、只保留最好的候选项和分数。三次重复都倾向重置，包括单 agent 的情况。&lt;/p&gt;
&lt;p&gt;最后一笔账是隐性的，也是我认为最容易被低估的。重置这个动作，把失败成本从「模型跑偏了」转移到了「你的笔记写得好不好」上。笔记写得差，重置一次就丢一次进度，重置三次下来还不如让它继续跑偏。这属于记录纪律的范畴，而不是技术选型，它也没有标准答案。&lt;/p&gt;
&lt;h2 id=&#34;三个判断&#34;&gt;三个判断&lt;/h2&gt;
&lt;p&gt;写到这里，我想把几个结论摆明确。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;买更大的窗口不解决这个问题。&lt;/strong&gt; 一个来自厂商自己技术报告的证据：Gemini 2.5 的技术报告附录里写着，上下文明显超过 10 万 token 之后，agent 开始重复它历史里的动作，而不再合成新计划。注意这是在厂商大力宣传百万级窗口、甚至预告两百万级窗口的同期报告里写下的。窗口从 10 万涨到 100 万，中间没有发生任何跟惰性有关的机制变化。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;分界线是「工作区」和「状态」有没有分开。&lt;/strong&gt; 分开之后，窗口多大都不太要紧，因为关键状态本来就不住在窗口里；没有分开，窗口越大，堆在里面的错误越多，而且堆得越久越难退出来。前面那些系统的做法本质上都是同一件事的不同实现：把该活的留在环境里，把该扔的扔在上下文里。&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;下一个真问题是「有计划的遗忘」。&lt;/strong&gt; Breunig 的预测是，个人 agent 会不断累积记忆和技能，最后自己长出互相冲突的指令，所以有计划的遗忘会成为一个关键未解问题。这个判断我很同意，而且它的方向跟过去两年整个行业是反着的：这两年所有人都在建记忆，记忆层、向量库、知识图谱，很少有人认真设计过「什么该被删掉、什么时候删」。遗忘需要被当成一个功能来设计，不是清缓存。这也跟我之前拆过的 &lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261020-agent-memory-system-engineering/&#34; &gt;Agent 记忆系统&lt;/a&gt;那篇正好接上：那篇讲怎么把记忆建起来，这篇讲为什么必须给记忆配一个垃圾桶。&lt;/p&gt;
&lt;p&gt;最后一个观察，跟这一层为什么难做成生意有关。清空上下文、写一份短笔记、起一个新实例继承环境，这三个动作本身没有任何门槛，任何人今天下午就能实现。难的是决定&lt;strong&gt;什么必须被留下来、留下来多久、给谁看&lt;/strong&gt;。这属于策略与责任，跟模型能力不是一个方向的东西。回到 Anthropic 那句注解，他们说预期小模型即使完全不用 harness 也会随着能力变强而变强，那意味着 harness 的价值会随模型一起被重估。能被重估的是机制，不能被重估的是「谁来决定留下什么」。&lt;/p&gt;
&lt;p&gt;相关阅读：&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261020-agent-memory-system-engineering/&#34; &gt;《Agent 记忆系统设计》&lt;/a&gt;、&lt;a class=&#34;link&#34; href=&#34;https://www.yesmiracle.net/post/20261014-agent-fleet-operation-layer/&#34; &gt;《94 位顶级工程师，只有 8 位还在逐行读 Agent 的代码》&lt;/a&gt;&lt;/p&gt;
</description>
        </item>
        
    </channel>
</rss>
