最近一个月我连续参与了几批智能体项目的技术评审,一个现象特别明显:单看Agent的Demo,个个都能眼前一亮;一旦要求同批交付三五个Agent,团队就开始互相甩锅——写Prompt的说模型不稳定,做后端的说工具调用老报错,业务方说回答根本不符合口径,测试那边更头疼,压根不知道拿什么当预期结果。问题不在某个环节,而是大家一直在用“热启动”的方式做Agent,批量交付却需要一套工程化的质量流程。
我建议直接引入软件工程里那个老牌的V模型。听起来像是把传统软件测试模型硬搬到AI应用上,但真正拆开落地之后会发现,V模型不是过时的流程,反而是给LLM这类非确定系统兜底最务实的办法。这篇我写一下自己在多个Agent项目里,怎么把“批量进入V模型”拆成可执行的动作:需求怎么拆、场景怎么画、测试怎么跑、坑怎么避。适合正在做Agent应用、并且开始面临交付压力和技术团队管理的朋友参考。
1. 为什么智能体开发会倒在这道“质量墙”上
1.1 热启动与冷交付之间的矛盾:从“一个Demo”到“一批Agent”的差距
大部分团队做Agent的第一阶段都是“热启动”:拿着OpenAI或本地模型,写一个ReAct循环,挂两个内部工具,调几轮Prompt,跑通一个演示场景就给老板看。一个人做菜可以凭手感,但餐厅要开连锁,就必须让每个厨师都按标准菜谱走。Agent从1个变成10个的时候,靠手感是不行的。
批量交付的困难不只是数量乘10,而是三类问题同时被放大。第一是需求不一致,不同Agent由不同人写Prompt,行为标准五花八门。第二是非确定性放大,同一个Prompt,今天跑对明天跑错,测试没法交代。第三是依赖复杂化,Agent要调内部API、数据库、第三方服务,任何一个上游抖动都会让Agent输出不可用。这三类问题叠在一起,就成了质量墙。
我见过最典型的场景是:客服Agent上线前一周才想起来要做“超出知识库范围的问题拒绝话术”,结果业务方和研发吵了一下午。这类问题如果放在V模型的需求阶段去定义,根本走不到上线前。
1.2 AI Agent的系统边界:它比传统代码多了哪三层不确定性
V模型在传统软件里管的是“功能是否正确实现”和“是否满足需求”,但Agent比传统代码多了三层不确定性,必须搞清楚这三层,才能设计对应的验证手段。
第一层是输入不确定性。用户不会按你想好的话术提问,同一个意图可能有几百种表达方式。第二层是执行不确定性。给定完全相同的Prompt和历史消息,LLM的输出是有分布的,不是单点确定的。第三层是输出不确定性。模型可能输出格式错误、引用工具结果时改数字、一本正经地编造不存在的订单状态。
这三层不确定性意味着,传统软件测试里那种“用例+预期结果”的二维模型不够用。V模型的应对方式不是试图消除不确定性,而是把不确定性量化成可接受的失败率,并把验收预期前置到开发之前。简单说,先定义“多好才算好”,再动手实现。
1.3 V模型的本质是把“验收预期”前置
V模型的经典结构,左边是需求分析、概要设计、详细设计,右边是单元测试、集成测试、系统测试、验收测试。左边逐层分解,右边逐级验证,每一级验证都和左边某一层对应。
放Agent项目里,左边不是画架构图,而是把业务目标拆成行为契约,把行为契约再拆成组件约束;右边也不是写测试脚本,而是用历史样本、模拟工具、端到端场景去回放和判分。这个映射关系一旦建立,批量交付就从“每个Agent自由发挥”变成了“同一套轨道上批量晋级”。
我用一个直观说法跟团队解释:V模型解决的不是流程问题,是预期管理。业务方想要什么、能接受的失败率是多少、哪些话术是底线,这些在左岸定义清楚;右岸的每一级测试都在回答“做到没有”和“偏离多少”。没有这个前置预期,AI项目的返工成本比传统项目高得多,因为改一处Prompt可能牵动整体行为变化。
2. V模型在Agent项目里的真实形态:从需求拆到验收
2.1 左侧四层需求:从业务目标到组件约束
传统V模型的需求层级是“业务需求—系统需求—功能需求”,我在Agent项目里把它改成了四层:业务目标、用户场景、行为规范、组件约束。
业务目标是可量化、可验收的业务结果,不跟具体技术绑定。比如“订单状态查询Agent的准确率不低于90%”“营销文案Agent的生成内容合规通过率不低于95%”。用户场景是典型对话流或任务流,描述用户带着什么意图进来,Agent要做完哪几件事才算成功。行为规范是Agent在交互过程中的边界,包括回复风格、必须调用的工具、禁止触碰的操作、超时和异常时的兜底话术。组件约束是技术侧的限制,例如Prompt模板版本、工具接口定义、记忆库Schema、模型版本。
以订单状态查询Agent为例,四层需求可以写成:
- 业务目标:订单状态、物流节点查询准确率≥90%,人工介入率≤10%。
- 用户场景:用户说“我的订单到哪了”→Agent识别意图→调用订单查询工具→提取物流节点→以标准格式回复。
- 行为规范:只能查本人授权订单;查不到时不允许编造物流信息,必须给出引导话术;涉及退款、投诉等敏感意图时直接转人工。
- 组件约束:基于统一订单查询服务,接口超时3秒必须降级;Prompt里禁止附带任何业务数据库字段名。
这四层写下来,开发者和业务方都能看懂。很多项目只写了第一层“提高效率”,那后面一定会在验收时扯皮。
2.2 右侧四级验证:从验收指标到单轮行为检查
右岸验证我也做四级拆分,和左岸四层一一对应,而不是笼统地叫“测试”。
单元测试对应组件约束,验证单个能力,比如意图识别、工具参数抽取、单轮回复是否包含关键字段。集成测试对应行为规范,把LLM和工具串起来,验证工具调用是否合规、异常路径是否有兜底。系统测试对应业务目标,用端到端场景模拟用户真实任务,看完整流程是否跑通。验收测试对应用户场景,由业务方参与打分,定义Agent在现实流量下的交付分数。
每级测试都需要明确的判分维度。我常用的是这样一套:
- 正确性:是否命中了标准答案或标准动作。
- 完整性:是否覆盖了必要的字段、步骤或提示信息。
- 工具合规:是否按要求调用工具、没有越权动作。
- 风格一致:是否遵守语气、人称、话术边界。
四个维度可以按场景设权重。客服Agent正确性占0.4,风格一致占0.3;数据查询Agent正确性和完整性分别占0.5和0.3。权重要在测试前定,不要跑完样本之后按结果倒推。
2.3 “批量”的本质是模板复用:需求与验证的Schema化
批量进入V模型,最大的杠杆是需求与验证的模板化。如果每个Agent都从零画一遍V,成本并不比原来的自由开发低多少。我做的第一件事是把“需求—验证”的映射做成一份Schema,每个Agent都是一张配置表。
一个Agent的Schema大致长这样:
agent_id: order_query_v1 business_goal: accuracy: ">=90%" human_handoff_rate: "<=10%" scene: - "用户查询订单物流" - "用户查询订单状态" behavior_rules: - "必须调用 order_query 工具" - "查不到时使用安抚话术并转人工" - "拒绝输出非授权订单信息" component_constraints: - "接口超时降级到静态话术" - "prompt_version: v3" judge_weights: correctness: 0.4 completeness: 0.2 tool_compliance: 0.2 style: 0.2一份Schema同时承载了左岸需求和右岸判分。批量交付时,不同Agent的区别只在业务目标、行为规范和组件约束里,验证框架是同一套。团队里的测试人员看到这个Schema就能写用例,不再需要每个人从头理解个Agent的运行逻辑。
另一个好处是,低代码平台搭出来的Agent也能套这个Schema。我见过用各类智能体平台搭的Agent,导出清单之后按同一份Schema补全“业务目标”和“行为规范”,照样能走验证流程。模板化不是限制灵活性,而是让灵活性有边界。
3. 批量入场前的准备工作:需求池、场景矩阵与红线清单
3.1 需求访谈时逼着业务方给出“可验证口径”
很多Agent项目立项时只有一句话:“做一个客服机器人提高响应效率。”这句话没法验证,必须把它拆成具体的、可量化的口径。我的经验是,需求访谈时不要只记录功能描述,要逼着业务方回答几个问题:
- 用户说什么样的话应该触发这个Agent?
- 判断“回答正确”的标准是什么?
- 查不到答案时,Agent应该拒绝、编造、还是转人工?
- 一次对话的合理时长和成本上限是多少?
这些问题会逼出口径。比如业务方说“用户不满意”,你要追问“用什么指标衡量不满意?是重复提问次数,还是主动点转人工按钮?”这样把“不满意”变成“连续两次追问同一问题,则转人工”。有了可验证口径,验收才不会滑向主观判断。
做这件事时要注意,业务方往往急于上线,会认为这些问题是“流程形式主义”。我通常直接给示例:上一个项目因为没定义“查不到订单”的处理方式,Agent上线后编造了物流节点,伤害了好几个核心用户。这个例子比任何道理都有说服力。
3.2 场景矩阵:批量识别Agent复杂度等级
批量管理一批Agent,不能每个都从头评估,需要一张场景矩阵做批量诊断。矩阵的维度是:业务域、用户意图、工具依赖、不确定度。
不确定度是我额外加的一列,用来判断Agent是否需要复杂的规划能力,还是简单的直通流程就能解决。比如“查询天气”意图明确、工具单一,不确定度低;“分析财报并生成投融资建议”涉及多步推理、多工具组合,不确定度高。矩阵长这样:
| Agent | 业务域 | 用户意图 | 工具依赖 | 不确定度 | 建议范式 |
|---|---|---|---|---|---|
| 订单查询助手 | 客服 | 查状态/查物流 | 订单API | 低 | 直通 |
| 营销图文生成 | 增长 | 生成商品素材 | 素材库+翻译 | 中 | 规划器 |
| 经营数据分析 | 经营 | 问答+图表生成 | 数仓+绘图 | 高 | 子Agent编排 |
矩阵让团队一眼看出资源应该集中在哪里。低不确定度Agent用简单Prompt+工具直通,高不确定度Agent才需要复杂编排和强化测试。批量交付时,不要把所有Agent都做成一个复杂度,那是成本灾难。
3.3 红线清单:提前给LLM立规矩
批量Agent共用一个模型底座,很多风险是通用的。我把这些通用风险抽象成一份红线清单,在每条Agent进入开发前就绑上去,而不是等测试发现问题再补。
红线清单的典型内容:
- 禁止调用操作类工具(删除、转账、改价),如触发必须人工审批。
- 涉及用户手机号、身份证、地址时必须脱敏展示。
- 任何查询无结果时,禁止编造数据,必须返回兜底话术。
- 用户表达投诉、威胁、法律纠纷意图时,立即转人工或安全处置。
- 单次对话的Token消耗和调用次数设硬上限。
红线要分级,例如“禁止执行”“需审批”“可自动执行但记录日志”。每条红线在左岸进入行为规范,在右岸进入工具合规判分。红线清单的意义是让规则跨Agent复用。不需要每个Agent单独定义一遍,新增Agent时直接继承通用红线,再补充自己的特有边界。
4. 左岸设计与实现:Prompt、工作流、工具边界如何一次做对
4.1 Prompt模板化:把提示词当成版本化接口来维护
批量环境下最忌讳把Prompt当成一段“写出来的台词”贴死在代码里。我把Prompt当成一个版本化、可参数化的接口,通过配置注入变量。
模板结构通常分三段:角色与任务、约束与边界、输出格式。角色与任务说明Agent的身份和本轮目标;约束与边界注入红线清单中的规则;输出格式强制LLM按JSON输出关键字段,方便后续解析判分。示例:
你是[role_name],需要完成[task_desc]。 约束条件: 1. 只能基于[allowed_tool_list]中的工具回答问题。 2. 工具返回失败时,不得编造结果,必须输出[fallback_template]。 3. 涉及[redline_type]时,必须转人工。 输出格式: 请输出JSON,包含如下字段: {"intent": "...", "tool_call": {"tool": "...", "params": {...}}, "reply": "..."}从纯文本Prompt改成模板化接口后,测试时可以直接替换role_name、task_desc、allowed_tool_list等变量生成不同样本。这就让“批量改Prompt”变得可追踪——每次变更对应一个版本号,测试报告里能看出哪个版本引入了回归。
4.2 工作流搭建的三种范式与选型依据
工作流搭建是热搜里频繁出现的词,但它不是越复杂越好。我在项目里把Agent工作流归成三种范式,按可验证性来选型。
第一种是“单业务串行直通”,一个Prompt完成意图识别、工具调用和回复生成。适合意图单一、工具固定的低不确定度场景。优点是流程短、好测试,缺点是复杂任务处理不了。第二种是“规划器模式”,模型先规划步骤,再逐步执行工具。适合中等复杂度的任务,例如营销图文生成,需要先查询素材库、再翻译、再组装。第三种是“子Agent编排”,由主Agent拆解任务,分派给多个子Agent或工作流节点执行,再汇总结果。适合高不确定度的复杂分析场景。
三种范式的对比:
| 范式 | 适用场景 | 可验证性 | 成本 |
|---|---|---|---|
| 单业务串行直通 | 意图单一、工具固定 | 高,单链路好构造用例 | 低 |
| 规划器模式 | 多步推理、顺序依赖 | 中,需验证规划质量 | 中 |
| 子Agent编排 | 多任务并行、角色分工 | 低,链路长、状态复杂 | 高 |
选型原则很简单:能用直通解决的不要上规划器,能用规划器解决的不要上子Agent编排。复杂度每升一级,右岸测试的用例量和排查难度几乎是成倍增加的。
4.3 工具层统一契约:避免V模型右岸集体翻车
工具调用是Agent项目里最容易翻车的环节。LLM对工具参数的抽取经常出错,工具返回的数据也千奇百怪。批量交付前,必须给所有工具定一个统一契约。
我要求的工具Schema至少包含四块:工具名、入参定义、出参定义、错误码。出参必须区分status、data、error_code三个字段,这样Agent才能判断“成功但有数据”“失败但有原因”“成功但数据为空”。示例:
{ "tool": "query_order", "params": { "order_id": "string", "user_id": "string" }, "output": { "status": "success|failed|empty", "data": {}, "error_code": "string" } }统一契约还有两个额外要求。一是幂等性,尤其查询类Agent重试时不能让数据重复或崩溃。二是日志协议,每次工具调用必须记录入参、出参、耗时、token消耗,否则右岸测试没法排查问题。没有这个契约,测试阶段会发现一个Agent报错,排查半小时才发现是工具返回格式和Prompt里的格式要求不一致。这类问题应该在左岸设计阶段就消灭。
5. 右岸验证执行:四级测试怎么批量跑起来
5.1 单元测试:把模型行为降维成确定性指标
单元测试在Agent里不是测代码,而是测单个模型能力。比如意图识别准不准、工具参数抽取对不对、单轮回复是否包含必要字段。把这些能力做成固定样本集,跑批次,统计通过率。
我的做法是每个能力准备50条黄金样本,覆盖正常、边界、异常三类。样本固定,跑批脚本固定,模型参数固定。例如意图识别测试,用temperature=0.2跑三轮,统计判对率;我们的准入门槛是≥95%。低于这个值,不允许进入下一级验证。这里的关键是把模型行为“降维”成确定性指标,而不是纠结单条对错。当前模型随机性再大,在固定参数下跑批次还是有统计规律的,用这个规律做判断即可。
黄金样本集要纳入版本管理。每次模型升级、Prompt模板变更后,全量重跑一遍,看哪些样本从对变错了,这就是回归分析。没有黄金样本集,Agent项目永远是修了东墙漏西墙。
5.2 集成测试:Mock服务与真实调用按什么比例跑
集成测试是把LLM和工具串起来之后,验证Agent在“工具可能出错”的情况下表现如何。这里的关键是Mock服务的使用比例。
集成测试第一轮建议全Mock,目的是验证流程逻辑,不依赖真实API的稳定性。Mock工具可以模拟三类返回:正常返回、空返回、异常返回。空返回测试Agent是否编造数据,异常返回测试Agent是否走兜底话术。第二轮再混合真实调用,一般真实调用占30%-50%,验证真实接口延迟和数据格式是否符合预期。
我踩过的坑是:第一轮就全真实调用,结果一个上游接口字段变了,测试挂了一半,大家浪费半天去排查,最后发现根本不是Agent的问题。集成测试阶段的职责是把Agent自身的问题和工具的问题分开,不要混在一起。Mock服务先滤掉Agent问题,真实调用再暴露集成问题。
5.3 端到端测试与业务验收:用“分数卡”开会
端到端测试是从模拟用户完整会话开始的,验证Agent在真实任务链路上的表现,指标包括任务成功率、平均耗时、Token成本、人工介入率。端到端环境要尽量贴近生产,使用真实工具,但注意写操作要降级或标记为测试账号。
验收阶段,我习惯用一张“验收分数卡”和业务方开会,而不是把几十页测试报告扔给业务方。分数卡长这样:
| 指标 | 目标 | 实测 | 结论 |
|---|---|---|---|
| 准确率 | ≥90% | 93% | 通过 |
| 完整性 | ≥85% | 81% | 不过 |
| 工具合规 | 100% | 100% | 通过 |
| 人工介入率 | ≤10% | 12% | 不过 |
开会时不要把所有问题堆在一起说,按分数卡逐项过,每个未达标项给出原因和修改期限。业务方参与度会明显提高,因为他们看的是业务口径,不是技术术语。分数卡上“不过”的项目,才是进入返工流程的项目。
5.4 线上回放:把V模型闭环变成持续回归
端到端测试做完不代表V模型结束了,上线后还缺最后一环——流量回放。Agent上线积累真实对话后,定期截取有代表性的历史会话,构造成回归测试集。以后每次改Prompt、换模型、调工具,都用同一批历史会话重新跑一遍对比分数。
线上回放的样本要覆盖:成功案例、失败案例、转人工案例、边界案例。运行回放不用追求和线上完全一致,重点看新旧版本在同样输入下,哪些样本分数变化了。分数掉了就说明本次变更引入了回归,需要回滚或修复。
这一环的价值是让V模型“闭”起来。传统V模型到验收结束就完了,但Agent变更频繁,没有持续回放机制,上线后很快又会退化。回放相当于把V模型的右岸无限延伸到线上,让质量处于持续监控状态。
6. 批量实录:一次三个Agent并行交付的关键路径
6.1 难度分级让三个Agent错峰并行
上个月我按这套流程同时推进了三个Agent:订单查询助手、营销内容生成、经营数据分析。团队就六个人,没有三套班子分别做,核心做法是按复杂度分级错峰并行。
订单查询助手是低不确定度,走直通范式,需求拆解、Prompt模板、测试都很快,两周内可以做验收。营销内容生成是中不确定度,要用规划器模式,先让它在单测阶段多磨两轮。经营数据分析是三个里最复杂的,需要子Agent编排,团队进度排在第三,前面Agent跑通的工具Schema和质量模板直接复用它。
三个Agent在V模型的不同阶段并行,大家各自有明确的目标。订单查询在右岸端到端测试时,营销内容在左岸做设计,数据分析还在需求池。这样避免了“所有人同时写Prompt”的拥挤,也避免了“一个人同时盯三个Agent”的混乱。
6.2 实测数据:不同验证级别的成本差异
在三个Agent并行期间,我记录了每级验证的实际成本,结果验证了一个判断:问题越早被发现,成本越低。
| 验证级别 | 单次成本(相对值) | 常见返工时长 | 备注 |
|---|---|---|---|
| 单元测试 | 1 | 分钟级 | 50条样本跑批次 |
| 集成测试 | 3-5 | 小时级 | 需要Mock和真实环境切换 |
| 端到端测试 | 8-10 | 天级 | 涉及多轮交互和真实工具 |
| 验收测试 | 15-20 | 周级 | 业务方参与,返工周期最长 |
一个明显的例子:订单查询Agent在单元测试阶段发现“物流节点抽取”准确率只有78%,只改了一个字段映射,花了半小时。如果这个问题漏到验收阶段,业务方会看到一堆物流信息错位,至少返工两天。批量交付时,团队最容易犯的错误是跳过单测直接跑端到端,看起来快了,实际上把成本堆到了最后面。
6.3 批量交付中最容易被低估的三件事
三个Agent并行交付下来,有三件事超出所有人预期,需要特别提醒。
第一是外部API变更的连锁影响。营销内容生成Agent依赖的翻译服务在高峰期改了一次返回字段,导致集成测试大面积失败。应对办法是把所有外部依赖包一层适配器,并针对依赖变化设立专项回归。第二是Prompt版本管理混乱。三个人同时改Prompt,没有版本控制的话,测试报告根本说不清是哪个版本的结果。我们后来把Prompt模板收进代码仓库做版本管理,和代码一起评审。第三是业务口径变化。业务方看到Demo后经常调整话术要求,这不是坏现象,但必须走“需求变更”流程,改动之后对应的黄金样本集和红线清单要同步更新,不能口头改一下Prompt就完事。
这三件事的共同点是,看起来都是“小问题”,但在批量场景下会被数量放大,最终影响整体交付节奏。
7. 反常识的失稳点与容错设计:这些坑我在实战里踩过
7.1 为什么同一条Prompt会“时好时坏”
很多团队第一次跑V模型会被一个问题搞懵:同一个Prompt,十个样本里八个对两个错,重跑一遍,错的两个换成了另外两个。这不是V模型流程有问题,而是LLM的本质特性——它的输出是采样结果,不是函数结果。
理解这一点后,我对测试基线的态度发生了一个重要转变:不再追求“100%确定性通过”,而是定义允许失败率和重试策略。比如正确率目标是90%,那就允许10%的波动,只需要确认波动边界稳定。同时,生产环境的Agent要配置重试机制:当输出不符合JSON Schema时自动重试一次;连续两次不符合时,降级为固定话术。LLM的不确定性是天花板,V模型要做的是在这个天花板下划出可控区间。
7.2 工具脏数据导致的“一本正经胡说八道”
实测中最危险的一类错误,是LLM把工具返回的数字引用错。比如工具返回一个订单有3个物流节点,LLM回复时改成了“已签收”。原因通常是工具返回结构复杂,模型在生成回复时发生信息损耗。解决这个问题的关键是“强制结构化输出+解析后校验”。
Prompt里强制模型先输出结构化JSON,再基于JSON解析结果生成最终回复。解析层做严格校验:遍历JSON里所有数字和状态字段,和工具返回的原始数据字段做比对,不一致就拦截。拦截后采用回退方案:不生成模型自由发挥的回复,而是用工具返回字段直接填模板。例如:
订单[order_id]当前状态为[status],最新物流节点为[latest_node]。这句话里所有字段都来自工具返回的原始数据,模型只做拼接,不参与改写。这能有效杜绝“一本正经胡说八道”的问题。设计原则是:关键事实数据,模型可以组织语言但不能改写数值。
7.3 三档容错:重试、换路、人工接管
结合“自主容错控制”这个方向,我在Agent里做了一套三档容错机制,从低到高分别是:重试、换路、人工接管。
第一档重试:工具调用超时或返回系统错误,自动重试1-2次。第二档换路:重试无效或模型输出连续校验失败,切换到备用逻辑。比如订单查询API挂了,换到读写分离的只读副本;查询类失败没有副本,就降级为话术引导和转人工。第三档人工接管:涉及红线操作、连续失败超过阈值、用户情绪强烈时,交给人工处理。
阈值配置我一般这样设定:
| 触发条件 | 动作 |
|---|---|
| 工具超时1次 | 自动重试 |
| 连续重试2次失败 | 切换备用路径 |
| 连续3次任务失败 | 触发人工接管 |
| 涉及转账、删除等红线工具 | 直接人工审批 |
| 单轮对话token超限 | 截断并引导转人工 |
这套三档容错不是一次性做出来的,是在线上问题复盘里一遍遍补出来的。最开始只设计了重试,结果碰到订单API连续故障,Agent反复重试拖垮了下游服务,才加了熔断和换路。容错设计的核心原则是:不要让Agent在没有出口的循环里消耗资源,所有异常路径都要有终止条件。
我实际操作下来最深的体会是:AI智能体的开发方式和传统后端服务真的不太一样。传统系统追求逻辑完备,Agent系统追求的是边界清晰、验证充分、容错兜底。V模型不是给Agent开发增加流程负担,而是给非确定性系统划出了确定性的轨道。批量交付不是把N个Agent的复杂度简单相加,而是通过一套统一模板和验证机制,让复杂度增长变成线性,甚至更低。如果你们团队也正卡在“Agent很好演示但很难交付”的阶段,不妨把每个Agent都画到V模型里去,左侧写清楚行为契约,右侧定义好验证指标,剩下的事会顺很多。