ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

多人多AI协同架构:代理代为交互的系统设计与落地

多人多AI协同架构:代理代为交互的系统设计与落地 最近在拆一个AI底座项目遇到了一个挺有意思的问题怎么让“多个真人用户”和“一大群AI代理”在同一张协作桌上工作而且把“AI代理”当成中间交互的中转层。单人单AI的对话产品大家都熟了多代理流水线Agent Pipeline的工具也越来越多但多用户、多AI之间真正以“代理”为交互通道的系统化设计真正聊透的其实不多。这篇就结合我实际踩坑的经历把“多人×多AI协同”背后的系统架构拆开讲清楚。这个内容适合谁看你如果是做协同办公/IM机器人的或者想在企业内部搭一个多模型服务网关再或者对“AI代理社会”这类研究方向感兴趣都能从这里拿到一套能落地、可复现的架构思路。先给个结论多人多AI协同这件事和一对一对齐的对话有本质区别它的架构重心不在“模型多聪明”而在“代理怎么替各方把话说清楚、把路由做对、把上下文隔离开”。1. 为什么要研究“代理代为交互”的多人多AI协同1.1 从“单打独斗”到“群聊式”多代理协作先说一个基础判断AI应用正在经历从“问答式”向“协作式”迁移。问答式的核心是一问一答用户提问、模型回答哪怕背后用到了多代理RAG检索增强生成对用户来说只是一个对话窗口。而协作式的核心是“多条工作线同时在推进”里面有真人、有AI代理、有机器人工具大家不只是在聊天而是共同完成一个项目。这个变化带来了一个以往不用太在意的维度参与方数量。单代理模式里系统只需要处理“用户→代理→模型”这样一个链路多代理流水线里系统处理的是“任务在多个代理之间顺序或并行流转”但到了“多人多AI”事情变成了“多对多”的网状互动。人不仅和AI交流还需要看到AI之间怎么协作、互相验证、补充信息AI也要能够理解多个用户的身份、权限和意图而不能只对着一个抽象的用户说话。我见过不少团队在这个阶段走了弯路直接把多个AI拉到同一个IM群里结果几个代理在群里互相喊话刷屏速度比谁都猛人根本插不上话。问题出在哪缺少了一个“中间层”来执行代交互。这就好比你参加一个国际会议如果所有参会者都直接用各自语言即兴发言会场会乱成一锅粥必须有一个翻译/调度中心替每一方转述、归并、确认。1.2 “代为交互”的三个层次标题里的“代理代为交互”其实有好几层意思别急着把它当成一个技术名词跳过。第一层是“AI代理代理某个人类用户的交互”。也就是说每个用户侧可以有一个或者多个AI代理这个代理代表用户去参会、去提问、去记录、去整理行动项而不是用户本人逐字发言。这有点像邮件里的自动回复语音助手代办但显然要复杂得多因为代理需要基于对用户意图的理解动态生成高质量发言。第二层是“代理网关代为转发所有AI之间的交互”。多个AI代理不可能各自维护到其他AI的直连通道那样复杂度是乘积级别的而且改一个代理协议就要同步所有节点。所以需要一台“信使中枢”所有AI之间的通讯都经由它路由、过滤、记录。第三层是“代理层代替原始参与者做决策”。这个听着有点危险但在架构上反而是最重要的一层。当一个协作任务到了多模型边界不清楚的时候总要有人决定“这个问题交给哪个代理、哪些信息可以共享、谁的回答具备最终效力”。这就是代理层的“调度”职责。只考虑其中任何一层都会设计出偏科的系统。真正要紧的是把这三层统一到一个中央控制模型里而“代交互”不是简单地在代码里加个转发逻辑背后是一套消息机制、权限模型和状态同步体系。1.3 场景化的需求才是架构的起点只看概念容易飘我还是喜欢先用场景把它钉住。第一个场景是企业团队的知识库协作。项目群里有很多成员同时有文档代理、代码代理、合规代理、搜索代理。用户不是直接去问“给我找一下竞品信息”而是把任务扔给项目空间空间里的“管理员代理”先把需求拆成子任务分配给不同专业代理各代理把结果汇总到共享白板最后由“评审代理”收敛成一份结论。这个时候代理们所有交互都不是私下的而是通过一个公共的代理人机交互总线完成的。第二个场景是研发团队的“AI结对编程多角色评审”。代码代理写代码测试代理自动跑用例架构代理做评审产品经理代理盯着需求。这里面大量交互是代理之间自动出发的但每个动作都应该是可见、可干预、可追溯的。没有代交互层这事就没法做因为代理A想找代理B协作它得先找到B的地址和能力B回复后A要把结果反馈给真人用户还得让用户决定是否采纳。第三个场景是边缘机器人团队的协作。比如用ROS机器人操作系统把几台移动机器人的状态接进多代理系统——机器人代理负责路径规划感知代理负责目标识别调度代理负责资源分配人在场外通过交互层下发目标并且观察多代理的运行过程。这个场景里代交互要连通的不只是大模型接口还有真实世界的传感器和控制器。这些场景都是同一个抽象问题的具体表现如何把“协作”从点对点变成一组可管理、可观测、可兜底的代交互流程。2. 系统架构一个可落地的“多人×多AI”对称中枢2.1 不要把架构想成“聊天机器人加个总线”很多团队设计多AI协同的第一反应是“给聊天机器人加个消息队列”这是典型的低估。多AI协同架构本质上是一套分布式控制系统需要把接入、路由、编排、模型调用、工具执行、记忆存储这几个环节拆开。我一般喜欢用“七层模型”来组织方案和网络设备的分层思想类似每一层只负责一个职责层与层之间通过标准接口通信。层次核心组件职责类比接入层WebSocket/HTTP网关、会议室服务连接真人用户维护会话房间会议主持人的“签到台”身份权限层用户目录、角色映射、代理凭证管理确认“谁在说话”“谁可以听”门禁卡识别代理注册层Agent Registry能力声明Skill Manifest管理有哪些AI代理可用、擅长什么服务目录消息路由层Message Router / Dispatcher把消息转发给正确的代理和用户总机接线员编排决策层Orchestrator / 会话总管代理拆解任务、分派行动、收敛结论项目经理模型接入层Model Gateway统一请求多个云端/本地模型接口配电箱记忆与工具层存储引擎、工具适配器保存上下文、调起文件/机器人/搜索工具资料室工具箱我自己在实践的时候最深的感触是前两层决定了系统的“可用性”中间两层决定了系统的“智能度”最后两层决定了系统的“实用性”。绝大多数失败项目都是在第三、四层没有做分离硬把任务分解逻辑写死在了代码里导致加一个新代理就要改一遍核心逻辑。2.2 控制面与数据面的分离借鉴分布式交换机思路如果你不做网络可能对“控制面”“数据面”这两个词有点陌生。简单来说控制面负责“决定”数据面负责“干活”。在大型网络交换机的体系里控制面算路由表再怎么复杂也不应该影响数据包的高速转发。多AI协同架构也应该走同样的思路。在这个系统里控制面就是任务编排、代理选择、消息过滤这些高智慧判断数据面则是把一条消息按既定路径送到目标代理、把模型生成结果返回用户这些高频率动作。如果没有分离会出现一个很尴尬的情况核心代理在忙于理解用户意图的时候连一条简单的“收到”消息都发不出去整个系统看起来像死机了。我在实现的时候做了异步解耦路由器和编排器跑在同一个进程里但通过独立的worker线程处理数据转发模型调用也是异步非阻塞的。这样做的好处是即使某个代理调用一个大模型超时其他代理之间的消息转发不受影响。这个设计思路我在读Linux内核IOMMU软件架构分析的时候又有了更深感触见下文第3.2节。2.3 路由不是“简单匹配”它分三个层级代理路由是代交互系统的心脏。很多开源项目直接拿消息里的关键字去匹配代理标签效果很差。因为真实场景里用户说的需求往往含糊其辞“帮我看看这个方案行不行”到底是问技术代理还是产品代理还是合规代理我的实践是把路由拆成三级。第一级是“广播感知级”。每条消息进系统之后先发一个元信息存根给所有代理代理不全文阅读只看到意图标签和消息长度然后决定自己是否有兴趣响应。这个机制可以避免一次全量匹配错误导致的消息丢失。第二级是“意图路由级”。编排器基于大模型或者意图识别小模型把消息归到已知意图类别映射到代理能力标签。比如“写代码”“跑测试”“查政策”“做翻译”这些意图都有明确的代理映射。第三级是“精确调度级”。当需要多个代理协同的时候编排器会发出一个任务清单List里面明确列出每个代理应该完成的子任务和提交截止时间避免代理互相等待。这个三级路由类似于在实际工作中先让人人知道有会再有人明确该谁发言最后再给每个发言人派活。2.4 连接多人、多代理的两个关键映射一张网里既有真实的人又有AI代理如果大家的身份模型不统一后面所有权限和消息校验都会变成一团浆糊。我把系统里的一切参与者统一抽象为一个“Principal”实体不区分它是“用户”还是“代理”。这样一个关键概念出现了房间Room。房间既可以包含真实用户也可以包含AI代理用户和代理都可以加入多个房间。内部的交互对象在系统层面都被映射为“房间中的一个成员ID”。这样设计最大的好处是权限控制变成了一张简单的准入表——成员A能不能发消息给成员B就看两个人在不在同一个房间、有没有通过隐式或显式的订阅关系。另一个关键映射是“人类用户与代理之间的绑定关系”。每个用户可以有助理代理这个助理代理在房间中代表用户接收公开消息、提取行动项并定期向用户生成摘要。这个映射放在身份权限层里做系统会根据绑定关系做消息的“代接收”。但不要让代理完全替用户做决定需要设置一个“需要人工确认”的开关否则用户很快就失去对系统的信任。3. 核心机制消息协议、上下文隔离与多AI协作范式3.1 统一消息封套所有参与者都说同一种“语言”如果每一对代理之间都自定义通讯协议系统就会退化成一个“全网状耦合”的怪物。必须设计一套统一的消息封套Message Envelope所有参与者发消息的时候都往这个封套里填标准字段。一个简化版的消息结构是这样{ protocol: multi-agent-collab/v1, message_id: msg_8f81a2bc, timestamp: 1723809123456, sender: agent:project-assistant, recipients: [agent:code-reviewer, agent:test-runner], sequence: 12, intent: request_review, priority): high, payload: { task_id: T-2024-08-001, chunk: 需要评审的代码片段/文档片段, format: code/diff }, context_policy: { visible_fields: [task_id, chunk], share_policy: explicit }, budget: { max_tokens: 8000, deadline_ms: 20000 } }这里最容易被忽略的是context_policy字段它决定了一条消息可以被哪些代理在多大程度上写入长期记忆。刚设计这套东西的时候我没太在意后来发现没有这个字段所有代理都会把接收到的消息原封不动地塞进系统提示词里上下文爆炸得非常快。budget字段也很实用。多代理协同里经常出现一个代理调用另一个代理服务结果子代理超时父任务也被拖垮。预算字段会让接收方提前知道自己能占用多少上下文窗口和多少时间超过就及时降级返回而不是死等。3.2 上下文隔离聊着聊着就串味多代理协同最大的技术隐患不是“模型不够强”而是“上下文互相污染”。代理A收到了一段敏感信息顺手写进了模型上下文代理B在下一个任务中又无意间引用了代理A的内容最后用户面对的是一个信息边界完全混乱的系统。这让我想到了IOMMUInput/Output Memory Management Unit的设计。在Linux系统的IOMMU软件架构里每个设备能被映射到不同的I/O页表也就是给每个设备划分独立的地址域设备说“我要读写内存地址X”IOMMU会把它转译成这个设备真正能访问的物理内存越权的访问直接被拦截。多代理系统的上下文隔离其实是同一哲学每个代理的模型上下文就像一块独立的“内存域”你不能让任何一条流入的消息默认就能写入所有领域。我的做法是设置三种存储空间私人空间只有代理自己可以读写的临时工作区模拟系统提示词的一部分。适合放一些敏感中间结果。共享黑板所有代理可见适合存放任务定义、里程碑结论、决策日志。但写入前要经过编排器检查。引用空间允许有条件的跨代理引用。比如代码代理可以引用测试代理生成的“用例ID”但无法读取测试代理的完整原始日志。长期记忆层我把消息按照房间、主题Thread、任务Task三个维度切分。每个代理只被注入当前主题和当前任务相关的记忆而不是这个房间里的全部历史消息。这个操作可以说立竿见影地降低了上下文混乱概率。3.3 多AI协同的几种组织范式别一根筋用主管代理很多人一听多代理马上想到“一个主管代理拆任务、几个工人代理干活”但这个模式并不是万能的。我整理了四种协同范式按实际使用情况选择范式工作机制适用场景风险点主管-工人一个编排代理负责拆解和合并结构清晰的流水线任务主管代理是单点故障任务稍复杂就容易想当然共享黑板所有代理读写同一份任务全局态自发协作探索性、创意类任务边界不清需要很强的字段级访问控制竞标-仲裁多个代理分别提出方案仲裁代理选择最佳方案评审、代码评审评审成本高可能出现“老好人式”仲裁订阅发布事件总线代理订阅感兴趣的事件发布方不用关心谁接监控、告警、消息通知类循环事件容易被不同代理重复响应需要去重我在大部分项目里用的是“混合模式”先用主管-工人做任务拆解用共享黑板做状态同步最后用竞标-仲裁做质量关卡。纯粹用一种范式要么太死板要么太失控。3.4 本地模型与工具链的接入决定了系统能否真的跑起来系统架构再漂亮最终要让模型跑起来。市面上有大量“AI代理助手本地模型”的需求动力基本是三个隐私合规、离线可用、成本控制。本地模型接入这一层我通常建议不要在应用代码里直接调本地模型的HTTP接口而是统一过一个模型网关。模型网关可以理解成一个配电箱。它记录每个模型的上下文窗口大小、推理速度、价格再根据请求复杂度做选路。开发环境直接用Ollama跑量化模型生产环境用vLLM或者TensorRT-LLM做并发推理服务都是通过同一套OpenAI兼容接口暴露给上层。接本地模型之后多AI协同的底层部署问题就出来了。第一件事是搞清楚运行架构我用uname -m看机器是x86_64还是aarch64这决定了基础镜像怎么选。遇到过一个ARM架构国产Linux环境U盘安装系统之后很多容器镜像都不兼容后来统一编译了ARM镜像才解决。如果你要在边缘设备上跑多代理协同别忘了STM32这类嵌入式芯片也能跑非常轻量的推理模型架构思路和云端完全不一样更适合做工具事件检测而不是复杂推理。工具链方面“OpenClawROS”这类整合玩法现在很火。OpenClaw可以管理代理日常杂活ROS则给了代理真实世界的行动能力。我最近做的机器人协作场景就是通过一个ROS Bridge容器把机器人的状态话题转化成了标准消息封套AI代理订阅“odom”话题来感知位置发布“cmd_vel”指令去控制移动。这样代理不仅会说话还能“动手”系统真正拓展到了物理空间。4. 动手搭建一个最小可运行的“多人多AI”原型4.1 先明确最小边界如果你想复现这套架构建议第一步不要追求功能全而是搭一个只包含核心链路的骨架一个房间、三个代理、一个用户、一个编排器。目标就一个让用户的提问被编排器拆解为两个子任务两个代理分别处理最终合并成一条回复。我采用的是最简单的技术组合WebSocket负责消息传输Python写逻辑层模型统一接本地Ollama避免云API的追溯问题。部署在一台Linux服务器上用uname -m确认架构后开始装依赖。硬件不需要多好一块普通的消费级GPU就能跑两个量化小模型分别用于“意图拆解”和“专业回答”。4.2 核心代码骨架下面这段代码不是最终生产版本但能清晰展示“消息路由代交互”的核心流程import asyncio import json from dataclasses import dataclass dataclass class Envelope: sender: str recipients: list intent: str payload: dict context_policy: dict class Room: def __init__(self, room_id: str, orchestrator, agents: dict): self.room_id room_id self.orchestrator orchestrator self.agents agents async def dispatch(self, env: Envelope): # 1. 先经过编排器做意图处理控制面 plan await self.orchestrator.plan(env) # 2. 根据计划向目标代理投递消息数据面 for step in plan: target self.agents.get(step[agent]) if not target: continue # 每个代理都有独立的上下文窗口只传当前子任务需要的字段 sub_env self._truncate_context(env, step[visible_fields]) await target.process(sub_env, step[instruction]) def _truncate_context(self, env: Envelope, visible_fields: list): limited {k: v for k, v in env.payload.items() if k in visible_fields} return Envelope( senderenv.sender, recipients[env.sender], intentenv.intent, payloadlimited, context_policyenv.context_policy )这里的核心思想是做个很轻的“上下文裁剪器”根据编排器的决策把传给每个代理的payload限制到最小可见字段。这在实践中极大减少了代理之间的信息泄露。4.3 编排器提示词模板别小看这一层编排器本质上也是一个AI代理但它不负责写具体内容它只负责“怎么切、怎么发给谁、怎么合并”。我给编排器的系统提示词写得很细不是随便来一句“你负责任务分配”。经验更丰富的读者会知道太松的编排器会凭空造出不存在的代理名还会把任务拆得七零八落。一个可靠的最小模板包含这几部分代理清单、意图分类规则、禁止行为、输出JSON格式。代理清单里有每一个代理的名称、能力描述、擅长边界这里拿代码代理举例{ agent: code-reviewer, capabilities: [code_review, diff_explain], input_filters: [source_code, language, commit_sha], output_format: review_comment, max_tokens: 4096 }编排器只输出结构化的计划不做自由文本决策。这样“决定”和“干活”完全分离就算编排器出了问题你也能通过检查JSON快速定位。真实跑起来之后你还会发现一句著名的多渠道踩坑“AI代理之间不能看见对方全部的输出”。我第三版加了“黑名单”机制某些字段互相之间完全不可见只有用户和归档日志可见。这样既保证了协同又保留了边界。这里的“编好提示词”不是要你把所有规则塞进几百行而是把“不可跨越的边界”写清楚。规则越少、边界越硬实际效果越好。4.4 把原型跑起来的几个检查点跑通一次完整交互后别急着加功能先确认四件事一是消息到达率。是不是每条消息都稳定到达了目标代理我建议加消息序号和ACK回执代理收到消息后返回一条确认信号。没有确认机制后续排查问题就是灾难。二是上下文隔离有效性。找一条包含敏感字段的测试消息看非授权代理的上下文里有没有出现这个字段。如果出现了大概率是消息封套的字段裁剪没做对。三是编排器是否出现幻觉代理。我之前遇到过编排器输出一个根本不存在的代理名导致消息被静默丢弃。后来给路由加了一步“代理名单校验”不在名单里的目标直接废弃并上报。四是响应时延是否可接受。从用户发消息到收到合并结果我给自己定的及格线是单人本地模型条件下10秒内。超过这个值去看是不是模型排队太严重或者某个子代理被慢速工具卡住了。5. 实战踩坑与排查速查5.1 多代理系统最典型的五个故障这套系统跑了半年我实打实踩过的坑比预想中多。挑最值得说的五个并提出解决方案。第一个是代理循环刷屏。两个或者多个代理对同一件事不断回复“我觉得他说得对”“我再补充一点”形成无限对话。根本原因是事件总线没有“话题闭合机制”。我的对策是给每条消息设置时有效签名TTL超过限制或者当仲裁代理已经给出结论后消息自动失效禁止继续追加。第二个是上下文污染延迟爆发。上下文隔离做了一些但没做干净结果A任务的信息被B任务无意引用。这种问题往往在几轮交互之后才暴露。对策上文已经说了三空间存储和按领域可见字段裁剪。第三个是模型幻觉直接进入消息路由。因为模型生成的路由结果不总是靠谱可能把一个“查询天气”的任务发给了“代码生成”代理。只靠意图识别根本不够。我加了关键意图的硬编码校验天气类请求走固定路由代码类请求先扫关键词再映射代理不纯靠模型判断。第四个是代理之间没有任何收敛机制。多个代理各自输出观点没人综合最后用户看到五个分散的片段。解决这个问题需要在编排层增加一个汇总代理Synthesizer负责把多个代理的结果合并成结构化的单条回复同时附上每个来源的标记。第五个是用户权限失控。用户A把一条消息发到了会议室系统里所有的AI代理都可以看到用户很不满意。我引入了“可见圈”概念每条消息可以指定受众群体包括用户、代理组、所有参与者默认不公开。5.2 排查速查表症状可能原因快速排查路径推荐对策某AI代理收不到消息路由目标不在注册表检查编排器输出JSON里的agent字段增加代理名单校验非法目标丢弃加告警代理回复超级慢模型排队、工具调用阻塞看模型网关监控按预算字段确认拆分长任务超时降级模型并发调参多个代理内容互相引用错乱上下文隔离失效查最近三条消息的payload字段强制visible_fields白名单清理共享黑板代理之间无限辩论缺少话题闭合机制查看消息TTL和仲裁代理是否有最终结论引入裁决代理设置消息过期时间用户觉得“AI们在自嗨”汇总代理缺失或太弱查看最终回复是否经过Synthesizer增加汇总代理输出决策摘要和行动项本地模型频繁OOM并发服务配得不合理看GPU显存和模型量化位数换小模型或调低并发必要时多卡分配5.3 治理与成本控制架构最后的兜底多人多AI系统一旦上线运行消耗的不只是算力还有人力的注意力。我强烈建议在架构设计阶段就把治理规则嵌进去而不是事后打补丁。我的经验是设三层限制一是消息频率限制Rate Limit防止某个代理突然因为异常触发暴风式广播二是运算预算限制每个任务都有token预算用完后代理只能递交“半成品未完成原因”三是人工复核开关关键任务必须等真实用户按下“确认”按钮才继续执行。审计日志单独存一份。所有代交互消息、路由决策、上下文裁剪动作、工具调用记录都进日志库。好在现在开源生态里有很多日志收集工具你只需要统一日志格式就够用了。写在最后的实操体会这套“代理代为交互”的架构我最大的体会不是技术实现本身有多难而是“边界感”比“智能度”更能决定系统的成败。多AI协同跑得越high信息边界的维护就越重要一旦上下文污染和权限失控出现再聪明的模型也救不回来。如果让我给后来者一个保守的建议那就是第一版架构千万不要把编排器设计得太聪明。用一个相对机械的路由策略跑通全链路再慢慢加入大模型能力。我就是太早在编排器里加入自由文本任务拆分结果花了很多时间在调试“编排器自己制造的混乱”反而把最需要打磨的消息路由和上下文隔离晾在了一边。还有一个细节在Linux下确认好系统架构再选镜像在ARM设备上不要强行套x86镜像否则后续模型部署会处处碰壁。这个方向后续值得扩展的路径很多比如让代理具备“跨房间记忆迁移”的能力、把模型网关升级成按任务自动选择云端和本地模型再比如把ROS工具接入扩展到更复杂的多机器人协作场景。先把消息封套、三级路由、上下文隔离这三个底层做扎实你就能在它之上长出自己的玩法。
返回列表