第 2 章 · Harness 是什么

同一个卖家,两套“跑法”

上一章那个想查竞品价格的跨境卖家,你大概已经默认:给他装个 Agent,它就能自己查、自己看、自己答。但先停一下——到底是什么在背后让这件事真正“跑”起来?

同一个查价任务,如果换一套底层“跑法”,结果可能天差地别:一套跑法让它老老实实查三次就收手、每一步都可回放;另一套跑法让它原地打转烧了一晚上 token,还查不出根因。近年来多个基准(SWE-bench、AgentBench、Terminal-bench)都验证过一件事:同一个模型,换一套底层执行系统,分数能差十到二十几个百分点。

这个“底层执行系统”,就是本章的主角——Harness(执行引擎 / 宿主)。这一章回答四个问题:它到底是什么、怎么判断一个 Agent 有没有像样的 Harness、pi 这个具体实现长什么样、以及它和别的 Harness 比又如何。

Harness 是什么:从“会聊天的模型”到“会干活的系统”

回到第 1 章那句话——Agent = Model + Scaffolding + Harness。三个词拆开,职责完全不同:

  • Model(模型):大模型本身。负责理解和推理,“下一步该做什么”由它判断。但它自己不会动——不打开浏览器、不跑命令、不记上次发生了什么。
  • Scaffolding(脚手架):模型看得见的规则层。系统提示、工具说明、输出格式、解析逻辑。它告诉模型“该按什么规则行动”。
  • Harness(狭义,执行引擎):模型看不见的执行层。它负责把模型的决策真的变成动作——调模型、解析输出、执行工具、把结果放回上下文、管理循环/重试/超时/停止。

一句话记牢:

Scaffolding 决定 Agent 应该按什么规则行动;Harness 决定这些行动如何被真正执行。

“Harness” 在工程里有两个口径,先分清,后面才好说话:

  • 狭义 Harness = 执行引擎:上面说的那一层。pi 的 packages/agent/src/harness/ 就是它。
  • 广义 Harness = 模型之外整套工程系统:把 Scaffolding、工具路由、上下文管理、权限异常、子任务编排全算进来,公式写成 Agent = Model + Harness。本书标题“企业级 Harness 智能体”用的是这个广义口径。

还有一个你会在基准测试里撞见的含义:评测语境下的 Harness,指一个隔离的、自动化的测试沙盒——用 mock 工具、注入故障、限制步数,安全地把 Agent 跑一遍打分。它本质就是把“执行层”标准化、可复现。本书附录 D 会展开。

回到卖家的查价任务:模型只是每轮说“我该去查竞品页”;Harness 才是那个真的打开页面、把价格读回来、再塞回对话、决定要不要继续查的那一层。模型是大脑,Harness 是把大脑的决策变成真实动作的手和脚。

从技术运行时到企业 AI 能力底座

在企业里,Harness 不能只回答“模型怎么调用工具”,还要回答“这次执行服务于什么结果、处于哪个业务状态、用了哪些企业数据、谁允许它采取这个动作、结果如何被评估”。因此,本书所说的广义 Harness,是业务流程与模型执行之间的运行与治理底座

AI 业务能力要素Harness 需要承担的责任
明确经营结果把业务目标、任务类型和结果标识带入每次运行,使轨迹能够关联到最终结果。
真实业务流程管理任务状态、步骤依赖、异常分支、重试、暂停和恢复,而不是只完成一次问答。
可信企业上下文按任务装配必要的数据、规则、知识、历史和权限,并记录来源、版本与时效。
清晰人机分工根据风险决定自动执行、人工确认、转交或拒绝,保存审批人与决策依据。
可调用系统工具注册、校验并审计 ERP、CRM、OMS、浏览器和外部服务的调用。
持续评估优化记录轨迹、成本、质量、风险和业务结果,让线上反馈进入回归集与下一轮改进。

业务流程决定 Agent 要完成什么,Harness 决定它如何安全、可观测、可控制地持续运行。

这也解释了为什么不能先造一个“万能 Agent 平台”再找业务场景。更稳妥的顺序是:先选定一个真实流程和可衡量结果,再交付最小完整闭环;只有多个闭环反复出现相同的运行、权限和评估需求时,才把它们沉淀为公共 Harness 能力。

如何判别:一个 Agent 到底有没有 Harness

先说清楚:下面这 10 项不是某个标准组织颁布的条文,而是一张“判别透镜”——它从 Hugging Face 的 Agent 术语表(明确区分 Model / Scaffolding / Harness),以及 pi、OpenAI Agents SDK、Claude Agent SDK、LangGraph 等真实开源 harness 的共性能力中提炼而来。你拿它逐项打勾,就能判断一个 Agent 到底有没有像样的 Harness、差在哪一层。

别再问“它用了哪个模型”——那和“Agent 好不好”几乎无关。按下面这张清单逐项核查,每一项缺失,都说明 Harness 不完整或不成熟

#维度具备 Harness 的标志缺失的信号
1执行循环有独立 loop,把“模型输出→工具执行→结果回填→下一轮”串成闭环只能问答、不能连续行动
2工具执行工具有注册、参数校验、执行(并行/串行)、结果回填模型只“建议”执行,自己不动手
3状态持久化会话可保存、恢复、回放每次从零开始,关掉就没了
4循环控制/停止有停止判定(最大轮数/达到目标)、能中止容易无限循环、无法中途停
5异常兜底工具失败、格式非法、超时都有兜底,不崩一个工具报错整个 Agent 挂掉
6上下文工程有 token 估算、压缩/摘要、裁剪上下文无限膨胀,超窗就崩
7可观察性事件流/钩子,能看每步、记录轨迹黑盒,无法调试、无法评估
8权限/安全边界沙箱、权限系统、危险操作确认任意执行、无边界
9扩展机制技能/扩展/子代理可被加载调度写死逻辑,无法自我扩展
10动态切换运行时可换模型、调工具集、调策略绑定单一模型,不可配置

拿这张清单去拆任何一个 Agent(包括你以后要造的),就能精准定位“差在哪一层”。比如一个只会问答的 chatbot,第 1、2、4、6、7 项全空——它根本不是 Agent,只是个模型套了层壳。一张“能跑原型”但第 3、5、8 项缺失,就是“能跑不能上生产”。

记住这个顺序:先明确业务结果与执行边界,再建设刚好够用的 Harness。 后面四十多章讲的 ReAct、工具、技能、上下文、多 Agent,都是把业务闭环稳定托住的工程能力。

用 pi 看 Harness 长什么样(概览)

pi 这个项目,全名就是 “Pi Agent Harness”——它从命名起就把“Harness”当第一公民。它的执行引擎全在 packages/agent/src/harness/ 下,对照上面的清单,每项都能指到具体位置:

清单维度pi 怎么做的(文件指向)
执行循环agent-loop.tsrunAgentLoop(双层循环)
工具执行agent-loop.tsexecuteToolCallsParallel/Sequential + before/after 钩子
状态持久化session/ 的会话树(id/parentId,可分支、可回放)
循环控制/停止agent-harness.ts 的阶段机 + shouldStopAfterTurn + abort()
异常兜底工具异常→createErrorToolResult 回填,循环继续
上下文工程compaction/ 的 token 估算 + LLM 结构化摘要
可观察性全链路事件(agent_startagent_end)+ subscribe/on 钩子
权限/安全边界无内置(诚实边界),靠容器化(第 28 章)
扩展机制工具/技能/Hooks/编排四个扩展面(第 35 章)
动态切换运行时 setModel/setThinkingLevel/setTools

注意 pi 的诚实边界:它不内置权限系统——清单第 8 项靠外部容器化补(第 28 章的 Gondolin 微 VM / Docker / OpenShell),不是引擎自带。这也是评估任何 Harness 时要睁大眼睛看的一点:有些能力是“内置”,有些是“留给外部”。

这一层到底在代码里长什么样、每个文件管什么,书末附录 F《pi Harness 代码地图》会带你逐文件走一遍。现在你只需建立框架:pi 把“狭义 Harness”显式抽成一个 harness/ 模块,和 Scaffolding(system-prompt.ts)、运行时入口(agent.ts)严格分离——这正是“Agent = Model + Scaffolding + Harness”在代码层的直接印证。

对比其它 Harness:开源社区真正实现了 Harness 的项目

光看 pi 不够。下面挑几个开源社区里真正把“执行引擎”做出来的重要项目,按上一节的判别维度横向比一比。它们和 pi 一样,核心都是“让 Agent 真正跑起来的那层”,只是抽象层次和心智模型不同:

维度piOpenAI Agents SDKClaude Agent SDKLangGraphAgno
循环暴露度可读可改的代码 + 生命周期钩子AgentLoop 接口可定制框架管循环 + sub-agent显式画成图,控制最细agent.run() 隐藏
工具执行并行/串行 + before/after 钩子函数工具 + handoff工具 + 权限门节点里调类型化工具
状态/持久化会话树(可分支、JSONL)Sessiontranscript 回放checkpointer + 时间旅行Memory(session/agent)
上下文压缩内置 LLM 结构化摘要手动/上下文管理手动/上下文管理手动有 summarizer
可观测/轨迹事件流 + 会话格式内置 tracing流式事件LangSmith内置
权限/沙箱无内置,靠容器化应用层自加内置 allow/deny + 沙箱应用层自加应用层自加
扩展心智在其上构建(harness 视角)agents + handoffagent + sub-agent图(流程视角)电池全含(应用视角)
语言TypeScriptPython · JSTypeScript · PythonPython · JSPython

(Microsoft 的 AutoGen / AG2 也是重要的多 Agent 运行时,侧重多 Agent 对话与代码执行;因其心智模型偏“多 Agent 协作”而非“单 Agent 执行引擎”,此处不展开,但同样可用上面 10 条清单判别。)

一条主线贯穿:它们底层跑的都是同一套模式(ReAct、工具与技能、上下文工程、多 Agent 发散收敛)。差别只在抽象层次与心智模型——理解了模式,你在哪家 harness 里都能很快上手。这也是本书贯穿的用意:我们学的是模式,不是某个 harness 的 API。

量级差别真实存在:有的 harness 是单语言、单进程的轻量实现(如 pi),有的用多语言、多进程把编排/执行/推理拆到不同运行时。但无论量级,上面 10 条判别清单都适用——只是“重”的实现把更多能力内置了。

动手看看

打开任意两个你熟悉的 Agent 项目(或框架文档),用第一节那张 10 条清单逐条打勾:

  1. 它有独立的执行循环吗?还是只是“问一次答一次”?
  2. 工具是真正被“执行”并回填结果,还是只生成一段“建议你运行 XXX”的文本?
  3. 会话关掉再打开,还能接着聊吗?能回到历史某个节点分叉吗?
  4. 它会不会无限循环?有没有“最大轮数”“预算上限”这种硬刹车?
  5. 一个工具报错,是整个 Agent 挂掉,还是被兜住继续跑?

打勾的过程,就是你建立“Harness 判断力”的过程。你会发现:很多号称“Agent”的产品,在第 1、2、4 项上就已经露怯。

小结

  1. Harness 是 Agent 的执行引擎:狭义=模型看不见的那层(调模型、执行工具、管循环/停止);广义=模型之外整套工程系统。它与 Scaffolding 的区别——前者决定“如何执行”,后者决定“按什么规则行动”。
  2. 别问“用了什么模型”,要按 10 条清单判别 Harness:执行循环、工具执行、状态持久化、停止条件、异常兜底、上下文工程、可观察性、安全边界、扩展机制、动态切换——缺一项,Harness 就不完整。
  3. pi 把狭义 Harness 显式抽成 packages/agent/src/harness/,与 Scaffolding 严格分离,是“Agent = Model + Scaffolding + Harness”在代码层的印证;其诚实边界是不内置权限,靠外部容器化补。
  4. 不同 Harness 差别在抽象层次与心智模型,不在底层模式:pi(在其上构建)/ LangGraph(图)/ Agno(电池全含)/ Claude Agent SDK(agent+sub-agent)/ OpenAI(agents+handoff)跑的都是同一套模式。
  5. 先明确业务结果与执行边界,再建设刚好够用的 Harness:ReAct、工具、技能、上下文、多 Agent 都是托住业务闭环的工程能力,不是脱离流程独立存在的技术清单。
  6. 你学的是模式,不是某个 Harness 的 API——有了这张判别框架,换任何 Harness 你都能照清单快速看清它“有什么、缺什么”。

下一章,我们钻进 Harness 最里面的那个齿轮:ReAct 循环——看清“模型输出→工具执行→结果回填”这一最小闭环到底怎么转。