Anthropic 适用于长期运行代理的有效工具 精读笔记
info
Anthropic 近期发布的工程博客《Effective harnesses for long-running agents》提出了一套面向长期运行任务(如持续数小时/数天的软件开发)的 AI Agent 架构设计与工程机制。本文对该论文进行了深入的精读与结构化总结,提炼出核心技术点、关键流程、失败案例及经验教训,并附上可直接落地的配置代码示例,旨在帮助工程师理解并应用该架构于实际项目中。
一、文章整体理解
本文聚焦 AI Agent 在处理跨多个上下文窗口的长时任务(如持续数小时/数天的软件开发)时的核心痛点——离散会话间的状态断裂与进度一致性问题。随着 AI 能力提升,开发者越来越需要 Agent 承接复杂长任务,但现有上下文窗口限制和压缩机制(compaction)无法解决 Agent“一次性贪多”或“过早宣告完成”的问题,导致项目进展混乱、功能残缺。这一问题在工程实践中至关重要,因为长时任务的自动化是 Agent 落地的核心场景,而状态管理和增量推进是自动化可靠性的基础。作者的核心思路源自人类软件工程师的协作模式,设计了“初始化 Agent + 编码 Agent”的双角色架构,通过环境标准化、进度结构化、增量开发、强制测试,让 Agent 能跨会话持续推进任务,同时保持环境清洁可继承。
二、核心技术点拆解
技术点 1:双 Agent 架构(初始化 Agent + 编码 Agent)
- 解决问题:长时任务中“初始环境无标准”和“会话间进度无衔接”的双重问题,避免 Agent 重复工作或偏离目标。
- 传统方式不足:单一 Agent 既负责环境搭建又负责功能开发,导致初始架构混乱、后续会话无法快速理解前置状态,且缺乏明确的任务分解边界。
- 设计方案:
- 初始化 Agent:仅在首次会话执行,输出三件核心产物——
init.sh启动脚本 (统一开发环境)、claude-progress.txt进度日志(结构化记录历史操作)、feature_list.json功能清单(全量需求拆解),并完成初始 Git 提交。 - 编码 Agent:后续所有会话执行,专注单功能增量开发,会话前后通过读取进度文件和 Git 日志衔接状态,结束时提交代码并更新进度。
- 初始化 Agent:仅在首次会话执行,输出三件核心产物——
- 关键 trade-off:
- 优点:职责边界清晰,环境和需求标准化,后续 Agent 无需重复搭建和探索,提升效率。
- 缺点:增加了初始配置成本,对初始化 Agent 的需求拆解能力要求极高;若初始功能清单遗漏需求,后续需手动修改(且有破坏原有结构的风险)。
技术点 2:结构化功能清单(feature_list.json)
- 解决问题:Agent 过早宣告任务完成、功能开发无明确范围、进度不可量化的问题。
- 传统方式不足:仅依赖高层级提示(如“构建 claude.ai 克隆版”),Agent 无法感知全量需求边界,容易遗漏功能或误判完成状态;Markdown 等非结构化清单易被 Agent 随意修改。
- 设计方案:
- 由初始化 Agent 基于用户提示拆解全量功能(示例中达 200+ 项),每项包含分类、描述、测试步骤、是否通过(passes)字段。
- 强制规定编码 Agent 仅能修改 “passes” 状态,禁止删除或编辑测试步骤(通过强提示约束)。
- 采用 JSON 格式存储,利用模型对 JSON 结构的尊重性,减少不当修改。
- 关键 trade-off:
- 优点:需求边界清晰,进度可视化,避免功能遗漏和过早收尾。
- 缺点:初始拆解耗时较长,复杂项目的功能分类和测试步骤设计难度大;JSON 格式灵活性低,不适合快速迭代的需求变更场景。
技术点 3:增量开发 + 清洁状态约束
- 解决问题:Agent 一次性实现过多功能导致上下文溢出、代码遗留 bug 或文档缺失,后续会话需花费大量时间修复的问题。
- 传统方式不足:无明确开发粒度限制,Agent 倾向于“一锤子买卖”式开发,超出上下文窗口后功能半成品遗留,且无强制清洁要求。
- 设计方案:
- 增量开发:编码 Agent 每次会话仅允许选择一个未完成的高优先级功能开发。
- 清洁状态要求:代码需达到可合并到主分支的标准(无重大 bug、文档完整、结构规整),通过 Git 提交(含描述性提交信息)和进度文件更新固化状态。
- 关键 trade-off:
- 优点:降低单次会话的上下文压力,减少功能半成品,后续 Agent 可直接接手开发。
- 缺点:开发效率看似降低(单次仅完成一个功能),但避免了返工成本,长期收益更高;对 Agent 的代码质量和提交规范要求严格。
技术点 4:端到端测试强制化(结合浏览器自动化工具)
- 解决问题:Agent 仅完成代码编写但未验证端到端功能,导致“标记完成但实际不可用”的虚假进度问题。
- 传统方式不足:无明确测试要求时,Agent 仅依赖单元测试或简单接口调用验证,忽略用户视角的端到端流程(如浏览器交互),遗漏实际使用场景的 bug。
- 设计方案:
- 强制要求编码 Agent 使用 Puppeteer MCP 等浏览器自动化工具,模拟人类用户操作流程(如点击“新建聊天”、输入查询、验证响应)。
- 测试结果作为功能“passes”状态修改的唯一依据,未通过端到端测试的功能不得标记为完成。
- 关键 trade-off:
- 优点:大幅提升功能可用性,减少“纸面完成”的虚假进度,降低后续返工风险。
- 缺点:增加了 Agent 的工具使用复杂度和会话耗时;受限于浏览器自动化工具能力(如无法识别原生弹窗),部分场景测试覆盖不全。
技术点 5:会话初始化标准化流程
- 解决问题:编码 Agent 启动时需花费大量 tokens 探索环境状态、排查遗留问题,导致效率低下且易因环境异常引入新 bug。
- 传统方式不足:Agent 启动无固定流程,依赖自主判断环境状态,容易遗漏遗留 bug 或重复探索已有信息。
- 设计方案:
- 执行
pwd确认工作目录,明确文件操作范围; - 读取
claude-progress.txt和 Git 日志(git log --oneline -20),快速衔接历史进度; - 读取
feature_list.json,选择高优先级未完成功能; - 执行
init.sh启动开发服务器,运行基础端到端测试,验证环境可用性。
- 关键 trade-off:
- 优点:减少 Agent 的探索成本,快速定位环境问题,避免在破碎环境上开发新功能。
- 缺点:标准化流程占用部分会话 tokens;若基础测试用例设计不完善,仍可能遗漏环境异常。
三、关键流程 / 机制复盘
1. 整体工作流程(初始化+编码循环)
整套设计只有一个循环。 初始化只跑一次,之后每次会话都是同一段流程重复执行,会话之间靠三个文件传递状态 —— 下面两小节分 别拆开这两段。
2. 编码 Agent 单会话流程
单会话是一段固定的线性流程,分四段:
| 段 | 步骤 | 要点 |
|---|---|---|
| ① 探测 | pwd 确认工作目录 → 读 claude-progress.txt → 读 feature_list.json → git log --oneline -20 | 先把上一次会话留下的状态读回来,不靠记忆 |
| ② 验证 | 执行 init.sh 启动开发服务器 → 用 Puppeteer 测核心功能 → 修掉发现的 Bug | 先确认环境是好的再动手,否则新功能会叠在破环境上 |
| ③ 开发 | 选 1 个高优先级未完成功能 → 编码 → 端到端测试 | 一次只做一个,测不过就回到编码 |
| ④ 固化 | git commit(带描述性信息)→ 更新进度日志 → 把该功能标成 passes:true | 三样一起做完才算结束,少一样下次会话就接不上 |
3. 流程核心说明
输入
- 用户高层级需求提示(如“构建 claude.ai 克隆版”);
- 工具集(bash、Git、Puppeteer MCP 浏览器自动化工具、文件读写工 具)。
中间状态演进与步骤职责
- 初始化阶段(仅执行 1 次)
- 执行者:初始化 Agent
- 职责:
- 拆解用户需求为结构化功能清单(
feature_list.json),所有功能初始标记为“passes: false”; - 编写
init.sh脚本(包含开发服务器启动、基础环境配置); - 创建
claude-progress.txt日志文件,记录初始化操作; - 初始化 Git 仓库并完成首次提交。
- 拆解用户需求为结构化功能清单(
- 输出:标准化初始环境(含 3 个核心文件+Git 仓库)。
- 编码阶段(循环执行至所有功能完成)
- 执行者:编码 Agent
- 会话内步骤:
a. 环境探测:
pwd确认目录 → 读取进度文件/Git 日志 → 读取功能清单; b. 环境验证:执行init.sh启动服务器 → 用 Puppeteer 测试基础功能(如聊天、主题切换),修复遗留 bug; c. 功能开发:选择 1 个高优先级未完成功能,编写代码; d. 功能测试:用浏览器自动化工具执行端到端测试,确保功能可用; e. 状态固化:Git 提交(含描述性信息)→ 更新claude-progress.txt→ 修改功能清单中该功能的“passes”状态为 true; - 输出:新增 1 个可用功能 + 清洁的代码仓库 + 更新后的进度/功能文件。