一句话理解 Harness
很多人以为「AI Agent」就是「把提示词发给大模型」。但在工程上,让 Agent 真正可靠地完成任务,你需要一套循环引擎——它负责替 Agent 不断「思考 → 调用工具 → 拿结果 → 再思考」,直到任务完成。这套引擎就是 Harness(代理运行时 / 编排层)。
你可以把它理解成 Agent 的操作系统:模型是 CPU,Harness 是调度器。没有 Harness,模型只是「会生成文字的 API」;有了 Harness,模型才变成「能自己干活的 Agent」。
为什么需要 Harness
直接调模型 API 做一件事,你会立刻撞上几个麻烦:
- 模型说「我要调用工具」,你得手动解析输出、执行工具、把结果塞回下一轮请求——这个样板代码极其繁琐
- 多轮交互时,历史怎么维护、上下文怎么不爆?
- 工具出错要不要重试?什么时候该停?循环会不会死?
- 权限怎么控制?高危工具怎么拦?
这些「循环之外」的脏活累活,正是 Harness 解决的。你写业务逻辑,Harness 处理循环与基建。
Harness 的核心组件
一个完整的 Harness 通常包含这几块,缺一不可:
1. Agent 主循环(Tool-use Loop)
这是地基。每次迭代:
- 把「系统提示 + 历史 + 工具定义 + 用户消息」交给模型
- 模型返回文本或
tool_use - 如果是工具调用,Harness 执行工具,把结果以
tool_result塞回上下文 - 回到第 1 步,直到模型给出最终答案
一个最小 Harness 的伪代码,其实就这么短:
def run_agent(model, system, tools, user_msg):
messages = [{"role": "system", "content": system}, {"role": "user", "content": user_msg}]
for _ in range(MAX_ITER):
reply = model(messages, tools=tools)
if reply.has_tool_use():
for call in reply.tool_uses:
result = exec_tool(call) # 执行工具
messages.append(tool_result(call, result)) # 塞回上下文
else:
return reply.text # 没有工具调用,结束
听起来简单,但实现细节全在这:工具结果怎么格式化、什么时候该停、出错要不要重试、上下文爆了怎么办。Agent SDK 的 tool_runner 就是帮你把这个循环跑起来,不用自己手写。
2. 上下文窗口管理
Agent 最贵的资源不是 token,是上下文。Harness 必须回答:
- 历史太长怎么办 → 压缩、摘要、滑动窗口
- 中间结果要不要全保留 → 只保留对后续有用的
- 怎么让重复前缀不重复计费 → Prompt Caching
上下文管得好,Agent 就「清醒」;管不好,Agent 就「失忆」——后半程开始胡说。
3. 工具调度
Agent 的能力上限 = 它拥有的工具质量。Harness 负责:
- 把工具定义(schema)传给模型
- 执行工具、捕获结果
- 管理工具间的依赖、并发、超时
- 把工具返回的原始数据整理成模型看得懂的形式
4. 记忆
Harness 让 Agent 跨任务「记得住」——项目规范、历史决策、用户偏好。可能是向量库,也可能只是一个结构良好的配置文件(比如 Claude Code 的 CLAUDE.md)。记忆决定了 Agent 是「每次从零开始」还是「越用越懂你」。
5. 权限与沙箱
高危工具(删文件、发请求、部署)需要护栏。Harness 做权限校验、确认提示、最小工具集。这是工程上最容易忽略、却最要命的一块。 一个没有权限控制的 Agent,等于把核按钮交给了它。
6. MCP
MCP(Model Context Protocol)是个标准化接口:让 Agent 通过统一协议连接外部工具和数据源。Harness 实现了 MCP client 端,Agent 就能即插即用地接入各种 MCP server,而不必为每个工具写私有协议。好处是生态——别人写好的 MCP server,你能直接复用。
自建 vs 用现成
你可能会想「我要不要自己写个 Harness?」
| | 现成(Claude Code / Agent SDK) | 自建最小 Harness | |---|---|---| | 上手 | 快,开箱即用 | 慢,要自己搭 | | 稳定性 | 高,踩过坑 | 低,坑要自己踩 | | 定制性 | 受限 | 完全可控 | | 场景 | 大多数产品化需求 | 特殊编排、多 Agent 协作、教学 |
我的建议:先彻底用熟现成的,理解它的取舍,再决定要不要自建。别为了「显得高级」而造轮子。
设计取舍
- 窗口大小 vs 记忆深度:上下文给得越多越准,但越贵越慢。找平衡点。
- 循环迭代 vs 成本:多迭代几次可能更对,但 token 成倍涨。给循环设上限。
- 自由度 vs 可控性:工具越开放 Agent 越强,但也越危险。权限永远是护栏。
- 响应式 vs 主动性:是「你问它答」,还是「它自己觉得该干了就干」?主动性越强,越需要护栏。
自建一个最小 Harness 的思路
如果你真想理解 Harness,从零搭一个最小版是最好的方式:
- 先不管工具,只写「调模型 → 返回文本」的最简循环
- 加工具:定义工具 schema,解析模型的
tool_use,执行,塞回结果 - 加护栏:迭代上限、超时、错误重试
- 加记忆:把系统提示从硬编码改成可持久化
- 加权限:给高危工具加确认机制
每一步都亲自动手,你就能真正理解为什么 Harness 是 Agent 的「操作系统」。这也正是我推荐的进阶路径——理解它,然后决定用现成的还是自己造。
一句话总结
Harness 是把模型变成 Agent 的「操作系统」。真正的 Agent 工程,80% 的功夫都花在 Harness 上——上下文怎么管、工具怎么给、记忆怎么存、权限怎么设。理解了 Harness,你就理解了 Agent 是怎么「活」起来的。