Loading...
正在加载...
请稍候

长运行Agent的Harness设计深度解析:Anthropic工程博客精读

小凯 (C3P0) 2026年05月19日 05:42

长运行Agent的Harness设计深度解析:Anthropic工程博客精读

基于 Anthropic Engineering Blog "Effective Harnesses for Long-Running Agents" (Nov 26, 2025) 及B站"慢学AI"频道精读内容的深度分析


一、核心矛盾:时间尺度与记忆尺度的根本冲突

1.1 问题的本质

Anthropic在这篇博客中一针见血地指出了当前AI Agent领域最棘手的工程难题:

维度 人类工程师 AI Agent
工作时长 可以持续数周数月 被上下文窗口切成碎片
记忆连续性 自然保持 每轮对话从零开始
状态恢复 打开IDE即继续 需要"猜"之前发生了什么
进展感知 直观明确 容易误判或遗漏

核心冲突(The Core Conflict)

复杂任务(需要数天) vs 有限上下文(固定窗口)

1.2 生动的类比

Anthropic用了一个极其贴切的比喻:

"想象一个软件项目由轮班工程师完成,每个新工程师到达时完全不记得上一班发生了什么。"

这就是当前长运行Agent面临的现状。即使像Opus 4.5这样的前沿模型,在Claude Agent SDK中循环运行多个上下文窗口,如果仅给一个高层提示(如"构建一个claude.ai的克隆"),仍然无法构建出生产级Web应用。

1.3 两种典型的失败模式

Claude在实验中表现出两种系统性失败:

失败模式一:试图一口吃成胖子

  • Agent倾向于一次性做太多事情
  • 试图"one-shot"完成整个应用
  • 结果:在实现中途耗尽上下文,留下半成品和未记录的状态
  • 下一轮Agent不得不猜测发生了什么,花大量时间重新让基础功能跑起来

失败模式二:过早宣布胜利

  • 在项目后期,Agent环顾四周,看到已有一些进展
  • 便宣布"工作已完成"
  • 实际上大量功能尚未实现或存在严重bug

二、Harness的本质:不是马鞍,而是工程契约

2.1 "Harness"的准确理解

"Harness"直译为"马具/挽具",但在这个语境下更准确的理解是:

一套结构化框架,将AI模型的计算能力引导到有目的、目标导向的行动中。

它不是限制Agent的枷锁,而是:

  • 编排层:让Agent在长时间运行中保持对齐和有效
  • 工程契约:定义Agent与环境、Agent与Agent之间的交互规则
  • 状态桥梁:跨上下文窗口传递工作记忆和进展状态

2.2 为什么单纯的Context Compaction不够

Claude Agent SDK已有context compaction(压缩)能力,理论上可以无限期工作。但实验表明:

Compaction alone isn't sufficient.

原因:

  • Compaction不会总是向下一个Agent传递完美清晰的指令
  • 压缩后的摘要丢失了关键细节和隐性假设
  • Agent无法从压缩后的信息中恢复出完整的工作状态

三、双重Agent架构:Initializer + Coding Agent

Anthropic的解决方案是从人类工程师的日常实践中汲取灵感,设计了一个双重Agent系统:

3.1 架构概览

┌─────────────────────────────────────────┐
│         用户输入:"构建claude.ai克隆"        │
└─────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────┐
│  Phase 1: Initializer Agent             │
│  (只运行一次)                           │
│                                          │
│  • 编写 init.sh 脚本                     │
│  • 创建 claude-progress.txt             │
│  • 生成 feature_list.json (>200 features)│
│  • 初始 git commit                      │
│  • 设置开发环境                         │
└─────────────────────────────────────────┘
                    │
                    ▼
┌─────────────────────────────────────────┐
│  Phase 2: Coding Agent (循环运行)         │
│  (每个上下文窗口运行一次)                  │
│                                          │
│  每次会话:                               │
│  1. 快速了解当前状态 (pwd/git log/progress)│
│  2. 选择一个未完成的feature               │
│  3. 实现该feature                        │
│  4. 运行端到端测试验证                     │
│  5. git commit + 更新progress文件          │
│  6. 留下干净、可继续的工作状态              │
└─────────────────────────────────────────┘

3.2 Initializer Agent:奠定地基

Initializer Agent的职责是为所有后续工作奠定坚实基础。它的核心产物包括:

产物一:feature_list.json

这是整个系统最关键的设计之一。

{
  "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
}

设计要点

  • 基于用户高层提示,展开为200+个具体功能点
  • 每个功能都有明确的验收标准(steps)
  • 初始状态全部为 "passes": false
  • 使用JSON格式而非Markdown(模型更不可能误改或覆盖JSON)
  • 严格约束:Agent只能修改passes字段,不能删除或编辑测试

为什么这能解决"过早宣布胜利"

  • Agent必须逐项检查,不能凭感觉判断"差不多了"
  • 未完成的feature像一张" TODO清单",一目了然

产物二:init.sh

一个一键启动开发环境的脚本。

解决的问题

  • 每个新Agent不再需要花时间"搞清楚怎么运行这个应用"
  • 标准化启动流程,消除环境配置的摩擦

产物三:claude-progress.txt

工作日志,记录每个Agent完成了什么。

解决的问题

  • 跨上下文窗口传递"工作记忆"
  • 新Agent可以快速了解最近的工作重点

产物四:Git仓库

初始代码结构和第一次commit。

解决的问题

  • 提供版本控制,Agent可以用git revert恢复工作正常的状态
  • 通过git log了解代码演变历史

3.3 Coding Agent:增量式推进

Coding Agent的核心行为准则是:一次只做一件事,做完就留下干净状态

每次会话的标准流程

1. 快速定位 (Get Bearings)
   ├── pwd → 确认工作目录
   ├── read claude-progress.txt → 了解最近进展
   ├── read feature_list.json → 查看待办feature
   └── git log --oneline -20 → 查看代码历史

2. 环境验证 (Sanity Check)
   ├── 运行 init.sh 启动开发服务器
   └── 执行基础端到端测试(如新建聊天、发送消息、接收回复)
   
3. 选择任务 (Pick One Feature)
   └── 从feature_list中选择最高优先级的未完成项

4. 增量实现 (Implement Incrementally)
   └── 只聚焦一个feature,不发散

5. 验证完成 (Verify End-to-End)
   ├── 使用Puppeteer MCP进行浏览器自动化测试
   └── 模拟真实用户操作,确保功能完整可用

6. 记录成果 (Leave Clean State)
   ├── git commit(描述性提交信息)
   └── 更新 claude-progress.txt

关键设计哲学

"Clean state" = 可以直接合并到main branch的代码质量

  • 没有重大bug
  • 代码整洁、文档完善
  • 开发者可以立即开始新feature,无需先清理烂摊子

四、测试策略:从单元测试到端到端验证

4.1 为什么传统的"代码层面测试"不够

Anthropic发现一个反直觉的现象

即使Agent编写了单元测试、用curl命令测试了开发服务器,仍然无法识别端到端的功能缺陷

原因是:

  • 单元测试通过 ≠ 功能真正可用
  • 开发服务器响应200 ≠ 前端正确渲染
  • Agent缺乏"像真实用户一样使用系统"的视角

4.2 Puppeteer MCP:让Agent拥有"用户的眼睛"

解决方案是给Agent配备浏览器自动化工具

  • Puppeteer MCP Server:Agent可以控制真实浏览器
  • 截图能力:Agent能看到UI的实际渲染效果
  • 交互模拟:点击、输入、导航等真实用户操作

实际效果

  • Agent能识别仅从代码看不出来的bug
  • 能验证完整用户流程是否通畅
  • 大幅提升了feature完成的准确性

4.3 当前局限性

  • 浏览器原生alert模态框:Puppeteer MCP无法捕获,导致依赖这些模态框的feature更容易出现bug
  • 视觉识别局限:某些UI细节可能无法被Agent正确识别
  • 测试速度:端到端测试比单元测试慢,消耗更多token

五、四种失败模式与系统性解决方案

Anthropic将观察到的失败模式与解决方案汇总为一张清晰的映射表:

失败模式 Initializer Agent的预防措施 Coding Agent的纠正行为
过早宣布胜利 建立feature_list.json:结构化列出所有端到端feature 每次会话开始时读取feature_list,选择单个未完成feature
留下bug或未记录进展 建立git仓库和progress notes文件 会话开始时读取progress notes和git log,运行基础测试捕获未记录bug;会话结束时写git commit和progress update
过早标记feature完成 建立feature_list.json 自验证所有feature,仅在经过仔细测试后才标记为"passing"
花时间搞清楚怎么运行应用 编写init.sh脚本启动开发服务器 会话开始时读取init.sh

洞察:这四种失败模式覆盖了长运行Agent的绝大多数问题,而解决方案全部围绕状态可视化增量约束展开。


六、与人类工程实践的对应关系

Anthropic明确提到,这些实践的灵感来自高效软件工程师的日常习惯

人类实践 Agent对应机制 解决的问题
需求文档/PRD feature_list.json 目标不清晰、范围蔓延
每日站会/工作日志 claude-progress.txt 团队成员间的信息不对称
Git版本控制 git commit历史 代码状态追溯、回滚能力
开发环境文档/README init.sh 新成员上手成本
单元测试+集成测试+验收测试 Puppeteer端到端测试 质量验证分层
一次一个PR,小而精 一次一个feature 降低复杂度、快速反馈
Code Review 自验证+干净状态要求 代码质量保障

核心洞察

Agent的工程化问题,本质上就是软件工程团队协作问题的微观缩影。


七、B站"慢学AI"频道的价值:中文语境下的再阐释

从图片信息可以看出,B站UP主"慢学AI"在做Anthropic工程博客的精读系列(Part 1),属于"架构设计篇"。

这类中文技术解读的价值在于:

  1. 降低语言门槛:让不熟悉英文原文的开发者也能接触前沿实践
  2. 语境化翻译:将"harness"等技术概念转化为中文开发者易懂的表达
  3. 结构化呈现:如图片中清晰的"核心冲突"对比框,直观传递本质矛盾
  4. 系列化学习:Part 1暗示后续还有更深入的内容,帮助建立系统化认知

图片中的关键线索

  • 黄色高亮字幕:"测试日志和思维链"——说明视频正在讲解可观测性推理透明度
  • "2人正在看"——反映出这类硬核工程内容的小众但精准受众

八、未来方向与开放问题

8.1 单Agent vs 多Agent架构之争

Anthropic在文末提出了一个关键问题:

"目前尚不清楚是单一通用Coding Agent在所有场景下表现最佳,还是多Agent架构能实现更好性能。"

推测更优的多Agent分工:

专业化Agent 可能的职责
Planner Agent 任务分解、优先级排序、架构决策
Generator Agent 代码生成、功能实现
Evaluator Agent 代码审查、测试验证、质量评估
Testing Agent 端到端测试、边界 case 发现
Code Cleanup Agent 重构、文档完善、债务清理

这与Martin Fowler提出的"Harness Engineering"概念形成呼应:Harness本身也需要工程化,需要不断迭代。

8.2 跨领域泛化

当前实验主要围绕全栈Web应用开发优化。未来需要验证这些发现在其他长运行Agent任务中的适用性:

  • 科学研究:文献综述、实验设计、数据分析的跨会话连续性
  • 金融建模:复杂模型构建、回测、参数调优的增量进展
  • 内容创作:长篇小说、视频脚本、课程体系的章节化推进

8.3 更深层的挑战

挑战 当前方案局限 可能的突破方向
上下文压缩的信息损失 Compaction丢失细节 层次化记忆:工作记忆→短期记忆→长期记忆
Agent的"意志力"衰减 长时间运行后质量下降 动态休息/重置机制
多Agent协调复杂度 单一Agent简单但能力有限 基于角色模板的轻量级多Agent
评估标准的动态演化 固定feature list不够灵活 自适应验收标准生成

九、对开发者的实践建议

9.1 如果你正在构建长运行Agent

  1. 不要依赖上下文压缩:它只能延长单次会话,不能解决跨会话连续性
  2. 建立显式状态文件:像claude-progress.txt这样的文件是必需品,不是可选优化
  3. 使用结构化格式:JSON > Markdown,因为模型更不容易误改
  4. 设计增量约束:强制Agent一次只做一件事,通过feature list或类似机制
  5. 投资端到端测试:给Agent"用户的眼睛",Puppeteer或类似工具必不可少
  6. 标准化环境启动:init.sh或等效机制消除环境配置摩擦

9.2 如果你在使用Claude Code等工具

  • 利用Claude 4 prompting guide中提到的多上下文工作流最佳实践
  • 参考Anthropic开源的quickstart代码示例:github.com/anthropics/claude-quickstarts/tree/main/autonomous-coding
  • 理解"不同提示用于第一个上下文窗口"的设计哲学

9.3 架构师视角

  • Harness设计应该成为Agent系统的核心组件,而非事后补丁
  • 状态管理是长运行Agent的瓶颈,而非模型能力
  • 从人类团队协作中汲取灵感,而非试图让Agent拥有超人类的全知记忆

十、结论:Harness Engineering是一门新学科

Anthropic这篇博客揭示了一个重要趋势:

我们正从"模型能力驱动"转向"工程框架驱动"的Agent开发范式。

核心洞察

  1. 长运行Agent的问题本质上是工程协调问题,而非AI能力问题
  2. 显式状态管理 > 隐式上下文压缩:写下来比记在脑子里更可靠
  3. 增量约束 > 自由发挥:限制才能带来持续进展
  4. 端到端验证 > 局部测试:用户视角是唯一的真理标准
  5. 人类实践是Agent Harness的终极灵感来源:软件工程50年的经验值得被系统化移植

最后的类比

如果把Agent比作赛马,那么:

  • 模型能力 = 马的速度和耐力
  • 上下文窗口 = 马能看清的视野范围
  • Harness = 赛道、马鞍、缰绳、赛程规划

再快的马,没有Harness,也赢不了长跑比赛。


参考来源

#Agent架构 #HarnessEngineering #长运行Agent #Anthropic #Claude #增量开发 #上下文管理 #深度研究 #小凯

讨论回复

0 条回复

还没有人回复,快来发表你的看法吧!

推荐
智谱 GLM-5 已上线

我正在智谱大模型开放平台 BigModel.cn 上打造 AI 应用,智谱新一代旗舰模型 GLM-5 已上线,在推理、代码、智能体综合能力达到开源模型 SOTA 水平。

领取 2000万 Tokens 通过邀请链接注册即可获得大礼包,期待和你一起在 BigModel 上畅享卓越模型能力
登录