目标:从 Agent 工程的角度,解释 Harness 是什么、由什么组成、如何构建,以及它如何嵌入 AI 应用逻辑。

更新日期:2026-08-03

一、先给出结论

在 Agent 场景中,Harness 是包裹在大模型周围、负责把“模型输出”变成“可控行动”的运行与治理层

一个大模型本身主要做一件事:根据输入生成下一段输出。它并不天然拥有可靠的工具调用循环、文件系统、身份权限、长期记忆、任务状态、重试恢复、审批流程或结果验证。Harness 把这些能力连接起来,使模型能够:

  1. 理解任务和当前环境;
  2. 规划下一步;
  3. 选择并调用工具;
  4. 读取工具结果并继续执行;
  5. 判断是否完成、失败或需要人工介入;
  6. 在安全边界内修改外部世界;
  7. 输出可追踪、可评估、可恢复的结果。

可以用一个工程化公式理解:

Agent = Model + Harness + Tools + Environment + Policies + Evaluation

其中:

  • Model 负责理解、推理、生成决策候选;
  • Harness 负责执行循环、上下文、工具编排、状态、权限、验证和生命周期;
  • Tools 负责读写外部系统;
  • Environment 是 Agent 实际工作的世界,例如代码仓库、数据库、浏览器、CRM;
  • Policies 规定什么可以做、什么必须审批、什么绝对不能做;
  • Evaluation 检查 Agent 是否真的完成了目标,而不是只说“完成了”。

因此,Harness 不是一个更好的 Prompt,也不是单纯的 Agent SDK。它是把模型接入真实任务环境后,决定 Agent 行为边界与执行方式的系统。

二、Harness 这个词为什么容易混淆

“Harness”原意是给动物套上的控制装备。放到 AI 中,它强调的不是替模型思考,而是让模型的能力可以被使用、约束、观察和恢复。

当前至少有四种常见用法:

用法 主要含义 关注点
Agent harness / scaffold 让模型成为可行动 Agent 的执行层 工具循环、状态、上下文、权限、恢复
Evaluation harness 运行和评分 Agent 评测的基础设施 任务、环境、轨迹、评分、聚合
Agent SDK / runtime 提供底层 Agent 编程原语和运行时 Agent 对象、会话、路由、调度、事件
Harness 产品或协议 某个具体厂商产品,或用于描述 Agent 配置的标准 配置、插件、技能、MCP、治理、分发

本文重点讨论第一种,即 Agent harness,并在后文说明它与其他三种概念的关系。

Anthropic 的定义是:Agent harness(或 scaffold)是让模型能够作为 Agent 工作的系统,它处理输入、编排工具调用并返回结果;而 evaluation harness 是端到端运行评测的基础设施。Anthropic:Demystifying evals for AI agents

三、Agent Harness 的边界:什么算,什么不算

3.1 最小定义

如果一个系统至少具备下面的闭环,它就接近一个最小 Agent harness:

接收任务
  ↓
构造模型上下文
  ↓
调用模型
  ↓
解析模型要执行的动作
  ↓
检查动作是否被允许
  ↓
执行工具并获得结果
  ↓
把结果回灌给模型
  ↓
判断完成、继续、失败或升级

核心不是“是否使用了某个框架”,而是是否存在一个由系统控制的行动闭环

3.2 不一定算 Harness 的东西

  • 只有一次 LLM 调用和一次文本返回的问答接口:通常是 LLM 应用,不是完整 Agent harness。
  • 只有固定步骤的工作流:如果每一步、分支和参数都完全由代码预先决定,更接近 workflow;它可以包含 harness,但本身未必是 Agent harness。
  • 只提供工具定义的函数库:这是 tool layer,不是 harness。
  • 只负责连接模型供应商的客户端:这是 model client 或 SDK,不是完整 harness。
  • 只运行测试集并给分的系统:这是 evaluation harness。

边界不是绝对的。固定工作流中加入模型决策、工具循环和运行时恢复后,它可能同时是 workflow 和 harness。判断重点应放在:谁在控制每一轮执行,以及 Agent 是否能在任务过程中根据环境反馈调整行动。

四、Harness 的组成部分

可以把 Harness 拆成十个相互配合的部分。不同框架的命名不同,但工程职责大体一致。

4.1 任务入口与会话层

负责接收用户请求、任务 ID、用户身份、租户信息、会话历史和运行配置。

典型职责:

  • 创建一次 Agent run;
  • 绑定用户、组织、项目和权限;
  • 保存会话消息与任务状态;
  • 支持同步、流式、后台和长时间运行模式;
  • 在断线、超时或进程重启后恢复。

一个重要区分是:

  • Conversation history:用户与 Agent 之间发生过什么;
  • Task state:任务已经完成了哪些步骤、哪些副作用已经发生;
  • Memory:未来任务可能复用的稳定信息。

三者混在一起会导致上下文膨胀、重复执行和状态错误。

4.2 指令与上下文构造

Harness 在每次模型调用前构造上下文,通常包括:

  • 系统级行为规则;
  • 当前任务说明;
  • 用户身份与授权范围;
  • 当前环境信息,例如工作目录、时间、仓库状态;
  • 工具列表、参数 schema 和使用规则;
  • 相关记忆与检索结果;
  • 已完成动作、工具返回值和错误信息;
  • 完成标准、禁止事项和升级条件。

OpenAI 的 harness engineering 实践强调,知识应该放在结构化、可维护的文档中,而不是堆成一个巨大的手册;短入口文件只负责索引,详细知识由更深层的文档作为事实来源。OpenAI:Harness engineering

因此,Prompt 不应承担所有逻辑。好的 Harness 会把规则分流到:

  • Prompt:解释目标和行为方式;
  • Tool schema:限制输入输出形状;
  • 代码:执行不可妥协的业务规则;
  • 权限系统:限制主体可以触达的资源;
  • 测试和评估:验证最终行为。

4.3 模型调用层

负责选择模型、设置推理参数、发起调用、处理流式输出和处理模型错误。

应考虑:

  • 模型是否支持结构化输出和工具调用;
  • 上下文窗口与输出预算;
  • 成本和延迟预算;
  • 超时、限流、重试和熔断;
  • 是否允许不同步骤使用不同模型;
  • 模型版本变化后的回归评测。

模型是 Harness 的决策引擎,但不是安全边界。任何高风险约束都应该在模型之外再验证一次。

4.4 Agent Loop:行动循环

这是 Harness 最核心的部分。典型伪代码如下:

def run_agent(task, session):
    state = load_task_state(session)

    for step in range(MAX_STEPS):
        context = build_context(task, state)
        decision = model.generate(context, tools=allowed_tools(state))

        if decision.is_final:
            result = validate_final_answer(decision, state)
            if result.ok:
                persist_success(session, result)
                return result
            state.add_validation_error(result.error)
            continue

        action = parse_tool_call(decision)
        policy = authorize(action, state)

        if policy.requires_human:
            return pause_for_approval(session, action)
        if not policy.allowed:
            state.add_tool_error(action, policy.reason)
            continue

        observation = execute_tool(action, state)
        state.record(action, observation)

    return escalate(session, reason="step limit exceeded")

一个生产级循环还需要加入:幂等键、重试分类、超时、并发限制、取消、断点恢复、预算控制和副作用记录。

4.5 工具与工具编排

工具是 Agent 影响外部世界的接口。Harness 不只是把工具列表塞进 Prompt,还要负责:

  • 工具发现和选择;
  • 参数校验;
  • 工具调用前的授权;
  • 工具调用后的结果标准化;
  • 工具错误分类;
  • 是否允许并行调用;
  • 是否需要用户确认;
  • 写操作的幂等与回滚策略;
  • 对工具调用进行审计。

工具最好按风险分级:

风险级别 例子 默认策略
读取文档、查询订单、计算汇率 自动执行,记录日志
创建草稿、修改非关键数据、发送内部通知 限定资源,可配置审批
付款、删除数据、发外部邮件、发布代码 强制审批或双重确认

OpenAI 建议根据只读/写入、可逆性、权限范围和财务影响评估工具风险,并在高风险函数执行前暂停检查或转人工。OpenAI:A practical guide to building agents

4.6 状态、记忆与上下文压缩

Agent 的“记忆”至少分为三层:

  1. 短期上下文:本次任务的消息、工具结果和中间结论;
  2. 任务状态:结构化记录任务阶段、实体 ID、审批状态、已执行副作用;
  3. 长期记忆:用户偏好、组织知识、历史事实和可复用经验。

上下文压缩不是简单截断旧消息。更可靠的做法是把对后续决策有用的信息提炼成结构化摘要,并保留原始轨迹的可追溯引用。Microsoft Agent Framework 的 Harness 实现把 token-budget-aware compaction 作为防止长工具循环溢出上下文的重要能力。Microsoft Agent Framework:Agent harnesses

4.7 权限、审批与安全护栏

安全层应至少包含:

  • 身份认证:谁在发起任务;
  • 授权:该主体能访问哪些数据和工具;
  • 作用域限制:Agent 只能在指定项目、目录或租户内工作;
  • 输入防护:提示注入、越权指令、恶意文件和不可信网页内容;
  • 工具防护:参数、资源、速率、审批和副作用;
  • 输出防护:敏感信息、错误承诺、越权内容和格式校验;
  • 人工介入:高风险或连续失败时暂停。

护栏不能只写成 Prompt 里的“请小心”。确定性规则应由代码和权限系统执行;LLM 评审适合处理语义相关性、意图判断和复杂内容审查,但不能替代基础授权。

OpenAI 将护栏描述为分层防御,并强调它们需要与认证、授权、访问控制及常规软件安全措施结合,而不能单独承担全部安全责任。OpenAI:A practical guide to building agents

4.8 结果验证与完成判定

“模型说完成”不等于“任务完成”。Harness 应定义可观察的完成条件:

  • 数据库中是否真的产生了记录;
  • 文件是否真的存在并通过测试;
  • 订单状态是否已更新;
  • 邮件是否被成功投递;
  • API 返回是否满足 schema;
  • UI 操作后的页面状态是否符合预期。

完成判定可以是:

  • 规则判断;
  • Schema 验证;
  • 查询外部系统状态;
  • 单元测试或集成测试;
  • 另一个模型作为 judge;
  • 人工确认。

Anthropic 特别强调评估 Agent 时应检查环境最终状态,而不只是对话轨迹。例如订票 Agent 声称“已订票”并不代表数据库中真的存在预订记录。Anthropic:Demystifying evals for AI agents

4.9 可观测性、轨迹与审计

至少记录一次 Agent run 的:

  • 输入任务与版本;
  • 使用的模型和参数;
  • Prompt/上下文版本;
  • 每次模型调用;
  • 每次工具调用及参数摘要;
  • 工具结果、错误和重试;
  • 审批事件;
  • token、延迟和费用;
  • 最终结果和验证结果。

轨迹既是调试材料,也是安全审计和评估数据。要注意脱敏、访问控制、保留期限以及不要把密钥、完整个人信息或不必要的敏感内容写入日志。

4.10 生命周期、恢复与人工接管

生产 Agent 必须有明确的状态机,例如:

QUEUED → RUNNING → WAITING_APPROVAL → RUNNING
                    ↓
                 SUCCEEDED
                    ↓
             FAILED / ESCALATED / CANCELLED

需要定义:

  • 最大步骤数和最大运行时间;
  • 每类错误是否重试;
  • 工具调用是否幂等;
  • 用户断线后是否继续;
  • 审批超时如何处理;
  • Agent 卡死如何检测;
  • 什么情况下转人工;
  • 部分副作用发生后如何补偿。

五、Harness、Runtime、SDK、Workflow 和 Evals 的关系

可以用分层方式理解:

业务应用 / UI / API
        ↓
Workflow 或业务编排
        ↓
Agent Harness:本轮怎么思考、调用、验证、继续
        ↓
Agent Runtime:会话、持久化、调度、路由、事件、基础设施
        ↓
Model API + Tool APIs + External Systems
  • SDK 是开发者使用的接口和编程工具;
  • Runtime 是让 Agent 可运行、可持久化、可调度的基础设施;
  • Harness 是决定 Agent 每一轮行为的控制层;
  • Workflow 是更高层的业务流程,可以调用一个或多个 Agent;
  • Evaluation harness 是在隔离环境中运行任务、收集轨迹并评分的测试系统。

Cloudflare 的描述很清楚:runtime 回答“Agent 住在哪里、如何保持持久”,harness 回答“Agent 每一轮做什么”。Cloudflare Agents:Harnesses

六、从场景出发:如何用 Harness 构建 Agent

不要先问“应该用哪个框架”,而要先描述任务的环境、动作和风险。

6.1 场景一:客服订单处理 Agent

业务目标

用户说:“我的订单还没收到,帮我处理。”

Agent 需要做什么
  1. 识别用户和订单;
  2. 查询物流状态;
  3. 判断是否超过承诺时间;
  4. 根据政策选择补发、退款或转人工;
  5. 在需要写入或产生费用时申请审批;
  6. 更新工单并向用户解释结果。
Harness 配置
  • Context:用户身份、订单 ID、地区、售后政策版本;
  • Tools:get_orderget_shipping_statuscreate_ticketissue_refund
  • Policy:退款金额超过阈值必须人工审批;
  • Validator:退款记录真实存在、工单状态正确;
  • Memory:保存用户偏好,但不把一次性物流信息永久记忆;
  • Recovery:退款接口超时后查询幂等键,不能盲目重复退款;
  • Escalation:缺少订单、政策冲突、连续两次工具失败时转人工。

这里 Harness 的价值在于:模型可以负责理解自然语言和选择路径,但不能直接决定“退款已成功”。成功必须由工具返回和外部状态验证共同确认。

6.2 场景二:代码修改 Agent

业务目标

用户说:“修复这个 bug,并提交一个可审查的修改。”

Harness 需要提供
  • 工作目录和仓库状态;
  • 文件读取、搜索、编辑、测试、版本控制工具;
  • 明确的修改边界;
  • 代码风格、架构约束和测试命令;
  • 高风险命令审批;
  • 每一步的 diff 和测试结果;
  • 完成标准:问题复现、修复、回归测试、diff 检查。

OpenAI 的 harness engineering 经验说明,Agent 更依赖严格边界、可预测结构、可机械验证的架构约束。把反馈持续沉淀为文档、lint、结构测试和自动清理流程,会比不断增加一份巨型提示词更稳定。OpenAI:Harness engineering

推荐执行闭环
读取任务 → 检查仓库 → 复现问题 → 定位根因 → 修改代码
    → 运行测试 → 检查 diff → 生成说明 → 请求 review/提交

每一个“完成”都应该绑定可验证的证据,而不是只依赖模型的总结。

6.3 场景三:研究与分析 Agent

业务目标

“分析某行业在过去一年中的变化,并给出有来源的结论。”

Harness 设计
  • 任务分解:定义问题、搜集资料、交叉验证、计算、写作;
  • 工具:搜索、网页读取、文档解析、表格计算;
  • 来源策略:优先一手资料,记录 URL、发布时间和访问时间;
  • 状态:已检索来源、待验证结论、冲突证据;
  • 验证:每个关键结论必须有证据引用;
  • 预算:限制搜索次数、页面长度、总 token 和总时间;
  • 输出:将事实、推断、不确定性分开。

这里不应只做“搜索结果拼接”。Harness 要求 Agent 管理研究状态,并在写作前检查证据覆盖率和引用完整性。

6.4 场景四:浏览器/GUI 操作 Agent

当 Agent 通过截图、鼠标和键盘操作网页或桌面软件时,Harness 还要提供:

  • 当前页面和窗口状态;
  • 截图、点击、输入、滚动工具;
  • 操作前后的状态检查;
  • 防止点击付款、删除等高风险控件的审批;
  • 失败后的重新定位和恢复;
  • 沙箱账号与测试数据。

GUI Agent 的验证必须检查最终页面或后端数据状态,因为视觉动作本身不能证明业务操作成功。

七、从零构建一个 Harness 的步骤

第一步:定义任务边界

用一页纸写清楚:

  • 用户目标是什么;
  • Agent 可以做哪些动作;
  • Agent 不能做哪些动作;
  • 哪些动作会产生不可逆副作用;
  • 任务完成的可观测证据是什么;
  • 失败后交给谁;
  • 预算、延迟和准确率目标是什么。

如果这些问题无法回答,先不要扩大 Agent 自主权。

第二步:建立工具契约

每个工具都应有:

  • 清晰名称和描述;
  • 严格输入 schema;
  • 严格输出 schema;
  • 权限要求;
  • 风险级别;
  • 幂等策略;
  • 超时和重试策略;
  • 审计字段;
  • 失败语义。

工具返回值要让模型知道“发生了什么”,但真正的权限和业务校验应在工具服务端执行。

第三步:实现最小循环

先只实现:构造上下文、调用模型、执行工具、回灌结果、停止条件。然后再加入记忆、审批、压缩、并发、恢复等能力。

停止条件至少包括:

  • 模型返回最终答案;
  • 任务状态满足完成条件;
  • 超过步骤或预算;
  • 连续失败;
  • 用户取消;
  • 需要人工审批。

第四步:把不可妥协的规则移出 Prompt

例如:

  • “不能访问其他租户数据”由授权中间件执行;
  • “金额不能超过上限”由业务服务执行;
  • “只能编辑工作目录”由沙箱执行;
  • “输出必须符合 JSON”由 schema 验证执行;
  • “提交前必须通过测试”由 CI 或验证器执行。

Prompt 负责提供语义指导,代码负责提供硬约束。

第五步:加入状态与幂等

不要只依赖消息历史推断状态。为任务建立结构化状态,例如:

{
  "task_id": "task_123",
  "phase": "awaiting_approval",
  "order_id": "order_456",
  "refund_amount": 99.0,
  "executed_actions": [
    {"name": "get_order", "idempotency_key": "..."}
  ],
  "pending_action": "issue_refund",
  "attempts": 1
}

这样可以避免 Agent 因为上下文丢失而重复执行付款、退款、发信或删除。

第六步:设计人工接管

人工介入不是 Agent 失败的反面,而是生产系统的正常分支。应明确:

  • 哪些动作强制审批;
  • 审批人看到哪些上下文和证据;
  • 审批后 Agent 如何继续;
  • 拒绝后如何修改计划;
  • 超时如何取消或转人工;
  • 人工能否直接接管会话。

第七步:建立评估 Harness

评估系统至少需要四类对象:

  1. 任务集:代表真实目标和边界案例;
  2. 环境:沙箱数据库、代码仓库、浏览器或模拟 API;
  3. 轨迹记录:模型调用、工具调用和中间结果;
  4. 评分器:检查最终状态、过程约束和用户体验。

不要只评最终文本。应同时评估:

  • 任务成功率;
  • 工具选择准确率;
  • 错误恢复率;
  • 越权/危险动作拦截率;
  • 人工升级准确率;
  • 平均步骤数、延迟和成本;
  • 结果的事实性和引用覆盖率。

八、一个实用的 Harness 目录结构

下面是适合中小型 Agent 项目的逻辑结构,具体文件名可以按团队规范调整:

agent-app/
├── agent/
│   ├── instructions.md       # 行为与任务说明
│   ├── loop.py                # Agent loop
│   ├── context.py             # 上下文构造
│   ├── state.py               # 任务状态
│   ├── policies.py            # 权限、审批与风险策略
│   ├── validators.py          # 工具和最终结果验证
│   └── recovery.py             # 重试、恢复、补偿
├── tools/
│   ├── read_tools.py
│   ├── write_tools.py
│   └── schemas.py
├── memory/
│   ├── session_store.py
│   └── long_term_memory.py
├── observability/
│   ├── tracing.py
│   └── redaction.py
├── evals/
│   ├── tasks/
│   ├── environments/
│   ├── graders/
│   └── runner.py
└── docs/
    ├── domain-rules.md
    ├── tool-contracts.md
    └── failure-handbook.md

这个结构体现一个原则:Agent 的知识、工具、政策、状态、评估和恢复逻辑都应该是可发现、可审查、可测试的工程资产。

九、常见反模式与为什么会失败

9.1 把所有东西都塞进一个 System Prompt

问题:规则难以验证、容易过时、彼此冲突,模型也无法稳定区分建议和硬约束。

改进:把规则拆到 schema、代码校验、权限、测试、文档和 Prompt 中。

9.2 没有真正的完成验证

问题:Agent 说“已完成”,但外部系统没有变化,或者只完成了一半。

改进:对最终状态做查询、断言或测试,并将证据返回给用户。

9.3 工具权限过大

问题:一个看似无害的工具可能让 Agent 访问所有数据、执行任意命令或产生不可逆副作用。

改进:按最小权限、资源范围和风险分级设计工具;高风险动作必须审批。

9.4 用对话历史代替任务状态

问题:压缩、断线、并发或重试后,Agent 可能忘记已经执行过什么。

改进:用结构化状态和幂等键记录副作用。

9.5 无限循环与盲目重试

问题:成本飙升、重复写入、模型在同一错误上打转。

改进:限制步骤、时间、token 和工具重试次数;对错误分类;超过阈值就升级。

9.6 只测演示样例

问题:Happy path 很好看,遇到权限不足、工具超时、脏数据、模糊请求和提示注入就失败。

改进:用真实任务构建评估集,并加入对抗、边界、恢复和最终状态测试。

9.7 过早采用多 Agent

问题:通信、权限、状态和调试复杂度成倍增加,问题责任边界变模糊。

改进:先用单 Agent + 清晰工具完成任务;只有在职责、权限或并行性确实需要时再拆分。

十、如何判断一个 Harness 是否成熟

可以用下面的成熟度模型做自检:

等级 特征
H0:模型调用 一次 Prompt,一次返回,没有工具闭环
H1:工具循环 能调用工具并继续,但状态、权限和恢复很弱
H2:可控 Agent 有结构化状态、工具契约、停止条件、验证和审批
H3:生产 Harness 有沙箱、审计、可观测性、评估、幂等、恢复和人工接管
H4:可演进系统 失败能沉淀为新工具、规则、文档、测试和自动治理,系统持续改善

OpenAI 的 harness engineering 文章展示了 H3/H4 的一些特征:用结构化文档作为知识源,用架构约束和 lint 机械化执行原则,用评估、反馈和周期性清理保持 Agent 工作环境的可维护性。OpenAI:Harness engineering

十一、在 AI 应用逻辑中的落地建议

如果你的应用只是问答

不需要一开始就构建完整 Harness。先做模型调用、检索、引用和输出验证;当系统需要多步工具调用或持久任务时,再加入 Agent loop。

如果你的应用需要查询数据

优先设计只读工具、权限范围和结果 schema。让 Agent 负责选择查询路径,让后端负责授权和数据过滤。

如果你的应用需要写入数据

先定义幂等、审批、回滚/补偿和最终状态验证,再开放工具。写操作的可靠性通常比 Prompt 质量更重要。

如果你的应用需要长任务

把任务状态从会话消息中独立出来,使用队列或持久执行机制,支持断点恢复、取消和人工接管。

如果你的应用需要高自主性

不要只增加模型能力。优先增加:更好的工具、更清晰的环境、更强的验证、更细的权限、更完整的轨迹和更有代表性的评估集。

十二、最终理解:Harness 到底是什么

最简洁的定义是:

Harness 是 Agent 的执行控制系统:它把模型的语言与推理能力放进一个有工具、有状态、有环境、有权限、有反馈、有验证和有恢复机制的闭环中。

模型决定“下一步可能做什么”;Harness 决定:

  • 模型看到了什么;
  • 它可以调用什么;
  • 调用前是否被允许;
  • 调用后如何处理结果;
  • 什么时候继续或停止;
  • 怎么确认真的完成;
  • 出错时如何恢复;
  • 高风险时谁来批准;
  • 如何记录、评估和改进。

所以,构建 Agent 的核心不是把一个 LLM 接到几个 API 上,而是设计一个可验证的行动闭环。模型能力决定上限,Harness 的工程质量决定实际可用性。

十三、整体执行流程

下面的流程图展示一次 Agent Run 的主路径,以及审批、工具失败、验证失败、超限和人工接管等分支。

最终回答

工具调用

格式错误或不可理解

拒绝

需要审批

拒绝

通过

自动允许

成功

可重试失败

不可重试失败

否,可修复

用户请求或系统事件

创建 Agent Run

加载身份、租户和权限

初始化任务状态、预算和幂等上下文

构造当前轮上下文

上下文是否完整且在预算内?

补充上下文或压缩历史

压缩或补充后仍可继续?

转人工:上下文不足或预算耗尽

调用模型

模型返回什么?

验证最终回答和任务完成条件

解析工具名称、参数和调用意图

分类错误并决定是否重试

工具参数通过 Schema 验证?

记录参数错误并反馈模型

执行权限、资源范围和风险检查

策略是否允许执行?

记录拒绝原因并反馈模型

暂停任务并请求人工审批

审批结果?

记录拒绝并结束或要求修改计划

执行工具

工具执行结果?

保存工具结果、轨迹和副作用

判断是否转人工或结束失败

更新任务状态和已执行动作

达到停止条件?

执行最终状态验证

外部状态和输出是否满足完成条件?

记录验证差异并反馈模型

标记成功并返回结果

仍有步骤、时间和重试预算?

转人工或标记失败

是否需要人工介入?

转人工并附带完整轨迹

标记失败并返回可解释错误

持久化最终状态、指标和审计记录

通知用户、调用方或下游系统

十四、一次完整 Agent Run 的时序

流程图适合看分支,时序图适合看各参与者之间如何交互。一次完整执行至少涉及用户、Harness、模型、工具、策略服务、状态存储和验证器。

Validator Tool Service Model State and Memory Policy Service Harness Validator Tool Service Model State and Memory Policy Service Harness alt [Approval required] [Automatic execution allowed] alt [Approved and executable] [Rejected or malformed] alt [Model requests a tool] [Model returns a final answer] loop [Until completed, escalated, failed, or cancelled] alt [Task succeeded] [Task needs human intervention] [Task failed] User Submit task Authenticate and authorize user Identity, scope, and policy context Create run and load state Session history and task state Load relevant memory and checkpoint Context fragments and prior observations Build prompt, tools, budget, and constraints Generate next decision Final answer or tool call Parse and validate tool arguments Check tool risk, resource scope, and approval Allow, deny, or require approval Request approval with evidence Approve or reject Execute approved tool call Tool result or classified error Persist action, result, and side effect Updated checkpoint Persist rejection and feedback Validate output and external task state Pass, repairable mismatch, or failure Persist validation result Return result and completion evidence Return pending status and escalation context Return explainable failure and next action User

十五、Harness 的任务生命周期

Harness 不应把 Agent Run 视为一个只有成功/失败两种结果的函数。生产系统需要显式表示排队、运行、等待审批、恢复、取消和升级等状态。

"worker accepts run"

"user cancels"

"high-risk action detected"

"approval granted"

"approval rejected or timeout"

"user cancels"

"transient error or process restart"

"checkpoint restored"

"recovery exhausted"

"needs user input"

"user provides input"

"input timeout"

"validated completion"

"unrecoverable error"

"risk or retry threshold exceeded"

"user or system cancellation"

queued

running

cancelled

waitingApproval

escalated

recovering

failed

paused

succeeded

状态设计的关键原则:

  • running 表示 Harness 正在推进任务,不代表模型正在生成文本;
  • waitingApprovalpaused 必须持久化,不能只停留在进程内存;
  • recovering 要依赖 checkpoint 和幂等键,避免重复副作用;
  • succeeded 必须来自验证器,而不是模型的一句“已完成”;
  • escalated 表示需要人或其他系统接管,不等同于简单失败。

十六、Harness 的组件关系

下面的架构图展示 Harness 如何位于模型、工具和业务系统之间。Harness 不是工具,也不是模型,而是负责把它们组织成可控闭环的中间层。

Agent Harness

User, UI, API, or Event

Run Manager

Context Builder

Loop Controller

Model Adapter

Tool Orchestrator

Lifecycle and Recovery

Policy and Approval Gate

Output and State Validator

Trace and Audit

Task State and Memory

LLM Provider

MCP or Function Tools

Internal APIs

Sandbox or Workspace

Databases, CRM, Payments, CI

Files, Browser, Repository

Identity and Access Control

Logs, Metrics, Traces, Evals

十七、单轮循环的核心逻辑

一轮 Agent 执行可以抽象为:

工具动作

最终答案

不可解析

当前任务、状态和环境观察

构造模型上下文

模型生成决策

决策类型?

参数和权限验证

输出和外部状态验证

错误分类和反馈

允许执行?

执行工具

得到工具结果

持久化 checkpoint

满足完成或停止条件?

返回最终结果

验证通过?

仍有预算?

失败或人工接管

十八、执行过程中的关键数据

一次完整 Run 的数据可以用下面的结构表达。实际系统可使用数据库、事件流或持久化工作流引擎保存这些信息。

{
  "run_id": "run_123",
  "task": "修复订单查询接口的超时问题",
  "status": "running",
  "identity": {
    "user_id": "user_456",
    "tenant_id": "tenant_789",
    "scopes": ["repository:read", "repository:write", "ci:run"]
  },
  "budget": {
    "max_steps": 30,
    "max_duration_seconds": 900,
    "max_tool_retries": 3
  },
  "state": {
    "phase": "testing",
    "completed_steps": ["inspect", "reproduce", "edit"],
    "pending_step": "run_tests"
  },
  "executed_actions": [
    {
      "tool": "run_test",
      "idempotency_key": "run_123-test-001",
      "status": "succeeded"
    }
  ],
  "completion_evidence": [],
  "trace_id": "trace_abc"
}

十九、如何从图落到代码

建议将 Harness 的职责拆成几个明确接口:

class Harness:
    def run(self, task, session):
        state = self.state_store.start(task, session)

        while not state.should_stop():
            context = self.context_builder.build(state)
            decision = self.model.generate(context, self.tool_registry.describe(state))

            if decision.is_final:
                verdict = self.validator.check_final(decision, state)
                state = self.state_store.record_validation(state, verdict)
            else:
                action = self.tool_registry.parse(decision)
                permission = self.policy.authorize(action, state)

                if permission.requires_approval:
                    state = self.approval.pause(state, action)
                    return state

                if not permission.allowed:
                    state = self.state_store.record_rejection(state, permission.reason)
                    continue

                result = self.executor.execute(action, state)
                state = self.state_store.checkpoint(state, action, result)

        return self.state_store.finish(state)

这段代码表达的不是某个框架的 API,而是 Harness 的职责分界:

  • context_builder 决定模型看什么;
  • model 产生下一步候选决策;
  • tool_registry 定义模型能调用什么;
  • policy 决定动作是否被允许;
  • executor 产生真实副作用;
  • validator 判断任务是否真的完成;
  • state_store 让任务可恢复、可审计;
  • approval 处理高风险人工介入。

二十、从一个用户请求到最终结果的完整示例

以“帮我退款”为例,Harness 的执行过程可以概括为:

Verifier Payment API Policy Gate Order API Model Harness Verifier Payment API Policy Gate Order API Model Harness User "帮我退款" Provide user, order context, policy, and tools Call get_order Query order Order status and refund amount Return order observation Call issue_refund Check amount, ownership, and risk Require human approval Show refund details and ask approval Approve Issue refund with idempotency key Refund accepted Query refund status Refund exists and is successful Confirm refund with evidence User

注意:如果支付 API 返回“请求已接受”,Harness 仍然不应直接告诉用户“退款已到账”。它可以告诉用户“退款请求已提交”,或者继续查询最终状态,取决于业务定义的完成条件。

二十一、图中的关键设计原则

1. 模型提出动作,Harness 执行动作

模型的工具调用是意图,不是授权。Harness 必须在执行前完成参数、身份、权限和风险检查。

2. 工具结果是下一轮观察,不是最终事实

工具结果可能是中间状态、异步受理或部分成功。必要时必须通过独立验证器查询外部系统。

3. 状态要独立于对话

消息历史适合帮助模型理解语境,结构化任务状态适合保证系统正确性。不能用自然语言历史替代幂等键和事务状态。

4. 完成必须可验证

模型输出“完成”只是候选结论。只有规则、测试、外部系统查询或人工确认通过后,Harness 才能将 Run 标记为成功。

5. 失败是流程的一部分

工具超时、权限拒绝、上下文不足、审批拒绝和预算耗尽都应成为显式分支,而不是隐藏异常。

十、阅读 Mermaid 图时的主线

如果只记住一条执行主线,可以按下面顺序阅读:

任务入口
  → 身份与权限
  → 初始化状态
  → 构造上下文
  → 调用模型
  → 解析工具调用
  → 策略检查与审批
  → 执行工具
  → 保存观察和 checkpoint
  → 继续下一轮
  → 验证外部状态
  → 成功、失败、恢复或人工接管

这条主线就是 Harness 的本质:围绕模型建立一个可循环、可控制、可验证、可恢复的行动系统。

参考资料

  1. Anthropic — Demystifying evals for AI agents
  2. OpenAI — A practical guide to building agents
  3. OpenAI — Harness engineering: leveraging Codex in an agent-first world
  4. Microsoft Learn — Agent harnesses
  5. Cloudflare Agents — Harnesses
  6. Harness Protocol — Overview
Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐