news 2026/9/29 16:02:12

多Agent系统构建实战:从流程拆解到生产部署

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
多Agent系统构建实战:从流程拆解到生产部署

1. 构建思路:先拆流程,再谈Agent

1.1 为什么多Agent不等于“多个模型实例”

OpenAI Agents SDK构建指南系列写到第五篇,我默认你已经把一个能跑的Agent项目攥在手上了。如果还没有,建议先回头补齐前四篇的内容。这一篇要解决的,不是“怎么调用工具”这种基础问题,而是“如何把一个demo级别的Agent,重构成一套能协作、能扩展、能上生产的多Agent系统”。

我自己最近接的一个实际项目特别能说明这件事。客户要做一个制度条例学习助手,需求听起来不大:员工提问,它回答制度条款。但真正拆开之后,考验的是“意图判断、语义检索、溯源引用、权限过滤、多轮追问”这五层能力的协作。任何一个环节交给同一个Agent去处理,Prompt都会膨胀到失控,实测效果就是回答像“和稀泥”——什么都能说一点,什么都不够精准,而且无法定位错误出在哪个环节。

多Agent不等于开多个会话任务。很多人误以为“我并行调五个模型,让它们各干各的,最后合并结果”就叫多Agent。这是把负载均衡和多智能体协作搞混了。真正的多Agent系统,核心是职责划分和上下文隔离:每个Agent是独立进程,有自己的提示词、工具集、记忆范围和触发条件。它们之间的通信是结构化交接,而不是把所有信息都塞进一个共享上下文里。

我在重构那个学习助手时,用的类比是“餐厅后厨”。一个人既收银又掌勺还传菜,客流小的时候没问题,客流一大必然崩。Agent也一样:一个Agent同时承担意图识别、信息检索、报表计算、权限校验,大模型会变“贪心”,倾向于用最省事的方式回答问题,而不是按照你设想的逻辑链路去执行。拆成前厅(对话管理)、后厨(制度检索)、传菜口(生成回复)三个Agent之后,每个环节的上下文都变得轻量、纯粹,出了问题一眼就能看到是哪个环节翻的车。

SDK里承接Agent之间分工协作的东西是Handoff(交接)机制,它不单纯是“调用另一个Agent”,而是把当前会话状态、消息历史、意图上下文切换给目标Agent。实践中有个常被忽视的细节:Handoff时需要显式声明交接理由和转移目标,否则模型在边界模糊时会频繁来回踢皮球,陷入两个Agent互相“让贤”的死循环。

1.2 三种协作模式的选择逻辑

根据我拆项目的经验,多Agent协作逃不开三种基础模式:顺序流水线、路由分发、嵌套层级。每种模式都不是万能的,选错模式,后面再调参都救不回来。

顺序流水线适合流程固定的业务,比如工单自动处理:第一步分类工单,第二步提取关键信息,第三步匹配解决方案,第四步生成回复。每一步的输入是上一步的输出,Agent之间像工厂传送带上的工位。优势是流程可预测、调试简单,劣势是“一条路走到黑”——如果中间某一步的判断出现了偏差,后面所有步骤都会跟着错,而且没有回头机制。

路由分发是另一种常见的用法:前面有一个轻量的Router Agent负责意图分诊,把请求派给相应的垂直Agent。制度条例学习助手用的就是这种模式。员工问“年会报销上限是多少”,Router直接判定为“报销制度”,转给报销Agent;如果追问“为什么去年能报销两次今年不行”,Router判定为“政策对比需求”,转给差异分析Agent。两个Agent各守一摊,Prompt各自维护,互不干扰。

嵌套层级则更复杂一些,适用于研究型或规划型任务:父Agent负责总体目标拆解,子Agent负责执行子任务,子Agent还可以继续下派孙Agent,形成树形结构。这种模式最强大的地方是可以实现“计划-执行-反馈-修正”的闭环。

不同模式选型的判断条件,我一般看两个维度。第一看“分支数量”:整个业务流程里明确的意图分支是否超过三个,超过就适合用路由分发。第二看“容错需求”:单步结果不可逆的还是可回退的,可回退用流水线就能解决问题,需要兜底重试的考虑嵌套层级。决策时可以用下面这张表快速匹配:

业务特征推荐模式典型场景
流程固定、步骤清晰顺序流水线工单分类、数据清洗
分支多、意图差异大路由分发智能客服、学习助手
任务复杂、需要逐步推演嵌套层级研究报告、方案生成

这里要说一个容易犯的错:嵌套层级不是“越深越好”。子Agent嵌套超过三层,消息传递耗时会指数级上升,而且大模型在长链路中的记忆衰减非常明显。我自己踩过的坑是四层Agent链路上,最内层Agent几乎完全忽略父Agent给定的约束,回答风格跑偏到无法直视。最后的解决办法很简单,压缩到两层,加上每层的结构化总结回传,效果反而稳了不少。

2. SDK核心组件进阶:工具、记忆、上下文的实战定型

2.1 工具进阶写法:让Agent“会正确使用”而不是“疯狂乱调用”

工具是多Agent系统的“手脚”。SDK的工具注册机制很灵活,但灵活不代表你随便写个函数标注一下就能用得好。我见过太多人把工具参数设计成嵌套JSON对象,结果模型生成参数时频繁漏字段,各种报错。这里有一条硬性经验:参数能平铺绝不嵌套,能用简单类型绝不搞复合结构。

举个对比。采购系统里有个“生成采购申请单”工具,参数设计成“requester_info嵌套对象(姓名、部门、员工号)”,模型有时候只填姓名不填员工号,然后报参数缺失错误。改成三个平铺参数request_name、request_dept、request_empid之后,错误率直接下降一半。模型的JSON生成能力没有你想的那么稳,平面结构永远比嵌套结构更容易被准确生成。

工具描述同样值得打磨。模型不是通过函数名理解工具,而是通过description理解工具的。description写得含糊,模型就会在边界场景里自作主张。我的写法模板是“在什么情况下使用这个工具、执行后会做什么、会返回什么、如果无法满足条件应该怎样”。句式和长度都有讲究,太短模型无法理解边界,太长又占上下文窗口。两到三句话是我实测性价比最高的长度。

还有一个很多人忽视的地方:工具内部不要抛裸异常。Agent SDK遇到工具抛异常时,会把异常信息回传给模型,模型会尝试自行修正或换一种调用方式。这本来是好设计,但如果异常信息格式混乱(比如直接打印traceback堆栈),模型根本不知道下一步该做什么,只会反复重试同一个失败调用。正确的做法是:在工具内部捕获所有异常,然后返回结构化错误对象,包含code、message和suggestion三个字段。

顺手给一个简化版示范(基于Python):

def query_inventory(product_id: str) -> dict: try: data = inventory_api.send(product_id) if data is None: return {"code": "404", "message": "商品不存在", "suggestion": "请检查商品ID后重试"} return {"code": "200", "message": "查询成功", "data": data} except TimeoutError: return {"code": "503", "message": "库存服务超时", "suggestion": "请稍后重试"} except Exception as exc: return {"code": "500", "message": f"内部错误: {exc}", "suggestion": "联系管理员排查"}

这样模型拿到返回值就知道是换个ID重试,还是等待一会儿再查,而不是对着一个traceback干瞪眼。

2.2 记忆策略:让Agent“记得住”又不会“记太杂”

长任务场景里,记忆是维持多轮对话流畅性的关键。但记忆不是“把用户说过的话全部原样存起来”那么简单。所有对话历史都攒着,上下文窗口迟早爆,更麻烦的是模型会被大量无关的历史噪声干扰,注意力分散到错误的地方。

我的做法是把记忆分三层。第一层是短期记忆,也就是当前会话窗口里的完整对话,不用特殊处理,跟着消息历史走;第二层是摘要记忆,当消息历史超过阈值时,触发一次摘要Agent,把前面的对话压缩成结构化结论(用户目标、已解决事项、待办事项、关键偏好);第三层是长期记忆,把跨会话的关键事实写入向量库或KV存储,在会话启动时主动检索注入。

实现摘要记忆有个关键的触发时机问题。我曾经困惑“到底多少轮对话才该触发摘要”,最后实测的经验是:当原始消息文本累计超过6000个token时触发比较合适。低于这个值,摘要反而会丢失上下文细节;高于这个值,上下文窗口的压力已经开始拖慢生成速度了。同时摘要本身要有轻微的信息冗余,宁可多保留细节,也不要为了精简而丢掉后续推理需要的关键事实。

用SDK搭建摘要记忆,可以在运行时动态拼装系统提示词。每个Agent启动时,先读取长期记忆里的用户档案,拼进系统提示词;消息历史超过阈值时,调用摘要Agent对旧对话重写。

提示:摘要Agent本身也是一个Agent,它的输出结构最好用JSON格式固定下来,字段包括goal、resolved、pending、preferences,这样下游解析成本极低,也方便后续代码调试。

2.3 上下文管理:省钱和保质的平衡点

一个被严重低估的成本黑洞是上下文冗余。同一个大段参考文档,如果传给三个子Agent各一份,token消耗就是三倍。而且多Agent并行执行时,每个Agent都会读取同一个基础资料,费用成倍增长。

我在项目里是这么控制成本的:基础资料统一读一次,由Router负责摘要提取,然后只把摘要部分传给下游。原始文档只在需要深度检索时按需提取。比如制度条例学习助手,法律条文原始文本有几十万token,不可能全量塞给Agent。我的做法是启动时先做一次向量化,普通问答走检索增强生成(RAG)路径,只把最相关的几段文本拼进提示词。只有在用户明确要求对比多个制度差异时,才动用全局读取功能。

另外值得关注的是工具返回值的token管理。当你调用一个返回大数据集的工具,工具返回结果会完整留在上下文里。如果这个结果只被中间过程使用一次,后面根本不需要再引用它了,它就变成纯成本。早期的API版本对工具结果没有做自动截断,后面需要手动的做法是:工具返回值里如果数据量大,在返回前先做预处理,只保留模型推理真正需要的字段,而不是把整个数据库表结构原样返回。

这个“裁剪返回值”的思维特别重要。一个外部接口返回200个字段,Agent做一次判断可能只需要5个,剩余195个全是噪声。裁剪过后,既省token,又减少模型在无关字段上产生幻觉的概率。属于一举两得的优化。

3. 知识库与业务系统:Agent正式接上企业“地气”

3.1 知识库构建:不只是“把文档扔进向量库”

Agent要回答公司制度、产品手册、故障排查手册,背后一定得有一个知识库撑腰。但“知识库构建”四个字,门槛全在细节里。我自己帮客户搭过农业知识库、故障数据库、制度条例库,结构不同,但有三条共通的实践心得。

第一,数据清洗比向量化更重要。原始文档里常见的格式混乱、表格分页、页眉页脚干扰,如果不清洗直接分块,检索质量会惨不忍睹。我见过一个故障库,同一个故障处理方案因为故障描述换行方式不同被拆成了十几个碎片,检索出来总是残缺版本的答案。清洗的标准动作包括:统一换行符、去除页眉页脚、表格转纯文本时用分隔符保留结构、繁体简体统一。

第二,分块策略按文档类型差异化设计。制度条例适合按条款分块,每条制度一个块;故障排查手册适合按“现象-原因-解决方案”三元组分块;产品手册适合按“功能模块-参数说明-操作步骤”分块。统一的固定字数切块是最偷懒也最容易劣化检索效果的做法。切块的时候还要保留元数据字段,至少要记录来源文档、章节编号、更新日期,这样回答时才能做溯源引用。

第三,检索优化比“加更多向量”更重要。如果Top K检索出的结果不够精准,提高K值只会引入更多无关文本。我的优化路线是:先用向量检索召回候选,再用重排序模型精排,最后设置相关性阈值滤掉低分内容。这个“向量召回+重排+阈值过滤”三件套,基本上把RAG检索质量拉高了一个层级。没有重排模型时,可以先用关键词过滤做一次粗排,效果也能接受。

顺带说一个制度条例场景里的特殊细节:权限隔离。不同岗位的员工能看的制度范围不同,这个过滤必须在检索时完成,而不是检索后靠Prompt约束模型“不要泄露不应看到的内容”。后者完全不可靠,模型没那么听话。在检索阶段就根据用户级别过滤掉无权访问的知识块,才是工程上可信的方案。

3.2 业务系统接入:让Agent调用API而不是直连数据库

Agent要落地到企业场景,必然要和企业内部系统“握手”。这里我有一条很坚决的原则:Agent永远不要直连生产数据库。理由很简单,Agent的查询语料是自然语言生成SQL的,出一次错误的DELETE或者不限定WHERE条件的SELECT,代价是你担不起的。

正确的姿势是“工具层适配”:把业务操作封装成工具函数,Agent只负责决定“调哪个工具、传什么参数”,真正执行SQL的还是那些经过review的代码。权限控制也落在工具层:工具函数内部检查当前请求者的身份和权限位,没有权限直接返回错误码,压根不给Agent触碰数据的空间。

集成外部系统的过程里,超时和连接池管理是两个隐藏雷区。Agent调用工具可能触发外部系统API,而大模型的思考时间加上多次工具调用,会让同一条链路上对上游系统的请求压力远超日常。我的做法是给每个工具调用设一个硬超时,比如5秒,超过就返回失败,并在工具内做连接复用。如果上游系统响应本身比较慢(比如报表服务),建议做成异步任务:Agent先创建任务,返回任务ID,之后轮询任务状态,而不是死等同步结果。

还有一点需要特别警示:不要把内部API的完整Swagger文档一股脑丢给模型。模型只会被大量无关接口搞晕,还可能自行拼出你没打算开放的接口调用路径。正确做法是,只挑选Agent真正需要使用的5到10个接口,编写精简版描述,注册为工具。接口越多,模型的选择成本越高,选错的概率越大。

4. 生产部署与稳定性:能演示和能上线是两回事

4.1 部署形态与容量评估

本地跑通的Agent,和线上扛住真实流量的Agent,中间隔着一整条工程化的沟。部署的第一步是把Agent服务无状态化:所有会话状态、记忆数据落到外部存储(Redis或数据库),服务实例本身不保存任何运行状态。这样扩容变成“多复制几个实例”那么简单。

无状态化做完了,才能谈容量评估。我用的估算口径是“单次完整任务的token总消耗”。别只看Prompt里的系统提示词长度,要把多轮交互、工具返回值、模型生成内容全算进去。按我的经验,一个普通的企业客服Agent,单次简单问答消耗800到1500 token,一次复杂的研究型问答可能破5000 token。拿这个数字乘上预估并发量,就能粗略估算每分钟token峰值消耗,从而决定模型规格和预算。

并发连接数的评估也不难。SDK支持异步并发,但下游模型API限流通常是瓶颈。一个稳妥的处理是引入请求队列和速率限制,注意别让Agent的tool call火焰风暴把上游系统打崩。

部署时的连接清理同样关键。长时运行的服务,数据库连接池、Redis连接、外部API的连接复用,都需要定期检查。我遇到过一次线上事故,就是因为一个工具函数每次都新建HTTP客户端,跑了两周以后连接数全部积压在那里,内存直接爆掉。工具函数里必须复用连接对象,这是个教训。

4.2 可观测性:日志、追踪、告警三板斧

多Agent系统的排错难度远超单体程序。你看到的只是用户输入和最终输出,中间经过Router、各个子Agent、多次工具调用,任何一层出错都会导致最终结果变质。没有观测手段,排查就变成了盲人摸象。

可观测性的基础是结构化日志。所有Agent的输入输出、工具调用的入参出参、每一步的耗时和token消耗,都按JSON格式落日志。日志还要带request_id链路追踪字段,这样从用户请求进来,到多个Agent协作完成,全程时序可以串起来看。线上查问题的时候,request_id就是定海神针。

告警规则也有必要提前埋好。我常用的规则有这几种:单次任务耗时超过某阈值(比如30秒);同一个工具连续失败超过3次;token消耗异常激增;Agent回调整跌到某个比例以下。回调整跌这个指标很容易被忽视,但它其实是观察Agent行为质量的关键指标——本来应该调用工具的环节没有调,或者调了错误工具,这种偏差最终会体现在回复质量上。

我还建议建立“语义回归测试集”。Agent系统改一次Prompt或升级一次模型,效果可能就变了。维护一套固定的测试用例集,定期跑一遍,对比输出结果是否满足预期,成本虽高,但在企业落地场景里几乎不可省略。我见过太多项目,升级一个模型版本之后,线上效果断崖式下跌,团队却过了一个星期才发现。

5. 踩坑实录与高频问题排查速查

5.1 五个高频故障及排查方法

多Agent项目跑久了,难免碰到以下问题,我这里按“现象-原因-方案”格式化整理,方便你直接当工具表查。

故障现象常见原因排查与解决方案
工具反复被调用但参数总是错工具参数嵌套过深或描述边界模糊改成平面参数结构;补全描述中的适用场景和边界条件
上下文越长,回复质量越差历史消息冗余、摘要记忆没触发设置消息历史阈值;引入摘要压缩;裁剪工具返回值
两个Agent互相“让贤”Handoff触发条件宽泛显式定义交接理由;收紧交接触发条件;设置最大交接轮数
用户问常识性问题也触发知识库检索路由策略没有识别“不需要工具”的场景在Router的提示词里显式声明“不触发工具”的判定条件
升级模型后回答风格突变没有语义回归测试建立固定用例集;改版后先灰度,对比线上效果再全量切换

5.2 我自己摸出来的几条调试心得

最后说几条常规文档里不会写的东西。

第一,给工具描述做A/B测试。我原以为工具排错只在逻辑层,后来发现工具描述写着“计算员工报销额度”和“根据公司报销制度计算员工当年可报销剩余额度”,模型触发工具的准确率差异非常明显。描述里带上“边界条件”和“预期返回结构”,会让模型的理解准确度上一个台阶。建议每次改动工具描述后,都拿固定用例集跑一遍对比效果。

第二,用小样本集做快速回归。不用建几千条用例的大测试集,几十条覆盖典型场景的用例就够日常回归了。每次调完Prompt或工具,本地先跑一遍这小几十条,能拦住大部分劣化。

第三,成本算总账,别只看单次调用价格。多Agent架构下,一次用户请求可能产生5到10次模型调用。把全链路都算进去之后,有些看起来“单次很便宜”的小模型选择,实际总成本反而更高,因为它的推理能力不足导致需要更多轮重试和修正。综合考量后,选择一个中等规格模型往往比“省钱用小模型”更划算。

结尾

写到这里,正好是系列第五篇的收尾位置。按系列规划,下一篇会聊更进阶的微调与对齐话题,这里预告一句也不算剧透。

回到今天讲的内容。从单Agent到多Agent系统,表面上改写的是代码结构,实际上是变换了思考方式。你得先能拆解业务,才谈得上构建Agent;你得先承认模型不是万能的,才愿意给它配工具、配记忆、配知识库;你得先接受线上和本地不一样,才肯花力气做无状态化、做监控、做回归测试。这些都不是SDK直接教给你的能力,但恰恰是Agent项目能不能活下来的关键。

我在实际项目中最大的体会是:构建Agent的时间分配,应该是一分在写提示词和调工具,九分在搭观测体系和做回归测试。理由很简单,提示词和工具是“开发”,而观测体系是“保障”。没有保障体系的开发,上线即裸奔。每次踩坑后回头看,能让你快速定位“是哪个环节变了”的,从来不是直觉,而是日志和trace。

最后分享一个小技巧作为本期结尾:在Agent系统上线前,先故意做一次“故障演练”——手动断开知识库接口、模拟模型服务超时、把某个工具返回值改成异常格式,然后观察Agent的行为响应是否符合预期。经历过这轮演练的系统,上线后的稳定性会让你省很多事。

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

华硕H81M-CT主板USB过流保护故障维修全记录

1. 一块被判死刑的H81主板,到底值不值得救 华硕H81M-CT这块板子,玩过LGA1150平台的朋友应该都不陌生。H81芯片组,定位入门,当年品牌机、办公机出货量巨大,现在二手市场几十块到一百出头就能捡到。问题来了——这板子有…

作者头像 李华
网站建设 2026/9/29 16:00:34

RV1103B平台SC132GS全局快门Sensor设备树配置避坑指南

1. 为什么SC132GS在RV1103B上值得单独写一篇避坑指南 SC132GS这颗Sensor在RV1103B平台上属于典型的"看起来简单、配起来要命"的器件。它是一颗132万像素的全局快门CMOS图像传感器,MIPI CSI-2接口输出,常见于智能车视觉、工业扫码、机器视觉这类…

作者头像 李华
网站建设 2026/9/29 15:59:23

2026辽宁铝木窗选购指南:从保温原理到源头工厂避坑要点

2026年辽宁铝木窗选购,听起来像是个装修小决定,但我在沈阳和大连跑了十几家门窗厂之后,可以负责任地说一句:这件事的坑,远比大多数人想象得多。就拿去年冬天来说,我一位朋友家新装的断桥铝窗,窗…

作者头像 李华
网站建设 2026/9/29 15:58:53

基于STM32的智能鸽舍系统:抗干扰电路与嵌入式驯养实践

1. 项目概述:这不是玩具,是鸽舍里的“智能管家”你见过给鸽子装智能手环的吗?不是那种贴在腿上、三天就掉的装饰品,而是真正嵌入鸽舍结构、能实时感知鸽群状态、自动调节环境、记录个体行为、甚至干预异常活动的一整套硬件系统。这…

作者头像 李华
网站建设 2026/9/29 15:58:50

OpenCV分水岭算法与形态学后处理:粘连目标分割优化实战

简介:这份316页的PDF文档面向具备一定OpenCV基础的图像处理学习者与算法工程师,聚焦分水岭算法与形态学后处理相结合的图像分割优化方案,帮助解决传统分水岭算法过分割严重、区域边界不精确等实际痛点。文档共50个大章节,从图像分…

作者头像 李华
网站建设 2026/9/29 15:57:07

制造业供应链成熟度评估模型与集成计划流程框架落地指南

简介:这份PPT资料面向制造业集团供应链管理者、计划与运营岗位从业者,聚焦供应链管理成熟度评估与集成计划流程框架搭建。内容围绕多种订单组织方式并存、计划模式规则不清、集成计划以职能为中心、采购执行多部门多窗口等痛点,给出顶层设计、…

作者头像 李华