Agent Harness 是把模型输出转化为受约束、可观测工作的运行时控制层。它不会让模型天然拥有权威,而是决定模型能看到什么上下文、哪些动作提议有效、使用谁的凭证、如何执行副作用、提交什么状态,以及失败后能否继续。
本文讨论 AI 智能体运行时基础设施,不涉及电气线束、测试夹具硬件或机械工程中的 Harness。
本文只负责架构与数据流。相邻搜索意图由以下页面承接:
- Harness Engineering:学科定义、范围与组织边界。
- Harness Engineering 实战指南:MCP、工作流、沙箱与 Human-in-the-Loop 实现。
- Agent Harness 评测指南:回放、故障注入与发布门禁。
- Agent Harness 术语:简明实体定义。
直接回答
不存在一个标准化的 Agent Harness 产品,也没有全行业强制一致的组件清单。团队可以用应用代码、Agent SDK、状态机、队列、策略服务、隔离 Worker 和事件管道组合实现。
真正稳定的是责任边界:
模型负责提议;Harness 负责授权、执行、记录与恢复。
只有 Prompt 或 Tool Calling API,不等于生产级 Harness。Harness 必须保留概率性提议与权威副作用之间的边界。
Agent Harness、Agent Loop、Runtime 与工作流引擎的边界
不同厂商会混用这些术语。设计系统时应定义内部契约,不能假设名称存在统一含义。
| 概念 | 主要职责 | 谁决定下一步 | 它不能证明什么 |
|---|---|---|---|
| 模型 | 根据输入上下文生成文本、结构化输出或工具提议 | 模型推理 | 权限、执行、持久化或正确性 |
| Agent Loop | 重复模型决策、环境观察与动作,直至终态 | 通常由模型在运行时限制内动态决定 | 持久状态、隔离或副作用安全 |
| 工作流引擎 | 执行预定义 DAG、状态机或调度计划 | 应用代码或声明式图 | 模型选择的动作已经获得授权 |
| Agent Runtime | 承载并调度一个或多个 Agent 会话 | Runtime 加已配置的循环或工作流 | 某种具体策略、证据或恢复设计 |
| Agent Harness | 中介一次运行的上下文、能力、策略、状态、副作用、证据与恢复 | 模型提议,确定性控制决定能否执行 | 绝对安全或模型推理一定正确 |
Anthropic 的工程文档提供了相近的区分:Workflow 沿预定义代码路径执行,Agent 则动态决定过程与工具使用。两者都可以运行在 Harness 内;模型获得的自主权越大,Harness 契约就越需要显式化。
四个架构平面
将职责划分为四个平面,比背诵固定的“六层架构”更利于落地。
1. 控制平面
控制平面拥有不能下放给模型文本的决策:
- 身份、租户、目的与资源上下文
- 能力白名单与工具 Schema 版本
- 策略评估与审批要求
- 步数、墙钟时间、Token、费用、重试与字节预算
- 取消、终止与升级规则
模型可以建议执行某个动作,但不能自行增加能力、扩大凭证范围或把自己的动作标记为已审批。
2. 执行平面
执行平面把已授权提议转换为有边界的操作:
- 模型与 Provider Adapter
- 工具注册表和参数校验
- 按负载风险选择沙箱或隔离 Worker
- 单工具超时、并发限制与输出上限
- 稳定操作 ID 与下游幂等键
沙箱可以收窄故障影响范围,但不能替代授权。一个与宿主机隔离的进程,仍可能滥用 API 凭证或发出外部可见请求。
3. 状态平面
状态平面是“运行已知什么、系统已提交什么”的事实源:
- Run、Step、Tool Call 与 Approval 标识
- 使用乐观并发控制的版本化运行状态
- 消息、产物与结果引用
- 检查点及等待中的人工决策
- 预算计数器与终态
- 副作用状态:
not_started、in_flight、committed、failed或unknown
线程检查点与长期记忆是两个不同的数据产品。例如 LangGraph 把线程级图状态 Checkpointer 与跨线程应用数据 Store 分开。混用两者,会让保留、删除、授权和恢复边界难以定义。
4. 证据平面
证据平面解释一次运行,但不把模型的私有推理当成事实:
- 结构化生命周期事件与分布式 Trace
- 策略和审批决策
- 工具请求元数据与受限结果
- 状态转换、耗时、错误与预算
- 业务结果与评测标签
OpenTelemetry 的 GenAI 语义约定仍在演进,可以用于映射跨厂商的 Span、Metric 和 Event。应用自身仍应维护稳定的事件契约,再按当前约定输出遥测数据。
核心组件与责任归属
四个平面通过以下组件落地:
| 组件 | 负责内容 | 关键不变量 |
|---|---|---|
| 请求网关 | 认证、租户、Request ID、输入限制 | 先解析身份,再选择能力 |
| 运行协调器 | 状态机、租约、预算、取消 | 每次状态更新只有一个版本化转换胜出 |
| 上下文构建器 | 指令、消息、检索数据、产物引用 | 不可信内容保持为数据,不能上浮为策略 |
| 模型网关 | Provider 请求、结构化响应、模型元数据 | 模型输出只是提议,不是授权 |
| 工具注册表 | 版本化 Schema、风险类别、Executor 绑定 | 只能调用已注册能力 |
| 策略与审批服务 | Allow、Deny、Redact 或 Suspend | 审批绑定主体、参数、资源与过期时间 |
| 工具执行器 | 隔离、超时、操作键、结果分类 | 重试不能悄悄复制已提交副作用 |
| 状态与检查点存储 | 版本化快照、决策、副作用 Journal | 从已提交证据恢复,而不是依赖模型记忆 |
| 事件与评测 Sink | 脱敏事件、Trace、结果、测试 Fixture | 遥测可诊断,但不能变成敏感信息仓库 |
这些组件可以同进程部署,也可以拆成独立服务。分布式部署本身不会产生正确性,只会增加网络失败和一致性决策,仍需要契约约束。
端到端数据流
最重要的边界位于提议与执行之间。Schema 校验回答“数据格式是否正确”;策略回答“这个主体能否因这个目的,对这个资源执行该操作”;审批回答“指定审批人是否授权了这一次具体副作用”。三者不能合并。
版本化运行记录
一次运行应显式表达并发、审批和副作用。下面是应用级示例,不是通用行业标准:
{
"runId": "run_01J...",
"stateVersion": 12,
"status": "waiting_for_tool",
"stepId": "step_07",
"actor": {
"tenantId": "tenant_acme",
"principalId": "user_42",
"purpose": "resolve_support_case"
},
"proposal": {
"model": "provider/model-version",
"tool": "create_support_ticket",
"toolVersion": "3",
"callId": "call_09"
},
"policy": {
"decision": "allow",
"approvalId": null
},
"effect": {
"operationKey": "run_01J:call_09:create_support_ticket:3",
"status": "in_flight"
},
"budgets": {
"stepsUsed": 7,
"stepsLimit": 12
}
}
不要单独用可变 Prompt、时间戳或参数哈希充当操作身份。应在分发前生成稳定的语义操作 ID 并持久化。下游 API 支持幂等时,传递该键并保存资源 ID;不支持时,必须定义状态查询或对账路径。
用状态转换替代无界 while 循环
五行 while 循环适合解释 Tool Calling,却会隐藏生产契约。运行生命周期应显式建模:
created
-> running
-> waiting_for_approval
-> waiting_for_tool
-> running
-> completed | failed | cancelled | needs_reconciliation
每个转换都应声明:
- 预期状态版本
- 触发事件
- 策略与预算前置条件
- 状态变更
- 发出的事件
- 外部副作用是否可能已经存在
提交转换时使用 Compare-and-Set 或等价事务。租约可以减少并发执行,但租约会过期、Worker 会崩溃,因此不能替代状态版本。
失败与恢复语义
只有系统能判断副作用是否发生时,重试才是安全动作。
| 失败位置 | 对副作用的认知 | 默认处理 |
|---|---|---|
| 模型在形成提议前失败 | 无外部副作用 | 在模型与运行预算内重试 |
| 提议未通过 Schema 或策略校验 | 无已授权副作用 | 拒绝、要求修正或终止 |
| 工具被接收前分发失败 | 通常无副作用,但需核对传输契约 | 使用同一操作 ID 有界重试 |
| 工具分发后超时 | 未知 | 查询操作状态或进入对账,不能盲目重试 |
| 工具已提交,但状态写入冲突 | 副作用可能已经提交 | 按操作 ID 查询,再提交已知结果 |
| 审批过期或被拒绝 | 无已审批副作用 | 取消提议或返回规划 |
| 运行暂停期间策略发生变化 | 旧决策可能失效 | 恢复前重新评估 |
| 执行中取消 Worker | 取决于工具 | 尝试协作式取消,并分类最终副作用 |
unknown 是合法的运行状态。把它折叠为 failed 会造成重复副作用;把它折叠为 completed 会掩盖缺失工作。
信任与授权边界
所有跨边界数据在确定性控制验证前都应视为不可信:
- 用户、检索与工具内容: 都可能包含 Prompt Injection,应与系统策略和工具定义分离。
- 模型提议: 校验类型、范围、资源 ID 与业务规则。结构化输出只改善解析,不能证明真实或有权执行。
- 工具结果: 限制大小、验证 Schema、标记来源,禁止返回文本悄悄修改策略。
- 凭证: 绑定主体、Audience、Scope 与操作。MCP 安全文档明确警告 Token Passthrough 与 Confused Deputy 风险。
- 审批: 展示具体资源和副作用,绑定不可变参数,并设置过期时间。
- 遥测: 导出前脱敏 Secret 与个人信息,Trace 的访问控制和删除策略应与生产状态分别定义。
OWASP 把 Excessive Agency 的根因归为过多功能、过大权限或过度自主。因此,能力收敛必须进入架构:暴露最小工具面,授予最窄凭证,并按影响与可逆性决定是否需要人审。
预算与终止条件
只有 maxSteps 不够。至少独立定义:
- 墙钟时间
- 模型请求数与 Token
- 按风险类别划分的工具调用和重试
- 并发任务
- 输入、输出与产物字节数
- 能可靠取得 Usage 时的费用
- 审批等待时长
终止必须可确定。已经验证的业务结果、显式拒绝、策略拒绝、取消、预算耗尽、不可恢复错误或需要对账,均可进入终态。“模型声称已完成”只能作为待验证的提议。
应记录和评测什么
记录可观察证据,不记录隐藏思维链:
- Request、Run、Step、Call、Approval 与 Operation ID
- 模型、Prompt 模板、工具 Schema、策略和 Executor 版本
- 每次转换前后的状态版本
- 提议类别、策略结果、审批结果与副作用状态
- 可取得时的耗时、重试、Token 与费用
- 脱敏错误码和受限结果元数据
- 最终业务结果与确定性检查
具体设计见 Agent 可观测性。发布前测试可参考 Agent Harness 评测指南,其中覆盖场景 Fixture、工具替身、故障注入、轨迹检查和 Judge 辅助评分。
生产准入清单
- [ ] 选择工具前已经解析认证身份与租户上下文。
- [ ] 工具 Schema、风险类别和 Executor 版本已经注册。
- [ ] 模型输出始终按不可信提议进行校验。
- [ ] 策略与审批在模型之外执行。
- [ ] 凭证绑定 Audience 与 Scope,不盲目透传 Token。
- [ ] 运行状态有版本,检查点可以跨 Worker 重启恢复。
- [ ] 副作用操作使用稳定 ID、幂等机制或对账路径。
- [ ] 时间、步数、Token、重试、字节、并发与费用限制显式配置。
- [ ] 取消和未知结果都有文档化状态转换。
- [ ] 事件结构化、脱敏、受访问控制并限制保留时间。
- [ ] 测试覆盖重复分发、提交后超时、审批过期、策略变化、重启与取消。
- [ ] 人员能够检查证据,并恢复或终止暂停的运行。
参考资料
- The Anatomy of an Agent Harness, LangChain:规划、工具、子 Agent、上下文与执行逻辑的厂商工程分类;可用于理解组件,但不是行业标准。
- Building Effective Agents, Anthropic:Workflow 与 Agent 的边界,以及优先采用简单可组合模式的原则。
- Agents SDK, OpenAI:当前 SDK 对 Loop、Tool、Guardrail、Session、Approval 与 Trace 的责任划分;厂商 API 会变化。
- Persistence, LangGraph:线程检查点与跨线程 Store 的区别。
- Security Best Practices, Model Context Protocol:Confused Deputy、Token Passthrough 等授权风险;部署时需核对适用的 MCP 规范版本。
- LLM06:2025 Excessive Agency, OWASP GenAI Security Project:过多功能、权限和自主性带来的风险。
- OpenTelemetry GenAI Semantic Conventions:仍在演进的 GenAI Span、Metric 与 Event 语义约定。
总结
Agent Harness 架构不是更长的 Prompt,也不是某个品牌框架。它是把模型提议与权威副作用分开的运行契约。
可持续的设计必须显式管理身份、策略、状态版本、操作 ID、审批、预算、可观测事件与未知结果。建立这些边界后,团队才能替换模型 Provider 或编排库,而不丢失系统的运行保证。