news 2026/9/17 7:20:21

多智能体系统企业落地:Plan模式与主子Agent协作实战复盘

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多智能体系统企业落地:Plan模式与主子Agent协作实战复盘

把多智能体系统真正接到企业业务里,和跑 Demo 是两码事。我们在售后工单自动处理这条链路里,从最初单 Agent 硬撑,到最后切换成 MultiAgent 架构,中间踩的坑比预想多得多。这篇复盘想重点讲两套机制:一套是 Plan 模式,让 Agent 想清楚再做;另一套是主子 Agent 协作,把任务拆给不同角色分头干活。两者都不是什么新鲜概念,但在企业级场景里真正落地,有不少细节值得展开。如果你也在做 LLM 应用集成,正在纠结要不要上 MultiAgent,或者担心多 Agent 会失控,这篇文章应该能给你一些直接可参考的思路。

1. 从单 Agent 到 MultiAgent:我们为什么走到这一步

1.1 单 Agent 在真实业务流程中的三个瓶颈

最初我们也是“一个 Agent 打天下”:把工具列表、业务规则、知识库摘要全部塞进同一个 System Prompt,然后让模型自己决定调用哪些工具、按什么顺序处理。在演示环境里效果还行,一放到生产流量上就原形毕露。

第一个瓶颈是上下文膨胀。售后场景需要先查订单、再查物流、还要判断退款策略,每一步都要把中间结果拼回去继续推理。多轮下来,Prompt 里的历史消息和工具返回结果越堆越长,模型开始“忘掉”最开始的目标,甚至把之前步骤里的临时字段当作最终答案输出。上下文一长,首字延迟也跟着涨,线上体验立刻出问题。

第二个瓶颈是工具调用的不可控。单 Agent 拥有全部工具的调用权,它会自作主张去调用一些当前场景根本不需要的接口。比如用户只是问“退款到账要多久”,Agent 却先去查了商品库存接口,白白增加耗时不说,偶尔还会因为权限配置不当触发报警。

第三个瓶颈是职责边界糊在一起。业务方希望我们能快速新增一个“优惠券计算”能力,但如果还是那个全能 Agent,任何改动都要重新做全量回归,生怕影响已有功能。改动风险大、上线速度慢,这是最让团队难受的地方。后来我们意识到,问题不在于模型能力,而在于架构没有一个清晰的任务拆解和职责隔离机制。

1.2 Plan 模式和主子 Agent 协作各自解决的问题

MultiAgent 架构本身不是目的,我们要解决的是“让每个环节都能被理解、被控制、被替换”。为此引入了两个核心机制。

Plan 模式解决的是“执行顺序”问题。传统 ReAct 是边想边做,Agent 每一步都根据当前状态临时决定下一步动作。好处是灵活,坏处是每一步都有发散的可能,长链路跑下来特别容易偏离主线。Plan 模式要求 Agent 在动手之前先输出一份完整的执行计划,比如“第一步调用订单查询工具;第二步核对退款状态;第三步生成回复草稿”,然后系统按计划逐步执行。计划先行,意味着模型在动笔之前先做了全局规划,链路中期的随意性被大幅压缩,同时计划本身可以被记录、审计、甚至人工干预。

主子 Agent 协作解决的是“职责划分”问题。主 Agent 相当于一个前台调度员,负责接需求、拆任务、发指令、收结果;子 Agent 则是后台的专业员工,各自负责订单、物流、优惠券等垂直领域。子 Agent 不需要知道其他 Agent 的细节,主 Agent 也不需要掌握每个业务域的完整规则。边界清晰之后,每个子 Agent 的 Prompt 规模变得可控,工具列表也精简到和自身职责强相关,上下文问题自然缓解。

这两套机制是配套的:Plan 模式负责“怎么干活”,主子协作负责“谁来干活”。单用 Plan 模式,任务还是会落到一个庞大的 Agent 身上;单用主子协作,子 Agent 内部依然可能思路混乱。

2. Plan 模式:让 Agent 先想清楚再做

2.1 Plan 不是“想法”,而是结构化的执行产物

很多团队对 Plan 模式的理解是“在两句话之间插入一句‘让我想想’”,这其实误解了 Plan 的用途。对我们来说,Plan 是一份可以被程序解析、校验、执行的 JSON 结构。

我要求规划模块输出的计划包含几个固定字段:目标是当前任务的复述,steps 是每一步的操作描述,tool 指定这一步要调用的工具名,input 给出调用该工具的输入参数模板,dependencies 标出哪些步骤之间有先后关系。模型先输出这份 JSON,由调度器解析后逐步执行。

这样设计的好处有三个。一是可校验,JSON Schema 在模型输出后立刻做格式校验,字段缺失、类型不对都能在第一时间拦截,避免执行到一半发现参数是空值。二是可审计,任何一步出了问题,直接看计划里这一步的设计和实际执行结果,就能定位是规划错了还是工具返回错了。三是可介入,如果业务要求某些高风险操作必须人工审批,那调度器在遇到对应步骤时可以暂停执行,等技术或业务人员确认后再继续。

2.2 计划执行循环:执行、校验、重规划

Plan 模式不是简单的“计划完就照着做到底”,而是一个循环。

调度器拿到计划后,会按步骤逐个执行。每执行一个步骤,都会把工具返回结果喂回给一个校验模块,由校验模块判断这一步是否真正完成了预期目标。比如计划里写“调用订单查询工具获取订单状态”,正常情况下工具会返回“已发货”或“退款中”。如果返回的是“订单不存在”,校验模块会标记这一步异常,触发重规划。

重规划由规划器接收当前状态和失败原因,输出一份新的计划,替代剩余步骤。这里有个细节:重规划并不是每次失败都需要做,对于可重试的工具超时类错误,我们会先做“重试”,连续失败达到阈值才升级为重规划。重规划也不能无限触发,我们在系统里设了最大重规划次数,超过之后就转人工处理,避免 Agent 在同一个节点上反复打转。

核心循环用伪代码可以写得很直白:

plan = planner.plan(task, context) for step in plan.steps: result = executor.execute(step) if not validator.is_success(step, result): if retry_count < max_retry: retry_count += 1 result = executor.execute(step) else: plan = planner.replan(task, context, step, result) if replan_count >= max_replan: handoff_to_human(task, context, plan) break replan_count += 1 continue context.append(step, result) final_answer = summarizer.summarize(context)

这段代码会在我们内部的一个“多 Agent 调度服务”里运行,服务本身不感知业务细节,它只负责按计划驱动执行、收集结果、触发校验和重规划。

2.3 让 Plan 稳定输出的三个关键参数

大模型生成计划本身也带有随机性,想要让它保持稳定,必须在请求参数上做约束。

温度参数建议直接拉低。我们内部跑规划器的模型,温度设在 0.1 到 0.2 之间,目的是让同一个任务在不同时间进来时,产出的计划尽量一致。计划不稳定带来的问题比想象中大:同一种售后问题,今天走退款流程,明天走人工审核流程,业务方根本没法接受。

结构化输出必须用 JSON Schema 强制约束,不能只靠 Prompt 里写一句“请输出 JSON”。强约束能显著降低解析失败率。我们实测下来,加了 Schema 约束之后,规划结果的非法 JSON 率从百分之五左右降到了百分之零点几,这个差距在生产环境里非常可观。

另外要设执行步数上限。单任务最多跑 12 步,超过就认为规划异常,强制转人工。这个指标不是拍脑袋定的,是我们统计了 2000 条线上真实工单的 Agent 任务执行步数,发现绝大多数功能正常任务在 8 步内能完成。上限设得比正常值高出一半,既给复杂任务留出余量,又能兜住模型失控的情况。

3. 主子 Agent 协作:把专业的事交给专业的 Agent

3.1 主 Agent 的角色:调度器,不是百科全书

在主从架构里,最容易犯的错误是让主 Agent 继续承担大量业务推理。比如问主 Agent“用户的退款资格怎么判断”,它凭记忆给你编了一个规则,但规则早就更新过了,这就出问题了。

主 Agent 的正确角色应该是调度器:理解用户请求,拆解成子任务,分发给合适的子 Agent,然后把子 Agent 的结果汇总成最终回答。主 Agent 不需要知道“七天无理由退货的具体条件是什么”,它只需要知道“有个售后策略 Agent 能处理这类问题”,然后把这个子任务派出去。

因此主 Agent 的 System Prompt 里最核心的是“能力地图”:列出有哪些子 Agent、每个子 Agent 擅长什么、什么情况下应该调用哪个。Prompt 里明确要求主 Agent 不要自己猜测业务规则,所有业务判断必须基于子 Agent 的返回结果。这句话看着简单,但在真实场景里是牵制主 Agent 幻觉的关键。

我会在能力地图里写清楚每个子 Agent 的“适用场景”和“不适用场景”,避免主 Agent 乱派单。比如物流 Agent 只负责查询物流轨迹,不负责判断物流延误赔偿,后者必须交给售后策略 Agent。这种显式的边界约束,比“你是一个智能助手”有用得多。

3.2 子 Agent 的注册与调用协议

子 Agent 的接入不能是零散的,我在架构里引入了一个类似服务注册的概念:每个子 Agent 在启动时向调度中心注册自己的“能力描述”和“输入输出出入参格式”。

注册的条目主要有四个字段:name 是子 Agent 的唯一标识,description 是给主 Agent 看的能力说明,input_schema 声明子 Agent 期望的输入结构,output_schema 声明它的返回结构。主 Agent 发起调用时,调度中心会根据 input_schema 做一次参数校验,缺参数直接拦截,不发给子 Agent。

这里的关键是输出标准化。子 Agent 的返回结果统一分成 status、data、message 三段结构。status 是 success、failed 或 need_human;data 是真正的业务结果;message 是给主 Agent 看的简短摘要。统一格式的价值在于,主 Agent 和校验模块不需要针对每个子 Agent 单独做适配,整个系统的组装成本大幅下降。

子 Agent 内部仍然可以有自己的推理逻辑。比如售后策略 Agent 内部可能还分“查规则—匹配政策—生成结论”几步,但对外它只需要暴露简洁的入参和出参。这种封装思想,做过后端服务的人应该很熟悉:内部爱怎么拆怎么拆,对外接口稳定就行。

3.3 主子协作的记忆与上下文管理

多 Agent 协作里最容易被忽视的是记忆管理。主 Agent 如果每次收到子 Agent 的完整业务结果,几轮下来上下文又膨胀了。

我们的做法是分层记忆:主 Agent 只维护一个结构化的“全局上下文”,记录任务的当前状态、已完成步骤、关键结论摘要;子 Agent 则维护各自的局部记忆,比如订单 Agent 在自己的上下文中记录原始订单数据和查询结果,不需要把这些细节全部回传。

主 Agent 收到的子 Agent 结果不是 data 的完整原始值,而是 message 摘要加上一个指向详细结果的引用。例如物流 Agent 返回时,主 Agent 只看到“物流轨迹共 5 条,最新状态为派送中”,详细轨迹数据存到临时存储里,若最终回答需要引用,再由主 Agent 或摘要模块按需读取。这样既保证关键信息不丢失,又控制住了主 Agent 的上下文规模。

这个机制上线后,一个更直接的收益是成本下降。主 Agent 的输入 Token 不再随子任务数量线性增长,整条链路的调用成本估算下来低了不少。多 Agent 不是架构花活,它确实能在工程上带来实际回报。

4. 实操过程:一个售后工单场景的完整实现

4.1 场景定义与流程编排

用一个实际场景串一下整个链路:用户提交一条售后工单,内容是“我买的鞋上周收到,穿了一天开胶了,想退货,订单号是 123456”。

用户消息进来后,主 Agent 先做全局规划。按照 Plan 模式的流程,它会先解析出关键信息,然后确认这里涉及三个子任务:第一,调用订单 Agent 核对订单状态,确认这双鞋在可售后周期内;第二,调用售后策略 Agent,根据订单信息返回是否支持退货以及退货条件;第三,调用回复生成 Agent,把前面两步的结果组织成一段给用户的最终答复。

这里有一个设计点:主 Agent 不会在规划阶段直接调订单接口,而是把“需要订单 Agent 去查”作为计划中的一步。真正的查询发生在调度器执行该步骤时,由订单 Agent 根据输入参数去查后端接口。规划和执行分离,让整个流程的可控性和可观测性都上了一个台阶。

流程编排好之后,调度器加载计划,开始逐步执行。每一步都记录执行耗时、调用结果、是否触发重试或重规划,最终生成一条完整的执行轨迹,供后续复盘使用。

4.2 关键调度逻辑与 Prompt 参考

主 Agent 调度逻辑可以简化成下面这段伪代码:

class MasterAgent: def handle(self, user_request): plan = self.planner.plan(user_request) context = {"request": user_request, "steps": []} for step in plan.steps: sub_result = self.dispatcher.invoke(step.target_agent, step.input) context["steps"].append({ "step_id": step.id, "agent": step.target_agent, "input": step.input, "output_summary": sub_result.message, "status": sub_result.status }) if sub_result.status == "failed": plan = self.planner.replan(user_request, context, step) if not plan: return self.escalate_to_human(context) return self.summarizer.summarize(context)

每个子 Agent 的 Prompt 则按“角色 + 职责边界 + 输出格式”三块来写。以售后策略 Agent 为例:

你是售后策略判断助手。 你的职责:根据传入的订单信息和用户诉求,查询售后规则库,判断是否符合退货、换货、维修条件。 你不负责:查询订单明细、编辑订单状态。 输入:订单编号、用户诉求描述。 输出要求:返回 JSON,字段包括 can_service(布尔值)、policy_name(命中的规则名称)、reason(判断理由)。 注意:如果订单信息缺失,输出 can_service 为 false,并在 reason 中说明缺失字段。

这个 Prompt 我们不追求花哨,重点是把边界说清楚。只要子 Agent 把“做什么、不做什么、输出什么”理解对,后续系统稳定性就有保障。

4.3 可观测性设计与效果评估

MultiAgent 系统如果只是“能跑”还远远不够,生产环境必须有足够好的可观测性,否则出了问题连从哪查起都不知道。

我们在每条执行链路里都打了结构化日志:主 Agent 的规划结果、每一步调用的子 Agent、入参和出参摘要、重试次数、重规划原因。所有日志统一进到日志平台里,按 traceId 关联。业务人员和技术人员可以共同查看单个工单从进入到结束的完整处理过程。

评估指标我们重点看三个:任务成功率、平均执行步数、平均处理耗时。任务成功率指最终给出有效答复且业务方认可的比例,这是最核心的指标。平均执行步数和平均处理耗时是联动指标,用来发现架构或模型配置是否退化。比如某次升级后平均步数从 6 涨到 10,就要检查是不是主 Agent 规划变啰嗦了,或者子 Agent 返回质量下降导致频繁重规划。

还有一个“人工接单率”值得单独监控。它反映的是系统主动放弃、转人工的任务占比。人工接单率过高说明自动化能力不足,过低可能意味着系统在硬撑一些它处理不了的任务而质量不达标。我们给自己定的安全线是不超过百分之十五,超过就说明该调模型或调应用逻辑了。

5. 落地过程中的坑与排查方法

5.1 高频问题速查表

现象可能原因排查与解决思路
主 Agent 规划结果频繁解析失败模型输出未严格遵守 JSON 格式启用结构化输出约束;对规划结果做二次容错解析;在 Prompt 中增加“只输出 JSON,不要解释”要求
子 Agent 返回结构不统一各子 Agent 的 Prompt 缺少输出模板强制用 output_schema 校验子 Agent 返回;在子 Agent 层增加格式转换模块
任务执行到一半偏离原计划目标上下文信息过载或主 Agent 被中间结果带偏降低主 Agent 上下文保留量;增加“当前目标”字段让模型持续对齐原始任务
同一任务进入重规划死循环重规划触发条件设置过于宽松设置最大重规划次数;对同一失败节点使用退避策略
工具返回内容过长导致上下文膨胀工具结果未做摘要直接拼接进上下文增加结果摘要模块;长文本改为存储引用,按需读取
线上偶发性超时多级调用链路叠加导致耗时过长对子 Agent 调用设置超时时间;对非关键路径做并行化;增加缓存

5.2 三个值得单独说透的避坑细节

第一个细节是“不要过度依赖模型来修正格式”。早期我们做过一个尝试,子 Agent 返回非标准 JSON 时,让主 Agent 去修复再继续执行。表面上解决了问题,实际是把异常处理压力转移到了模型推理上,多一轮推理就多一次延迟和成本,而且主 Agent 自己也可能修错。后来改成在子 Agent 出口做硬校验,格式不对直接让子 Agent 重出一次,重出两次仍不对就走默认兜底。这样处理链路更短,行为也更可预期。

第二个细节是并行子任务一定要控制并发度。虽然主子架构支持多个子任务并行执行,但底层业务接口往往有 QPS 限制。我们在一次压测里发现,主 Agent 同时派出 6 个子任务去查订单,订单服务的响应时间直接翻了三倍。后来调度器里加了并发信号量,默认最多同时执行 3 个子任务,整体 QPS 上去了,后端接口压力反而稳住了。

第三个细节是子 Agent 之间不要横向通信。子 Agent 如果互相依赖,比如订单 Agent 想直接从物流 Agent 那拿数据,这种横向通信很快会把系统变成一团乱麻。在主从架构里,所有信息都必须经过主 Agent 中转。虽然多了一次传递,但换来的是清晰的调用链和可控的故障边界。实际改动中,只要发现某两个子 Agent 之间出现高频横向调用,我们就把它提炼成一层新的主 Agent 能力,而不是放开横向通道。

5.3 上线前后的两条经验

上线前一定要做一轮针对计划模式的“案例压力测试”。只用几个标准测试用例是不够的,要专门找那些边界模糊、信息缺失、易触发幻觉的例子去测。比如用户只说了“要退货”但完全没提供订单号,主 Agent 是否能识别出缺参数并主动索要?这类用例在跑测试时很容易暴露出规划器的薄弱环节。

上线后要留出足够长的“人机并行观察期”。我们没有在切换第一天就让系统全量接管,而是先让 Agent 和人工客服并行处理一段时间,用真实流量检验计划执行和主子协作的质量。观察期内如果遇到 Agent 处理不理想的情况,记录它不是难事,难的是把它归因到规划问题、子 Agent 问题还是工具接口问题。日志里的 traceId 是唯一的抓手,所以前面强调的可观测性设计,在这个阶段的价值体现得特别明显。

这轮落地做完之后,我个人的体会是:MultiAgent 真正的难度不在于搭架子,而在于每一层都做到可控。Plan 模式让思考路径有迹可循,主子协作让任务边界清晰明了,再加上围绕格式、超时、并发做的各种防御,系统才从“看起来聪明”变成了“用起来靠谱”。如果接下来要在这个架构上做扩展,我比较看好把更多审核类、质检类任务也沉到子 Agent 层,让主 Agent 专心做调度和兜底。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/17 7:20:10

Win11下解决SQL Server 2016安装0x851A001A错误

先跟遇到同样问题的朋友说一句&#xff1a;这个错误别怕&#xff0c;它比你想象的常见&#xff0c;也比你想象的容易解决。我在Windows 11上给一台新机器部署SQL Server 2016时&#xff0c;装到数据库引擎配置那一步&#xff0c;进度条突然停住&#xff0c;过一会儿弹出一个错误…

作者头像 李华
网站建设 2026/9/17 7:19:34

Windows Docker Desktop 安装与镜像构建全流程指南

Windows 上想跑容器&#xff0c;绕不开 Docker Desktop 这个桌面端工具&#xff0c;而真正让人卡住的往往不是 Docker 本身&#xff0c;而是从"装不上"到"装上了但起不来"&#xff0c;再到"起来了却不知道镜像怎么建"。我自己从早期的虚拟化方案…

作者头像 李华
网站建设 2026/9/17 7:19:30

MySQL绿色版保姆级教程:ZIP免安装从配置到维护一次说透

第一次用Windows装MySQL&#xff0c;我踩了个大坑&#xff1a;用官方MSI安装包装完&#xff0c;服务起不来&#xff0c;配置文件散落在各个目录&#xff0c;想卸载重来又卸不干净。后来我彻底转向绿色版&#xff0c;也就是ZIP免安装版&#xff0c;从下载、解压到配置、使用全程…

作者头像 李华
网站建设 2026/9/17 7:19:26

程序员子女职业选择:代际传递现象与技术行业影响

1. 职业代际传递现象观察最近在技术社区看到一个有趣的话题&#xff1a;程序员子女成为程序员的比例究竟有多高&#xff1f;这个问题背后反映的是职业代际传递现象。作为从业十余年的技术人&#xff0c;我观察到身边确实存在不少"码二代"案例&#xff0c;但具体数据如…

作者头像 李华
网站建设 2026/9/17 7:19:23

Agent Skills实战:从Function Calling到可复用技能库

最近半个月&#xff0c;陆陆续续有朋友在群里聊 Agent Skills&#xff0c;我发现不少人第一反应是“给智能体加几个工具”&#xff0c;然后就开始堆 function calling&#xff0c;结果玩了两天就放弃了。这个理解不能说错&#xff0c;但确实把维度想低了。今天这篇我不聊概念 P…

作者头像 李华
网站建设 2026/9/17 7:18:20

Android音频特效开发:MediaPlayer的attachAuxEffect详解

## 1. 项目概述在Android多媒体开发中&#xff0c;MediaPlayer的attachAuxEffect接口是一个容易被忽视但极具实用价值的功能点。这个看似简单的API调用背后&#xff0c;隐藏着从应用层到底层音频系统的完整调用链路。作为在音视频领域踩坑多年的开发者&#xff0c;今天我就带大…

作者头像 李华