Agent Harness 架构设计与实现:面向生产环境的 Agent Runtime 全景落地指南
关键词:Agent Harness、LLM Runtime、Tool Calling、Workflow、Kubernetes、可观测性、资源治理
一、为什么 Agent 系统真正难的不是“会调用模型”,而是“跑不飞、压不垮、查得清”
这两年很多团队都能在几天内做出一个“看起来能工作”的 Agent Demo:
- 用户输入一个任务
- LLM 规划步骤
- 自动调用若干 Tool
- 读写记忆
- 最后返回答案
从 Demo 视角看,Agent 已经“跑起来了”。
但只要系统进入真实生产环境,问题会立刻从“功能是否可用”升级为“系统是否可控”。
典型故障并不复杂,却足以让平台级事故在几分钟内形成:
- 某个 Tool 响应异常,LLM 连续重试同一动作,导致推理循环失控
- 某个租户瞬时流量暴增,模型网关被打满,拖垮其他业务租户
- 某次 Prompt 注入诱导 Agent 读取敏感上下文并向外发送
- 长会话不断膨胀,Context Window 爆炸,单次请求成本失控
- Pod 滚动发布时直接中断活跃任务,造成多步骤任务状态不一致
- 缺乏 Trace 与审计日志,事故发生后只能看到“模型超时”,却看不到是哪个 Tool、哪个会话、哪一轮决策出了问题
这背后的核心矛盾是:
大多数团队把 Agent 当成“提示词应用”开发,却必须把它当成“分布式运行时系统”治理。
所谓 Agent Harness,本质上就是解决这个矛盾的运行时基础设施。它不是一个花哨的“Agent 框架封装层”,而是负责把 Agent 从“能跑”提升到“可治理、可扩展、可审计、可演进”的关键中间层。
本文不讨论如何写一个酷炫 Demo,而是从生产落地角度系统回答四个问题:
- Agent Harness 到底解决什么问题,它和普通 Agent Framework 的边界在哪里?
- 一套可落地的 Harness 架构应该如何分层,控制面和数据面如何协同?
- 在高并发、强隔离、多租户场景下,如何做好状态管理、限流、调度、可观测性和故障恢复?
- 如果要真正上线,一套生产级代码骨架、部署方式和演进路线应该长什么样?
二、什么是 Agent Harness:它不是 Agent Framework,而是 Agent Runtime
很多概念在讨论时容易混在一起,我们先把边界划清。
2.1 三层抽象:Framework、Runtime、Platform
一个完整的 Agent 系统,通常至少可以分为三层:
| 层次 | 主要职责 | 常见能力 |
|---|---|---|
| Agent Framework | 描述 Agent 的行为逻辑 | Prompt 模板、Tool Schema、Planner、Memory 接口 |
| Agent Harness / Runtime | 承担 Agent 的执行治理 | 状态机、调度、限流、超时、重试、隔离、审计 |
| Agent Platform | 提供平台级运营与治理 | 多租户、配额、观测、灰度、成本分析、策略中心 |
可以把它理解为:
- Framework 决定“Agent 想做什么”
- Harness 决定“Agent 如何安全、稳定地做”
- Platform 决定“整个组织如何大规模运营这些 Agent”
很多系统失败,不是因为 Planner 不够智能,而是因为把 Runtime 的复杂度误塞进了业务代码和 Prompt 中,结果形成以下反模式:
- 业务服务自己维护对话状态
- Tool 执行直接起线程或 goroutine 裸跑
- 模型调用没有统一超时、配额和熔断
- Agent 结果没有审计日志
- 记忆压缩策略散落在各个业务模块
- 发布时直接重启实例,任务中断无人感知
这会导致系统在规模扩大后几乎无法维护。
2.2 Harness 解决的五类核心问题
一个成熟的 Agent Harness,至少要解决以下五类问题:
1. 执行治理
Agent 的执行不是一次函数调用,而是一个多轮状态推进过程:
用户输入 -> 推理 -> Tool 调用 -> 状态更新 -> 下一轮推理 -> 终止
Harness 需要把这个过程建模成一个**可控状态机**,而不是一段无限 while 循环。
2. 资源治理
LLM 调用贵、慢、不稳定;Tool 执行可能占用数据库、网络、CPU、内存;长会话会吞噬上下文窗口。Harness 要对这些资源做统一治理:
- 并发配额
- Token 配额
- 时延预算
- 资源上限
- 优先级调度
3. 安全治理
Agent 是“会自动执行动作的系统”,它天然比普通问答应用风险更高。Harness 必须承担:
- Prompt 注入隔离
- Tool 权限边界控制
- 数据脱敏
- 审计留痕
- 租户隔离
4. 可观测与可追责
没有高质量观测,Agent 出问题时你只能看到“最终回答错了”,但看不到:
- 错在第几轮推理
- 是哪个 Tool 返回异常
- 是否发生模型重试
- 哪个租户消耗了异常 Token
- 哪条策略拒绝了执行
Harness 需要记录完整的**执行轨迹、资源消耗和决策证据链**。
5. 演进承载
从单 Agent 到多 Agent,从短链路问答到长事务工作流,从单机到多集群,这些演进如果没有 Harness 作为承载层,系统会越来越难扩展。
2.3 一句话定义
Agent Harness 是面向 Agent 的运行时内核,负责把“非确定性的智能决策”封装进“可治理的工程执行框架”中。
三、先看事故现场:为什么很多 Agent 系统一上线就进入失控区
在正式谈架构之前,先看一个真实得不能再真实的案例抽象。
某客服自动化平台做了一个售后 Agent,职责是:
- 解析用户问题
- 判断是否需要查订单
- 调用订单 Tool
- 判断是否需要退款
- 调用退款审批 Tool
- 生成回复
测试环境一切正常,但上线一周后出现 P0:
- 某类异常订单返回半结构化错误信息
- LLM 将其错误地理解为“工具调用失败,需要再次尝试”
- 同一轮对话里重复调用订单查询 Tool 2000 多次
- 下游订单服务线程池打满
- 数据库连接池耗尽
- 整个平台出现雪崩,其他业务租户也被牵连
复盘后发现,系统几乎没有任何运行时护栏:
- 没有限制最大迭代数
- 没有限制单轮最大 Tool 调用数
- 没有区分“可重试错误”和“业务终态错误”
- 没有模型与 Tool 的调用预算
- 没有为单个租户设置并发与成本隔离
- 没有任务中断恢复与降级策略
所以真正的问题不是“模型偶尔会犯错”,而是:
我们默认一个非确定性系统会永远表现为确定性系统。
Harness 的意义,就是承认 Agent 不可靠,然后用系统设计把不可靠性圈进可控边界。
四、生产级 Agent Harness 的总体设计:控制面 + 数据面 + 治理面
如果只把 Harness 画成“LLM + Tool + Memory”的三件套,其实远远不够。
生产级设计应至少分成三层:
- 控制面(Control Plane):策略、配置、路由、租户治理、发布与灰度
- 执行数据面(Data Plane):真正跑 Agent 的执行引擎与状态机
- 观测治理面(Governance Plane):监控、审计、计费、追踪、风控
4.1 架构总览
┌────────────────────────────────────────────────────────────────────────────┐ │ Control Plane │ │ Agent Registry Policy Center Prompt Registry Model Routing Quota │ │ Release/Gray Tenant Config Tool Catalog Cost Control ACL │ └───────────────────────────────┬────────────────────────────────────────────┘ │ ┌───────────────────────────────▼────────────────────────────────────────────┐ │ Entry Layer │ │ HTTP / gRPC / MQ / WebSocket / Batch Trigger / Scheduler │ └───────────────────────────────┬────────────────────────────────────────────┘ │ ┌───────────────────────────────▼────────────────────────────────────────────┐ │ Harness Runtime │ │ Session Router Run Scheduler Workflow Engine State Machine │ │ LLM Gateway Tool Executor Memory Manager Guardrail Engine │ │ Retry Engine Circuit Breaker Backpressure Checkpoint Manager │ └───────┬───────────────────────┬───────────────────────┬────────────────────┘ │ │ │ ┌───────▼────────┐ ┌─────────▼────────┐ ┌────────▼────────────────────┐ │ Tool Sandbox │ │ State Storage │ │ Memory & Knowledge │ │ WASM / Sidecar │ │ Redis / Postgres │ │ Vector DB / Cache / Summary │ │ Rate Limit │ │ Object Storage │ │ Session Recall / RAG │ └───────┬────────┘ └─────────┬────────┘ └────────┬────────────────────┘ │ │ │ ┌───────▼───────────────────────▼───────────────────────▼────────────────────┐ │ Governance Plane │ │ Metrics Tracing Audit Log Cost Ledger Risk Detection SLO/Alerting │ └────────────────────────────────────────────────────────────────────────────┘4.2 控制面为什么是第一优先级
很多团队会先做执行循环,再补治理。这个顺序在实验期可以接受,但在生产期会产生明显问题:
- 无法按租户做模型路由
- 无法按环境做 Prompt 灰度
- 无法对不同 Agent 类型配置不同 Tool 白名单
- 无法快速止损某个异常 Tool 或某个高成本模型
控制面的本质,是把“经常变化的运营策略”从“稳定执行引擎”里剥离出来。
建议把以下配置全部控制面化:
- Agent 模板与版本
- 可选模型与路由权重
- Tool 白名单 / 黑名单
- 每租户并发、TPM、RPM、预算上限
- 记忆保留策略
- 高风险 Prompt 规则
- 审批链与人工接管阈值
4.3 数据面应该坚持的设计原则
Agent Harness 的数据面要遵循六条原则:
- 状态显式化:每轮推进都要有清晰状态,不允许隐式跳转
- 有界执行:每个环节必须有时间、次数、并发、Token 上限
- 失败可恢复:关键节点要能 Checkpoint,避免任务整体重做
- 副作用隔离:Tool 的外部写操作要有幂等和审批边界
- 多租户可隔离:配额、队列、模型预算不能互相污染
- 全过程可追踪:任意一次输出都能追溯到执行链路
五、核心运行模型:把 Agent 从 while 循环升级为可治理状态机
5.1 状态机比“循环”更适合生产系统
Demo 中常见写法如下:
for { 调用 LLM 如果返回 tool call,则执行 tool 把结果再喂给 LLM 如果没有 tool call,则结束 }这个写法的问题在于:
- 无法准确记录状态推进
- 不利于重试和断点恢复
- 不利于插入审批、降级和人工接管
- 很难表达并发 Tool、挂起、恢复、回滚等复杂流程
更好的方式是将 Agent 执行建模为状态机。
5.2 推荐状态模型
CREATED -> QUEUED -> RUNNING -> WAITING_LLM -> WAITING_TOOL -> WAITING_APPROVAL -> SUMMARIZING -> COMPLETED -> FAILED -> CANCELLED -> DEAD_LETTER其中:
CREATED:任务已创建但未进入调度QUEUED:等待执行资源WAITING_