一声棒喝,本不立文字
偏要著録,已是二义

Anthropic · 工程博客

长时间运行 agent 的有效 harness

Effective harnesses for long-running agents

二〇二六年五月八日 · 英文原文

Anthropic 介绍 Claude Agent SDK 的 long-running agent 方案:用 initializer agent 建环境、生成 JSON 功能清单与 init.sh,coding agent 单功能增量开发,借助 claude-progress.txt、git history、commit、Puppeteer MCP 跨 context window 衔接。作者 Justin Young。

随着 AI agent 能力增强,开发者越来越希望让它们承担复杂任务,这类任务需要持续数小时甚至数天的工作。然而,让 agent 在多个 context window 之间持续稳定推进,仍然是一个未解决的问题。

长时间运行的 agent 面临的核心挑战在于,它们必须在离散的 session 中工作,而每个新 session 开始时都不记得此前发生过什么。可以想象一个软件项目由轮班工作的工程师负责,每位新到岗的工程师都不记得上一班发生了什么。由于 context window 有限,而大多数复杂项目无法在单个 window 内完成,agent 需要一种方式来衔接不同 coding session 之间的断点。

我们开发了一个双重方案,使 Claude Agent SDK 能够在许多 context window 之间有效工作:一个 initializer agent 在首次运行时设置环境,另一个 coding agent 负责在每个 session 中进行增量推进,同时为下一个 session 留下清晰的 artifacts。你可以在配套的 quickstart 中找到代码示例。

Claude Agent SDK 是一个强大的通用 agent harness,擅长 coding,也适用于其他需要模型使用 tools 来收集 context、制定计划并执行的任务。它具备 context management 能力,例如 compaction,使 agent 能够在不耗尽 context window 的情况下处理任务。从理论上讲,在这样的设置下,agent 应该可以在任意长的时间内持续做有用的工作。

然而,compaction 并不足够。开箱即用时,即使是像 Opus 4.5 这样的 frontier coding model,在 Claude Agent SDK 上跨多个 context window 循环运行,如果只给它一个高层 prompt,例如“build a clone of claude.ai”,也无法构建出生产质量的 web app。

Claude 的失败表现为两种模式。首先,agent 往往会试图一次做太多事——本质上是尝试 one-shot 整个 app。这经常导致模型在实现到一半时耗尽 context,让下一个 session 接手一个半实现且没有文档说明的功能。随后 agent 必须猜测之前发生了什么,并花大量时间尝试让基础 app 重新运行起来。即便使用 compaction 也会发生这种情况,因为 compaction 并不总是能向下一个 agent 传递足够清晰的指令。

第二种失败模式通常出现在项目后期。在一些功能已经构建出来之后,后续的 agent instance 会查看周围状态,看到已经取得进展,然后宣布任务完成。

这将问题分解为两部分。首先,我们需要设置一个初始环境,为给定 prompt 所需的所有功能打下基础,使 agent 能够逐步、逐功能地工作。其次,我们应当 prompt 每个 agent 朝目标进行增量推进,同时在 session 结束时让环境保持 clean state。这里的 “clean state” 指的是适合合并到 main branch 的代码状态:没有重大 bug,代码有序且文档充分,总体而言,开发者可以轻松开始开发新功能,而无需先清理无关的混乱状态。

在内部实验中,我们用一个两部分方案解决了这些问题:

这里的关键洞见,是找到一种方式,让 agent 在从全新的 context window 开始时快速理解工作状态;这通过 claude-progress.txt 文件以及 git history 来实现。这些实践的灵感来自高效软件工程师日常所做的事情。

在更新后的 Claude 4 prompting guide 中,我们分享了一些 multi-context window workflow 的最佳实践,包括一种 harness 结构,它使用“针对第一个 context window 的不同 prompt”。这个“不同 prompt”要求 initializer agent 设置环境,并提供未来 coding agent 高效工作所需的全部必要 context。这里,我们将更深入介绍这类环境的一些关键组成部分。

为了解决 agent one-shot 一个 app 或过早认为项目完成的问题,我们 prompt initializer agent 编写一个全面的功能需求文件,对用户的初始 prompt 进行扩展。在 claude.ai clone 的例子中,这意味着超过 200 个功能,例如“用户可以打开一个新 chat,输入 query,按下 enter,并看到 AI response”。这些功能最初都被标记为 “failing”,这样后续 coding agent 就能清楚知道完整功能应是什么样子。

我们 prompt coding agent 只能通过修改 passes 字段的状态来编辑这个文件,并使用措辞强硬的指令,例如“It is unacceptable to remove or edit tests because this could lead to missing or buggy functionality.” 经过一些实验后,我们决定使用 JSON 来做这件事,因为相比 Markdown 文件,模型不太容易不恰当地修改或覆盖 JSON 文件。

在有了这个初始环境脚手架后,下一轮 coding agent 被要求一次只处理一个功能。这种增量式方法被证明对于解决 agent 倾向于一次做太多事的问题至关重要。

一旦开始增量工作,模型在完成代码修改后仍然必须让环境保持 clean state。在我们的实验中,诱导这种行为的最佳方式,是要求模型用描述性 commit message 将进展提交到 git,并在 progress file 中写下进展总结。这让模型能够使用 git 回滚不良代码变更,并恢复 code base 的可工作状态。

这些方法也提高了效率,因为它们消除了 agent 需要猜测此前发生了什么、并花时间尝试让基础 app 重新运行起来的必要。

我们观察到的最后一个主要失败模式,是 Claude 倾向于在没有适当测试的情况下将功能标记为完成。如果没有明确 prompt,Claude 往往会修改代码,甚至使用 unit test 或针对 development server 的 curl 命令进行测试,但无法意识到该功能并没有端到端工作。

在构建 web app 的场景中,一旦明确 prompt Claude 使用 browser automation tools,并像人类用户一样完成所有测试,Claude 在端到端验证功能方面总体表现良好。

为 Claude 提供这类 testing tools 显著提升了性能,因为 agent 能够识别并修复仅凭代码本身并不明显的 bug。

仍然存在一些问题,例如 Claude 的 vision 限制,以及 browser automation tools 的限制,使其难以识别每一种 bug。例如,Claude 无法通过 Puppeteer MCP 看到 browser-native alert modals,因此依赖这些 modals 的功能往往更容易出 bug。

在上述所有条件都具备后,每个 coding agent 都会被 prompt 按一系列步骤来了解当前状态,其中有些步骤相当基础但仍然有用:

这种方法在每个 session 中为 Claude 节省了一些 token,因为它不必自行弄清楚如何测试代码。让 initializer agent 编写一个 init.sh script 也很有帮助,该 script 可以运行 development server,并在实现新功能之前执行一个基础的端到端测试。

在 claude.ai clone 的例子中,这意味着 agent 总是先启动本地 development server,并使用 Puppeteer MCP 开始一个新 chat、发送一条 message、接收一个 response。这确保 Claude 能够快速识别 app 是否被留在了 broken state,并立即修复任何现有 bug。如果 agent 转而先开始实现新功能,很可能会让问题变得更严重。

基于这些设置,一个典型 session 会从以下 assistant messages 开始:

这项研究展示了 long-running agent harness 中一组可能的解决方案,使模型能够跨多个 context window 进行增量推进。然而,仍有一些开放问题。

最值得注意的是,目前仍不清楚单个通用 coding agent 在跨 context 工作时是否表现最佳,或者是否可以通过 multi-agent architecture 获得更好的性能。像 testing agent、quality assurance agent 或 code cleanup agent 这样的专门 agent,似乎有理由在软件开发生命周期中的子任务上做得更好。

此外,这个 demo 针对 full-stack web app development 做了优化。未来的方向是将这些发现泛化到其他领域。很可能其中部分或全部经验都可以应用于其他类型的 long-running agentic tasks,例如科学研究或 financial modeling。

作者:Justin Young。特别感谢 David Hershey、Prithvi Rajasakeran、Jeremy Hadfield、Naia Bouscal、Michael Tingley、Jesse Mu、Jake Eaton、Marius Buleandara、Maggie Vo、Pedram Navid、Nadine Yasser 和 Alex Notov 的贡献。

这项工作体现了 Anthropic 内部多个团队的共同努力,他们使 Claude 能够安全地进行 long-horizon autonomous software engineering,尤其是 code RL 和 Claude Code 团队。欢迎有兴趣参与贡献的候选人在 anthropic.com/careers 申请。

译自 Anthropic · 工程博客 · 录于 二〇二六年五月八日