多人多AI一起干活这事,听起来很热闹,真做起来第一个坑就是“没人牵头”。我几年前在团队里牵头搞过一段内部AI工具整合,当时大家手上有好几个大模型服务、本地跑着一个开源模型,还有几个人各自写了脚本调用。表面看是各干各的,实际上每天都在重复调接口、拼上下文、对结果。真正让我下决心研究“代理层”的契机,是某次评审会:三个成员分别用三个不同模型问了同一个需求,三份答案互相矛盾,最后还得人肉开会解决。这次经历之后我就一直在琢磨,能不能让系统里的AI代理替人去交互、去调度,让多个AI像开发组一样协作起来。这篇文章就是围绕“基于AI代理代为交互的多人多AI协同系统架构研究”这个项目写的,目标很直接:讲清楚代理层为什么必须有、协同引擎怎么设计、落地时哪些坑是躲不掉的。适合正在搞多模型接入、多Agent协同、或者想把AI能力做成团队基础设施的架构师和后端工程师参考。
1. 这个系统到底在解决什么问题
1.1 我为什么觉得“直接调API”不够用
很多人第一反应是:多AI协同不就是把多个API拼在一起吗?用户提问,代码里写死先调A模型再调B模型,结果拼一拼就完事了。我一开始也是这么干的,但实际跑起来全是问题。
第一个问题是上下文割裂。用户跟模型A聊完需求,又跑去模型B问实现方案,两个模型互相不知道对方说了什么,用户得自己把A的结论复制粘贴给B。一次两次行,次数多了根本记不住,上下文一长就开始丢信息。
第二个问题是权限和身份混乱。多人共用一个系统时,怎么知道这句话是产品经理问的还是后端工程师问的?不同角色对同一问题想要的答案粒度完全不同。没有代理层统一管理身份,AI就只能“一视同仁”,最后谁都不满意。
第三个问题是工具碎片化。有人写了脚本调模型A做总结,有人写了脚本调模型B做翻译,还有人用模型C做代码审查。这些脚本之间没有任何联系,没法编排、没法复用、没法审计。本质上就是每个团队都在重复造轮子。
所以我后来想明白了:多个AI不是问题,缺一个“统一调度的大脑”才是问题。这个大脑就是AI代理层。它不负责具体生成内容,而是负责理解用户意图、分配合适的AI执行、收拢结果再统一返回。用一句话概括——代理是用户和多个AI之间的“翻译官+调度员”。
1.2 核心需求清单与功能边界
项目正式立项的时候,我带着团队把需求捋了一遍,最终收敛成下面这五条核心能力:
- 统一交互入口:用户只对接一个代理,不用关心背后到底有几个AI在跑。
- 意图路由:用户一句话过来,代理判断该交给哪个AI,或拆分成多个子任务分给多个AI。
- 任务编排:支持按顺序、按依赖、按并行三种执行模式,多AI协作时有明确流程。
- 记忆与上下文共享:会话级、项目级记忆统一存储,多AI之间通过代理传递必要的上下文。
- 权限与隔离:每个用户的代理实例相互隔离,防止串数据、越权访问。
同样重要的是明确非目标。我们不做模型训练、不做领域微调、不做花哨的对话UI(第一阶段只提供API和简单Web控制台)。项目最容易膨胀的地方就在这里,聊着聊着就想去优化模型本身,一旦跑偏,架构研究就变成了调参工程,核心问题反而没人管了。
边界划清楚之后,整个团队的精力就都集中在“代理怎么设计、协同引擎怎么实现”上,方向感会清晰很多。
1.3 这个项目最适合谁参考
我自己是后端出身,平时主要做分布式系统设计,所以这套架构天然带着“服务化、消息驱动”的味道。如果你有以下情况,参考价值最大:
- 公司内部已经接了多个大模型服务,但使用方式停留在“各调各的”,想统一管理。
- 你正在做多Agent方向的技术预研,想知道除了LangChain这类框架,自己从底层搭一套协同系统要考虑什么。
- 你负责的团队多人共用一套AI工具,经常遇到上下文混乱、结果不一致、权限没法控制的问题。
- 你对“本地模型+云端模型”混合调度感兴趣,想设计一个能随时切换、降级的架构。
我写这篇博文时会尽量把设计思路、关键决策和踩坑过程都讲出来,不会只给一个“看起来很完美”的架构图然后就结束。实际系统里每个配置项背后都有血泪教训。
2. 代理层的核心机制设计:代理到底在“代”什么
2.1 用户-代理-多AI的三角关系
这个系统的核心关系其实非常简单,就三层:
- 用户层:人只跟代理交互,发需求、收结果。
- 代理层:每个用户(或每个会话)持有一个代理实例,代理保存用户偏好、身份信息、上下文摘要。
- AI服务层:后面挂一堆模型服务,云端大模型、本地开源模型、专用小模型,统统都行。
代理不是聊天机器人。聊天机器人的逻辑是“收到话 -> 生成回答”,代理的逻辑是“收到话 -> 判断意图 -> 可能拆解 -> 调用一个或多个AI -> 汇总 -> 返回”。多出来的这一大段就是“代为交互”的核心价值。
我举个例子你就明白了。用户说:“帮我看看这个接口的QPS上不去,是不是代码有问题,顺便给个优化方案。”
普通聊天机器人会把这句话原封不动丢给模型,然后等一个回答。代理则会做这么几步:
- 先分析意图:这是一个代码评审+性能优化类问题。
- 查看上下文:用户最近在项目A里聊过这个接口的设计,代理把相关设计文档摘要带上。
- 路由决策:代码审查类任务交给代码能力强的模型A,性能分析类建议交给推理能力强的模型B。
- 并行执行:同时调两个模型,拿到结果后做一致性校验,如果有冲突,代理做裁决。
- 汇总返回:把两个结果合并成一份结构化报告。
这就是“代”的本质——代理把用户从“自己管理多个AI”这件事里解放出来。
2.2 会话与消息协议的设计:给AI们传纸条
多个AI之间怎么通信?直接互相调API是不现实的,模型服务没有“主动找另一个模型聊天”的机制。我采用的办法是引入统一消息协议,所有AI之间的信息传递都走协议格式。
协议按JSON设计,核心字段长这样:
{ "message_id": "msg_8f3a2c1b", "session_id": "sess_20241107_001", "source_agent": "user_agent_zhang", "target_agent": "model_service_code_review", "message_type": "task_assign", "payload": { "task_id": "task_20241107_001", "task_type": "code_review", "content": "需要审查的代码片段或文件路径", "context_refs": ["历史讨论摘要", "相关设计文档"], "timeout": 30, "callback_topic": "agent_zhang_result_channel" } }消息类型我固定了几种:task_assign(任务分配)、task_result(任务结果回传)、context_query(上下文拉取)、nofitication(进度通知)、human_handoff(需要人工介入)。这个分类不复杂但很实用,所有协同流程最终都能映射到这几类消息上。
刚设计这套协议时我犯过一个错:把“带全部上下文”当成默认行为。每条消息都把整个对话历史带过去,看起来省事,实际上模型输入瞬间爆掉,费用也飙升。后来改成引用制——消息里只放上下文摘要和引用ID,目标AI如果需要详细信息,通过context_query消息到记忆服务拉取。这个改动让Token消耗下降了差不多一半。
2.3 上下文与记忆的分层:别把上下文窗口当仓库
每个模型的上下文窗口都有限,几万Token看着多,塞几轮对话摘要、几段代码、几个参考文档就见底了。而协同系统里,多个AI共享一个项目的历史,这个量级根本没法全量塞进去。
我用了三层记忆结构来解决:
| 层级 | 存储内容 | 生命周期 | 使用方式 |
|---|---|---|---|
| 会话级记忆 | 当前任务的对话记录、临时状态 | 会话结束即清理 | 直接拼入Prompt |
| 项目级记忆 | 项目约定、决策记录、长期上下文 | 项目周期内保留 | 按相关性筛选后以摘要形式注入 |
| 个人级记忆 | 用户偏好、常用风格、习惯 | 长期保留 | 由代理在路由时附加 |
关键不在存储,而在怎么筛选和压缩。我写了一个轻量的上下文摘要器,每次对话达到预设阈值(比如20轮)就跑一次摘要,把关键决策、未解决问题、当前的共识提炼成300字以内的结构化摘要。原始对话存数据库作为可查询的“历史档案”,未来某个Agent需要时,用关键词检索取片段。
有人问我为什么不直接用模型做全量总结,那样质量更高。道理没错,但成本太高——每个会话每20轮跑一次全量总结,一天下来模型调用量翻好几倍。权衡之后还是选择“轻量摘要+按需检索”的组合,效果够用,成本可控。
3. 整体系统架构:为什么必须分层
3.1 五层架构划分与各层职责
项目跑了一段时间后,我对架构的诉求就一句话:每一层都能独立替换,不拖累其他层。最终收敛成了五层结构:
接入层 → 代理层 → 协同引擎层 → AI服务层 → 数据层- 接入层:负责多用户连接管理、身份认证、API网关。WebSocket和HTTP都在这层统一暴露给外部调用方。
- 代理层:核心的一层。每个用户分配一个常驻代理实例,代理持有用户偏好、会话摘要、路由策略,负责理解用户输入并触发协同流程。
- 协同引擎层:代理把任务交到这里。引擎负责拆解任务、编排执行顺序、调度多个模型、汇总结果。它不关心业务语义,只关心“任务怎么流转最优”。
- AI服务层:统一封装所有模型服务。不管是云端API、本地Ollama、还是自研模型,都通过标准接口暴露给上层,屏蔽掉供应商差异。
- 数据层:存消息、会话、任务状态、记忆摘要。我用PostgreSQL存结构化数据、Redis做缓存和消息队列,后面我会解释为什么要用Redis Stream。
这个分层的直接影响是:换模型供应商不用动上层逻辑,加新功能不用碰数据层,出问题查日志能快速定位在哪一层。我见过很多协同系统最后变成一团乱麻,基本都是没守住分层边界——协同引擎里直接写了调用模型的代码,代理层又自己搞了一套任务存储。
3.2 关键技术选型:框架、消息、存储
关于Agent框架,当时纠结过是用LangChain这类现成框架还是自研。实测下来,LangChain的AgentExecutor在单Agent场景非常好用,但多Agent协同、自定义路由、权限隔离这些需求反而成了束缚,为了绕过框架限制花费的时间比省下的还多。后来决定只借鉴框架思想,核心代码自研——引入LangChain的Tool抽象和Callback机制,但任务编排、消息传递、记忆管理全部自己写。
消息传递这块我踩过一个大坑。最初用同步HTTP调用,A模型调用B模型时直接等结果返回,结果就是:B模型超时,A模型卡住,用户等半天,整个链路雪崩。后来换成Redis Stream做异步消息队列,所有任务都投递到队列,各个AI服务作为消费者异步处理。流式队列的好处有三个:失败可以重试、任务可以追踪、高峰期能削峰。如果任务量再上一个量级,可以平滑迁移到Kafka,不影响上层代码。
存储层选择很简单:PostgreSQL存持久化数据(会话、任务、记忆摘要),Redis做热点缓存。部署上用一个docker compose文件起全套服务,个人开发机、小团队服务器都能直接跑。GPU机器专门跑本地模型,CPU机器跑代理和协同引擎。实测下来在普通4核8G机器上,代理层和引擎层跑得很轻松,瓶颈永远在模型推理那边。
3.3 为什么要用多Agent而不是一个超级Agent
我在设计过程中一度动摇过:能不能就搞一个超级Agent,把所有能力都塞进去,靠Function Calling调用工具,这样逻辑更简单?试了一个月后放弃了,原因如下:
- 上下文冲突:一个Agent同时处理编程问题、翻译任务、数据查询、会议纪要,各种上下文混在一起,模型经常“串台”——回答编程问题时参考了翻译任务里的语境。
- 工具膨胀:工具越加载越多,模型在Function Calling时选错工具的概率直线上升,错误率随工具数量非线性增长。
- 权限粒度难控制:一个Agent掌握所有工具,就没办法实现“普通成员不能用高危操作”“管理员才能访问敏感信息”这种精细化控制。
- 单点故障:超级Agent一旦状态错乱,全体下线;多Agent架构下,某个域的Agent挂了不影响其他域。
多Agent的代价也有,主要是消息通信开销比单体大、整体调试链路更长。但换来的是清晰的边界、独立的演进空间、分域故障隔离,对协同系统来说这些优点远大于代价。
4. 关键流程实现:任务编排与路由是核心引擎
4.1 任务分发的两种模式
我把实际跑过的任务梳理了一下,发现九成情况都能归入两种模式。
问答模式:用户提问,代理判定由某个AI就能解决。代理把上下文摘要带上,路由到最合适的模型服务,拿结果返回。这个模式最简单,适合翻译、摘要、单点知识查询。
流水线模式:用户给一个相对复杂的目标,代理拆解成多个子任务,按依赖关系依次或并行执行。比如“把这份需求文档拆成开发任务并生成初步技术方案”,流程是:模型A做需求结构化 -> 模型B做架构设计 -> 模型C按架构设计生成任务列表。每一步的输出作为下一步的输入。
路由决策我用的是启发式规则+模型评分的双重方案。先用硬规则过滤:用户指定的模型优先、敏感任务走本地模型、代码任务优先代码模型。如果规则没有命中,再由一个轻量模型对任务做分类评分,选出得分最高的两个候选,取其一执行。有人觉得用模型做路由太绕,但我实测下来规则只能覆盖七成场景,剩下三成长尾需求必须靠模型理解语义才能路由准确。
4.2 多AI协同的三种策略:编排、并行、投票
协同策略是引擎的核心,我总结了三种模式,对应不同任务形态:
编排模式(Orchestration):任务有明确依赖链时用这种。比如“先做代码规范化检查,再做性能分析,最后生成汇总报告”——三个任务有先后顺序,前一个结果影响后一个的输入。协同引擎维护一个轻量DAG(有向无环图),节点是子任务,边是依赖关系,按拓扑序执行。这个模式最稳,推荐优先用。
并行模式(Parallel):子任务之间互相不影响时全量并行。比如“同时让三个模型对同一份文档做不同类型总结——干货版、详细版、PPT大纲版”,三个任务独立,谁先完成谁先写入结果,全部完成后统一汇总。并行模式最大的收益是延迟,最怕的是结果质量参差不齐时没人裁决,所以并行模式一定要配结果合并器。
投票模式(Ensemble):需要高可靠性判断时让多个模型交叉验证。比如关键代码的安全审查、敏感信息的判断、需求文档的完整性检查,三个不同模型独立跑,结果做多数表决或加权评分。投票模式成本最高,用的时候一定要克制,我只在四类场景开投票:安全审查、重大决策、数据校验、对外发布内容检查。
4.3 失败重试与降级:AI也会“掉链子”
模型服务不是稳定的,这是做系统设计时必须接受的现实。我见过的情况包括:超时挂了、返回了一堆空内容、生成了纯乱码JSON、自己编了好几个不存在的函数名。协同系统面对这些故障,最简单的做法就是让调用方重试,但重试几次、怎么重试、对方一直不行怎么办,这才是关键。
我最终实现了这么一套机制:
- 超时控制:每个模型调用默认超时30秒,按任务复杂度动态调整。单个任务超过两个超时周期就终止并降级,避免拖垮整条流水线。
- 熔断器模式:连续5次调同一个模型如果全部失败,熔断器打开,后续请求直接路由到备用模型或本地模型,不再尝试主模型。熔断器每30秒做一次半开试探,恢复成功就关闭熔断。
- 结果校验器:模型返回后不直接信任,先用校验器判断格式对不对、内容非空、关键字段是否齐全。校验不过会带校验错误信息重试一次,让模型有机会自纠。
我还在引擎里加了一个降级优先级表,每个任务类型都预置了主备方案。比如任务类型是“代码生成”,主模型是云端大模型,备选是本地代码模型,最后兜底方案是返回“当前模型暂不可用并给用户说明”。整套机制上线后,模型服务偶发故障时,用户的感知从“系统坏了”变成了“慢了但能用”。
5. 落地过程中踩过的坑:多模态、隔离、稳定性
5.1 模型输出不听话,怎么办
做系统最烦的不是功能写不出来,而是模型好好说着话突然不按格式来了。我遇到最典型的问题是:要求返回JSON,模型偏偏在JSON前后加了段解释文字;要求返回代码,结果代码里引用了根本不存在的库。
三个办法治它:
第一,结构输出约束。Prompt里明确给出输出模板和JSON Schema示例,同时在解析侧做容错——用正则先提取JSON片段,剥离前后噪声再解析。
第二,失败后带错重试。解析失败时,把解析错误原文拼进新Prompt,告诉模型“你刚才的输出格式有问题,请修正后再输出”。实测带错重试的成功率能到九成以上。
第三,校验逻辑兜底。实在解析不出来,就返回给用户一个明确提示,不要给一笔乱码。宁可不给结果,也不能给错结果。
5.2 多Agent之间的“信息孤岛”问题
跑了两个多月后团队又反馈一个问题:Agent A整理的需求文档,Agent B完全不知道,导致B在做技术方案时凭空脑补了一版需求。
这就是信息孤岛。后来我在协同引擎里加入共享工作记忆区的概念。每个项目有一个唯一的上下文库,任何Agent产生的关键输出都要写入。别的Agent执行相关任务时,代理层会在路由时自动检索该项目最近的重要上下文注入Prompt。有一个“唯一事实源”的锚点存在,多Agent之间的信息一致性一下子提升了很多。
5.3 权限隔离与安全隔离
多人共用系统最大的安全隐患是“代理越过边界”。我当时设计了一个简单的隔离模型:租户隔离 + 角色权限 + 工具白名单。
- 租户隔离:每个用户的代理实例运行在独立上下文空间,数据层查询强制带user_id过滤条件,SQL层面兜底防串数据。
- 角色权限:管理员、普通成员、访客三级角色,决定谁能发起哪些类型的任务、谁能看到哪些项目的记忆。
- 工具白名单:某些操作(比如删除项目记忆、覆盖权威文档)只有指定角色能触发,代理路由时会做前置校验。
对用户来说,最直观的体验就是:你在这个会话里聊的内容,另一个用户在他的代理里完全看不到。这一点在多用户场景是硬要求,上线前务必反复测试权限边界。
5.4 常见问题速查表
| 现象 | 可能原因 | 处理方式 |
|---|---|---|
| 任务一直排队不执行 | 消息队列积压、消费者挂了 | 检查Redis Stream消费组状态,重启消费者 |
| 多个Agent回答风格不一致 | 没有统一的系统提示词模板 | 在代理层做提示词模板管理,统一前缀和规则 |
| 模型返回内容串了其他项目 | 上下文注入时没有做项目过滤 | 检查记忆检索逻辑,确认带上了project_id过滤条件 |
| Token消耗突然飙升 | 上下文摘要失效或携带了过多历史 | 检查摘要器是否触发,降低上下文引用阈值 |
| 本地模型机器CPU跑满 | 并发请求过高 | 加请求队列、限制并发数,必要时做模型实例扩容 |
| 部署环境是aarch64或国产系统 | 镜像架构不匹配,node或依赖版本过旧 | 提前确认基础镜像支持对应架构,统一锁定node版本 |
还有几个经验值得一提。一是日志要全链路追踪,从用户请求进来到每个子任务完成都要埋点,否则排查问题时会疯掉。二是所有模型调用都要记录Token消耗,方便后续做成本归因。三是尽量把模型服务部署成独立进程,不要和协同引擎混布,避免模型推理占用大量资源把引擎拖死。
6. 我最后的实操体会
整个项目做下来,我最深刻的体会是:先跑通最小闭环,再谈架构完美。最初我们花了太多时间在设计“理想架构”上,后来发现很多设计没有数据支撑,真不如先把“一个用户+两个AI模型+一个代理+一个消息队列”的最小系统跑起来,再根据实际瓶颈迭代。这个最小系统我们花了一周时间就打通了,之后一个月都在做编排策略、故障处理、权限控制这些真正影响体验的东西。
另外一个小建议:多Agent系统的调试比单Agent难得多,一定要在代理层和引擎层都加上“过程可视化”能力。我们实现了一个简单的任务流转面板,可以实时看到任务从代理到引擎再到每个模型服务的完整链路,包括每次调用的输入摘要、输出结果、耗时、Token数。没有这个面板,出了问题就只能对着日志猜。
这个架构后面还有几个方向可以扩展:把本地模型和云端模型做成本感知的混合调度,让长任务自动切到本地低成本模型;做Agent能力市场,不同Agent通过统一协议互相提供能力;加一个模型评测服务,基于历史结果对模型输出打分,让路由策略持续进化。这些后续有进展了我再单独写。