从去年开始,我把 ModelEngine 从“跑通 Demo”逐步推进到了生产环境,期间最大的感受是:企业级的 AI 系统,靠单个大模型硬扛是不现实的,真正需要的是一套能编排、可控制、能审计的多智能体协作机制。这篇文章就把我在 ModelEngine 上构建“企业级 AI 团队”的思路、配置、部署和排障过程完整记录下来,适合正在做智能客服、内部助手、多步骤自动化决策的团队参考。
1. 为什么“单个大模型”撑不起企业级业务
很多团队一开始都会走一条路:把业务规则全部塞进一个 Prompt,让一个大模型处理所有请求。这种方案在 Demo 阶段没问题,一旦进入生产环境,痛点会集中爆发。我最早也这么干过,后来被线上问题逼着切换成了多智能体架构。
1.1 单体 Prompt 的天花板
单个大模型处理复杂业务时,Prompt 会越来越长。比如一个客服系统,既要判断用户意图,又要查订单,还要处理退款、安抚情绪、识别风险,所有指令堆在一个 Prompt 里,表面看很省事,实际会遇到三类问题:指令冲突、行为漂移和排障困难。
- 指令冲突:不同角色的规则互相干扰。让模型“语气热情”的同时“严格拒绝超额退款”,模型往往会顾此失彼,经常在边界场景上做出意料之外的选择。
- 行为漂移:今天调好了一个场景,下周因为新增了一条规则,模型在其他场景上的表现就变差了。修改一个模块,影响的是全局。
- 排障困难:用户反馈回答不对,你只能对着几千字的 Prompt 猜是哪个规则出了问题,没有清晰的调用链路,无法快速定位。
更麻烦的是成本。一个大模型处理任何请求,无论简单复杂,都会消耗相近的 token 和延迟。高频简单问题被大模型“大材小用”,成本很难降下来。
1.2 多智能体协作的核心价值
多智能体的思路,本质上是把一个庞大的全能型“员工”拆成多个各司其职的“小员工”。每个智能体只负责一个明确的小任务,用适合自己的模型,遵守自己那份 Prompt。这样做有三个明显优势。
第一是职责边界清晰。意图识别只负责输出结构化意图,订单查询只负责调用外部接口并格式化结果,退款处理只负责执行退款策略。出了问题,看是哪个智能体的输出不合理,直接定位到人。
第二是模型选型灵活。高频的路由、质检任务,用响应快的小模型就够;真正需要生成回复或处理复杂推理的节点,才调用大模型。整体的平均成本和延迟都下来了。
第三是故障半径可控。退款接口超时不会影响整个链路,可以通过降级策略把请求转到人工处理,而不是让整个系统都被拖死。
1.3 ModelEngine 到底在解决什么问题
ModelEngine 不是又一个聊天框架。它更像一套企业内部的工作流引擎,只不过执行单元从“函数”变成了“智能体”。它主要解决三件事:消息如何在智能体之间流转、工作流的并行与分支怎么编排、会话状态和上下文怎么在多个智能体之间共享。
实际用下来,我的理解是:它的核心抽象是「数据流 + 控制流 + 会话状态」。数据流决定了一个智能体的输出能不能作为另一个智能体的输入;控制流决定了请求是走串行、并行还是条件分支;会话状态则是整个协作过程中的“共享便签”,让不同智能体知道当前用户发生了什么、已经做到哪一步了。理解了这三个维度,后面搭团队就顺了。
2. 搭建团队的前提:角色设计与流程编排
把多智能体系统比作公司,第一件事不是招人写代码,而是画组织架构图。智能体角色没有设计好,后面每一步都是坑。
2.1 角色不是随便起的,先做职责拆分
我见过不少团队一上来就定义“客服智能体”“销售智能体”,这种粒度太粗。角色拆分的核心原则是:一个智能体只做一件可以独立描述清楚的事。判断标准很简单——如果这个智能体的 Prompt 里需要写“同时”两个字,说明它应该拆开。
比如售后场景,我不会只定义一个“售后 agent”,而是拆成:
- 意图识别 agent:只负责把用户的话归类成订单查询、退款申请、投诉、其他,输出一个 JSON。
- 订单查询 agent:根据用户提供的订单号调用订单接口,把结果转成简洁的摘要。
- 退款处理 agent:核对退款政策、计算可退金额、调用退款接口。
- 质检 agent:检查前面所有 agent 的输出是否合规、有没有风险表述。
- 人工兜底 agent:当意图不明确或流程走到异常分支,直接转人工。
每个角色的输入输出都需要用 schema 约束住。什么意思?就是让模型按固定结构返回数据,不要让它自由发挥。意图识别的输出必须是{"intent": "refund", "confidence": 0.92},而不是一段自然语言。结构化的中间结果,是后面流程编排和路由判断的前提。
2.2 编排方式:串行、并行、条件分支
角色定好了,接下来要看怎么把它们组织起来。ModelEngine 的编排基本是三类模式,对应不同的场景。
- 串行:A 的输出作为 B 的输入,适合有依赖关系的任务,比如先识别意图,再查询订单。
- 并行:多个独立任务同时执行,比如同时查订单、查优惠券、查库存,适合能并行计算的节点,能显著降低响应时间。
- 条件分支:根据某个节点的输出决定走哪条路,比如意图是退款就走退款流程,意图是投诉就走投诉流程。
实际配置里,条件分支最容易出错。很多人喜欢在 workflow 里写各种判断,但判断条件依赖的字段一定要在前面先结构化好。不要在分支条件里去依赖自然语言描述,模型输出稍微一变,流程就断裂了。
2.3 一个“售后客服团队”的完整配置示例
这里给一个简化版配置,完整还原了我第二版售后系统的结构。真实实现里节点 id 会更多,但骨架就是这样。
agents: - id: intent_router model: fast_model prompt: "识别用户意图,只返回结构化结果" output_schema: type: object properties: intent: type: string enum: ["order_query", "refund", "complaint", "other"] confidence: type: number customer_id: type: string - id: order_query model: large_model tools: [query_order_api] input_from: [intent_router] output_schema: type: object properties: order_status: type: string message: type: string - id: refund_handler model: large_model tools: [refund_api, check_policy_api] input_from: [intent_router] parameters: refund_threshold: 5000 - id: quality_check model: fast_model input_from: [order_query, refund_handler] prompt: "检查上述输出是否包含风险承诺、违规表述或敏感词" - id: human_handoff type: notification notify_target: "oncall_group" need_human: true workflow: - start - run: intent_router - switch: - condition: intent == "order_query" and confidence >= 0.7 then: [order_query, quality_check] - condition: intent == "refund" and confidence >= 0.7 then: [refund_handler, quality_check] - condition: confidence < 0.7 then: human_handoff - default: human_handoff这个例子有几个关键细节要强调。
- 每个 agent 的
input_from指定了数据来源,串行关系就藏在里面。 switch里用了confidence >= 0.7作为路由保护。模型识别不准的时候,宁可转人工,也不要往下走流程。- 退款节点设置了阈值参数,超过 5000 的申请会走人工审批,这个在业务上是必须的。
- 质检节点放在所有生成节点之后,相当于又一道护栏。
这个配置跑起来之后,整个链路的行为从“一个大模型自由发挥”变成了“一条有红线、有分支、有兜底的固定流水线”。业务方来问某个单子怎么处理的,我能直接指出它在哪个分支、过了哪些节点,这是单体 Prompt 做不到的。
3. 核心协作机制实战:记忆、路由与消息传递
角色和流程定好了,真正让智能体“协作”起来的是三个底层机制:共享记忆、消息路由和消息传递。这块如果理解不透,配出来的系统经常会出现“各干各的、互相不通气”的问题。
3.1 共享记忆与状态管理
多智能体协作最基础的需求是:B 智能体怎么知道 A 智能体刚才说了什么?答案是需要一份共享记忆。我把它理解成工位旁边的公共白板,任何节点都可以往上面写信息,但要遵守约定。
在 ModelEngine 这类引擎里,共享记忆通常分成两层。
- 会话级状态:记录当前用户对话过程中的临时信息,比如用户身份、订单号、已执行的步骤。
- 全局级配置:记录所有会话都适用的规则,比如退款阈值、风控开关、模型参数。
实际操作里,我建议遵守两条纪律。
第一,智能体对共享状态尽量“只读”,需要写入时使用自己独立的命名空间。比如订单查询 agent 只写order_query.result,退款 agent 只写refund_handler.result,不要大家共用一个大字段。否则并行执行的时候,后写的数据把先写的数据覆盖掉,排查起来特别痛苦。
第二,不要把长对话历史全部塞进每个智能体。企业级场景下,很多对话历史对当前任务没有帮助,全部传给每个智能体既浪费 token,又容易造成“上下文漂移”。更好的做法是每个智能体只接收必要的结构化摘要,再加上最近几条原始消息。
3.2 消息路由与条件匹配
路由是编排的发动机。我在实践中反复强调:路由条件必须基于结构化字段,不能基于自然语言判断。
什么意思?意图识别 agent 的输出必须是{"intent": "refund", "confidence": 0.95}这种格式,然后 workflow 里用intent == "refund"判断。如果意图识别 agent 的输出是“用户想要退款”这种自然语言,路由就没法稳定工作了。
另外,路由判断一定要带上置信度阈值。模型识别用户意图不可能百分百准确,低置信度时强行走自动流程,后续节点会用错误的前提做一堆无用功,最后用户还要投诉。我的做法是:confidence < 0.7一律走人工兜底,这一步能让自动解决问题率稍微下降一点,但整体用户体验提升一大截。
3.3 流式输出、外部工具与数据落库
企业级系统绕不开外部依赖。退款要调支付接口,订单查询要调订单服务,这些都不是模型自己能完成的。ModelEngine 里,把外部工具包成可调用的函数,智能体在需要的时候触发调用。
这里有一个关键设计:智能体不能自己“实现”外部功能,它只能“编排”对工具函数的调用。退款 agent 不需要真的知道退款接口怎么实现,它只需要按照 schema 向工具函数传参,比如{"order_id": "123456", "amount": 88.5},然后拿到结果继续处理。
数据落库也很重要。每个智能体的输入、输出和中间决策,都应该有持久化记录。我见过不少团队只记录最终回答,中间节点完全不落库。等到用户投诉说“你们的系统承诺给我双倍赔偿”,你根本查不到是哪个智能体做出了这个承诺。后来我在每个节点都加了审计日志,这才算真正可控。
注意:工具函数的返回值也要定义 schema。如果工具返回乱格式的数据,智能体后续处理时很容易产生幻觉,随意解读不存在的字段。
4. 部署与可观测性:让 AI 团队稳定“上班”
多智能体系统不是开发完就结束了,部署和上线后的稳定性比单体系统要求更高。毕竟你现在是让一堆“数字员工”在线上协作,任何一个环节掉链子,整个流程都会卡住。
4.1 模型接入与资源配置
多智能体架构的优势之一是可以用不同模型干不同的事。我在生产环境里做了两类模型配置。
| 节点类型 | 模型定位 | 核心要求 | 典型用途 |
|---|---|---|---|
| 路由、质检节点 | 快模型 | 低延迟、低费用 | 意图识别、格式校验、合规检查 |
| 生成、决策节点 | 大模型 | 强推理、高质量 | 生成回复、处理复杂退款策略 |
配置层面,ModelEngine 做了模型供应商抽象,你可以在不改业务代码的情况下切换不同模型。但我们线上不配“默认所有节点都用大模型”,而是每个 agent 单独指定模型。这个细节能让成本差好几倍。
在并发配置上,我建议给不同节点设置不同的最大并发数。路由节点并发可以高一点,因为它是快模型、耗时不长;外部工具调用节点反而要限流,防止瞬时大量请求打到下游订单服务的接口,把对方打挂。
4.2 并发量与费用估算
上线前,一定要做容量和费用估算。我有一套简单的估算公式:
单请求平均智能体调用次数 = 每条业务请求经过的有效节点数。
假设一天有 1 万用户提问,每个用户平均产生 3 次请求,平均每条请求串行经过 3 个智能体节点,那么一天的总 LLM 调用次数是:
10000 × 3 × 3 = 90000 次
再假设平均每次调用的上下文总量约为 1200 token(输入 800 + 输出 400),那一天的 token 总量约为:
90000 × 1200 = 1.08 亿 token
按当前主流商业模型的价格估算,这个量级的日成本大概在几百元到上千元之间。如果你全部用大模型处理,同样的调用次数单次 token 成本可能翻 2~3 倍。所以,用快模型处理路由和质检,不是抠门,是合理降本。
4.3 日志、追踪与告警
多智能体出问题时,最怕的是没有“调用链”。一个请求从入口进来,一路上经过哪些节点、每个节点用了什么模型、消耗了多少 token、结果是什么,这些必须全部能被追踪。
我的做法是:给每个外部请求生成一个唯一的 trace id,从入口网关开始传递给后续所有节点。日志里除了记录输入输出,还要记录模型名称、token 数、耗时、状态码。这样排查问题就像看新闻联播一样,按时间线把整个流程拉出来。
告警规则也要单独定,不能只监控服务器指标。我比较关注三类指标:
- 错误率:智能体调用失败率超过 1%,说明链路有问题。
- 延迟:P95 响应时间超过预期阈值,说明慢模型节点需要优化。
- 费用:每日 token 消耗环比增长超过 20%,触发提醒,检查是不是出现死循环或异常重复调用。
5. 企业落地中的高频问题与排查技巧实录
这个章节全是真金白银的踩坑记录。我在多智能体系统上线后,遇到过不少集中爆发的问题,很多都是代码测试时发现不了的。
5.1 智能体之间死循环
问题表现:某段时间费用快速增长,日志里发现两个智能体在反复互相调用,同一个请求一直循环到超时。
根因:工作流里存在回环。比如 A 智能体输出异常结果触发了 B 智能体的分支,B 又调用了 A,而且没有设置最大跳数。
排查方式:先看 trace id 相关的日志,数一下同一个请求经过了多少个节点。如果出现几十次重复的节点记录,基本就是死循环。
解决办法:我给每条请求增加了最大跳数限制,默认 20 跳,超过直接熔断转人工。同时在 workflow 设计阶段就禁止出现“从下游节点指回上游节点”的显式回环。在 ModelEngine 里,尽量用 switch 表达条件,不要在一个节点内部去触发另一个节点的复杂逻辑。
5.2 输出格式不稳定
问题表现:部分请求走到路由节点的时候突然报错,提示 JSON 解析失败。
根因:模型输出偶发不合规,常见的有多了一个逗号、字段名变了、把布尔值输出成了字符串。
排查方式:看路由节点的输入日志,把那几次失败请求的原始输出捞出来对比,基本能发现规律。
解决办法:双重校验。第一层,在模型输出后立即做 schema 校验,不通过就重试一次;第二层,准备一个“宽容解析”兜底,比如尝试解析 JSON 里的某段内容。另外,在所有 prompt 里都要求“只输出 JSON,不要输出任何解释性文字”,能把异常率压到千分之几以下。
5.3 外部 API 调用失败与幂等
问题表现:有用户反馈被重复退款了。
根因:退款接口第一次调用超时,系统判断失败后自动重试,结果第一次调用其实已经成功了,第二次请求又执行了一遍退款操作。
排查方式:调取退款 agent 的工具调用记录,能看到同一个退款请求被提交了两次。
解决办法:所有写操作的外部工具必须支持幂等,调用时带上唯一的请求 id,服务端根据请求 id 去重。我在所有写操作工具里都加了request_id字段,并且在重试逻辑里改成“查询上一次请求的状态,如果未知结果就只查不重试”。这个原则适用于退款、转账、发券,不能只是口头上强调。
5.4 共享状态被莫名覆盖
问题表现:并行执行了查订单和查优惠券两个节点,最后回答里优惠券信息是对的,但订单信息却变成了空。
根因:两个并行节点都向同一个共享变量写入,后完成的节点覆盖了先完成节点的结果。
排查方式:看 trace 里两个节点的完成时间,再对照共享状态的最后一次写入时间。
解决办法:给每个 agent 配置独立的输出字段,然后再设计一个汇总节点去拼接结果。并行节点只写自己的 namespace,谁也不要碰别人的数据。
5.5 费用失控
问题表现:上线一周后成本比预估高出一倍多。
根因:口径不对。很多请求走了并行分支,实际 token 消耗比串行估算高;另外,某些节点设置了 unlimited 重试,失败一次就反复调用大模型。
排查方式:看每个节点的 token 统计,按节点维度排序,基本能找到大头。
解决办法:给所有大模型节点设置最大重试次数,默认 2 次。凡是低风险判断类任务一律切换成快模型。每周末出一份 token 消耗报表,按 agent 维度看趋势,哪里异常就查哪里。
这里整理成一个速查表,方便团队内部转发。
| 现象 | 可能根因 | 第一排查路径 | 长期对策 |
|---|---|---|---|
| 死循环 / 费用激增 | 流程存在回环 | 看同一 trace 的节点次数 | 加最大跳数,禁止回环 |
| JSON 解析失败 | 模型输出不规则 | 捞失败节点的原始输出 | schema 校验 + 宽容解析 |
| 重复退款 / 重复发券 | 写操作未做幂等 | 看工具调用记录 | 调用带 request_id,失败只查不重试 |
| 并行结果互相覆盖 | 共享变量没隔离 | 对照节点完成时间 | 独立 namespace + 汇总节点 |
| 成本超预期 | 重试/并行过度使用 | 按节点维度的 token 报表 | 限重试次数,快慢模型分流 |
6. 我的几点建议和踩坑体会
最后这部分不是总结,就是我这段时间摸爬滚打积累下来的朴素经验,希望后来的人少走点弯路。
6.1 从最小协作单元开始
第一版不要直接搭十个智能体,会把自己绕晕。我建议从“一个路由节点 + 两个执行节点 + 一个质检节点”起步。先跑通最简单的串行链路,确认共享记忆和路由都没问题,再慢慢加并行分支和复杂条件。一上来就追求大而全,往往连最基本的日志排查都做不好。
6.2 给每个团队配一个“质检智能体”
企业级场景,不能信任任何智能体的裸输出。质检节点放在流程末端,用快模型检查前面所有输出里有没有风险承诺、违规用语、误导性信息。这个节点非常关键,它相当于内容发布前的最后一道校对。我在客服系统里加了它之后,需要人工介入的高危投诉数量明显下降。
6.3 后续可以这样扩展
这套架构跑稳定之后,扩展方向很多。可以加入异步任务,把耗时的生成类工作放到队列里做,用户不用一直等待;可以加入人工审批节点,在退款超阈值、投诉升级等场景强制转人工;还可以做多团队编排,比如一个系统里同时跑“售前推荐团队”和“售后支持团队”,通过统一路由分配。ModelEngine 的数据流和会话状态模型足够支撑这些场景,关键还是业务规则要设计清楚。
有一点我特别想说:多智能体系统真正难的不是调模型,而是工程化习惯。输入输出结构、状态隔离、链路追踪、幂等控制、预算告警,这些才是企业级 AI 团队能不能稳定运转的底座。只要把这些基础打牢,换更好的模型、加更多智能体都是水到渠成的事。