Harness Engineering:如何构建可验证的 Agent 执行闭环

一个 Agent 最危险的状态,不是答错一次,而是它在答错之后仍然确信自己在推进。

它可能改完代码却不跑测试;工具失败后换着参数反复重试;已经碰到权限或生产边界,却把“继续尝试”误当成负责。模型再聪明,也不应独自承担这些系统级判断。

这就是 Harness Engineering 要解决的问题。

Harness 不是某一个框架的名字。它是 Agent 工作时所处的整套执行环境:任务、工具、仓库、权限、状态、测试、日志和反馈规则共同组成的“马鞍”。模型负责推理,Harness 负责让行动可观察、可验证、可恢复。

一、先看一个最小闭环

我认为一个可靠的 Agent 任务至少要能走完下面这条链路:

Observe → Plan → Act → Verify → Recover / Stop
阶段 Agent 应做什么 系统应提供什么
Observe 读取任务、状态、证据和边界 文档、日志、只读工具
Plan 选择最小且有信息增益的下一步 任务契约、成本/权限约束
Act 改文件、调用工具、执行命令 明确副作用、隔离环境
Verify 检查是否真的达标 测试、健康检查、diff、引用
Recover / Stop 失败时调整,越界时停下 重试规则、回滚入口、人工审批

很多所谓“Agent 不可靠”,实际上是最后两步没有被设计。系统允许它行动,却没有提供验证门槛和失败后的出口。

二、把三类边界放到系统里

1. 权限边界:不要把安全寄托在一句“请小心”

“不要误删文件”“不要直接上线”可以写在 Prompt 中,但更可靠的做法是让工具与环境本身区分权限。

可自主:读取文件、搜索、创建草稿、运行本地测试
需确认:提交 Git、发布网站、发送消息、创建云资源
禁止直连:删除生产数据、展示密钥、扩大访问权限

这让 Agent 在安全动作上不必犹豫,在高风险动作前又必须停下。权限不是对能力的惩罚,而是让自主性有可预测边界。

2. 验证边界:没有证据,就不算完成

“已修复”不应该是一个允许直接结束的状态。Harness 应要求不同产物给出不同证据:

代码修改 → 相关测试 + diff 审查
数据分析 → 可复现计算 + 分母/单位检查
调研结论 → 来源 + 交叉验证
线上发布 → 构建 + 健康检查 + 页面/接口验证

这里最关键的一点是:验证要尽量调用真实环境反馈,而不是让模型自评“看起来没问题”。

3. 停止边界:重试不是无限循环

没有停止条件的 Agent,很容易把一次暂时失败变成昂贵的循环。一个简单的重试策略就足够提升稳定性:

retry:
max_attempts: 3
retryable:
- timeout
- temporary_network_error
stop_and_escalate:
- permission_denied
- destructive_action_required
- test_failure_after_fix
- ambiguous_scope

它不替代现场判断,却把“什么时候继续、什么时候停下来问人”从临场情绪变成了明确规则。

三、一个完整例子:让 Agent 修 bug,但不让它赌运气

假设任务是“修复订单导出偶发空文件的问题”。一个没有 Harness 的 Agent 可能直接修改导出函数,然后回复“已经修复”。

更可靠的闭环是:

1. Observe:读取报错、导出条件、已有测试和最近改动。
2. Plan:先提出空文件的两个可验证假设;说明不改变导出 API。
3. Act:增加最小日志或测试夹具,再做局部修复。
4. Verify:运行原始失败 case、正常导出 case、边界数据 case。
5. Recover:若测试仍失败,保留证据并回到假设;三轮后停止并请求输入。
6. Stop:测试通过后只报告结果;若要部署,则等待发布确认。

注意,Harness 并没有承诺 Agent 一次就找到根因。它确保了错误不会被“修好了”这句话掩盖,也不会在失败后无限消耗时间和成本。

四、最小可用 Harness,不需要先造平台

个人项目不必一开始搭一套复杂控制台。可以先把下面四件事放进仓库:

AGENTS.md             # 入口、规则、命令、审批边界
scripts/validate.sh # 可确定执行的检查
docs/agent/progress.md# 长任务恢复点
tests/ # 关键行为的真实反馈

然后让任务默认经过:

./scripts/validate.sh
git diff --check
git status --short

这三条命令本身很朴素,但它们把“构建是否通过、diff 是否异常、是否混入无关修改”从口头承诺变成了证据。

五、三个容易被误解的地方

Harness 不是限制模型思考

它限制的是危险或无效的执行路径,不是要求模型按固定答案推理。模型仍可以探索假设、比较方案、选择工具;只是进入共享环境前必须满足规则。

Harness 不是无限增加检查

每增加一个门禁都会带来成本。优先自动化那些失败代价高、规则明确、误报可接受的检查。无法稳定判断的“写得优雅”不适合成为硬门禁。

Harness 不是多 Agent 的前提

一个单 Agent 也需要可靠闭环。多 Agent 只会把状态、权限和验证问题放大;如果单 Agent 无法证明完成,多开几个角色不会自动修复系统设计。

六、直接可用的 Harness 检查表

在下一项 Agent 自动化开始前,逐项回答:

  1. 它从哪里读取当前状态和关键约束?
  2. 哪些工具有副作用,是否明确标识了读、写、删除?
  3. 完成时必须拿出什么真实证据?
  4. 失败后最多重试几次,哪些错误必须立刻停下?
  5. 谁能批准外部写入、生产变更或范围扩大?
  6. 是否存在一条最小回滚或恢复路径?

只要其中两三项还回答不清楚,就先别急着让 Agent 自动执行更大范围的任务。

AI 实现摘要

  • 要解决的问题:为 Agent 建立 Observe、Plan、Act、Verify、Recover/Stop 的可靠执行闭环,避免无证据完成、越权和无限重试。
  • 适用版本与前置条件:适用于具备工具调用能力的 AI Agent;建议项目已有版本控制、测试或至少可执行的验证命令。
  • 输入、输出与验收标准:输入为一个有副作用或可能跨多步的任务;输出包含执行证据、失败恢复状态和明确停止点。验收时应能判断 Agent 是否验证了结果、是否遵守授权范围。
  • 文件改动清单:可新增 AGENTS.mdscripts/validate.sh、任务状态文件和测试夹具;按实际技术栈调整。
  • 完整命令:示例为 ./scripts/validate.shgit diff --checkgit status --short;应替换为项目真实命令。
  • 测试步骤与预期结果:故意制造一个测试失败或权限拒绝场景;预期 Agent 记录证据、按策略重试或停止,而不是宣布完成或无限循环。
  • 常见错误、回滚方法与安全边界:不要用自然语言代替系统权限。生产写入、数据删除、密钥访问和付费动作必须在工具与环境层受限,并保留人工确认。