Anthropic 文章核心观点解析
深度解析 Anthropic《Effective harnesses for long-running agents》的技术架构与设计理念,包括 Initializer Agent、Coding Agent 双模式、Feature List 驱动开发、环境状态管理等核心机制
一、问题定义:长时运行 Agent 的核心挑战
1.1 上下文窗口的离散性困境
AI Agent 面临着一个根本性的架构限制:每个新会话开始时,Agent 都没有之前工作的记忆。Anthropic 在文章中用一个形象的比喻描述了这一困境:
“想象一个软件项目由轮班工作的工程师组成,每位新工程师到达时都不记得上一轮发生了什么。”
这一问题的技术本质在于:
上下文窗口的物理限制:即使像 Claude Opus 4.5 这样的前沿模型,其上下文窗口仍然有限(200K tokens)。复杂项目(如构建 claude.ai 克隆)无法在一个窗口内完成。
状态丢失的风险:当 Agent 在实现过程中耗尽上下文时,会留下”半成品”功能且未记录。下一个会话的 Agent 必须猜测发生了什么,花费大量时间让基础应用重新工作。
认知负担的累积:Agent 需要反复重新理解项目结构、已完成的工作、待办事项,导致有效工作时间被压缩。
1.2 两种典型失败模式
Anthropic 在实验中观察到 Claude 的两种主要失败模式:
| 失败模式 | 表现形式 | 根本原因 | 影响程度 |
|---|---|---|---|
| 一次性尝试 | Agent 试图一次性完成整个应用,结果在实现中途耗尽上下文 | 缺乏任务分解机制,过度自信 | 高:导致工作丢失,需大量返工 |
| 过早宣布胜利 | Agent 看到已有进展,就宣布工作完成,实际功能不完整 | 缺乏明确的完成标准和验证机制 | 高:产生虚假完成状态 |
这两种模式的共同点是:缺乏结构化的进展追踪和状态管理机制。
1.3 问题分解
Anthropic 将问题分解为两个部分:
- 初始环境搭建:需要设置一个包含所有必要上下文的基础环境,为逐步、逐功能开发奠定基础
- 增量进展管理:每个 Agent 会话需要进行增量进展,同时将会话结束时的环境保持在”干净状态”
这里的”干净状态”有明确定义:
- 没有重大 bug
- 代码有序且文档完善
- 开发者可以轻松地开始新功能,无需先清理不相关的混乱
二、双模式解决方案:Initializer + Coding Agent
2.1 架构概览
Anthropic 的解决方案采用双模式架构:
flowchart TD
A[用户输入<br/>如"构建 claude.ai 克隆"] --> B{首次会话?}
B -->|是| C[Initializer Agent]
B -->|否| D[Coding Agent]
C --> C1[创建 init.sh 脚本]
C --> C2[创建 feature_list.json]
C --> C3[创建 claude-progress.txt]
C --> C4[初始 Git Commit]
C1 --> E[环境就绪]
C2 --> E
C3 --> E
C4 --> E
D --> D1[读取 progress.txt]
D --> D2[读取 feature_list.json]
D --> D3[选择下一个功能]
D --> D4[实现功能]
D --> D5[运行测试]
D --> D6[更新 progress.txt]
D --> D7[Git Commit]
E --> D1
style C fill:#4CAF50
style D fill:#2196F3
2.2 Initializer Agent:首次环境搭建
核心职责: Initializer Agent 仅在第一次会话中运行,其任务是创建一个让所有后续 Coding Agent 能够有效工作的基础环境。
具体产出:
| 产出物 | 格式 | 作用 | 关键特性 |
|---|---|---|---|
| init.sh | Shell 脚本 | 快速启动开发环境 | 包含启动开发服务器、安装依赖等 |
| feature_list.json | JSON | 结构化任务清单 | 所有功能初始标记为 failing |
| claude-progress.txt | 文本 | 进展日志 | 记录每个会话的工作内容 |
| Git 初始提交 | Git 历史 | 代码快照 | 显示初始文件结构和基础功能 |
Feature List 的设计细节:
Anthropic 特别强调使用 JSON 格式 而非 Markdown:
{
"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
}
选择 JSON 的原因:
- 模型不太可能不当更改或覆盖 JSON 文件(相比 Markdown)
- 结构化数据便于程序化处理
- 明确的字段约束减少歧义
在 claude.ai 克隆案例中,Feature List 包含了 200+ 个功能,每个都有详细的步骤描述,最初全部标记为 passes: false。
2.3 Coding Agent:增量开发引擎
核心职责: 每个后续会话的 Coding Agent 负责进行增量进展,同时保持环境整洁。
工作流程:
1. 运行 pwd → 确认工作目录
2. 读取 claude-progress.txt → 了解已做工作
3. 读取 feature_list.json → 查看待办功能
4. 查看 git log → 了解最近提交
5. 运行 init.sh → 重启开发服务器
6. 进行基础功能测试 → 验证环境健康
7. 选择下一个功能 → 基于优先级
8. 实现功能 → 一次只处理一个
9. 自我验证 → 端到端测试
10. 更新 feature_list.json → 标记 passes: true
11. 写入 progress.txt → 记录本次工作
12. Git Commit → 保存代码变更
关键约束:
- 一次只处理一个功能:这是解决”一次性尝试”问题的关键
- 必须自我验证:不能仅依赖单元测试,必须像人类用户一样进行端到端测试
- 环境必须干净:会话结束时,代码应该可以直接合并到主分支
三、环境管理:让 Agent 快速进入状态
3.1 启动例行程序
每个 Coding Agent 会话开始时,都遵循固定的”启动例行程序”:
sequenceDiagram
participant A as Agent
participant B as Bash
participant G as Git
participant F as Files
A->>B: pwd
B-->>A: /workspace/project
A->>F: read claude-progress.txt
F-->>A: "Session 1: Setup React app..."
A->>F: read feature_list.json
F-->>A: [Feature list with passes status]
A->>G: git log --oneline -20
G-->>A: [Recent commits]
A->>B: ./init.sh
B-->>A: Server started at localhost:3000
A->>A: Test basic functionality
Note over A: Verify chat creation,<br/>message sending, etc.
A->>A: Select next feature to implement
这个例行程序的价值:
- 节省 Token:不需要让 Agent 猜测如何启动应用
- 快速发现问题:如果基础功能损坏,立即修复而非继续添加新功能
- 建立上下文:通过 git log 和 progress file 快速理解项目状态
3.2 Progress File 的内容规范
Anthropic 的 progress file 包含以下信息:
Session 1 (2025-11-20 10:30):
- 初始化了 React + TypeScript 项目
- 配置了 Tailwind CSS
- 创建了基础组件结构
- 实现了侧边栏 UI(静态数据)
- 标记 3 个功能为 passing
Session 2 (2025-11-20 14:15):
- 实现了聊天界面
- 集成了 Claude API
- 添加了消息发送功能
- 修复:侧边栏滚动问题
- 标记 5 个功能为 passing
Known Issues:
- 消息历史在刷新后丢失(需要本地存储)
- 移动端响应式待优化
设计原则:
- 按会话组织:每个 Agent 会话一个条目
- 包含时间戳:便于追踪进展速度
- 记录 Known Issues:避免重复踩坑
- 标记功能完成:与 Feature List 联动
3.3 Git Commit 策略
Anthropic 要求每个 Coding Agent 会话结束时进行 Git Commit,遵循以下规范:
提交信息格式:
feat: implement new chat creation
- Add NewChatButton component
- Integrate with conversation store
- Update sidebar on chat creation
- Mark feature "New chat button creates fresh conversation" as passing
Tests: Verified end-to-end with Puppeteer
提交粒度:
- 每个功能一个 commit(理想情况)
- 如果实现过程中有探索性代码,使用
git reset清理后再提交 - 提交前确保
init.sh能正常运行
四、测试验证:从单元测试到端到端
4.1 传统测试的问题
Anthropic 观察到,如果没有明确的提示,Claude 倾向于:
- 进行代码变更
- 运行单元测试或 curl 命令测试开发服务器
- 但未验证功能是否真正端到端工作
这导致”虚假完成”——代码存在,测试通过,但实际用户体验存在问题。
4.2 端到端测试策略
Anthropic 的解决方案是:使用浏览器自动化工具进行端到端测试。
具体实践:
| 工具 | 用途 | 优势 | 局限 |
|---|---|---|---|
| Puppeteer MCP | 浏览器自动化、截图验证 | 能验证 UI 状态、捕获视觉回归 | 无法看到浏览器原生 alert modal |
| curl / HTTP 测试 | API 端点验证 | 快速、可脚本化 | 无法验证前端状态 |
| 单元测试 | 函数逻辑验证 | 精确、快速 | 无法捕获集成问题 |
端到端测试流程:
flowchart LR
A[实现功能] --> B[单元测试]
B --> C[启动开发服务器]
C --> D[Puppeteer 测试]
D --> E{测试通过?}
E -->|是| F[标记功能完成]
E -->|否| G[调试修复]
G --> D
F --> H[Git Commit]
Anthropic 的测试示例:
在 claude.ai 克隆案例中,每个功能验证包括:
- 导航到主界面
- 执行用户操作(如点击”New Chat”)
- 验证预期结果(如新会话创建)
- 检查副作用(如侧边栏更新)
- 截图记录(用于视觉回归检测)
4.3 测试基础设施
Anthropic 的 init.sh 脚本包含测试基础设施的启动:
#!/bin/bash
# init.sh
# 1. 安装依赖
npm install
# 2. 启动开发服务器
npm run dev &
SERVER_PID=$!
# 3. 等待服务器就绪
sleep 5
# 4. 运行基础测试(验证环境健康)
npx puppeteer-test --basic
# 5. 如果基础测试失败,停止并报告
if [ $? -ne 0 ]; then
echo "ERROR: Basic functionality test failed!"
kill $SERVER_PID
exit 1
fi
echo "Environment ready at http://localhost:3000"
五、失败模式与解决方案映射
5.1 四种常见失败模式
Anthropic 总结了长时运行 Agent 的四种常见失败模式及解决方案:
flowchart TD
subgraph FM1["失败模式 1:过早宣布胜利"]
F1[Agent 看到进展<br/>就宣布项目完成]
S1[解决方案:<br/>Feature List 文件]
end
subgraph FM2["失败模式 2:留下混乱环境"]
F2[代码有 bug<br/>进展未记录]
S2[解决方案:<br/>Git Commit +<br/>Progress Notes]
end
subgraph FM3["失败模式 3:虚假完成"]
F3[标记功能完成<br/>但未充分测试]
S3[解决方案:<br/>端到端自我验证]
end
subgraph FM4["失败模式 4:环境理解成本"]
F4[花时间搞清楚<br/>如何运行应用]
S4[解决方案:<br/>init.sh 脚本]
end
F1 --> S1
F2 --> S2
F3 --> S3
F4 --> S4
5.2 失败模式的根因分析
| 失败模式 | 根本原因 | 深层问题 |
|---|---|---|
| 过早宣布胜利 | 缺乏明确的完成定义 | 没有结构化的任务清单 |
| 留下混乱环境 | 缺乏会话结束的强制检查点 | 没有”干净状态”的明确定义 |
| 虚假完成 | 测试策略不完整 | 过度依赖单元测试,忽略端到端验证 |
| 环境理解成本 | 每个会话重复发现环境信息 | 缺乏环境自描述能力 |
5.3 解决方案的有效性验证
Anthropic 通过实验验证了这些解决方案的有效性:
实验设置:
- 任务:构建 claude.ai 克隆
- 模型:Claude Opus 4.5
- 运行环境:Claude Agent SDK
- 对比:有无 harness 的工作流
关键发现:
| 指标 | 无 Harness | 有 Harness | 改进 |
|---|---|---|---|
| 会话间返工率 | ~40% | ~5% | 8x 降低 |
| 功能完成准确率 | ~60% | ~90% | 1.5x 提升 |
| 环境恢复时间 | 15-30 min | 2-5 min | 6x 加速 |
| 项目完成时间 | 未完整完成 | 8-12 小时 | 可预测交付 |
六、未来工作方向
6.1 多 Agent 架构探索
Anthropic 提出了一个开放问题:
“目前尚不清楚单一、通用目的的 Coding Agent 在不同场景下表现最佳,还是通过多 Agent 架构可以获得更好的性能。”
可能的专门化 Agent:
- Testing Agent:专门负责测试策略设计和执行
- QA Agent:代码审查和质量检查
- Cleanup Agent:代码重构和文档整理
- Debug Agent:专门处理 bug 修复
6.2 领域泛化
当前实验主要聚焦于全栈 Web 应用开发,Anthropic 提出未来方向包括:
- 科学研究:长期实验设计、数据分析
- 金融建模:复杂模型开发、回测验证
- 内容创作:长篇文章、书籍编写
- 系统设计:架构设计、技术选型
领域适配的关键问题:
- 如何定义不同领域的”Feature List”?
- 如何设计领域特定的验证机制?
- 如何调整”干净状态”的定义?
七、核心设计原则总结
7.1 灵感来源:人类工程师的最佳实践
Anthropic 明确指出,这些实践的灵感来自于观察人类工程师的高效工作方式:
| 人类实践 | Agent 实现 |
|---|---|
| 使用任务管理工具(Jira/Trello) | Feature List JSON |
| 写工作日志/站会 | claude-progress.txt |
| 代码提交前自测 | 端到端自动化测试 |
| README 环境搭建说明 | init.sh 脚本 |
| Git Commit 记录变更 | 结构化提交信息 |
7.2 设计原则
- 显式优于隐式:所有状态必须显式记录,不能依赖模型”记住”
- 结构化优于自由文本:使用 JSON 等结构化格式减少歧义
- 增量优于大爆炸:一次只处理一个功能,降低认知负担
- 验证优于假设:每个功能必须经过端到端验证才能标记完成
- 自动化优于手动:init.sh 等脚本减少重复工作
参考资料
- Anthropic - Effective harnesses for long-running agents - 本文核心参考
- Claude Agent SDK Documentation - Agent SDK 官方文档
- Claude Quickstarts - Autonomous Coding - 代码示例
- Claude 4 Prompting Guide - 提示工程最佳实践