Harness 工程是什么?从概念到搭建一个可控的 AI Agent
目录
二、Prompt、Context 和 Harness 有什么区别?
最近 AI 圈出现了一个新词:Harness Engineering,通常翻译为 Harness 工程,也有人称为“驾驭工程”。
这个词听起来很新,但它解决的问题其实非常现实:
为什么同样使用 GPT、Claude 或 Codex,有些 Agent 能连续完成复杂任务,有些 Agent 却经常跑偏、忘记目标、乱调用工具,最后还无法判断自己到底做没做对?
很多时候,问题不只在模型,而在模型外面的那套运行环境。
这套运行环境,就是 Harness。
一、Harness 工程到底是什么?
Harness 原本指的是马具或缰绳。
马本身有力量,但如果没有缰绳、路线、障碍和骑手,它的力量并不能稳定地服务于目标。
AI Agent 也是一样。
模型可以理解语言、生成代码、调用工具,但它并不知道:
当前任务的边界是什么;
哪些工具可以使用;
每一步应该先做什么;
什么结果才算成功;
失败之后应该如何恢复;
上一次执行留下的状态在哪里。
Harness 工程,就是围绕 Agent 建立一整套“让它看得准、做得对、错了能恢复”的工程系统。
一个实用的定义是:
Harness 工程 = 提示词 + 上下文 + 工具 + 任务编排 + 状态管理 + 评估 + 约束与恢复
它不是某个框架,也不是一个固定产品,而是一种设计 Agent 的方法。
二、Prompt、Context 和 Harness 有什么区别?
这三个概念不是互相替代,而是范围逐步扩大。
Prompt Engineering 解决的是:
怎么把任务讲清楚,让模型理解你的要求。
例如:
你是一个 Python 工程师,请修复登录接口的参数校验问题,并保留现有 API 格式。
Context Engineering 解决的是:
怎么把模型需要的信息送到它面前。
除了任务本身,模型还需要知道:
项目目录结构;
相关代码;
接口文档;
测试结果;
团队规范;
历史执行状态。
Harness Engineering 解决的是:
怎么让模型在真实环境中连续完成任务,并且能被验证和纠错。
简单来说:
Prompt 是把话说清楚。
Context 是把资料准备好。
Harness 是把整个工作流程搭起来。
三、一个完整 Harness 通常包含什么?
一个实用的 Harness,至少可以拆成六层。
第一层:上下文管理
决定当前这一轮应该给模型看什么。
不要每次都把整个项目、所有规则、全部历史记录塞进上下文,而是按照任务动态加载。
第二层:工具系统
决定 Agent 能使用哪些工具。
例如:
读取文件;
搜索代码;
运行测试;
查看 Git diff;
调用接口;
发送消息。
工具不是越多越好。工具越多,Agent 越容易误用。
第三层:任务编排
规定 Agent 应该按照什么顺序工作。
例如:
先读需求;
再分析代码;
然后制定计划;
接着修改代码;
运行测试;
根据测试结果修复;
最后汇报结果。
第四层:状态与记忆
决定任务完成到一半后,下一轮如何继续。
任务状态不要只放在上下文里,而应该写入文件、数据库或任务系统。
第五层:评估与观测
决定如何判断 Agent 做得好不好。
不能只看 Agent 自己说“任务完成”,而要看测试、日志、输出格式和业务指标。
第六层:约束与失败恢复
限制 Agent 的危险行为,并为常见失败准备恢复路径。
例如:
限制修改目录;
限制工具调用次数;
禁止直接删除生产数据;
API 限流后自动重试;
任务超时后保存进度;
失败后从上一个检查点继续。
四、从 0 搭建一个代码 Agent Harness
下面用一个代码项目举例。
目标是:
让 Agent 为项目添加一个新功能,并且必须经过测试、代码检查和结果验收。
第一步:建立项目结构
在项目根目录增加以下文件:
project/ ├── AGENTS.md ├── progress.md ├── tasks/ │ └── task-001.md ├── scripts/ │ └── check.ps1 └── evals/ └── cases.md
这些文件分别负责:
AGENTS.md:项目规则和工作流程。
progress.md:任务进度和交接信息。
tasks/task-001.md:当前具体任务。
scripts/check.ps1:自动检查代码。
evals/cases.md:评估 Agent 是否完成任务。
第二步:编写 AGENTS.md
示例内容:
# 项目开发规则 1. 修改代码前,先阅读当前任务文件和相关模块。 2. 先给出简短实现计划,再开始修改。 3. 不要修改任务范围之外的文件。 4. 修改完成后必须运行 scripts/check.ps1。 5. 测试失败时,先分析错误原因,再继续修改。 6. 不要删除已有测试。 7. 最终报告必须包含: - 修改了哪些文件 - 运行了哪些检查 - 检查结果是什么 - 仍然存在什么风险 8. 每完成一个阶段,就把进度写入 progress.md。
注意,这个文件不应该写成项目百科全书。
只放最重要的规则,详细规范可以拆到 docs 目录中,需要时再读取。
第三步:定义一个具体任务
tasks/task-001.md:
任务:为用户模块增加邮箱格式校验。 要求: 1. 只修改用户模块相关代码。 2. 邮箱为空时返回明确错误。 3. 邮箱格式错误时返回明确错误。 4. 增加至少两个测试用例。 5. 不改变已有接口返回结构。 6. 完成后运行项目测试和代码检查。
任务越具体,Agent 越不容易跑偏。
不要只写:
“优化一下用户模块。”
应该写清楚:
改什么;
不改什么;
成功标准是什么;
如何验收。
第四步:加入自动检查脚本
如果项目使用 Node.js,可以创建 scripts/check.ps1:
$ErrorActionPreference = "Stop" npm test npm run lint git diff --check Write-Host "All checks passed."
如果是 Python 项目,可以替换为:
$ErrorActionPreference = "Stop" python -m pytest ruff check . git diff --check Write-Host "All checks passed."
关键不在于具体命令,而在于:
不要只告诉 Agent “请认真检查”。
要给它一个可以真实执行的检查入口。
第五步:规定 Agent 的执行循环
给 Agent 的工作流程可以固定为:
1. 阅读 AGENTS.md。 2. 阅读当前任务文件。 3. 阅读 progress.md。 4. 搜索相关代码和测试。 5. 输出实现计划。 6. 修改代码。 7. 运行 scripts/check.ps1。 8. 如果失败,分析错误并修复。 9. 再次运行检查。 10. 更新 progress.md。 11. 输出最终修改说明。
这比一句“帮我完成这个功能”稳定得多。
因为 Agent 不仅知道目标,还知道工作顺序和验收方式。
五、如何处理长任务?
长任务最容易出现两个问题:
第一,Agent 忘记最初目标。
第二,上下文越来越长,模型开始忽略早期信息。
解决方法是把状态写到文件里,而不是只留在对话中。
progress.md 可以这样写:
任务:增加邮箱格式校验 已完成: - 找到用户模块入口 - 找到参数校验类 - 增加了邮箱为空的测试 进行中: - 增加邮箱格式错误测试 待完成: - 运行完整测试 - 检查接口返回结构 - 更新任务说明 遇到的问题: - 当前项目使用统一异常处理,不能直接返回字符串
下一轮 Agent 开始时,先读取 progress.md,就能知道自己目前做到哪一步。
如果任务很长,还可以采用“分轮执行”:
第一轮:分析和规划。
第二轮:实现主要功能。
第三轮:补充测试。
第四轮:运行检查和修复。
每一轮都使用新的上下文,但通过文件保存任务状态。
这比让一个 Agent 在同一个超长对话里连续工作更稳定。
六、如何让 Agent 自己发现错误?
不要让执行 Agent 自己给自己打分。
一个更可靠的流程是:
规划 Agent:拆解需求 执行 Agent:修改代码 验收 Agent:运行测试和检查 修复 Agent:根据失败结果修改 再次验收
即使不使用多个模型,也可以把执行和验收分成两个独立阶段。
例如:
执行阶段只负责修改代码。
验收阶段只负责:
运行测试;
检查接口;
查看 Git diff;
验证输出格式;
确认是否满足任务要求。
验收必须尽量接近真实使用场景。
例如,做前端 Agent 时,不能只检查代码有没有语法错误,还要真正打开页面、点击按钮、提交表单,确认功能能用。
七、Agent 反复犯错时怎么办?
最重要的一条原则是:
不要只在提示词里提醒 Agent。
应该把解决方案沉淀到项目环境中。
例如,Agent 总是忘记运行测试:
错误做法:
“请注意,修改后一定要运行测试。”
更好的做法:
把测试写进 scripts/check.ps1,并规定任务完成前必须执行这个脚本。
再比如:
Agent 总是使用错误的代码格式。
可以增加:
代码格式检查;
Lint 规则;
提交前 Git Hook;
自动化测试;
类型检查。
Agent 每犯一次错误,环境就变强一点。
这就是 Harness 工程最重要的“复利效应”:
Agent 犯错 → 找到原因 → 把修复写入规则、测试或工具 → 下一次自动避免 → Harness 持续增强
八、如何建立评估集?
如果没有评估集,你只能凭感觉判断 Agent 是否变好了。
可以从过去真实任务中挑选 10 到 20 个案例,记录:
任务描述;
正确修改的文件;
预期测试结果;
不能修改的内容;
最终应该输出什么。
例如:
案例 1: 任务:增加邮箱格式校验 必须修改:user/service.py、tests/test_user.py 禁止修改:payment 模块 必须通过:python -m pytest
每次修改 Harness 后,都重新运行这些案例。
关注以下指标:
任务完成率;
测试通过率;
越权修改率;
平均执行轮数;
工具调用失败率;
人工返工时间。
这样才能知道改动到底有没有效果。
九、Harness 工程的五条实践原则
第一,状态外置,不要依赖模型记忆。
第二,执行和验收分离,不要让 Agent 自己当裁判。
第三,失败要沉淀成规则、测试或工具。
第四,规则文件保持简短,详细内容按需加载。
第五,技术债持续偿还,不要等到项目失控后再集中清理。
总结
Prompt Engineering 解决的是“怎么把任务讲清楚”。
Context Engineering 解决的是“怎么把正确资料送给模型”。
Harness Engineering 解决的是“怎么让 Agent 在真实环境中持续做对”。
真正可落地的 Harness,不是一个复杂的名词,而是一套可以执行的工程机制:
有明确任务;
有可控工具;
有固定流程;
有外部状态;
有自动检查;
有评估数据;
有失败恢复。
如果你正在使用 Codex、Claude Code、Cursor 或其他编程 Agent,不要只花时间修改提示词。
先从这几件小事开始:
建立 AGENTS.md;
建立任务文件;
加入自动检查脚本;
保存 progress.md;
整理一组真实评估案例。
这就是 Harness 工程最简单、也最有效的起点。
更多推荐


所有评论(0)