模型为什么需要 Harness:从一次推理到可运行系统
模型回了一句“退款已经处理”,真正该看的却是订单状态有没有变、支付流水有没有生成、第二次重试会不会又退一次钱。
Agent 落地后最先碰到的就是这个落差。模型越会理解目标、调用工具和处理长任务,系统越要交代它能看什么、能做什么、做到哪一步、失败后怎样恢复,以及谁能宣布完成。模型降低了生成候选决策的成本,没有降低系统承担后果的成本。包围模型、让它能在这些约束里运行的整套东西,统称为 Agent Harness。
只调用模型,离完成任务还差什么
Section titled “只调用模型,离完成任务还差什么”一次最简单的模型调用只有三件事:准备输入、请求模型、读取输出。
response = model.generate(messages)print(response.text)这段代码可以回答问题,却不能独立完成现实任务。把需求换成“帮我处理退款”,屏幕外的问题会立刻涌出来:
- 客户是谁,订单是哪一笔?
- 退款政策来自哪里,当前版本是什么?
- 模型能否直接退款,还是只能提出建议?
- 金额和币种怎样验证?
- 工具超时后能否重试?
- 第一次请求其实已成功,第二次重试会不会重复退款?
- 退款完成以后,谁读取数据库确认终态?
- 敏感信息能否进入日志?
这些都不是多写一句 Prompt 能解决的。它们属于身份、上下文、工具、状态、权限、可靠性和审计–模型给出候选动作,Harness 决定候选动作能否变成真实动作。
Harness 包住了什么
Section titled “Harness 包住了什么”先给一个可以直接拿来检查系统边界的定义:
Agent Harness 是包围模型的执行系统。它负责装配上下文和工具,管理状态与生命周期,执行并约束动作,收集环境反馈,记录证据,并决定循环是否继续。
Harness 不是产品名,也不等于 Agent Framework。它可以由一个 SDK 构建,也可以用普通 Python、数据库、队列、沙箱和日志系统组合出来。框架给出零件和默认值,Harness 是这些零件在具体应用里共同形成的运行边界。
下面这张仓库页里,Agent、Runner、Tool、Handoff、Guardrail、Session 和 Trace 看着是一串名词,值得注意的是它们各自对应模型某次选择的落点:能执行、能拒绝、能记录、能恢复。

图 1:OpenAI Agents SDK 展示了 Agent、Runner、Tool、Handoff、Guardrail、Session 和 Trace 等执行原语。来源见文末。
一套 Harness 至少要照看八件事
Section titled “一套 Harness 至少要照看八件事”不必为每一项先搭一套独立服务,但每一项都要有人负责。遗漏的地方,往往会在第一次真实副作用、长任务或故障恢复时暴露出来。
1. Context Assembly:给模型准备什么
Section titled “1. Context Assembly:给模型准备什么”模型每一次决策都依赖当前输入。Harness 要决定:
- 放入哪些系统规则;
- 提供哪些工具定义;
- 取回哪些历史状态;
- 检索哪些外部证据;
- 哪些内容应该压缩;
- 哪些不可信文本必须与系统指令隔离。
上下文不是仓库。把所有历史、工具和文档塞进去,既浪费预算,也会增加冲突和注入风险。
2. Model Adapter:怎样调用不同模型
Section titled “2. Model Adapter:怎样调用不同模型”不同模型在 Tool Call、结构化输出、并行调用、上下文长度、缓存和错误返回上并不完全一致。Harness 要把供应商差异转换成应用能理解的接口,同时保留必要的能力差异。所谓“随时切换模型”,如果只统一了请求格式却没有验证行为变化,得到的往往是虚假的可移植性。
3. Tool Runtime:动作怎样执行
Section titled “3. Tool Runtime:动作怎样执行”工具层至少需要处理:
- 参数验证;
- 身份和授权;
- 超时、重试与取消;
- 结果截断和错误整形;
- 并行与依赖;
- 有副作用动作的幂等;
- 运行环境和网络边界。
模型说“调用退款工具”,不代表应用必须照做。Tool Runtime 才是执行动作的地方。
4. State Management:事实保存在哪里
Section titled “4. State Management:事实保存在哪里”一次运行可能跨越几十步,也可能隔夜等待人工批准。Harness 要保存当前任务、工具结果、计划、工件、预算和待办事项。消息历史能帮助模型理解对话,但不是可靠的状态数据库;关键状态应该结构化、可版本化,并有明确的权威来源。
5. Policy and Guardrails:哪些动作不允许
Section titled “5. Policy and Guardrails:哪些动作不允许”安全规则不能只写在 System Prompt 里。模型可以理解规则,但执行系统必须独立检查高风险动作。常见控制包括目录和域名白名单、工具级权限、金额上限、敏感字段过滤、人工审批、速率限制,以及删除、付款、发布等动作的二次确认。
6. Loop Control:什么时候继续或停止
Section titled “6. Loop Control:什么时候继续或停止”Harness 负责运行 Agent Loop,也要负责限制 Loop:最大轮次、Token 预算、总时长、重复动作、无进展检测,以及成功、失败、暂停和取消等终态。没有这些限制,自治很容易退化成无限重试。
7. Observability and Evidence:发生了什么
Section titled “7. Observability and Evidence:发生了什么”一次 Agent Run 不应只留下最后一句回复。至少要能追踪模型调用、工具调用、Handoff、Guardrail、错误、延迟、Token 和关键状态变化。Trace 回答发生了什么,Evidence 回答任务是否完成,两者相关但不能互相替代。
8. Host Interface:怎样被产品使用
Section titled “8. Host Interface:怎样被产品使用”Agent 可能运行在聊天界面、IDE、后台任务、客服系统或移动端。Harness 需要把内部事件转换为产品能理解的流:文本增量、工具状态、审批请求、工件、错误和恢复入口。只能在命令行输出日志的 Harness,还不是完整的产品运行层。
把八件事放回同一笔退款
Section titled “把八件事放回同一笔退款”用户说:“上周买的耳机有杂音,帮我退款。”不要把它理解成模型“自己退了款”。一个可靠 Harness 的处理顺序大致是:
- 身份层确认用户和订单归属;
- 上下文层读取当前退款政策和订单状态;
- 模型判断还缺少哪些信息;
- 工具层读取物流和售后记录;
- 策略层判断金额是否需要人工批准;
- 模型生成退款动作参数;
- 工具层使用幂等键执行退款;
- 状态层保存交易编号和政策依据;
- 验证器重新读取订单与支付状态;
- 界面层向用户展示真实结果,而不是模型的预期结果。
模型在这条链里负责理解开放语言、补全信息和选择候选动作;身份、授权、交易、终态和审计仍由确定性系统负责。
为什么几十行循环很快会长成一套系统
Section titled “为什么几十行循环很快会长成一套系统”最小 Agent Loop 的确可以很短:调用模型,遇到工具请求就执行,把结果放回消息,再调用模型。一旦离开 Demo,下面四种压力通常会一起出现。
读天气和退订单不是同一级别的工具。动作一旦影响资金、数据、权限或公开内容,就必须增加审批、幂等、审计和回滚。
任务会跨时间
Section titled “任务会跨时间”用户可能十分钟后才批准,外部系统可能两小时后返回,任务也可能因为进程升级而中断。状态和恢复会从“可选功能”变成基本能力。
上下文会膨胀
Section titled “上下文会膨胀”运行越久,消息、工具和材料越多。Harness 必须选择、压缩和隔离上下文,否则模型会在一堆旧信息中做决定。
失败必须能解释
Section titled “失败必须能解释”Demo 失败可以重跑,生产故障需要知道是模型、工具、权限、数据、网络还是状态出了问题。没有 Trace,团队只能盯着最终回复猜。
所以 Harness 变厚,通常不是框架作者喜欢堆功能,是现实责任逐层进入了系统。

图 2:Harness Engineering 成为独立讨论对象,因为模型之外的执行环境会直接影响 Agent 的能力与可靠性。原始出处见图片来源台账。
四条设计路线,区别在控制权归谁
Section titled “四条设计路线,区别在控制权归谁”1. Code-driven:控制留在普通代码
Section titled “1. Code-driven:控制留在普通代码”OpenAI Agents SDK 和 PydanticAI 都重视普通 Python 的组合能力。模型可以选择工具,但应用能够用代码明确编排、验证和异常处理。[1][2]
它容易与现有工程体系结合,代价是长流程和复杂恢复需要额外设计。
2. Graph-driven:状态和路径显式化
Section titled “2. Graph-driven:状态和路径显式化”LangGraph 把 State、Node、Edge、Checkpoint 和 Interrupt 放在核心位置。[3]
它适合分支多、需要人工介入和恢复的任务。代价是图会增加设计负担,简单问题可能被过度建模。
3. Model-driven:把更多编排交给模型
Section titled “3. Model-driven:把更多编排交给模型”Strands 等项目强调模型负责规划和工具选择,应用用 Hook、Session 和策略限制运行。[4]
它能快速覆盖开放任务,但更依赖轨迹评测和权限约束。模型自由度越高,外部证据越不能少。
4. Runtime-driven:让持久化运行时拥有生命周期
Section titled “4. Runtime-driven:让持久化运行时拥有生命周期”Temporal、DBOS 等 Durable Execution 系统不负责模型推理,却能保存流程历史、重试活动和跨故障恢复。[5][6]
在长时 Agent 中,它们常与 SDK 或图框架组合:Harness 负责决策,Durable Runtime 负责“即使机器重启,这件事也不会凭空消失”。
四条路线可以叠加。要选的是控制权和状态归属,不是框架 Logo。
五个一上线就会出问题的误判
Section titled “五个一上线就会出问题的误判”误区一:Prompt 写清楚,权限就安全了
Section titled “误区一:Prompt 写清楚,权限就安全了”Prompt 是行为指导,不是访问控制。高风险动作必须由代码和基础设施检查。
误区二:消息历史就是状态
Section titled “误区二:消息历史就是状态”消息适合交流,不适合承担交易事实、锁、版本和幂等。结构化状态必须独立保存。
误区三:支持很多工具就是能力强
Section titled “误区三:支持很多工具就是能力强”工具越多,选择混淆和攻击面越大。生产系统需要工具搜索、按需加载和最小权限。
误区四:Trace 等于 Evaluation
Section titled “误区四:Trace 等于 Evaluation”Trace 能告诉你调用了什么,不能自动告诉你做得对不对。Eval 需要标准、数据集、环境检查或人工准则。
误区五:框架替你解决了生产问题
Section titled “误区五:框架替你解决了生产问题”框架可以提供原语,无法替你定义订单成功、隐私边界、业务补偿和责任人。
在复杂度上来之前,值得回看下面这张公开文章截图。它强调简单、可组合的模式,Harness 的目标也不是追求复杂,而是承接已经存在的现实责任。

图 3:Anthropic 建议优先使用简单、可组合的模式。Harness 的目标不是追求复杂,而是承接现实责任。来源见文末。
动手:写一张 Harness Contract(30 分钟)
Section titled “动手:写一张 Harness Contract(30 分钟)”选一个你熟悉的任务,例如“整理三份资料并输出摘要”。不要从框架 API 开始,先把下面八项写成一张可讨论的 Contract:
goal: 最终要产生什么可检查结果context: 模型能看到哪些材料tools: 可以调用哪些只读/写入工具state: 哪些事实必须结构化保存policy: 哪些动作禁止或需要审批limits: 最大轮次、时间和预算evidence: 怎样证明任务完成terminal_states: success / failed / paused / cancelled然后检查两件事:
- 把模型换成能力稍弱的模型,系统是否仍能安全失败?
- 运行到一半强制退出,是否知道从哪里恢复?
如果答案都是否,缺的通常不是新 Prompt,是 Harness 责任。这张 Contract 留下来,第 3 讲讨论 Loop 时会补上动作和终态的细节。
边界与下一步
Section titled “边界与下一步”上面列的八类责任不代表每个应用都要部署八套服务。简单任务可以只实现必要边界;一旦涉及资金、隐私、长时执行或公开发布,就不能把权限、状态和证据只留在 Prompt 里。模型继续增强也不会让这些责任自动消失,只会让重点更明显地从“教模型怎么说”移向“规定系统能做什么、怎样验证、怎样负责”。
下一讲进入 Harness 内部最小、也最容易失控的结构:Agent Loop。我们会从 ReAct 出发,看一次运行怎样在推理、行动和观察之间循环,以及停止条件为什么比“继续努力”更值得先设计。
资料与延伸阅读
Section titled “资料与延伸阅读”以下链接均为本章已经引用的官方文档或原始工程文章。先读 [1]、[3] 观察两种框架边界,再按长任务与运行时需要阅读 [5]、[6]。
[1] OpenAI, OpenAI Agents SDK. https://openai.github.io/openai-agents-python/
[2] Pydantic, PydanticAI. https://ai.pydantic.dev/
[3] LangChain, LangGraph Overview. https://docs.langchain.com/oss/python/langgraph/overview
[4] Strands Agents, Introducing Strands Agents. https://strandsagents.com/blog/introducing-strands-agents/
[5] Temporal, Durable Execution. https://docs.temporal.io/
[6] DBOS, Durable Workflows. https://docs.dbos.dev/
[7] Anthropic, Building Effective Agents. https://www.anthropic.com/engineering/building-effective-agents
[8] OpenAI, A practical guide to building agents. https://openai.com/business/guides-and-resources/a-practical-guide-to-building-ai-agents/