你见过赛车比赛吗?一个顶级赛车手,技术再好、反应再快,如果给他一辆没有刹车、没有仪表盘、油门踩到底就停不下来的车,你敢让他上赛道吗?大模型就像这个赛车手——它聪明、博学、反应快,但如果你不给它装上一套精心设计的”赛车系统”(刹车在哪、仪表盘显示什么、什么时候进站加油),它很可能跑着跑着就冲出赛道了。这个”赛车系统”,就是今天要聊的 Harness(工程骨架)

这是「小白讲 AI」系列的第 14 篇。上一篇我们聊了 Context Engineering——怎么管好 AI 看到的信息。这一篇我们往上再走一层:不只是管信息,而是搭建一整套系统骨架,让 Agent 在可控的轨道上自主运行。

一、开场类比:赛车手需要一辆好车

先来想一个问题:第 8 篇里我们说 Agent 能”自己干活”——它能调用工具、观察结果、决定下一步。但谁来决定它能调用哪些工具?谁来确保它不会无限循环下去?谁来在它做了一件危险操作之前拦住它

答案不是模型自己。模型只管”想”和”说”。管住模型的那套系统,才是 Harness。

回到赛车的类比:

赛车手(大模型) 赛车系统(Harness)
能力 开快车、判断弯道、选择路线 提供刹车、油门、方向盘、仪表盘
角色 做决策 执行决策 + 约束决策
如果缺了 有脑子没手脚 有手脚没脑子
现实产品 GPT-4、Claude、Gemini 等 LangChain、Claude Code 的底层系统

**模型是大脑,Harness 是身体。**一个再聪明的大脑,也需要一个可靠的身体来执行它的想法,并在必要时阻止它做傻事。

二、什么是 Harness:模型外面那一圈”脚手架”

Harness 这个词在英文里的本意是”马具”或”安全带”——把力量约束在正确的方向上。在 AI Agent 的语境下,Harness 指的是围绕大模型的所有非模型代码

换句话说:一个 Agent 应用 = 大模型 + Harness。

大模型负责理解语言、推理和生成文本。Harness 负责所有其他事情:

  • 告诉模型它有哪些工具可以用
  • 在模型每次回复后解析它的输出
  • 真正去执行模型请求的工具调用
  • 把工具的执行结果喂回给模型
  • 管理对话历史和状态
  • 在模型想做危险操作时拦住它
  • 决定什么时候该停止循环

如果把模型比作一个智囊,那 Harness 就是智囊身边的整个参谋部 + 后勤部 + 安全部。智囊出主意,参谋部负责执行,后勤部负责补给,安全部负责不让智囊做出格的事。

Harness 和 Prompt 的关系

上一篇聊的 Context Engineering 是 Harness 的一部分——具体来说,是 Harness 中负责”组装上下文”的模块。但 Harness 比 Context Engineering 大得多,它还包括工具管理、安全控制、状态管理、编排逻辑等等。

打个比方:如果 Agent 是一家公司,那么:

  • Prompt 是公司的使命宣言(告诉员工”我们是谁、做什么”)
  • Context Engineering 是信息管理部门(确保员工拿到正确的资料)
  • Harness 是整个公司的管理体系(组织架构、工作流程、安全制度、绩效考核全包了)

三、Harness 的五大组件

一个完整的 Harness 通常包含五个核心组件。我们逐个来看。

组件一:Tool Registry(工具注册表)

这是 Agent 的”工具箱清单”。它定义了 Agent 可以使用哪些工具,以及每个工具的用法。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# 工具注册表示例(伪代码)
tools = [
{
"name": "web_search",
"description": "在互联网上搜索信息",
"parameters": {
"query": "搜索关键词(字符串)"
}
},
{
"name": "read_file",
"description": "读取本地文件的内容",
"parameters": {
"path": "文件路径(字符串)"
}
},
{
"name": "run_python",
"description": "执行一段 Python 代码并返回结果",
"parameters": {
"code": "要执行的 Python 代码(字符串)"
}
}
]

Tool Registry 不只是一个列表,它还回答了几个重要问题:

  • Agent 能用什么?:只有注册了的工具才能被调用,没注册的连”菜单”上都看不到
  • 怎么用?:每个工具的参数格式、类型约束
  • 什么时候用?:工具的描述帮助模型判断在什么场景下该选用哪个工具

这就像一个新员工入职时拿到的”系统权限列表”——你能用内部邮件、能用项目管理工具、但不能直接操作生产数据库。

组件二:Context Assembly(上下文组装器)

这就是我们上一篇花了整篇文章讲的 Context Engineering 的具体实现。它负责在每次调用模型之前,把所有信息拼装成一个完整的上下文:

1
2
3
4
5
6
7
8
9
10
11
[System Prompt]
+
[压缩后的对话历史]
+
[RAG 检索到的相关文档]
+
[上一步工具调用的返回值]
+
[用户最新的输入]
=
最终发送给模型的完整 Prompt

Context Assembly 就像一个厨师在每道菜上桌前的”装盘”环节——把所有食材按正确的顺序和比例摆在盘子里,确保好看又好吃。

组件三:Guardrails(护栏系统)

这是 Harness 中最关键的安全组件。它确保 Agent 不会”跑偏”或”翻车”。

2026 年,业界总结出了一种叫做 Guardrail Layering(分层护栏) 的生产就绪模式,它在 Agent 执行的四个关键节点设置检查:

1
2
3
4
5
6
7
用户输入 ──→ [输入护栏] ──→ 模型处理 ──→ [输出护栏]
│ │
▼ ▼
[工具调用护栏] [后处理护栏]


工具执行结果 ──→ [结果护栏]

第一层:输入护栏(Input Guardrails)

在用户输入到达模型之前进行过滤。比如:

  • 检测 Prompt 注入攻击(用户试图通过特殊指令劫持 AI 的行为)
  • 过滤敏感信息(比如用户不小心贴了密码)
  • 验证输入格式

第二层:工具调用护栏(Tool Call Guardrails)

在模型决定调用工具之后、实际执行之前进行拦截。比如:

  • 不允许删除系统文件
  • 不允许向未授权的 API 发请求
  • 高危操作需要用户确认(”Agent 想要删除这个文件,是否允许?”)

第三层:工具结果护栏(Result Guardrails)

在工具返回数据后、喂给模型之前进行处理。比如:

  • 截断超长返回值
  • 脱敏(隐藏返回数据中的敏感信息)
  • 验证数据格式

第四层:输出护栏(Output Guardrails)

在模型生成最终回复后、发送给用户之前进行检查。比如:

  • 内容安全过滤(不输出有害内容)
  • 事实性检查(标记未经验证的说法)
  • 格式校验(确保输出符合预期的结构)

四层护栏像是一栋大楼的四道安全门——进大门要刷卡(输入),按电梯要验指纹(工具调用),出电梯要过安检(结果检查),离开大楼要签退(输出检查)。每一层都减少一层风险。

组件四:State Management(状态管理器)

Agent 在多步骤任务中需要记住”自己走到哪了”。State Management 负责维护这些状态:

  • 对话历史:之前说了什么、做了什么
  • 中间结果:每一步工具调用的返回值
  • 任务进度:10 步计划中现在走到了第几步
  • 变量存储:过程中产生的需要后续使用的数据

你可以把它想象成一个项目经理的笔记本——上面记着”任务 1 已完成、任务 2 进行中、任务 3 待开始,张三负责的部分已经交付了,李四的还没有”。

没有状态管理的 Agent 就像一个失忆的项目经理:每次开会都忘了上次说了什么,每件事都要从头讨论。

组件五:Orchestration Logic(编排逻辑)

这是 Harness 的”总指挥”,决定了整个 Agent 的工作流程。它回答的核心问题是:什么条件下走哪条路?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
# 编排逻辑示例(伪代码)
while not task_completed:
# 1. 组装上下文
context = context_assembly.build(history, tools, user_input)

# 2. 调用模型
response = model.generate(context)

# 3. 解析模型输出
if response.wants_to_call_tool:
# 走工具调用分支
tool_result = execute_tool(response.tool_call)
history.add(tool_result)
elif response.wants_to_ask_user:
# 走人机交互分支
user_reply = ask_user(response.question)
history.add(user_reply)
elif response.is_final_answer:
# 走结束分支
task_completed = True
return response.answer

# 4. 检查安全边界
if step_count > MAX_STEPS:
return "任务超出最大步数限制,已终止"

编排逻辑就是 Agent 的”交通规则”——红灯停绿灯行、转弯要打转向灯、超速要罚款。没有交通规则的城市,车再好也会出事故。

四、Bounded Execution:给 Agent 装上”熔断器”

在 Harness 的所有组件中,有一个设计理念在 2026 年被越来越多地强调:Bounded Execution(有界执行),也叫 Circuit Breaker(熔断器)模式。

为什么要”熔断”?因为 Agent 有一个天然的风险:无限循环

还记得第 8 篇里提到的 ReAct 循环吗?感知 → 思考 → 行动 → 观察 → 再思考……这个循环理论上可以一直转下去。如果 Agent 遇到一个它解决不了的问题但又不知道”放弃”,它就会陷入:试一下 → 失败 → 换个方式试 → 又失败 → 再换一个 → 还是失败……

每一次循环都要调用大模型的 API,每一次调用都消耗 Token、花钱、花时间。更糟糕的是,一个陷入循环的 Agent 可能会反复调用外部 API,触发对方的速率限制(Rate Limits)

来看一组 2026 年的真实数据(来自 Datadog 对上千家企业的生产环境监测):

2026 年 2 月,5% 的所有 LLM 调用 span 报告了错误,其中 60% 的错误来自速率限制。ReAct 式的可变循环和多 Agent 协作通过重试级联加剧了这个问题。

60%!超过一半的 LLM 调用错误都是因为”调太多次被限流了”。这就是为什么 Bounded Execution 如此重要。

Bounded Execution 的三条规则

规则一:最大步数限制

给 Agent 设一个硬上限:最多跑 N 步。比如设为 25 步——如果 25 步之内还没完成任务,就强制停止,返回”任务未完成”的提示。

1
2
3
4
5
6
MAX_STEPS = 25
for step in range(MAX_STEPS):
result = agent.run_one_step()
if result.is_done:
return result
return "任务在 25 步内未完成,请检查任务复杂度或提供更多信息。"

规则二:工具调用上限

每次循环中,限制单个工具被调用的最大次数。比如搜索工具最多调 5 次——防止 Agent 陷入”搜索 → 不满意 → 再搜索 → 还不满意 → 继续搜索”的无限循环。

规则三:超时机制

设一个总时间上限。比如整个任务最多运行 5 分钟。超时后强制中断,把已有的结果返回给用户。

这三条规则就像电路里的保险丝——正常运行时你感觉不到它的存在,但一旦电流过大(Agent 失控),它就会跳闸断电(强制停止),保护整个系统不被烧毁。

五、Harness vs Framework:它们是什么关系?

你可能已经注意到了:我们前面讲的 Harness 的五大组件——工具注册、上下文组装、护栏、状态管理、编排逻辑——不就是 LangChain、LangGraph 这些框架在做的事情吗?

没错。框架(Framework)就是别人帮你写好的 Harness。

Harness Framework
定义 围绕模型的所有非模型代码 提供通用 Harness 组件的开源库/商业工具
谁写的 你自己 社区/公司
灵活性 完全定制 在框架规则内定制
开发速度 慢(什么都要自己搞) 快(拿来就用)
学习成本 低(只需要了解你自己的代码) 高(需要学框架的概念和 API)

什么时候用框架?什么时候自己写 Harness?

  • 快速原型验证:用框架。你只是想验证一个想法可不可行,不需要从零造轮子。
  • 简单场景:自己写 Harness。如果你的 Agent 只需要调一两个工具、跑几步就完事,用框架反而是杀鸡用牛刀。
  • 生产级系统:要么用成熟框架的部分组件,要么自己写。很多团队的做法是”取框架之长”——用框架的状态管理模块,但自己写编排逻辑和护栏。
  • 特殊需求:自己写。如果你的场景有独特的安全要求、性能要求或业务逻辑,通用框架可能满足不了。

第 17 篇我们会详细对比市面上的主流框架(LangGraph、OpenAI Agents SDK、CrewAI 等),到时候你会更清楚如何选择。

六、一个完整的 Harness 长什么样?

让我们把五大组件拼在一起,看看一个完整的 Harness 的工作流程:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
用户发送消息


┌─────────────────┐
│ 输入护栏 │ ← Guardrails 第一层
│ 检查注入攻击 │
│ 过滤敏感信息 │
└────────┬────────┘


┌─────────────────┐
│ 上下文组装器 │ ← Context Assembly
│ 拼装 System │
│ Prompt + 历史 │
│ + 检索结果 │
└────────┬────────┘


┌─────────────────┐
│ 调用大模型 │ ← 模型本身
│ (推理 + 生成) │
└────────┬────────┘


┌─────────────────┐
│ 解析模型输出 │ ← Orchestration Logic
│ 判断:调工具? │
│ 问用户?结束? │
└────────┬────────┘

┌────┴────┐
▼ ▼
调用工具 生成回复
│ │
▼ ▼
┌────────┐ ┌────────┐
│工具调用│ │输出护栏│ ← Guardrails 第四层
│护栏 │ │内容安全│
└───┬────┘ └───┬────┘
│ │
▼ ▼
执行工具 返回给用户


┌─────────────┐
│ 结果护栏 │ ← Guardrails 第三层
│ 截断/脱敏 │
└──────┬──────┘


┌─────────────┐
│ 状态更新 │ ← State Management
│ 保存结果 │
│ 更新历史 │
└──────┬──────┘


回到"上下文组装器"
开始下一轮循环

每一个方框都是 Harness 的一部分。模型只负责中间那个”调用大模型”的步骤——剩下的全是 Harness 在干活。

这就是为什么我们说 Agent = 模型 + Harness。模型是引擎,Harness 是除了引擎以外的整辆车。

七、好的 Harness 与坏的 Harness

最后,让我们对比一下好的 Harness 和坏的 Harness 有什么区别:

维度 好的 Harness 坏的 Harness
安全性 四层护栏,关键操作需确认 没有护栏,Agent 想做什么就做什么
可控性 有熔断机制,超限自动停止 没有限制,Agent 可能无限循环
可观测性 每一步都有日志,可以追溯 “黑箱”运行,出了问题无从排查
灵活性 工具可插拔,流程可配置 硬编码,改一个地方要改一片
健壮性 工具调用失败有重试和降级 工具一报错整个 Agent 就崩了

一句话:好的 Harness 让 Agent 既能自主又不失控——像一匹好马加上一副好马具,既跑得快又不会把骑手甩下去。

总结

让我们回顾一下今天的内容:

  • Harness 是围绕大模型的所有非模型代码——模型是大脑,Harness 是身体。
  • 五大组件:Tool Registry(工具注册)、Context Assembly(上下文组装)、Guardrails(护栏)、State Management(状态管理)、Orchestration Logic(编排逻辑)。
  • Guardrail Layering:在输入、工具调用、工具结果、输出四个节点设置安全检查,是 2026 年的生产就绪模式。
  • Bounded Execution:给 Agent 装上”熔断器”——最大步数、工具调用上限、超时机制,防止无限循环和资源浪费。
  • Harness vs Framework:框架是别人写好的 Harness,选择取决于你的场景和需求。

如果说 Context Engineering 是”管好 AI 看到什么”,Harness 工程就是”搭好 AI 运行的整套系统”。前者是信息管理,后者是系统工程。


延伸阅读

  1. Building effective agents - Anthropic —— Anthropic 的 Agent 构建指南,详细讨论了工具注册、状态管理和安全设计。
  2. Datadog State of AI Engineering 2026 —— 基于真实生产环境遥测数据的行业报告,Rate Limits 和错误模式的数据来源。
  3. Agentic Design Patterns - Augment Code —— 2026 年 Agent 设计模式的系统总结,Guardrail Layering 和 Bounded Execution 的详细讲解。

小白讲 AI 系列第 14 篇完。下一篇我们聊聊 Loop 工程——Harness 搭好了”骨架”,那 Agent 的”心跳”到底是怎么跳的?从 Plan 到 Execute 到 Reflect,循环该怎么设计才靠谱?