引言:你的 AI Agent 表现差,真的是模型的锅吗?
你有没有遇到过这样的场景:
花了三周搭了一个 AI 测试 Agent,目标是自动跑回归、写用例、定位缺陷。结果 Agent 死循环、直接编报告、调了不存在的接口还觉得自己成功了......于是你的第一反应是------换个更强的模型?
换成 GPT-4,还是乱。换成 Claude 4.6,还是乱。
直到你打开那个 Agent 的 system prompt,发现里面只有一句话:
你是一个测试工程师,帮我测试这个系统。
就这,十三个字。
这不是模型的问题。这是 Harness(驾驭系统) 的问题。
一、Harness 驾驭工程是什么?
Harness Engineering(驾驭工程),是 2026 年初从硅谷迅速流行起来的 AI 工程化新范式。
这个词最早由 HashiCorp 联合创始人 Mitchell Hashimoto 在 2026 年 2 月的博客中提出:
"Harness engineering is the idea that anytime you find an agent makes a mistake, you take the time to engineer a solution such that the agent will not make that mistake again in the future."
------驾驭工程的核心理念是:每当发现 AI Agent 犯错,就构建一套工程化方案,确保它未来不会再犯同样的错误。
六天后,OpenAI 在百万行代码实验报告中正式采用这一术语,Martin Fowler 随即撰文深度解析。一个月内,Harness Engineering 成为 2026 年 AI 工程领域最核心的新范式。
核心公式
Agent = Model(模型)+ Harness(驾驭系统)
- 模型 是那匹有力量的烈马------提供强大的推理与生成能力
- Harness 是马具------缰绳、马鞍、嚼子------提供约束、引导、验证与反馈
模型决定了智能的上限 ,Harness 决定了系统稳定运行的底线。
有好发动机但没底盘没方向盘没刹车,跑起来只会撞墙。
与提示词工程的区别
驾驭工程是继 Prompt Engineering(提示词工程) 和 Context Engineering(上下文工程) 之后的第三次重心转移:
| 工程范式 | 关注点 | 解决的问题 |
|---|---|---|
| Prompt Engineering | 如何表达任务 | 单次输入-输出的质量 |
| Context Engineering | 模型看到什么 | 执行任务时的信息充分性 |
| Harness Engineering | 模型运行在什么系统里 | Agent 长期稳定、可控地执行 |
三者不是竞争关系,而是分层叠加的关系。
二、为什么测试工程师最容易踩这个坑?
这是一个有趣的悖论。
测试工程师天天和"系统边界"打交道,按理说最懂如何约束系统。但恰恰是太了解被测对象 ,反而忽略了 Agent 本身也是一个需要被测、被约束的系统。
心态上和第一次写测试框架一样------"先跑起来再说",system prompt 随手写一句,发现乱了就怪模型。
但其实,测试工程师天然拥有构建 Harness 的核心思维:
- 明确前置条件(Pre-conditions)
- 可重复执行的步骤(Test Steps)
- 可验证的预期结果(Expected Results)
把这套思维挪到 Agent 设计上,就是 Harness Engineering 的本质。
你对待被测系统的方式,就是你建 Agent Harness 应该有的方式。
三、Harness 六层结构详解
一个完整的 Agent Harness,可以拆解为以下六层。对于测试工程师来说,每一层都有熟悉的对应概念。
第一层:角色定义层(System Prompt)
这是 Harness 的地基,也是最容易被轻视的一层。
错误示范:
你是一个测试工程师,帮我测试这个系统。
正确的 System Prompt 应该包含:
| 要素 | 说明 | 测试视角类比 |
|---|---|---|
| 具体角色定位 | Agent 在整个系统中承担什么 | 测试用例的 Scope |
| 任务边界(能做什么) | 允许操作的范围 | 测试范围(In Scope) |
| 禁止项(不能做什么) | 明确不允许的行为 | 排除项(Out of Scope) |
| 歧义处理方式 | 不确定时如何行动 | 异常分支处理策略 |
关键原则:不写边界,模型会自己脑补,脑补版本往往不是你想要的。
第二层:工具设计层(Tool Design)
工具是 Agent 的"手",设计不当是 Bug 的高发地。
两条核心原则:
① 原子性(Atomicity):每个工具只做一件事。
❌ 一个工具:call_api_and_assert_and_log()
✓ 三个工具:call_api() + assert_response() + log_result()
这与单元测试的设计原则完全一致------每个测试只验证一件事。
② 防误用(Misuse Prevention) :工具描述中明确写出"什么情况下不该调用"。
真实案例:因 system prompt 不清楚,一个 AI 测试 Agent 把生产环境接口当测试接口调用了。
第三层:输出校验层(Output Validation)
不校验 Agent 输出,等于不写断言的测试用例。
正确做法:
python
# 强制 JSON 输出 + Schema 校验
from pydantic import BaseModel
class TestResult(BaseModel):
case_id: str
status: Literal["PASS", "FAIL", "SKIP"]
actual_response: dict
assertion_result: bool
# 校验不过 → 拒绝并重试 → 重试超次 → 终止报错
不做此层的后果: Agent 会静默地把字符串当对象处理,后续全错,最终生成一份充满"幻觉"数据的正式报告------这是比没有报告更危险的情况。
第四层:上下文管理层(Context Management)
这一层解决的是测试规模扩展的问题。
测试跑多了,token 窗口会爆。解决方案:主动管理上下文,决定哪些历史保留、哪些压缩摘要、哪些直接丢弃。
实践经验:
每轮测试结果只保留三行摘要,替换原始完整响应。50 个测试用例跑下来,上下文窗口依然游刃有余。
原始记录(几千 token):
HTTP 200 OK
{"user_id": 123, "name": "...", ...完整 JSON 响应...}
断言通过:状态码=200, 字段 user_id 存在
压缩摘要(几十 token):
用例 #001 PASS | 状态码200 | 断言通过
对测试工程师来说,这就是测试结果聚合的 Agent 版本。
第五层:错误恢复层(Error Recovery)
核心原则:把重试逻辑写进 Harness,不要让模型自己决定是否重试。
| 失败类型 | 建议策略 | 原因 |
|---|---|---|
| 接口超时 | 重试一次 | 网络抖动是合理的,重试有意义 |
| 断言失败 | 标记失败,继续下一条 | 业务 Bug,重试无意义 |
| 工具调用异常 | 降级处理或人工介入 | 环境问题,需要人工判断 |
这与测试框架中的 @retry、teardown、on_failure 钩子设计是同一套思路。
第六层:可观测层(Observability)
没有 trace,就没有定位问题的能力。
要求:每次工具调用、每次模型回复、每次校验结果,全部打结构化日志。
推荐工具:LangSmith 、Langfuse,或自建 trace 系统。
真实案例:
凭借完整 trace,15 分钟定位到"上下文第 38 轮之后,模型开始忽略 tool_choice 约束"。没有 trace,这个问题可能永远都是"玄学"。
这与测试工程师对测试日志的要求完全一致:每个步骤有记录,失败必有现场,复现有依据。
四、有 Harness vs 没有 Harness:同一个模型的两种命运
用一个对比案例来直观说明 Harness 的价值:
同一个任务:对 5 个接口用例执行回归测试
| 步骤 | ❌ 没有 Harness(只有一句 Prompt) | ✓ 有完整 Harness |
|---|---|---|
| 第 1 轮 | 模型自行决定"先理解架构",开始自由探索 | 读取测试用例列表,返回 5 个用例 |
| 第 2 轮 | 调用同一接口 3 次,觉得都成功了 | 执行用例 1,调用接口,获得响应 |
| 第 3 轮 | 编写测试报告,断言全部通过 | Schema 校验通过,断言状态码 200 通过,记录结果 |
| 最终 | 一个真实断言都没跑,报告纯属编造 | 5/5 用例均有实际响应数据支撑的报告 |
模型是同一个。差别只在 Harness。
五、测试工程师的 Harness 排查清单
当你的测试 Agent 表现不稳定时,按以下顺序排查(别急着换模型):
Step 1:看 System Prompt
□ 有没有明确的任务边界?
□ 有没有禁止项?
□ 有没有歧义处理策略?
→ 通常这一步就能解决 70% 的"模型问题"
Step 2:看工具定义
□ 每个工具是否只做一件事(原子性)?
□ 每个工具的 description 有没有说清楚"不该什么时候调用"?
→ 这一步解决剩余问题中的约一半
Step 3:看输出校验
□ 有没有结构化输出约束(JSON Schema)?
□ 有没有静默失败的地方?
→ 消灭幻觉报告的关键防线
Step 4:看日志
□ 有没有完整 trace?
□ 能不能复现问题?
→ 没有 trace 的 Bug 调试是在赌运气
真正因为模型能力不够造成的问题,其实很少。
六、从测试框架视角理解 Harness 的整体结构
Martin Fowler 在其 2026 年 4 月发表的 Harness Engineering for Coding Agent Users 中,将 Harness 的控制机制分为两个维度:
① 前馈控制(Feedforward / Guides)
- 在 Agent 行动之前施加约束,提高一次成功率
- 对应测试视角:测试前置条件、测试数据准备、环境 Setup
② 反馈控制(Feedback / Sensors)
- 在 Agent 行动之后观测结果,驱动自我修正
- 对应测试视角:断言验证、用例结果记录、失败重试
③ 执行类型区分:
| 类型 | 特点 | 对应工具 |
|---|---|---|
| 计算型(Computational) | 确定性、快速、CPU 执行 | 单元测试、Linter、Schema 校验 |
| 推理型(Inferential) | 语义分析、非确定性、GPU 执行 | AI Code Review、LLM Judge |
测试工程师对"计算型传感器"应该最为熟悉------它们就是我们每天在写的断言、类型检查、静态分析。把这些工具接入 Agent 的 Harness,就是在让 Agent 受益于几十年积累的软件工程经验。
七、对于 AI 时代测试工程师的启示
Harness Engineering 的出现,不是对测试工程师的威胁,而恰恰是测试工程师最擅长的领域的价值回归。
你们已经掌握的,正是 AI Agent 最需要的:
- 边界思维 → System Prompt 设计
- 用例设计 → Agent 任务分解
- 断言设计 → 输出校验层
- 异常处理 → 错误恢复策略
- 测试日志 → 可观测层
- 回归测试 → 持续迭代 Harness
在 AI Agent 快速普及的今天,测试工程师的角色正在从"测试被测对象"演进为**"设计让 AI 正确运行的约束系统"**。
而这,本质上正是测试工程一直在做的事情------只是现在,被测的对象变成了 AI。
结语
"Harness Engineering 不是什么新概念,测试工程师早就在做类似的事。只不过现在被测的对象变成了 AI,你得把同样的专业标准用上去。
你对待被测系统的方式------明确输入、可验证输出、可重复执行------就是你建 Agent Harness 应该有的方式。
下次 Agent 表现差,先别去找更大的模型。先看看你的 Harness 写了什么。"
参考资料
- Mitchell Hashimoto, Six Ways I Use LLMs --- 驾驭工程概念原点 (2026-02-05)
- OpenAI Engineering, Harness Engineering: Leveraging Codex in an Agent-First World (2026-02-11)
- Martin Fowler, Harness Engineering for Coding Agent Users (2026-04-02) --- https://martinfowler.com/articles/harness-engineering.html
- Anthropic Engineering, Effective Harnesses for Long-Running Agents --- https://www.anthropic.com/engineering/effective-harnesses-for-long-running-agents
- 鸡腿·测试的鸡腿, 什么是 Harness 驾驭工程?测试工程师造 AI Agent 时,驾驭比换大模型更急 (2026-04-01)
- Prompt、Context、Harness:AI Agent 工程的三层架构解析 --- 百家号 (2026-04-09)
- 告别"模型迷信":Harness Engineering 如何成为 AI 智能体架构的下一代护城河 --- 百家号 (2026-04-10)