49
49 / 50

长任务 Agent 的 Harness 设计模式

⏱️ 25分钟

长任务失败往往不是模型能力不足,而是每个 session 都不知道上一班工程师做了什么。Compaction 能压缩历史,但不能替代项目状态、验收清单和可恢复的检查点。Harness 的职责,就是让新 session 在几分钟内恢复现场,并且只推进一个可验证增量。


模型、Agent 与 Harness 的边界

用户目标
  ↓
Harness:启动、状态、预算、权限、重试、交接、评测
  ↓
Agent loop:观察 → 计划 → 调工具 → 记录结果
  ↓
模型:本轮推理与内容生成
  ↓
环境:代码库、浏览器、数据库、外部 API
应负责不应负责
模型当前上下文内推理记住几天前未持久化的决定
Agent loop工具调度和响应处理把“说完成了”当作完成证据
Harness状态、恢复、闸门、预算替模型写全部业务逻辑
环境保存真实结果用临时 console 输出充当状态库

四种常见失败

失败表现Harness 修法
一次做完整项目context 用尽时留下半成品每次只领取一个 feature
新 session 从零侦查重复读代码、猜上次进度progress.md + Git log + 初始化脚本
过早宣布完成单测通过就停止不可修改的端到端 feature list
环境已经坏了还继续开发新功能叠在旧故障上每个 session 开头跑 smoke test

Anthropic 的长任务实验采用 initializer agent 和 coding agent 两种首轮提示。它们可以使用同一个模型和工具;“两个 agent”指职责不同,不代表必须部署两套服务。


最小项目结构

agent-harness/
├── init.sh
├── feature_list.json
├── progress.md
├── runs/
│   └── 2026-08-25T10-00-00Z.json
└── workspace/

feature_list.json 是验收真相源

[
	{
		"id": "checkout-card-payment",
		"priority": 1,
		"description": "A signed-in user can complete a card payment",
		"steps": [
			"Open checkout with one item",
			"Enter valid test card details",
			"Submit payment",
			"Verify order status is paid",
			"Verify receipt is visible after refresh"
		],
		"passes": false,
		"evidence": []
	}
]

Coding agent 只允许把 passesfalse 改为 true,并追加 evidence。不能删测试、降低断言或改写用户结果来“让任务通过”。


Initializer session 做什么

Initializer 不应该开始写十个功能。它只建立可持续工作的地基:

  1. 把用户目标拆成端到端 feature list。
  2. init.sh,能确定性启动本地环境。
  3. 建立 progress 文件和 run record 格式。
  4. 运行一个最小 smoke test,证明基础环境可用。
  5. 创建第一个干净检查点。
#!/usr/bin/env bash
set -euo pipefail

test -f package.json
npm ci
npm run build
npm run dev

真实项目应加入端口、健康检查、超时和日志路径;不要用固定 sleep 猜服务已经启动。


Coding session 的固定协议

1. pwd:确认工作目录
2. 读 progress.md、feature_list.json、最近 Git log
3. 启动环境并跑 smoke test
4. 选择最高优先级的一个 failing feature
5. 实现最小 vertical slice
6. 跑单测、集成测试、真实 UI 流程
7. 保存证据后才标 passes=true
8. 写 progress 并提交干净检查点

progress.md 应回答事实问题,而不是写流水账:

## Current state

-   Active feature: checkout-card-payment
-   Last verified commit: 1a2b3c4
-   Dev command: npm run dev
-   Smoke test: passed at 2026-08-25T10:22:00+10:00

## Evidence

-   Unit: payment.service.test.ts
-   E2E: runs/checkout-card-payment.webm
-   Database: order ord_123 has status paid

## Next safe action

-   Verify receipt survives a hard refresh

“完成”的证据分层

层级证据能证明什么
代码diff、类型检查实现存在且能编译
单元deterministic tests局部规则正确
集成API/DB assertions服务之间能协作
用户流程浏览器/真实客户端用户结果确实可达
外部状态provider read-back发布、付款、消息等外部动作真实发生

如果目标是“发布视频”,本地文件或上传成功都不是最终状态;必须读回平台的 published URL。Harness 应把终点写成可验证的外部状态,而不是一句自然语言。


恢复与幂等

每个 task 建议有稳定 ID 和三态状态:pendingrunningverified。Session 崩溃后:

  1. 读取最后一个 append-only run record。
  2. 检查外部副作用是否已经发生。
  3. 已发生则补证据,不重复执行。
  4. 未发生则从最近检查点继续。
  5. 状态不确定时标 unknown,不猜成失败或成功。

对付款、发信、发布和删除操作必须使用 idempotency key 或 provider request ID。


预算与停止条件

Harness 应在执行前定义:

  • 最大模型调用次数和 token 预算。
  • 单次工具调用与整轮 session 超时。
  • 连续相同错误的停止阈值。
  • 需要人工批准的操作类别。
  • 什么条件算 blocked,什么条件允许降级。

没有停止条件的长任务不是 autonomous agent,而是不可控循环。


动手练习

为一个“用户上传 CSV,系统生成分析报告”的产品写 harness:

  1. 建立至少 12 条 feature JSON,覆盖空文件、错误编码和重复上传。
  2. 写 init 脚本与健康检查。
  3. 规定每轮只完成一条 feature。
  4. 为报告生成保存数据库记录和下载文件证据。
  5. 模拟 session 在写文件后、更新数据库前崩溃,并验证恢复不会生成重复报告。

自检

  • 新 session 不需要猜上一次发生了什么。
  • Feature list 不能被 coding agent 删除或弱化。
  • “通过”包含用户流程证据。
  • 外部副作用可通过 idempotency key 恢复。
  • Harness 有明确预算、超时和人工批准边界。

相关阅读

参考资料

📚 相关资源

常见问题

点击问题,查看本章对应的实践答案。

什么是 Agent Harness?和模型本身有什么区别?

Harness 是包在模型外面的执行框架,负责状态存储、session 交接、任务追踪和环境初始化。模型负责推理和写代码;harness 保证每个新 session 开始时能拿到完整的项目状态。没有 harness,每个 session 都从零开始。

为什么功能清单要用 JSON 而不是 Markdown?

Anthropic 的实践发现模型更不容易"顺手"改坏或覆盖 JSON 文件。配合硬规则——只允许把 passes 字段翻 true、禁止删改测试项——JSON 清单能可靠地充当跨 session 的唯一真相源。

Agent 跑通了单元测试和 API 调用,为什么还不能算完成?

代码层正确不等于端到端正确。单测和 curl 都返回成功时,真实 UI 仍可能是坏的。必须用浏览器自动化(如 Puppeteer MCP)像真实用户一样从界面走完整个流程,功能才能标记为通过。

这套两 agent 模式必须用 Claude Agent SDK 吗?

不必须。init.sh + features.json + claude-progress.txt + git 纪律这套结构不依赖特定框架——自研 agent loop、cron 定时拉起 Claude Code 都能套用,核心是把状态持久化到上下文之外。