跳转到内容

Agent Harness 的工程结构:控制权放在哪里

选择 Agent 框架时,最容易陷入功能表:谁支持更多模型、更多工具、更多 Memory、更多 Multi-Agent 模式。

这些功能当然重要,但更早的问题是:下一步由谁决定,状态由谁保存,失败以后谁负责。

同样一个退款任务,可以把控制交给模型、普通代码、状态图或持久化运行时。四种实现都能完成 Demo,遇到权限、暂停和崩溃时却会表现得完全不同。

Harness 设计的核心不是组件数量,而是控制权的放置。

一、三种平面:决策、控制与执行

Section titled “一、三种平面:决策、控制与执行”

为了看清 Harness,可以先分成三个平面。

模型理解目标、选择工具、生成参数、提出计划或 Handoff。

它擅长处理开放语言和不确定判断,不适合单独承担权限、事务和完成证明。

程序、图或策略引擎决定哪些动作可达、是否需要审批、预算是否允许、错误怎样恢复、什么时候停止。

控制平面承接业务责任。

工具、浏览器、终端、数据库、队列和沙箱真正改变环境。

执行平面必须返回结构化 Observation,并处理超时、幂等和资源隔离。

很多 Agent 故障的根源,是三个平面被压进一段 Prompt:模型既提议动作,又解释权限,还根据自己的解释宣布成功。

第 2 讲从职责解释 Harness,这一讲从工程模块重新组织。

统一模型调用、认证、重试、流式输出、Token 统计和能力差异。网关可以提供共同接口,但不能抹掉 Tool Call、结构化输出和缓存语义差异。

从目标、状态、Memory、检索和工具目录构建当前输入。它还负责预算、压缩、来源和不可信内容隔离。

执行 Agent Loop:调用模型、解析候选动作、调度工具、回填 Observation、处理 Handoff 和终态。

验证参数、检查授权、执行动作、整形结果,并管理超时、并发、幂等和副作用。

保存会话、任务状态、Checkpoint、工件和审批。消息历史只是其中一类数据。

执行最小权限、路径/域名白名单、内容过滤、预算、人工批准和取消。

记录 Trace、Span、事件、错误、成本和完成证据,为 Evaluation 和故障诊断提供数据。

模块可以合并在一个进程里,也可以拆成服务。分层的目的不是增加部署,而是让责任能被定位。

Model-driven:模型决定大部分下一步

Section titled “Model-driven:模型决定大部分下一步”

这种 Harness 提供工具和循环,让模型动态规划。

优势是代码少、适应开放任务快;风险是行为变化大,重复和误用工具更难提前发现。smolagents、Strands 的典型用法接近这条路线。[1][2]

适合探索、研究和低风险任务。进入写操作前,需要独立 Policy Gate。

应用用 if、函数和异常处理组织模型与工具。OpenAI Agents SDK、PydanticAI 都强调与普通 Python 组合。[3][4]

优势是团队熟悉、单元测试容易、控制明确;复杂分支和长时恢复则需要自行组织。

OpenAI Agents SDK 仓库

图 1:OpenAI Agents SDK 代表少量原语与普通代码编排的路线。来源见文末。

Graph-driven:状态和边拥有可达路径

Section titled “Graph-driven:状态和边拥有可达路径”

LangGraph、Microsoft Agent Framework Workflow 把状态、节点和边显式化。[5][6]

模型在节点内做开放判断,图决定下一步可以去哪里。它适合审批、循环、恢复和复杂分支,代价是图设计与迁移成本。

LangGraph 仓库

图 2:LangGraph 把 State、Node、Edge 和 Checkpoint 置于核心。来源见文末。

Runtime-driven:持久化运行时拥有生命周期

Section titled “Runtime-driven:持久化运行时拥有生命周期”

Temporal、DBOS 等系统把 Workflow 历史、Activity 重试、定时器和恢复变成运行时能力。[7][8]

它们不决定模型该说什么,却决定进程崩溃以后任务怎样继续。适合跨小时、跨天和有副作用的流程。

实际生产系统通常混合四者:Graph 规定大阶段,Code 执行确定逻辑,Model 处理开放节点,Durable Runtime 保存生命周期。

状态分散是 Harness 最难排查的问题之一。

同一个任务可能同时存在:

  • 模型消息历史中的“当前计划”;
  • 应用数据库中的任务状态;
  • LangGraph Checkpoint;
  • Memory Service 中的用户偏好;
  • Durable Runtime 的 Workflow 历史;
  • 外部业务系统的真实终态。

它们不能都声称自己是权威。

建议按问题分配:

状态 权威位置
订单是否退款 订单/支付系统
Workflow 运行到哪 Durable Runtime 或 Checkpoint Store
当前计划和中间工件 任务状态
用户长期偏好 Memory Store
模型看到的最近对话 Session History

模型上下文应该从权威状态生成,而不是反过来用模型文本覆盖权威状态。

五、Hooks 与 Middleware 为什么重要

Section titled “五、Hooks 与 Middleware 为什么重要”

框架常提供 Hook、Middleware、Interceptor 或 Event Handler。它们允许团队在不修改 Agent 逻辑的情况下加入:

  • 调用前权限检查;
  • 工具参数脱敏;
  • 预算计数;
  • Trace 属性;
  • 模型路由;
  • 结果缓存;
  • 审批和取消;
  • 错误分类。

这类扩展点是 Harness 的控制面。设计时要避免两个极端:所有逻辑塞进 Hook,导致执行顺序不透明;或者完全没有 Hook,只能修改框架内部。

好扩展点应明确时机、输入、是否可修改、错误传播和幂等要求。

六、OpenHarness 为什么值得看,又不能照单全收

Section titled “六、OpenHarness 为什么值得看,又不能照单全收”

OpenHarness 等项目尝试把 Toolkit、Memory、Governance、Swarm 和生命周期集中呈现,适合观察一个“完整 Harness”可能包含什么。[9]

OpenHarness 仓库页面

图 3:OpenHarness 展示了较完整的能力地图。能力面广不等于每个应用都应启用全部模块。

读这类项目时要分三层:

  1. 核心运行时哪些是必需的;
  2. 哪些是可选能力;
  3. 哪些依赖托管服务或特定基础设施。

完整架构适合学习边界,不适合成为每个项目的默认起点。

可以采用一条简单原则:

开放、可逆、低风险 -> 模型拥有更多选择
确定、不可逆、高风险 -> 代码/图/人工拥有控制
跨时间、需恢复 -> 持久化运行时拥有生命周期

例如客服 Agent:

  • 模型判断用户意图;
  • 代码验证身份和金额;
  • 图规定退款前必须经过政策检查和审批;
  • Durable Runtime 等待人工回复;
  • 支付系统保存最终交易事实。

这不是削弱 Agent,而是把不同能力放回适合的位置。

八、真实实验:同一个写操作,两种控制位置

Section titled “八、真实实验:同一个写操作,两种控制位置”

本讲的 control_placement.py 模拟模型提出 write_refund

第一条路径让模型直接提出写动作,但 Policy 发现没有审批,终态是:

{"terminal": "blocked", "reason": "approval_required"}

第二条路径由状态图先读取订单、经过审批节点,再执行写入,终态为 success

完整结果见 experiment-result.json

实验没有比较谁“更聪明”。它只说明:同一个候选动作,放在不同控制结构里,会得到不同的安全语义。

  1. 谁拥有 Agent Loop?
  2. 下一步由模型、代码还是图决定?
  3. 业务状态保存在哪里?
  4. 是否支持结构化 Checkpoint?
  5. 工具授权在哪里执行?
  6. 有副作用动作怎样幂等?
  7. 是否支持暂停、取消和人工审批?
  8. 进程重启后能否恢复?
  9. Trace 能否跨模型、工具和 Handoff?
  10. 是否能在框架外使用普通测试工具?
  11. 托管功能与开源核心怎样划分?
  12. API 变化时,状态和 Workflow 怎样迁移?

如果这些问题没有答案,“支持多少 Agent 模式”并不是最重要的。

Harness 设计不是寻找一个包办全部责任的框架,而是明确控制权、状态和失败责任。

模型负责开放判断,代码和图保留确定约束,持久化运行时承接时间,业务系统保存事实。

下一讲深入 Graph 和 State Machine:怎样把 Agent 的不确定性放进显式状态,让循环能验证、有界并且可恢复。


[1] Hugging Face, smolagents. https://github.com/huggingface/smolagents

[2] Strands Agents. https://github.com/strands-agents/harness-sdk

[3] OpenAI Agents SDK. https://github.com/openai/openai-agents-python

[4] PydanticAI. https://github.com/pydantic/pydantic-ai

[5] LangGraph. https://github.com/langchain-ai/langgraph

[6] Microsoft Agent Framework. https://github.com/microsoft/agent-framework

[7] Temporal Python SDK. https://github.com/temporalio/sdk-python

[8] DBOS Transact Python. https://github.com/dbos-inc/dbos-transact-py

[9] OpenHarness. https://github.com/HKUDS/OpenHarness