长程交接

随着 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 实例看到已有进展,就误以为整个任务已经完成。

这把问题拆成两部分:

  1. 先建立一个初始环境,为用户 prompt 所需的全部功能打好基础,让 Agent 能按步骤、按功能推进。
  2. 每个后续 Agent 都应该朝目标增量前进,并在会话结束时把环境留在干净状态。

这里的“干净状态”指接近可以合并到主分支的代码:没有重大 bug,代码有序、文档清楚,下一位开发者可以直接开始新功能,而不需要先清理无关混乱。

两部分方案

长程 Agent 交接模式 初始化器创建制品 → 持久交接 → 编码 Agent 接手并更新 初始化器 Session 1 • 创建 init.sh • 生成功能清单 • 创建 claude-progress.txt • 初始 git 提交 一次性设置 上下文桥梁 Context Bridge • init.sh • feature-list.json • claude-progress.txt • git history 持久 · 可读取 编码 Agent Sessions 2..N • 读取进度 • 选择一个功能 • 实现 + 验证 • 提交 + 更新 一次一个功能 创建 读取 更新 每个 Session 自给自足 从持久制品读取、做增量工作、为下一个 Session 留下干净状态

Anthropic 在内部实验中使用了两个角色。这里称它们为不同 Agent,是因为它们使用不同的初始用户 prompt;除此之外,系统 prompt、工具集合和整体 Harness 都是相同的。

Initializer Agent

第一次会话使用专门的 initializer prompt,让模型搭建未来 coding agent 所需的环境。关键产物包括:

  1. init.sh:用于启动开发环境的脚本,例如安装依赖、启动开发服务器。
  2. 功能清单:根据初始需求扩展出的完整端到端功能列表。
  3. claude-progress.txt:记录 Agent 已完成工作的进度文件。
  4. 初始 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 开始时都会被要求执行一组固定步骤来定位当前状态。这些步骤很基础,但很有用:

  1. 运行 pwd,确认当前工作目录。Agent 只能编辑这个目录下的文件。
  2. 阅读 git log 和进度文件,了解最近做了什么。
  3. 阅读功能清单,选择优先级最高且尚未完成的功能。

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。

这页有帮助吗?