ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

AI Agent从PoC到生产:Harness Engineering关键改造指南

AI Agent从PoC到生产:Harness Engineering关键改造指南

如果你现在去搜"AI Agent",满屏都是 Demo 视频和漂亮的架构图。但很少有人认真讲一件事:一个能跑通的 PoC,到底要经过哪些工程改造,才敢扔进 7×24 小时的生产环境。过去大半年,我前后参与了几个企业级 AI Agent 项目的评审和落地,发现同一个问题反复出现——PoC 阶段大家觉得"效果惊艳、两周就能上线",一进生产就变成"怎么什么都接不稳"。

问题不在模型本身,而在 Agent 外围那套支撑设施。这就是标题里"Harness Engineering"要表达的意思。Harness 直译是"马具",马具负责把马的力量传导到车、同时控制方向和速度。AI Agent 的 Harness 也扮演类似角色:它不负责模型推理这个"大脑",而是负责模型与现实世界之间的所有连接——工具调用、数据进出、结果校验、失败重试、日志追踪、成本配额、权限管控。把这些做厚,Agent 才能从"会聊天"变成"能办事"。

这篇文章我会从 Harness 的定义讲起,拆解 PoC 阶段最常埋的雷,再给出生产化改造的三根支柱、工具接入的管控思路、多 Agent 编排的边界问题,最后附一张可直接复制的落地清单。适合正在从原型走向生产的团队参考,也适合刚接触 Agent 工程化、想建立全局视角的人读。

1. Harness 工程到底在搭什么:Agent 与真实世界之间的那层骨架

1.1 先定义边界:Harness 把哪些事管起来

很多人以为 Agent 就是一个大模型加一个 API 接口,用户提问,模型回答。实际企业场景远不是这么简单。一个正经生产的 Agent,模型只是中间的一环,真正决定它能不能稳定干活的是它外围的 Harness。

我习惯把 Harness 分成六个层次来看:

  • 接入层:用户怎么把问题发进来,渠道是网页、IM 还是企业协作软件,消息格式怎么归一化。
  • 上下文层:该带哪些数据进模型,知识库检索怎么做,别把整个数据库都塞进提示词。
  • 工具层:Agent 能调用哪些 API,参数怎么校验,返回结果怎么解析。
  • 控制层:重试、超时、熔断、降级,以及常见的安全拦截和权限校验。
  • 观测层:每次调用花了多少 token、耗时多久、调用链是什么,出了问题能不能回放。
  • 质量层:离线评测数据集、回归测试、线上打分、人工反馈闭环。

在 PoC 阶段,这六层很多都可以不搭,因为演示场景可以从容选数据、手动重试、人工检查结果。但生产环境里这些层一层都少不得。少掉任何一层,短期可能没事,一旦遇到流量高峰或者奇怪输入,你就会在凌晨三点被报警电话叫醒。

1.2 PoC 与生产在指标上的真实差距

前面说的六层太抽象,换个更直观的对比。我用一张表列出同一个 Agent 从 PoC 到生产,几个关键维度的变化:

维度PoC 阶段生产阶段
调用量一天几十次,失败就手动重跑每秒几十上百次,失败要自动恢复
输入质量精心挑选的样例,格式规范真实用户输入,错别字、口语、恶意内容都有
失败容忍中断后人工介入即可必须有自动降级、熔断、逃生通道
可观测性控制台 print 就够全链路追踪、指标、告警、日志回放
安全管控基本忽略身份认证、权限隔离、全量审计
成本意识不看 token 花费每一轮对话的模型成本清晰可控

这张表不是理论推演,是我从多个项目里总结出来的。最典型的一个案例是某零售企业的客服场景:做 PoC 时,数据是团队手工整理的标准化工单,问题集中在"少发货""换地址"这几种类型,模型表现很好,评审会一片叫好。结果一对接真实工单系统,输入变成"我东西呢""地址给我改了,对就是那个"这种碎片化表达,效果断崖式下滑。不是模型变笨了,而是 Harness 的接入层和上下文层完全没有为真实输入做过设计。

所以说,PoC 到生产不是"把模型换大一号"就能解决的,真正要下功夫的是模型周围的支撑骨架。

2. PoC 阶段最容易埋下的三颗雷:Demo 不错,生产就炸

2.1 第一颗雷:Demo 用的"精修数据",在真实输入前掉链子

第一颗雷也是最常见的雷:PoC 阶段用精修数据做演示,但真实数据往往是"素颜"的。

做 PoC 的时候,团队通常会挑效果最好的几条记录来展示。这没有错,错的是没有同时用真实数据跑一遍。我的建议是,PoC 阶段就要做一次"脏数据压力测试":拿 100 条不经过任何筛选的真实输入,逐条看模型的表现,然后按失败类型分类。你会发现失败往往集中在几类:格式不规范、术语太口语化、上下文信息不完整、输入长度超出预期。

分类之后你就能判断哪些问题可以通过 Harness 修,哪些需要换模型或做指令微调。比如格式问题可以在接入层做标准化,术语口语化可以靠知识库补充同义词,上下文不完整可以自动拉取历史会话。这些都是在 PoC 阶段就能做的低成本改造,效果远比上线后打补丁好。

2.2 第二颗雷:Agent 的不确定性,会让测试工程师抓狂

第二颗雷是关于确定性的。同一个问题,让 Agent 跑两次,结果可能不一样。这在演示时无所谓,在生产和测试阶段就是大问题。测试工程师会问你:这个 bug 能稳定复现吗?答案是不能,因为模型的采样本身就有随机性。

这不是模型"不靠谱",而是 Agent 工程必须接受的一个常态。我遇到过某项目,Agent 在调用工具生成参数时,字段顺序和格式有时对、有时错,导致下游接口报错率高达三成。问题根源是模型在 JSON 输出时不够稳定。

应对办法有几层:第一,尽可能用结构化输出的方法,让模型输出严格遵守预先定义的 schema,而不是自由发挥;第二,在 Harness 层做输出校验,模型给的结果不符合 schema,就自动重试一遍,很多错误重试一两次就能纠正;第三,关键业务字段要做规则校验,比如金额必须大于零、日期必须符合格式,不能只靠模型自觉。把这三层叠起来,确定性能从"看运气"变成"基本可控"。

这里想多说一句:不要试图彻底消灭不确定性,那不可能。你要做的是让不确定性出现在可控的范围里,并且保证失败能被发现、被重试、被降级。

2.3 第三颗雷:工具调用失败被"静默吞掉"

第三颗雷最隐蔽,也最容易造成生产事故。Agent 调用工具时,工具返回了一个错误,但 Agent 没有把这个错误当回事,反而一本正经地回复用户"已完成"。这种"静默失败"我在不止一个项目里见过。

举例:某数据查询 Agent 负责帮内部员工查报表,PoC 时一切正常。上生产后有一天报表服务超时,工具其实返回了错误信息,但模型在生成回复时忽略了一段错误上下文,直接编造了一个"查询完成"的结果。用户拿到的是一份不存在的报表。这属于生产事故级别的问题。

解决方案是在 Harness 里做强制约束:工具调用结果必须是一个带状态码的结构,例如"成功"或"失败";如果状态是失败,模型必须如实说明,不得绕过;Harness 层面还可以设置安全阀——连续 N 次工具失败就直接中断流程,转向预案兜底,而不是让模型继续发挥。这个兜底可以是转给人工客服,也可以是返回一个明确的"系统暂时不可用"提示。宁可让用户看到真实的失败,也不能让用户拿到一个假成功。

3. 生产化改造的三根支柱:回归评测、链路追踪、护栏兜底

3.1 回归评测集:从"我看效果挺好"到"跑分说话"

PoC 阶段判断效果靠肉眼。生产阶段不行,你必须有一套可重复的评测机制,让每一次改动都能被量化。这里的关键是回归评测集。

第一件要做的事是沉淀用例。刚开始不用多,把 PoC 阶段跑过的真实输入、线上收集到的高频问题、已知的失败案例都汇总起来,先凑 50 到 100 条。这些用例要按场景分类,我建议至少覆盖以下几类:

场景类型说明示例
正常路径最常见的问题查询订单、查余额、提交工单
边界情况输入极短、极长、为空只有一个字、1 万字长文、空消息
恶意输入绕权限、注入、冒犯性内容试图让 Agent 删除数据、越权访问
工具失败依赖服务异常时的表现数据库超时、第三方 API 返回 500
歧义问题需要反问澄清的场景"那个东西怎么样了"缺少上下文

用例集建好之后,每次改动——不管是调提示词、换模型版本、改工具描述还是调整检索参数——都跑一遍完整回归。记录三个数字:任务成功率、平均工具调用次数、平均响应耗时。只要成功率不下滑,就说明改动是安全的。

这个过程前期很枯燥,但它是生产系统最底层的压舱石。没有它,你后面任何优化都是在盲改。

3.2 全链路追踪:一次请求从模型到工具的花费明细

第二个支柱是可观测性。PoC 时可以靠打印日志看结果,生产环境里你面对的是并发请求、多个模型调用、多次工具调用,没有链路追踪根本没法排查问题。

我给一个最简可行的方案。每个用户请求分配一个全局唯一的请求 ID,从入口开始,往后传给模型调用环节、工具调用环节、知识库检索环节,所有日志都带着这个 ID 一起打。每个环节生成一条 trace span,记录:

  • 请求 ID、用户 ID、会话 ID
  • 模型名称、模型版本、temperature 参数
  • 输入 token 数、输出 token 数
  • 工具名称、入参摘要、出参摘要、错误码
  • 各环节耗时和总耗时

有了这个数据,你可以回答几个关键问题:用户说"系统很慢",慢在哪一步?是模型推理慢还是工具响应慢?每个请求花了多少钱?有没有出现某个工具被异常高频调用的情况?这些信息在 PoC 阶段无所谓,生产阶段每一个都是刚需。如果 PoC 阶段没埋点,后面补的代价大概是两到三倍,我现在审核项目时会把这个缺失当成一个显著风险项看待。

3.3 三层护栏:入口、过程和出口的兜底

第三根支柱是护栏。我用三层结构来说。

入口护栏管的是输入。长度限制是必须的,超长输入要么截断要么拒绝;敏感信息检测也要放在入口,比如身份证号、银行卡号这类数据不应该进入模型上下文;再往上还有内容安全过滤。入口护栏的目的是一开始就把不该处理的东西挡在门外。

过程护栏管的是 Agent 的执行过程。工具白名单必须收敛,Agent 只能用业务必需的那几个工具;工具参数要做值域校验,日期不能往"13 月"传,金额不能是负数;关键执行动作要二次确认,比如"删除订""转账"这种不可逆操作,不能让 Agent 拿着权限就自己做了;还要有总的执行超时,超过了就终止本轮会话。

出口护栏管的是输出。模型生成的回答要做格式校验,该是 JSON 的必须是合法 JSON;涉及高风险的决策内容,比如医疗建议、法律判断、资金操作,必须强提示并征得用户确认,必要的时候直接转人工。我见过一个做得比较好的保险理赔项目:Agent 计算理赔金额后,出口护栏强制附加一行"此金额为预估值,最终以人工审核为准",就是这个细节,把不少纠纷挡在了门外。

三层护栏叠上之后,Agent 的行为边界就清晰了:不该进的进不来、不该做的做不了、不该说的说不出去。

4. 工具接入不是"教会 Agent 用 API",而是管控 Agent 的手脚

4.1 工具数量的收敛:给 Agent 十来个精兵,而不是三十个杂兵

接下来聊聊工具接入。很多团队做 PoC 的时候,恨不得把公司所有 API 都接进来,给 Agent 塞二三十个工具。但实测下来,工具越多,选择准确率越低。模型在 30 个工具里挑参数和意图,就像让一个人同时记 30 项待办,必然出错。

我的建议是给 Agent 的工具数量控制在 8 到 12 个以内。做法是把高频场景的同类型操作合并成一个工具,用参数区分不同的操作模式。比如"查订单"和"查物流"可以合并成一个"查询订单信息"工具,通过返回字段的粒度来区分。高频场景优先接入,低频场景宁可让 Agent 回复"该功能正在开通中",也不要硬塞一个容易误选的工具进去。

这里有个反直觉的发现:工具少了之后,不仅准确率上升,连响应速度都变快了。因为模型做工具选择时的候选空间变小,决策更快,上下文也少占 token。

4.2 工具描述的强制性字段

工具能不能被正确调用,很大程度取决于描述写得好不好。我审查过的项目里,很多工具描述写得跟 API 文档一样干巴巴,模型看不懂自然调不对。

一个合格的工具描述应该包含以下内容:

  • 功能说明:什么时候该用,什么时候不该用,用一句人话讲清楚
  • 参数说明:每个参数的含义、类型、取值范围、是否必填
  • 返回值说明:返回结构长什么样,什么状态算成功
  • 错误码说明:可能出现的错误和各自含义
  • 典型示例:一组输入输出对,帮助模型理解

举个例子。不要写"queryOrder(orderId: string)",而要写"该工具用于查询客户的订单详情和物流状态。当用户询问包裹位置、订单金额、商品清单时使用。参数 orderId 是订单编号,格式为 13 位数字。成功时返回订单状态和物流轨迹,失败时返回错误码 404 表示订单不存在。例如:输入 1234567890123,返回状态'已发货'及物流公司信息。"

描述写具体之后,模型误调用的概率会明显下降。这一步成本极低,收益却很大,值得用一次专项会议把所有工具描述逐条过一遍。

4.3 权限与逃生通道:让 Agent 的错误不变成事故

工具接进来之后,权限管控是最后一道闸。原则只有一条:给 Agent 的权限等于该场景所需的最小权限,不能把整个系统的权限都交给它。

实践中有几个具体动作。第一,不要用管理员账号的密钥去接工具,要单独为 Agent 申请最小权限账号。第二,数据隔离要在工具层做,比如 Agent 只能查询当前用户自己的订单,这一步不能只在提示词里说"你只能查自己的",要在接口层面强制过滤。第三,写操作要走更高一级的鉴权,涉及修改、删除、下单、转账这类动作,要单独校验身份并留审计日志。

另外一定要设计逃生通道。所谓逃生通道,就是当 Agent 连续失败、多次重试仍然无法完成任务时,系统能够自动转向人工处理的机制。某项目的做法是:判断 Agent 连续两次任务失败后,自动生成一条转人工工单,附上完整上下文,同时给用户推送一个友好提示。这让问题的最后一道兜底落在了可控的流程里,而不是让用户对着一个反复报错的机器人干瞪眼。

5. 多 Agent 协作里的边界与传话:别让 Agent 之间互相忽悠

5.1 子 Agent 的"地盘"怎么划

业务复杂之后,单个 Agent 往往会拆成多个子 Agent,比如一个负责意图识别,一个负责工具执行,一个负责总结回复。但拆不好会出大问题。

我的经验是:子 Agent 的划分要看"工具边界"和"知识边界",而不是按流程步骤。也就是说,一个子 Agent 应该尽量独占一类工具和一类知识,减少交叉。例如把"客户信息查询"和"订单操作"拆成两个 Agent,比拆成"售前 Agent"和"售后 Agent"更清晰——因为售前售后都可能查客户、都可能操作订单,它们的地盘是重叠的,重叠就会造成互相抢工具、互相干扰判断。

拆分之后,每个子 Agent 的提示词、工具列表、知识库都要尽量独立。工具列表要收窄到只跟它负责的领域相关,知识库也只挂它需要的片段。这样做的好处是上下文更干净,模型被无关信息干扰的概率更低。

5.2 传递的不只是 JSON,还有证据和置信度

多 Agent 协作里,子 Agent 之间要传数据。最常见的问题是:上游 Agent 只传一个"结论"给下游,比如"该客户的订单状态异常"。下游拿到之后怎么知道这个结论可不可靠?它无法判断。

所以子 Agent 之间传递的信息,不应该只是一句话,而应该是一个结构化的结果对象,至少包含三块:结果内容、置信度、证据来源。置信度指的是该 Agent 对自己结论把握有多大;证据来源指的是它依据的是哪些原始数据、哪个接口返回。下游 Agent 看到置信度低,可以选择追问或者转人工,而不是稀里糊涂地往上层传。

此外,传递链路里要加一道 schema 校验。上游传下来一个 JSON 对象,下游在消费它之前先校验字段是否齐全、类型是否正确。这个校验能挡住上游幻觉产生的不合法数据,避免错误信息在 Agent 网络里被层层放大。

5.3 编排层要防的三种死循环

多 Agent 系统的编排层,还得防三种死循环。

第一种是互相调用。Agent A 调用 B,B 反过来又调用 A,如果没有调用深度限制,两个 Agent 能互相念叨到天荒地老。解法是给整个链路设置最大跳数,超过就强制终止并返回失败。

第二种是任务重复执行。A 把任务传给 B,B 执行失败后又把任务传回 A,A 再次传给 B,形成重复。解法是在编排层记录每个任务的唯一 ID 和执行历史,同一任务重复进入时直接拦截或转为其他处理路径。

第三种是并发失控。多个子 Agent 同时发起工具调用,把下游依赖的接口打挂。解法是编排层统一做并发配额,比如同时最多允许 5 个工具调用,超过就排队等待。

这些隐患在只有两三个 Agent 的小规模场景里不太显眼,一旦规模上来,一定会暴露。编排层的核心职责不是"让 Agent 互相协作",而是"限制它们以不健康的方式协作"。

6. 直接抄的十二周落地清单,以及一个反向指标

6.1 十二周路线:从回归集到灰度发布的推进节奏

最后把上面所有的思考收拢成一张可以直接照着做的清单。按十二周推进,适合一个已经有了可用 PoC、准备冲刺生产的团队。

第一到第二周,做地基:

  • 汇总所有历史真实输入,按失败模式分类,建立首批回归评测集(目标 100 条)
  • 接入全链路追踪,确认每个请求都能回溯完整链路的日志
  • 建立成本统计口径,算出每条请求的平均 token 花费

第三到第四周,做工具治理:

  • 收敛工具数量到 12 个以内,合并同类项
  • 重写每个工具的描述,补齐参数、返回值、错误码、示例
  • 工具接口层做最小权限收敛,撤销一切多余权限

第五到第六周,做护栏:

  • 上线入口护栏:长度限制、敏感信息过滤
  • 上线过程护栏:参数校验、执行超时、操作确认
  • 上线出口护栏:输出校验、高风险内容提示
  • 建立逃生通道:连续失败自动转人工

第七到第八周,做灰度发布:

  • 影子模式跑一周,把线上真实流量复制一份喂给 Agent,只记录不回应
  • 打开 10% 真实流量,指定人工处理小组持续反馈
  • 稳定后逐步提升到 25%、50%,每个比例至少观察两天

第九到第十周,做成本优化:

  • 分析模型调用链,把简单任务切到小模型,复杂任务才用大模型
  • 优化提示词压缩 token 占用,去掉冗余的上下文
  • 建成本告警,单条请求超预算自动通知

第十一到第十二周,做迭代闭环:

  • 每周开一次评测复盘会,把新失败案例补进回归集
  • 每两周跑一次完整回归,对比改动前后的成功率变化
  • 建立版本化管理,所有提示词、工具描述、参数配置都要有历史版本

6.2 一个反向指标:哪些项目压根不该上 Agent

说完清单,再讲一个反向指标。一个项目该不该上 AI Agent,不是看"技术是否先进",而是看"场景是否适合"。我总结出三个不该上的信号,如果一个项目命中两个以上,建议慎重。

第一个信号是"允许犯错成本极低"——这个其实反而是可以上的;真正危险的信号是"错误影响不可逆且无法兜底"。比如让 Agent 直接操作生产数据库执行删除,又没有人工审批环节,这已经不是在建设产品,而是在制造事故通道。

第二个信号是用户输入极度不可预测且缺乏约束,如果你的场景里用户一个问题可以指向几十种完全不同的意图,而且没有任何对话澄清机制,Agent 会变成一本正经的胡诌机器。这个场景应该先做意图收敛或人工兜底,而不是硬上。

第三个信号是团队没有专职的工程负责人。Agent 上线不是终点,上线之后每天要有人盯追踪指标、跑回归用例、处理失败反馈、迭代提示词。如果这些事情最终落不到一个具体的人身上,系统大概率会悄悄退化,直到某天出大事。

这三个信号是反向指标。你的项目如果避开了它们,那上面的清单就是你的行军路线;如果撞上了,先回头把场景规则梳理清楚,再谈技术选型也不迟。

最后分享一个我个人的习惯。每个 Agent 上线前,我会让团队做一次"最坏情况演练":把输入换成乱码、把数据库连接断开、把某个依赖服务的响应延迟拉长五秒。在这种条件下,如果 Agent 能把错误如实暴露出来,而不是假装一切正常,我认为它才算真正拿到了进入生产的门票。这个标准听起来不高,但能做到的项目,其实没有几个。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进