一个 AI Agent 反复忘记决定、选错工具、跳过验证,很多人的第一反应是修改提示词、换模型或增加上下文。原文提出了另一个值得检查的方向:模型周围的运行环境是否完整。
这个环境通常被称为 Harness。它负责选择上下文、开放工具、保存状态、执行权限规则、检查结果、记录过程,并在失败后恢复。模型负责推理和提出下一步,Harness 决定它能看到什么、能做什么、哪些结果算证据,以及任务何时停止。
OpenAI 在 Codex 的 Agent 优先代码库实践中也记录了类似现象:早期进展较慢,原因在于环境定义不足,Agent 缺少完成高层目标所需的工具、内部结构和可检查信息。团队随后把精力转向补齐缺失能力,并让规则既能被 Agent 理解,也能由程序检查。
同一个模型,可以表现得像不同的 Agent
把同一个模型放进聊天框,它会回答问题。把它放进包含代码仓库、终端、测试、浏览器、项目说明、隔离工作区和审查流程的环境,它就可能完成软件交付。
模型参数没有发生变化,变化的是它能获取的信息和可执行动作。可靠性因此不能只看模型能力,还要看以下系统是否形成闭环:
请求 → 选择上下文 → 调用工具 → 保存状态 → 验证结果
→ 允许继续 / 局部修复 / 请求人工判断
缺少其中一环,Agent 都可能在看似合理的推理中偏离任务。Harness 工程的目标,是把这些环节设计成清晰、可观察、可约束的运行系统。
生产级 Harness 的七项职责
1. 把请求变成任务契约
Agent 开始执行前,需要知道目标、输入、输出、限制和完成条件。可以用一个很小的结构表达:
{
"goal": "交付功能",
"inputs": ["问题描述", "代码仓库", "设计稿"],
"output": "可审查的变更",
"constraints": ["不改数据库结构", "保持公开 API"],
"done_when": ["测试通过", "界面检查通过", "审查通过"]
}
这份契约防止任务在执行过程中悄悄变形。没有明确完成条件时,Agent 很容易交付另一个看似相关的结果,然后宣布完成。
2. 给 Agent 一张项目地图
Agent 需要项目知识,但无需在每次请求中装入全部文档。更实用的做法是用一份短入口文件告诉它:架构说明在哪里、测试规则在哪里、产品限制在哪里、安全要求在哪里。
OpenAI 的实践是让简短的 AGENTS.md 承担目录作用,详细知识保存在版本化的 docs/ 中,并按当前任务逐步读取。这样既节省上下文,也降低巨型说明文件过期后继续误导 Agent 的风险。
项目地图可以很简单:
AGENTS.md
├── 架构地图
├── 测试地图
├── 产品规则
├── 安全规则
└── 任务专用说明
3. 在合适的环境开放合适的工具
工具是模型与真实世界之间的接口。每个工具至少需要说明用途、输入、输出、失败状态和权限范围。
例如,读取工作区文件和在隔离环境运行测试可以默认允许;访问网络按任务范围开放;部署、删除和影响他人的操作需要额外批准。清晰的工具返回值也很重要。若工具失败后只返回模糊文本,模型只能猜测发生了什么。
工具数量同样要克制。当前任务用不到的工具可以按需发现,避免增加选择错误和上下文开销。
4. 把记忆写入持久状态
对话内容不适合作为唯一记录。长任务经历上下文压缩、会话重启、程序崩溃或人员交接后,决定和失败信息容易丢失。
更稳妥的方式是把关键状态写进仓库文件、任务记录或数据库:
{
"current_step": "verify_ui",
"artifacts": ["build.zip", "report.md", "screenshot.png"],
"decisions": ["保持现有数据库结构"],
"failures": ["390px 宽度下出现横向溢出"],
"pending": ["等待人工批准"]
}
下一次会话应继承工作的真实状态,而非依赖一段可能遗漏细节的口头回顾。
5. 先增加传感器,再增加自主执行范围
Agent 无法修正自己看不到的问题。测试、类型检查、Lint、截图、日志、指标和数据校验器,都在把“质量不错”转换成可检查证据。
不同任务需要不同信号:
| 任务 | 最小证据 |
|---|---|
| 代码修改 | 测试、类型检查、Lint |
| 界面修改 | 实际渲染、截图、交互检查 |
| 资料研究 | 来源检查、时间检查、矛盾检查 |
| 数据处理 | Schema、范围、完整性和新鲜度检查 |
Agent 负责生成结果,环境负责产生关于结果的证据,Harness 决定证据是否足够。
6. 在模型之外执行权限规则
模型可以建议动作,Harness 负责授权,工具只执行已经通过检查的请求:
模型建议 → 权限规则检查 → 工具执行
当操作昂贵、难以撤销或会影响其他人时,这种分离尤其重要。计划、批准和执行如果全部交给同一个概率系统,风险会集中在一次判断中。
7. 记录过程,并支持局部恢复
每次运行都应留下可读记录,包括请求、选取的上下文、工具调用、状态变化、验证结果、重试次数、费用、最终产物和回退点。
记录的目的不是保存所有噪声。它要能回答三个问题:哪里失败、为什么允许继续、如何恢复。出现问题后,应尽量回到最近的安全节点修复局部缺口,避免整条流程从头重跑。
把关键说明变成程序检查
只写在文档里的规则,迟早会被遗漏。重要边界可以同时表达两次:先用文字解释原因,再用测试、Lint、Schema 或权限策略强制检查。
例如:
说明:界面层不能直接查询数据库
检查:界面代码导入数据仓储层时,Lint 失败
一次失败由此可以带来四类改进:补充项目地图、改善工具说明、增加验证器、收紧权限。当前输出得到修复,后续任务也会受到同一条规则保护。
重试循环也属于 Harness
“一直尝试到成功”缺少控制条件。有效的循环需要证据、重试上限、费用预算和人工介入路径。
最多尝试 3 次
每次生成产物后立即验证
通过则结束
失败则记录具体缺口,只修复该缺口
超过上限则提交状态和证据,请人工判断
Anthropic 在长时间应用开发实验中采用了结构化交接文件,并把生成与评价分开。其报告指出,长任务会随着上下文增长失去连贯性,独立评价者也更容易对生成结果给出可执行反馈。这类结构增加了一些运行成本,适合多小时、可验证的复杂任务;短任务通常不需要完整的多角色编排。
从最小闭环开始
Harness 工程不要求团队先建设一套大型平台。可以按任务风险逐级增加能力:
- 短小、低风险任务:提示词、模型、一次人工审查;
- 常规工程任务:项目地图、受限工具、自动测试;
- 长任务:结构化状态、有限重试、恢复点;
- 高风险任务:权限门、完整追踪、人工批准。
每增加一层,都应对应一个真实失败。若 Agent 从未跨会话执行,暂时无需复杂的持久状态系统;若它可以修改生产数据,权限门和审计记录就不能省略。
一份可直接使用的检查表
在让 Agent 承担真实工作前,可以检查以下问题:
- 成功条件是否在执行前定义?
- Agent 能否快速找到当前任务需要的项目知识?
- 每个工具是否有明确用途、输出和失败状态?
- 执行环境是否与生产系统隔离?
- 重要决定是否保存在对话之外?
- 高风险动作前是否有证据和批准?
- 重试是否有次数和费用上限?
- 中断后能否从已保存状态继续?
- 工具调用和状态变化是否可以解释?
- 失败后是否更新了说明、测试、工具或权限规则?
- 最终产物是否可以回退?
如果多个答案是否定的,换更强模型可能只能暂时掩盖问题。可靠 Agent 的长期基础,来自清晰任务、适量上下文、受控工具、持久状态、可验证证据和可恢复流程。
Aide Hub 会继续分享 AI 助手、开发工具和软件工程实践。