
Anthropic 工程团队最近发了一篇文章,题目叫《Effective harnesses for long-running agents》。
文章讨论的重点不在模型参数,也不在 prompt 技巧,而是一个更实际的问题:
当一个 Agent 需要连续工作几个小时,甚至跨很多个上下文窗口(context window)时,怎么才能不把项目越做越乱。
只要任务稍微长一点,Agent 很快就会暴露出几种典型问题:
• 一次做太多,想一口气把整个项目做完
• 做到一半上下文断掉,下一轮接手时只剩一地半成品
• 已经做出一点东西后,下一轮很容易过早宣布“差不多完成了”
• 没做真正的端到端验证,就把功能标成 done
这篇文章把问题放回到了 harness。 长时 Agent 的问题,本质上是跨 session 交接的问题。
每一个新的 session,都是一个“刚来上班的人”。 如果没有明确的交接材料,它就只能靠猜。
Claude Agent SDK 本身已经有压缩整理(compaction),也有上下文管理能力。理论上看起来,好像 Agent 可以一直往下做。
但只靠这些还不够。
Anthropic 在内部做实验时发现,就算是很强的编码模型,面对一个高层级任务,比如“做一个 claude.ai 的克隆”,一旦跨多个上下文窗口,还是会掉进两个坑里:
第一类问题,是一次做太多。 模型会尝试把整个应用一口气做完,结果中途上下文耗尽,留下半套实现和一堆没说清楚的状态。
第二类问题,是过早收工。 后续 session 接手时,看见项目里已经有了页面、有了功能、有了提交,就很容易判断“差不多已经完成了”。
这两个问题叠在一起,长任务基本就跑不稳了。
所以文章的核心目标只有两个:
• 先把初始环境搭成一个适合分轮推进的状态
• 再让每一轮 session 都只做增量工作,并把状态交接清楚
整个 harness 分成两个角色:
只在第一轮运行。
它不负责长期开发,而是负责把后面要用的环境和交接材料先搭起来。文章里提到的几个产物包括:
• init.sh
• claude-progress.txt
• feature list
• 初始 git commit
这一步的作用,是先把后面几十轮 session 都要依赖的底子搭起来。
后面每一轮 session 都用这个角色。
它不再负责重新理解整个项目,而是按固定流程做增量推进:
• 先读交接材料
• 先确认当前环境是不是好的
• 只挑一个 feature 做
• 做完留下 commit 和进度记录
文章里有一句很关键的话:
关键不是让 agent 记住全部上下文,而是让它能快速理解当前工作状态。
这也是整篇文章的中心。

Anthropic 的做法是让 initializer agent 先把用户最初的需求展开成一份完整的 feature list。
在他们举的 claude.ai 克隆例子里,这份清单最后超过 200 个功能项。每一项都带步骤描述,而且一开始统一标成 passes: false。
这一步直接解决了两个问题:
• Agent 不会再凭感觉判断“项目差不多做完了”
• 每一轮 session 都知道接下来还有哪些具体功能没通过
文章里还专门提到,他们最后选了 JSON,而不是 Markdown。原因很简单:模型更不容易随意改坏 JSON 结构,也更不容易擅自删需求。
很多人给 Agent 留任务清单时,喜欢写成长篇 Markdown。对人类很友好,但对会反复编辑文件的模型来说,结构化格式其实更稳。
这是文里另一个很关键的约束。
前面那些失败案例,本质上都跟“做太多”有关。 所以 Anthropic 最后干脆把规则写死:每一轮 coding agent 只做一个 feature。
因为一旦把粒度压到“每轮只推进一个点”,session 的目标就会清楚很多:
• 开始前知道自己要补哪一项
• 过程中不容易发散
• 结束时更容易留下干净状态
换成更通俗的话,就是:
不要让 Agent 负责“完成产品”,而是让它负责“完成这一轮交接前的一个小目标”。
Anthropic 让 coding agent 在每轮结束前做两件事:
• 写 git commit
• 更新 claude-progress.txt
这两个东西分工很明确。
git commit 负责记录代码状态。
claude-progress.txt 负责记录这一轮到底做了什么、修了什么、还剩什么。
这样做的好处是,下一轮 session 开始时,不需要在目录里乱翻,也不需要猜上一轮到底做到哪。 它只要读 progress 文件,再看几条 git log,就能快速接上。
大家平时会要求 Agent “写完记得提交”,但很少要求它把对下一轮有用的状态说明也写下来。
如果没有这层交接文本,下一轮 session 往往还是要花很多 token 重新调查现场。

文章里专门列了一组 coding agent 每轮开始时要做的事情:
1. 跑 pwd
2. 读 progress 文件
3. 读 feature list
4. 看 git log
5. 找 init.sh
6. 启动开发环境
7. 先做一次基础验证
不是一上来就继续写代码,而是先确认:
• 我现在在哪个目录
• 上一轮做到了哪
• 当前基础功能是不是还活着
文章里甚至提到,在那个 claude.ai 克隆例子里,agent 每轮都会先把本地服务跑起来,再用浏览器自动化发一条消息,确认最基础的聊天流程还没坏掉。
因为如果项目已经处在一个坏状态里,继续往上加功能,通常只会让问题更乱。
这是文里另一条很重要的约束。
Anthropic 观察到,模型如果没有被明确要求,经常会把下面这些事情当成“已经测试过了”:
• 跑单元测试
• 用 curl 调一下开发服务器
• 看代码逻辑没问题
但这些都不等于真正的 end-to-end 验证。
在 Web app 这种场景里,他们发现一旦明确要求 Claude 使用浏览器自动化工具,按真实用户路径去点、去输、去看页面,效果会明显好很多。
这也是为什么文章里会反复提到 Puppeteer MCP。
当然,Anthropic 也没把这部分写得很乐观。文里明确承认,浏览器工具和视觉能力都还有盲区。比如浏览器原生 alert modal,Claude 通过 Puppeteer MCP 就看不到。
因为它说明文章想表达的不是“有了浏览器工具以后,长时 Agent 就稳了”,而是:
如果你想让长时 Agent 跑得更稳,端到端测试必须进入 harness。

表面上最显眼的是“initializer agent + coding agent”。
但更容易落到日常工作流里的,其实是后面这套工程纪律:
• 需求要外部化
• 进度要外部化
• 环境启动方式要外部化
• 每轮开始先重新确认现场
• 每轮结束必须留下可交接状态
换句话说,长时 Agent 想跑稳,靠的是“让每一轮都能顺利接班”。
把这套思路放回 Claude Code、Codex、OpenClaw 这些工具的场景里,也很容易对上:
• 为什么很多长任务做到后面会越来越乱 因为没有稳定的交接文件
• 为什么下一轮 session 总要先花很多时间调查现场 因为上轮没有留下结构化状态
• 为什么 Agent 经常做着做着就宣布完成 因为没有一份独立于当前上下文的 feature checklist
它没有把问题继续往模型能力上推,而是老老实实回到 harness 设计。
Anthropic 在文末也留了几个很清楚的边界。
第一,今天这套方法主要还是围绕全栈 Web app 开发验证出来的。 是不是能无缝迁到别的长任务场景,比如科研或金融建模,文章给出的说法仍然是“有可能”,不是“已经证明”。
第二,单一通用 coding agent 是否就是最优解,文章自己也没有下定论。 它明确提到,多 agent 架构也许会做得更好,比如:
• testing agent
• QA agent
• cleanup agent
第三,浏览器自动化和视觉识别仍然不是完整解法。 有些 bug 类型,今天的工具链还是会漏。
所以这篇文章更适合被理解成:
一套已经在工程里验证过、能明显提升长时 Agent 稳定性的 harness 设计。
它还不是终局,但已经足够具体。
如果你平时也在跑长任务 Agent,这篇文章最后留下来的,更多会是下面这几个外部化对象:
• feature list
• progress file
• init.sh
• git commit
• 每轮固定的开工检查
它们合在一起,才是长时 Agent 能跨很多个上下文窗口往前走的基础。
原文标题:Effective harnesses for long-running agents
发布于:2025-11-26
来源:Anthropic Engineering