长程交接
随着 AI Agent 能力变强,开发者越来越希望让它们承担需要数小时甚至数天完成的复杂任务。但要让 Agent 在多个上下文窗口之间持续、稳定地推进工作,仍然是一个开放问题。
长程 Agent 的核心挑战是:它必须在离散会话中工作,而每个新会话开始时都没有之前发生过什么的记忆。可以把它想象成一个轮班制软件项目:每个新工程师上班时,都完全不知道上一班做了什么。上下文窗口有限,大多数复杂项目又无法在单个窗口里完成,因此 Agent 需要一种机制,把多个编码会话连接起来。
Anthropic 的方案是一个两部分 Harness:第一次运行时使用 initializer agent 搭建环境;后续每次运行使用 coding agent 增量推进,并为下一次会话留下清晰产物。
长程 Agent 的问题
Claude Agent SDK 是一个通用 Agent Harness,适合编码以及其他需要模型使用工具、收集上下文、规划和执行的任务。它具备 compaction 等上下文管理能力,理论上可以让 Agent 在不耗尽上下文窗口的情况下继续工作。
但 compaction 本身并不够。即使是前沿编码模型,如果只给它一个高层 prompt,例如“做一个 claude.ai 克隆”,并让它在 Claude Agent SDK 上跨多个上下文窗口循环运行,通常也无法直接做出生产质量的 Web 应用。
Anthropic 观察到两类主要失败:
| 失败模式 | 表现 |
|---|---|
| 过度雄心 | Agent 试图一次性完成整个应用,常常在某个功能做到一半时耗尽上下文,留下半成品和缺失的交接信息。 |
| 过早宣告完成 | 项目进行到后期时,某个新 Agent 实例看到已有进展,就误以为整个任务已经完成。 |
这把问题拆成两部分:
- 先建立一个初始环境,为用户 prompt 所需的全部功能打好基础,让 Agent 能按步骤、按功能推进。
- 每个后续 Agent 都应该朝目标增量前进,并在会话结束时把环境留在干净状态。
这里的“干净状态”指接近可以合并到主分支的代码:没有重大 bug,代码有序、文档清楚,下一位开发者可以直接开始新功能,而不需要先清理无关混乱。
两部分方案
Anthropic 在内部实验中使用了两个角色。这里称它们为不同 Agent,是因为它们使用不同的初始用户 prompt;除此之外,系统 prompt、工具集合和整体 Harness 都是相同的。
Initializer Agent
第一次会话使用专门的 initializer prompt,让模型搭建未来 coding agent 所需的环境。关键产物包括:
init.sh:用于启动开发环境的脚本,例如安装依赖、启动开发服务器。- 功能清单:根据初始需求扩展出的完整端到端功能列表。
claude-progress.txt:记录 Agent 已完成工作的进度文件。- 初始 git commit:记录初始化阶段新增了哪些文件,作为后续工作的基线。
功能清单是这个方案的核心。为了避免 Agent 一次性做完整个应用,或过早认为项目已经完成,initializer 会把用户的高层需求展开成一份结构化功能文件。以 claude.ai 克隆为例,这可能意味着 200 多个功能,例如“用户可以打开新聊天、输入问题、按回车,并看到 AI 回复”。
所有功能一开始都标记为 failing,让后续 coding agent 能清楚看到“完整功能”到底包含什么。
{
"category": "functional",
"description": "New chat button creates a fresh conversation",
"steps": [
"Navigate to main interface",
"Click the 'New Chat' button",
"Verify a new conversation is created",
"Check that chat area shows welcome state",
"Verify conversation appears in sidebar"
],
"passes": false
}
Coding agent 只能通过修改 passes 字段来更新状态,不能删除或改写功能描述和测试步骤。Anthropic 还会使用非常明确的指令强调:删除或编辑测试是不可接受的,因为这可能导致功能缺失或存在 bug。
经过实验,他们选择用 JSON 保存这份清单,因为相比 Markdown,模型不太容易不恰当地修改或覆盖 JSON 文件。
Coding Agent
后续每个会话都使用 coding agent。它的目标不是一次做完所有事,而是每次只推进一个功能,并留下结构化更新。
增量推进是解决“过度雄心”的关键。Agent 一次只做一个功能,完成后必须验证,再进入下一个功能。
但只做增量还不够。模型还必须在改完代码后把环境留在干净状态。Anthropic 发现,最有效的方式是要求模型:
- 用描述清楚的 git commit 提交进度。
- 在进度文件中写下本轮做了什么。
- 必要时用 git 回滚错误修改,恢复到上一个可工作的代码状态。
这样可以避免下一轮 Agent 花大量时间猜测之前发生了什么,也避免每次都先修复基础应用。
环境管理
长程 Agent 工程交接的关键,不是让模型“记住更多”,而是把跨会话所需的信息外化到环境里,让每个新会话都能快速接上。
功能清单
功能清单要把高层需求拆成可验证的端到端行为。它既定义了“还剩什么”,也定义了“怎样才算完成”。
这个文件解决两类问题:
- 防止 Agent 一次性尝试完成整个应用。
- 防止后续 Agent 看到已有进展后误以为项目完成。
它也把成功标准固定下来。后续 Agent 只能标记某项是否通过,不能改写测试本身。
增量进展
有了初始环境后,coding agent 每次只选择一个未完成的高优先级功能。完成后,它要通过测试、更新进度文件、提交 git。
这种模式会让单次会话看起来更慢,但总体上更容易收敛。因为每轮会话都在一个已知可工作的状态上前进,并把新的可工作状态留给下一轮。
测试
Anthropic 还观察到一个重要失败模式:Claude 容易在没有充分测试的情况下把功能标记为完成。没有明确提示时,它可能会改代码,也可能运行单元测试或用 curl 请求开发服务器,但仍然没有发现功能端到端不可用。
在 Web 应用场景中,只要明确要求 Claude 使用浏览器自动化工具,并像真实用户一样测试,它通常能更好地验证功能端到端是否工作。
提供这类测试工具会显著提升表现,因为 Agent 能发现仅从代码层面不明显的 bug。
不过,问题并没有完全消失。Claude 的视觉能力和浏览器自动化工具本身都有边界。例如,通过 Puppeteer MCP,Claude 看不到浏览器原生 alert modal,因此依赖这类 modal 的功能更容易出问题。
如何快速接上工作
在上述环境准备好后,每个 coding agent 开始时都会被要求执行一组固定步骤来定位当前状态。这些步骤很基础,但很有用:
- 运行
pwd,确认当前工作目录。Agent 只能编辑这个目录下的文件。 - 阅读 git log 和进度文件,了解最近做了什么。
- 阅读功能清单,选择优先级最高且尚未完成的功能。
Initializer agent 还应该写好 init.sh,让后续会话不需要重新摸索如何运行项目。Coding agent 在实现新功能前,应先运行 init.sh,启动开发服务器,并做一次基础端到端测试。
以 claude.ai 克隆为例,Agent 每次开始都会启动本地开发服务器,然后通过 Puppeteer MCP 新建聊天、发送消息、接收回复。这样它能迅速发现应用是否已经处于损坏状态,并先修复已有问题。如果它跳过这一步直接开始新功能,很可能会让问题更严重。
一个典型会话开头会像这样:
[Assistant] 我会先确认当前目录和项目状态。
[Tool Use] bash - pwd
[Tool Use] read - claude-progress.txt
[Tool Use] read - feature_list.json
[Assistant] 接着检查最近的 git log。
[Tool Use] bash - git log --oneline -20
[Assistant] 现在检查是否有 init.sh,用它重启服务。
<启动开发服务器>
[Assistant] 然后进入应用,确认基础功能仍然正常。
<测试基础功能>
[Assistant] 基础功能正常后,再查看功能清单,选择下一个要实现的功能。
<开始实现新功能>
失败模式与对应方案
| 问题 | Initializer Agent 的行为 | Coding Agent 的行为 |
|---|---|---|
| Claude 过早宣告整个项目完成 | 根据输入规格建立结构化 JSON 功能清单,列出端到端功能描述 | 会话开始时读取功能清单,只选择一个未完成功能开始 |
| Claude 把环境留在有 bug 或进度未记录的状态 | 建立初始 git repo 和进度记录文件 | 开始时读取进度文件和 git log,并在开发服务器上跑基础测试;结束时写 git commit 和进度更新 |
| Claude 过早把功能标记为完成 | 建立功能清单 | 自行验证所有功能,只有经过仔细测试后才标记为 passing |
| Claude 花时间摸索如何运行应用 | 写出能启动开发服务器的 init.sh | 会话开始时读取并运行 init.sh |
未来工作
这项研究展示了一种长程 Agent 工程交接的可行方案,让模型能够跨多个上下文窗口持续增量推进。但仍然有一些开放问题。
最明显的问题是:跨上下文工作时,一个通用 coding agent 是否最好?还是多 Agent 架构会更好?例如,专门的 testing agent、quality assurance agent、code cleanup agent,可能能在软件开发生命周期的不同子任务上做得更好。
另外,这个 demo 主要针对全栈 Web 应用开发。未来需要把这些经验推广到其他领域。科学研究、金融建模等长程 agentic task,很可能也能应用其中一部分经验。
关键判断
这篇文章的核心不是“让上下文窗口无限变长”,而是把长程任务拆成一组可交接、可验证、可恢复的工程动作:
- 用 initializer agent 一次性搭好工作环境和成功标准。
- 用 coding agent 每轮只做一个功能,并留下干净状态。
- 用功能清单固定“完成”的定义。
- 用
claude-progress.txt和 git history 建立跨会话上下文桥梁。 - 用浏览器自动化等用户视角测试减少“看起来完成”的假阳性。
最有效的 Harness 不一定发明全新的 AI 工作流。它更像是在复制高效工程团队已经使用的实践:清晰交接、增量进展、可验证完成、干净移交。
来源
Effective Harnesses for Long-Running Agents — Justin Young, Anthropic, 2025.11。