Logo
热心市民王先生

Anthropic 文章核心观点解析

AI Agent 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 将问题分解为两个部分:

  1. 初始环境搭建:需要设置一个包含所有必要上下文的基础环境,为逐步、逐功能开发奠定基础
  2. 增量进展管理:每个 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.shShell 脚本快速启动开发环境包含启动开发服务器、安装依赖等
feature_list.jsonJSON结构化任务清单所有功能初始标记为 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 克隆案例中,每个功能验证包括:

  1. 导航到主界面
  2. 执行用户操作(如点击”New Chat”)
  3. 验证预期结果(如新会话创建)
  4. 检查副作用(如侧边栏更新)
  5. 截图记录(用于视觉回归检测)

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 min2-5 min6x 加速
项目完成时间未完整完成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 设计原则

  1. 显式优于隐式:所有状态必须显式记录,不能依赖模型”记住”
  2. 结构化优于自由文本:使用 JSON 等结构化格式减少歧义
  3. 增量优于大爆炸:一次只处理一个功能,降低认知负担
  4. 验证优于假设:每个功能必须经过端到端验证才能标记完成
  5. 自动化优于手动:init.sh 等脚本减少重复工作

参考资料

  1. Anthropic - Effective harnesses for long-running agents - 本文核心参考
  2. Claude Agent SDK Documentation - Agent SDK 官方文档
  3. Claude Quickstarts - Autonomous Coding - 代码示例
  4. Claude 4 Prompting Guide - 提示工程最佳实践