第 13 章:Harness Engineering
本章导读
- 核心问题:如何用 Harness 约束 Agent 的执行循环、验证和恢复。
- 关键词:Harness、Verification、Recovery、Checkpoint、Stop Condition
- 学习产出:设计只读 CI 失败分析 Harness,保证报告必须有证据且不能越权。
1. 本章要解决什么问题
到目前为止,我们已经讨论了:
- Agent 与 Workflow;
- Context Engineering;
- Tool Engineering;
- Skill 与 Project Knowledge。
但这些能力还不足以构成一个真正可靠的 Agent。
因为 Agent 不是一次模型调用,而是一个持续执行过程。
这个过程需要:
初始化
理解任务
加载上下文
制定计划
调用工具
观察结果
验证进展
处理失败
保存状态
继续执行
必要时停止或升级
管理这个过程的系统,就是 Harness。
很多人把 Agent 能力归因于 Prompt。
但在长任务中,真正决定效果的往往是 Harness。
本章核心观点是:
Harness 是包裹模型的运行时结构,负责循环、验证、恢复、状态、边界和持续推进。
本章回答:
- Harness 到底是什么;
- 为什么 Harness 比 Prompt 更重要;
- Long-running Agent 为什么会失败;
- Harness 应该包含哪些模块;
- 如何设计 Verification、Checkpoint、Recovery;
- 如何用 Java / Spring Boot 实现 AgentHarness。
2. 对应 Anthropic 文章
本章主要对应:
- Effective Harnesses for Long-running Agents
Anthropic 在这篇文章中讨论Long-running Agent 的问题。
一个关键观察是:
仅靠 compaction 不足以让 Agent 长时间稳定完成复杂工程任务。
Agent 可能会:
- 一次做太多;
- 中途上下文耗尽;
- 留下半完成状态;
- 下一个窗口不知道前面发生了什么;
- 后期只修补表面问题;
- 忘记验证;
- 在错误状态上继续构建。
解决这些问题,需要更好的 Harness。
3. 什么是 Harness
Harness 可以理解为 Agent 的运行时外壳。
它围绕模型提供:
任务输入
上下文管理
工具执行
状态管理
验证机制
重试策略
恢复机制
停止条件
可观测性
如果把 LLM 比作“大脑”,Tool 比作“手”,Context 比作“工作记忆”,那么 Harness 就是:
让大脑和手在一个受控流程中持续工作的运行时系统。
4. 为什么 Prompt 不够
一个 Prompt 可以告诉模型:
请先计划,再执行,最后验证。
但 Prompt 本身不能保证:
- 每一步真的被记录;
- 失败时真的重试;
- 测试真的被运行;
- 状态真的被保存;
- 超时后真的停止;
- 写操作真的被审批;
- 下一个会话真的能恢复。
这些都需要 Harness 用程序实现。
Prompt 是建议。
Harness 是机制。
5. Harness 的核心职责
5.1 Initialization:初始化
长任务开始前,Harness 应帮助 Agent “get up to speed”。
例如:
确认当前目录
读取项目进度文件
读取 AGENTS.md
检查 Git 状态
运行基础健康检查
选择下一项任务
Anthropic 的长任务实践中,Agent 会先了解当前状态,而不是直接开始实现新功能。
这能避免在破损状态上继续叠加修改。
5.2 Planning:计划
Harness 应要求 Agent 在行动前形成计划。
计划至少包含:
- 目标;
- 相关文件;
- 修改步骤;
- 验证方式;
- 风险;
- 是否需要用户确认。
计划不是为了形式,而是为了让任务可审查、可分解、可恢复。
5.3 Execution:执行
执行阶段包括:
- 调用工具;
- 修改文件;
- 运行命令;
- 读取结果;
- 记录步骤。
Harness 不应该让模型直接无限制执行。
执行必须经过:
- 工具权限;
- 超时;
- 审计;
- 错误处理;
- 结果压缩。
5.4 Verification:验证
验证是 Harness 的核心。
软件工程任务的完成标准不应该是模型说“完成了”,而是:
测试通过
构建通过
检查通过
页面可用
输出符合规格
人类确认
验证可以有多种形式:
- 确定性脚本;
- 单元测试;
- 集成测试;
- Lint;
- 类型检查;
- E2E 测试;
- 第二个模型评审;
- 人类审核。
5.5 Recovery:恢复
失败不可避免。
Harness 应定义失败恢复策略:
读取错误
分类失败
调整计划
重试可恢复步骤
回滚不可恢复修改
升级给人类
没有 Recovery 的 Agent 很容易陷入无限修补。
5.6 Checkpoint:检查点
Checkpoint 保存任务状态。
它应该包含:
- 当前目标;
- 当前计划;
- 已完成步骤;
- 工具结果摘要;
- 修改文件;
- 验证结果;
- 未解决问题;
- 下一步建议。
Checkpoint 让 Agent 可以中断后恢复。
5.7 Stop Condition:停止条件
Agent 必须知道什么时候停止。
停止条件包括:
- 任务完成;
- 达到最大迭代次数;
- 超时;
- 成本超限;
- 权限阻塞;
- 验证连续失败;
- 需要人工决策。
没有停止条件的 Agent 是风险。
6. Harness Loop
一个基础 Harness Loop:
Initialize
↓
Plan
↓
Act
↓
Observe
↓
Verify
↓
Reflect
↓
Checkpoint
↓
Continue / Stop / Escalate
注意:Reflect 不应该只是让模型自我感觉良好。
Reflect 应基于证据:
测试结果是什么?
工具返回什么?
计划是否完成?
是否出现新风险?
7. 架构图 / 流程图
7.1 Harness 总体结构
7.2 Harness Loop
7.3 验证机制
8. Java / Spring Boot 落地方案
8.1 AgentHarness
public interface AgentHarness {
AgentResult run(AgentTask task, HarnessPolicy policy);
AgentResult resume(String sessionId);
}
8.2 HarnessPolicy
public record HarnessPolicy(
int maxIterations,
Duration timeout,
BigDecimal maxCost,
Set<String> allowedTools,
boolean requireApprovalForWrites,
VerificationPolicy verificationPolicy
) {}
8.3 AgentSession
public record AgentSession(
String sessionId,
String taskId,
AgentStatus status,
AgentPlan currentPlan,
List<AgentStep> steps,
List<Checkpoint> checkpoints
) {}
8.4 VerificationRunner
public interface VerificationRunner {
VerificationResult verify(VerificationRequest request);
}
结果:
public record VerificationResult(
boolean passed,
String summary,
List<Evidence> evidence,
List<String> failures,
List<String> suggestedFixes
) {}
8.5 CheckpointStore
public interface CheckpointStore {
void save(Checkpoint checkpoint);
Optional<Checkpoint> latest(String sessionId);
}
8.6 RecoveryStrategy
public interface RecoveryStrategy {
RecoveryAction decide(AgentSession session, VerificationResult failure);
}
可能动作:
RETRY
REPLAN
ROLLBACK
ASK_HUMAN
STOP
8.7 Harness 伪代码
public class DefaultAgentHarness implements AgentHarness {
public AgentResult run(AgentTask task, HarnessPolicy policy) {
AgentSession session = initialize(task);
while (!shouldStop(session, policy)) {
AgentPlan plan = planner.plan(session);
AgentStep step = executor.execute(plan.nextAction(), session);
session = session.record(step);
VerificationResult verification = verifier.verify(toVerificationRequest(session));
if (!verification.passed()) {
RecoveryAction action = recovery.decide(session, verification);
session = applyRecovery(session, action);
}
checkpointStore.save(Checkpoint.from(session));
if (isComplete(session, verification)) {
return complete(session, verification);
}
}
return stopped(session);
}
}
9. 常见误区
9.1 把 Harness 当 Prompt 模板
Harness 是运行时机制,不是提示词。
9.2 只靠模型自我验证
模型自评有价值,但不能替代测试、脚本和证据。
9.3 没有 Checkpoint
长任务一定会中断或跨窗口。
没有 Checkpoint 就无法可靠恢复。
9.4 没有停止条件
Agent 必须有最大步数、超时和成本限制。
9.5 失败后无限重试
Recovery 应区分可恢复失败和不可恢复阻塞。
10. 贯穿案例:CI 失败分析 Agent
CI 失败分析 Agent 需要 Harness 来保证分析过程可靠。
一个只读 Harness 可以这样设计:
Initialize:
创建 session,读取用户权限、CI 摘要、AGENTS.md。
Plan:
判断失败类型,制定只读工具计划。
Act:
调用 CI、Git、代码搜索和文件读取工具。
Verify:
检查报告是否包含 rootCause、evidence、suspectedFiles、suggestedFix、confidence。
检查是否违反只读约束。
Checkpoint:
保存已验证事实、工具结果摘要和未确认假设。
Stop:
输出报告,或在证据不足时升级给人类。
Harness 的价值在于,它不依赖模型“自觉”完成这些步骤,而是用运行时机制强制执行验证、记录、停止条件和权限边界。
对于 build #4312,Harness 可以拒绝没有证据的报告,例如只写“可能是代码问题”是不合格的。合格报告必须引用失败测试、异常、关键栈帧和相关 Git Diff。
11. 本章小结
本章讨论了 Harness Engineering。
核心结论:
- Harness 是 Agent 的运行时外壳,负责循环、验证、恢复和状态。
- Prompt 只能建议行为,Harness 才能强制机制。
- 长任务需要 Initialization、Planning、Verification、Checkpoint 和 Recovery。
- 验证必须基于证据,而不是模型自我声明。
- 企业 Agent Harness 必须支持权限、审计、停止条件和人工升级。
一句话总结:
Prompt 决定 Agent 怎么想,Harness 决定 Agent 能否长期、可靠、可控地把事情做完。
12. 实践任务
任务 1:设计 Harness Loop
为“自动生成单元测试 Agent”设计完整 Harness Loop。
任务 2:实现 CheckpointStore
用数据库或文件实现保存和读取最新 Checkpoint。
任务 3:设计 VerificationPolicy
定义哪些验证必须通过:
- 测试;
- Lint;
- Diff 检查;
- 人类确认。
任务 4:失败恢复策略
列出 5 类失败,并定义 RecoveryAction。