posts/agent-context-engineering.md
Agent 长任务总跑偏,状态管理才是保险
让 Agent 修一个跨文件 Bug,最让人崩溃的时刻通常不是它报错。
而是它跑了二十几轮,读过半个仓库,改了三个文件,最后一本正经地开始解决你两小时前已经否掉的方案。原来的验收条件没了,失败过的尝试没了,连这次到底是修权限问题还是修缓存问题都变得含糊。
很多人这时候会盯着上下文窗口,觉得 200K、1M 还不够就再换个更大的模型。好家伙,窗口变大当然有用,但它解决不了一个更朴素的问题,任务本身到底存在哪里。
如果目标、约束、已验证的事实和下一步,全都只躺在聊天记录里,它们迟早会老去,被工具输出淹没,被摘要压扁,或者在一次新会话里直接蒸发。长任务 Agent 不是一个记忆力竞赛,它更像一个不停读写状态的程序。
这几天看到一篇关于 Agent harness 的梳理,里面把长任务常见的两种翻车说得很直白,上下文溢出和目标丢失。harness 这个词听着有点硬,其实就是给模型搭脚手架的那层工程,管工具、文件、会话、状态和恢复,不管模型参数本身。
我更愿意把它翻成一句更接地气的话,模型负责想下一步,harness 负责别让它把上一页忘得一干二净。

大窗口不是更大的抽屉
为什么窗口一大,Agent 还是会跑偏。
因为上下文不是抽屉,东西塞进去不等于模型会一直记得。Chroma 的 Context Rot 报告评测过多种模型,输入变长后,连简单的检索任务也会越来越不稳定。Anthropic 对这个现象的解释很有意思,token 越多,注意力要处理的关系越多,有限的注意力预算就被摊薄了。
这和我们看一个塞满临时文件、日志和截图的项目目录有点像。文件都在,没错。可你刚要定位那个 auth bug 时,第一反应未必能找到最关键的那一份。
长任务把这件事放大得很凶。Manus 在公开材料里提到,一个典型任务可能要走约 50 次工具调用,输入和输出 token 的比例接近 100 比 1。Agent 每读一个文件、跑一次测试、拿到一段日志,都在给上下文续杯。到后面,原始目标往往被挤到窗口中段。
那一段最危险。它还在,但不像刚刚说过那样显眼。
所以别把“上下文还没满”当成安全线。真正要问的是,当前窗口里有没有只为这一步服务的噪音,任务的关键状态有没有一个不依赖历史消息的落点。
先让不重要的东西别进来
长任务的第一个动作,不是写一个很会总结的 prompt,而是控制输入。
LangChain Deep Agents 的默认策略给了两个挺具体的数。工具返回超过 20,000 token 时,完整内容放进文件系统,消息里只留路径和前十行预览。会话占到窗口 85% 时,旧的写入和编辑调用会被改成指针,因为文件的完整内容已经在磁盘上。
这个顺序值得琢磨。先卸载,再压缩。
很多 Agent 一看到日志就把它全塞回对话,仿佛模型正在替我们保存一份永不丢失的备份。其实那只是把检索问题伪装成了阅读问题。几万 token 的构建日志,大多数时候只需要保留失败命令、错误位置、环境差异和指向完整日志的路径。其余内容让文件系统拿着就行。
Claude Code 的做法也很像。自动记忆有大小限制,MCP 工具默认先露出名字,完整 schema 用到时再取。它的官方上下文窗口示例里,一个研究子 Agent 读了 6,100 token 文件,最后只把 420 token 的结论交给父 Agent。
这不是省 token 的小技巧,而是在保护主任务的注意力。
你让一个子 Agent 花时间翻资料、跑搜索、看六份文档,它可以把辛苦活做完,再交回一个带文件路径、结论和不确定项的短交接。父 Agent 不需要重看全过程,只需要知道哪些事实已经确认,哪些地方还要查。厉害了,这才是多 Agent 真正有价值的地方,不是把一个任务切成十份然后祈祷它们在群聊里自行领悟。
如果你正在搭自己的工作流,可以先做一个很土但好用的规定,任何超过阈值的工具结果都落盘,回到上下文的只允许有摘要、可搜索路径和一行用途说明。阈值不必照搬 20,000 token,重点是它必须存在,而且能被日志和评测调整。
压缩时,保住的是任务契约
输入控制仍不够,压缩总会发生。
压缩不是把旧对话改短这么简单。它是在替下一段会话写交接文档。写得好,Agent 能接着做。写得差,它就会自信地从岔路口冲出去。
Claude Code 在压缩后会重新读取最近修改的文件,重新加载相关规则和已调用的 skill。它的文档也明确提醒,早期对话里的细节可能丢失,所以持久规则应该放到项目根目录的 CLAUDE.md,而不是靠聊天历史硬扛。
Deep Agents 的摘要把会话意图、已产生的工件和下一步单独放进字段。这个结构特别重要。普通摘要很容易写成“已经分析了项目并修改了部分代码”,看起来很完整,下一轮却不知道改了哪个文件、哪条约束不能碰、测试为什么没过。
别小看这种差别。摘要只要丢掉一次“不能修改 public API”或“用户已经否决方案 B”,后面的每一步都可能在错误的地基上越走越远。
OpenAI 的 Responses API 把压缩放到了服务端,返回一个需要原样带进下一次调用的压缩项。Claude 的开发平台也允许定制压缩指令。两边都在提醒同一件事,压缩提示不是一个顺手填的配置,它是运行时的契约。
我建议把每次压缩后的交接内容写成固定结构,不用花哨:
任务目标
不可违反的约束
当前阶段
已完成并验证的动作
失败尝试与原因
已修改的文件和关键路径
尚未确认的事实与来源
下一步唯一动作
这里最容易漏的是“失败尝试与原因”。很多 Agent 不是能力不够,是重启后又去撞了一遍同一面墙。错误日志可以留在文件里,但失败原因要留在状态里。一个写明“迁移方案因生产表锁风险被否决”的字段,往往比十页日志更值钱。

Todo 不是仪式,它是一段会更新的状态
很多人看 Todo 会觉得有点原始。都 2026 年了,难道还要让一个大模型反复读待办清单。
但这个原始动作有个很实际的作用。Manus 会维护并重写 todo.md,每一步勾掉已完成项。目标被反复放到上下文后部,模型更容易在当前注意力范围内看见它。消息历史会慢慢远去,短小的任务文件却可以每隔几步重新读回来。
这不是说所有任务都该挂 Todo。LangChain 在 2026 年 7 月发布的 Deep Agents v0.7 里,反而把默认的 write_todos 改成可选,因为他们在三类任务评测里看到,关闭待办时 reward 略好,成本也更低。它仍建议在长多步骤任务、较弱模型或需要展示进度的界面里启用。
有点子牛逼的地方正在这儿,工程上最靠谱的答案经常不是永远打开,也不是一刀切地关掉,而是把机制和任务类型绑起来。
一条能在十分钟内完成的格式调整,没必要每轮都读一遍计划。一个要跨多个服务、持续跑测试、可能经历压缩和恢复的 Bug 修复,Todo 就不再是展示进度的便利贴,它是状态恢复点。
更进一步,Todo 不应该只写“修复登录问题”。那是一句愿望,不是状态。它最好包含可以判定的阶段,例如复现是否完成、根因是否有证据、修改是否过测试、风险是否已复核。只要任务状态还可以靠一句笼统口号描述,它就还没真正被建模。
记忆也要交房租
状态要持久化,可持久化的东西也会反过来占预算。
Claude Code 会在压缩后从磁盘重新注入 CLAUDE.md 和自动记忆。Amazon Bedrock AgentCore Memory 能存事件,并通过提取策略把它们变成后续可检索的记忆。这里有个很容易踩的坑,AWS 的说明里提到,如果没有配置提取策略,原始事件虽然存下来了,却不会自动形成可用的检索结果。
存了,不等于下次找得到。好家伙,这和把每个会议录屏都丢进网盘,然后一年后靠脑内全文检索找结论,差不多。
更麻烦的是,长期记忆不是免费的。原文引用 ETH Zurich 的研究,LLM 自动生成的仓库上下文文件在两个基准上增加了 20% 和 23% 的推理成本,开发者自己提交的文件最高也增加了 19%。Claude Code 的建议很克制,CLAUDE.md 保持在 200 行以内,其它资料放进按路径加载的规则或 skill。
这里有一个很朴素的分层办法。
项目永远成立的约束,放常驻规则里,例如构建命令、代码规范、权限红线。当前任务独有的目标和进度,放任务状态文件里。长日志、大文档、截图和工具原始返回,落进可搜索工件库。每次恢复任务时,只加载前两层和真正相关的第三层。
别把记忆做成另一个无底洞。能被检索到的,不必常驻。能从路径再读的,不必反复塞回 prompt。
你的 Agent 到底有没有扛住长任务
最后这一步最容易被跳过,因为演示里它总是看着挺能干。
一个 Agent 能顺利完成十分钟任务,不代表它经得起压缩。一个 Agent 能在第一次跑通,不代表它在恢复后还知道自己为什么这么做。
LangChain 的做法很对味,他们会故意在任务中途触发摘要,检查 Agent 是否还在朝原目标推进,也测试被摘要掉的事实能不能靠文件搜索找回来。为了比较不同提示,他们甚至把压缩阈值降到窗口的 10% 到 20%,强行制造恢复场景。
这才是该测的东西。别只看它最后有没有给出一段看似正确的代码,还要看压缩前后,目标有没有变,失败路径有没有被重复踩,先前确认的约束有没有被悄悄删掉。
可以从一个很小的回归用例开始。让 Agent 完成一次跨文件修复,在中途注入冗长日志并强制压缩,然后检查四件事,是否仍引用原始验收条件,是否还认识被修改的文件,是否能指出上次失败原因,是否只执行状态文件写出的下一步。
四项里错一项,都不是“模型偶尔抽风”这么简单。那是状态没有被显式管理。
长任务 Agent 最终不是靠记住一切活下来的。它靠的是忘掉不重要的东西以后,仍能准确找回目标、约束、证据和下一步。
窗口当然重要,模型当然重要。但它们都不该是唯一的保险。
你现在的 Agent 工作流里,最容易在压缩后消失的那一行状态是什么?
参考资料
AWS 自主云端编码 Agent 设计指南 LangChain Deep Agents 的上下文管理 Claude Code 上下文窗口文档 Anthropic 的上下文工程指南 OpenAI Responses API compaction