基于AI代理代为交互的多人多AI协同系统架构研究
去年我们团队接了一个内部工具项目:把散落在各个同事手里的AI账号、本地模型统一纳管到一个协作平台上,让不同小组的人可以把自己的AI代理挂载进来,代理之间能够代替人去相互交递任务、核对结果、接力完成整个业务流程。项目跑了大半年,硬骨头不在某个模型回答得准不准,而在于"多人多AI协同"这个架构题——代理与代理之间怎么通信、身份怎么隔离、上下文怎么不串味、出问题怎么回溯。这篇文章就是把我们在架构设计和落地过程中趟过的路、踩过的坑,完整梳理一遍,写给正在做类似AI中台、Agent协作平台的朋友参考。
1. 多人多AI协同:先搞清楚我们在解决什么问题
1.1 真实场景中的四个典型痛点
先说我们最初遇到的四个问题,我相信只要做过多人共享AI能力的团队,都会深有感触。
第一个是上下文漂移。当A代理把一段中间结论转交给B代理时,如果只是简单地把文本"复制粘贴"到新对话里,B就丢失了任务的前后脉络。比如A已经分析完一份日志文件,交接时只给了B一句"问题可能在数据库连接池配置上",B基于这句转述去排查,接不住关键的历史数据和上下文。链路越长,信息失真越严重。
第二个是身份模糊。团队共用一个模型API Key的时候,系统日志里只有一个个请求,没人知道这个请求来自哪个用户、哪次会话、哪个代理。一旦需要排查"为什么财务组的代理会去调用报销系统的写接口",连基本的事件还原都做不了,更谈不上权限管控。
第三个是工具冲突。多个代理并行执行任务,可能同时调用同一份在线文档、同一个待办接口。A代理刚更新了文档内容,B代理拿到的还是旧快照,最后谁覆盖谁都没法判断。我们甚至出现过两个代理同时写同一个配置文件,导致任务直接失败的情况。
第四个是无法复盘。多AI协作一旦出错,定位问题的成本极高。是调度器的路由规则错了,还是模型本身给出了幻觉内容,抑或是工具调用超时?没有记录、没有指标,只能靠人工反复复现,效率极低。
这四点归结起来,指向一个核心诉求:代理之间的交互不能再是松散的人肉搬运,而要通过一套系统化的"代为交互"机制来完成——由平台以某个用户/代理的名义,替他去声明任务、传递上下文、约束范围、回收结果。这也是整个架构研究的前提。
1.2 架构目标与设计原则
基于上述痛点,我们在一开始就把架构目标定得很具体:
- 接入层要兼容不同类型模型,包括云端大模型API、本地私有化模型,甚至以后可能接入的传统规则型问答引擎。
- 编排层要负责代理之间的任务投递、路由、仲裁,并支持人对关键节点的人工介入。
- 数据层要严格隔离会话上下文,保证A代理不会读到B代理的隐私内容。
- 全链路要可观测、可审计,任何一次跨代理交互,都要能追溯到发起人、消费方、执行过程和最终结果。
在方案选型上,我们做过一次重要取舍。最开始有人建议做一个"全集中式大脑",由中央调度器统一指挥所有代理——它判断谁该做什么、命令谁去执行。这个方案听起来很优雅,实际落地会撞上一个大问题:不同代理背后的模型能力差异很大,有的擅长推理,有的擅长检索,有的只是工具型Agent,集中式大脑很难对所有任务给出准确的指派判断。一旦大脑调度错了,整个流程就卡死。
所以我们最终采用的是编排式联邦架构:每个代理保留自主决策空间,各自维护自己的上下文和策略;平台侧只负责做"交通管理"——注册、路由、限流、仲裁、审计,不替代代理做决定。这种架构的好处是降低了模块间的耦合度,代理可以随时调整自己的内部实现,平台的编排逻辑不会受到牵连;风险则是路由决策的质量依赖代理自身能力声明的准确性,所以我们在能力描述规范上花了比较多功夫,这个后面会细讲。
2. 整体系统架构设计与核心模块拆解
2.1 分层架构总览
我们的系统从下到上分为五层:接入层、代理网关层、编排引擎层、语义理解层、数据存储层。
接入层对接所有模型来源。云模型和本地模型都通过一个统一适配器接口暴露能力,对外只呈现一个标准化的"模型调用接口"。这样上层不需要关心背后是OpenAI的接口还是本地部署的Llama服务,只要给一个model_name就能发起推理。
代理网关层解决的是"谁在调用"的问题。每次请求进来,网关会校验AgentID和Token,把调用者身份解析出来,并附加上来源的TeamID、权限标签。这一层做不好,后面所有隔离和审计都无从谈起。
编排引擎层是整个系统的核心,负责任务路由、代际交接、仲裁、降级和限流。它不直接参与模型推理,而是维护一张任务状态机:创建、排队、分发、执行中、结果回传、仲裁、完结。
语义理解层做两件事:一是对任务文本做意图识别,辅助路由决策;二是对回传结果做质量评分,供仲裁环节参考。它本质上是多个轻量级模型的组合,不承载核心上下文。
数据存储层使用多租户隔离的KV存储加事件日志库。KV存储保存每个会话的上下文快照和任务状态,事件日志库记录每次代理交互的完整链路。
2.2 代理身份建模与会话隔离
做到"代为交互"的第一步,是让每个代理拥有一个可验证、可引用、可追踪的身份。我们在Agent Registry中维护了四个关键字段:AgentID、能力声明、绑定关系和模型路由策略。
其中能力声明用的是类JSON Schema的结构,声明了这个代理能处理什么任务、有什么限制、期望什么输入格式。举个例子,一个"代码审查代理"的能力声明大概长这样:
{ "agent_id": "code-reviewer-01", "team_id": "platform-dev", "capabilities": { "tasks": ["code_review", "dependency_check", "style_check"], "input_schema": { "language": "string", "code_snippet": "string", "confidence_threshold": "number" }, "constraints": { "max_input_tokens": 8000, "allowed_tools": ["git_reader", "sast_scanner"], "network_access": false } }, "model_route": { "primary": "local-llm-70b", "fallback": "cloud-llm", "timeout_ms": 30000 } }这份声明的作用不仅仅是给人看的,编排引擎在路由时会解析它,判断"某个任务是否该分发给这个代理"。如果代理声明了style_check能力但没声明code_review,调度器就不会把代码审查任务发过去。这比一开始我们用的"关键词匹配路由"可靠得多。
会话隔离方面,我们设计了三级ID体系:TeamID + AgentID + SessionID。任何一条上下文记录都带有完整的三级标识,查询上下文时强制要求在同一个TeamID和AgentID范围内。最关键的是,每个会话在上一次交互结束后都会生成一条"会话摘要",下一条任务交接时只传递摘要和必要的原始数据引用,而不是把整个历史消息一股脑塞给下一个代理。这一步直接解决了前文提到的上下文漂移问题——B代理拿到的虽然不是完整历史,但摘要保留了关键决策和引用地址,需要细节时可以按引用ID到数据层取原始内容。
2.3 "代为交互"的完整流程设计
"代为交互"这个概念,落到协议层面我们采用了发布-订阅与请求-响应混合模式。简单来说,同步调用用请求-响应,异步任务用事件总线,两种模式共存于同一套编排引擎之上。
一个典型的代为交互流程是这样的:
- 用户小陈通过前端向自己的"需求分析代理"发起指令:把最近一周的客服退款问题整理成质量改进项。
- 需求分析代理把任务包装成一个任务包提交到编排引擎。任务包包含目标描述、上下文摘要、期望输出结构、最晚完成时间,以及最重要的——请求来源和执行权限。
- 编排引擎在Agent Registry里查询哪些代理的能力声明匹配"质量问题分析"和"退款流程"。
- 引擎将任务包投递到匹配的"客服数据代理"的消息队列中,并附上回调地址。
- 客服数据代理接收任务包,执行工具调用和模型分析,将结果按任务包要求的输出结构回传。
- 编排引擎做结果聚合与质量评分,如果多个代理参与了同一任务,会进入仲裁环节。
- 仲裁通过后,结果返回给需求分析代理,再由它生成最终报告给用户小陈。
整套流程中,用户小陈没有直接跟客服数据代理说过一句话,是需求分析代理"代为"完成了这次交互。这种模式的收益在于:用户只需要维护自己与主代理之间的对话关系,复杂任务在多代理之间的传递完全由编排引擎处理,用户的认知负担大幅降低。
3. 关键机制落地:调度、仲裁与工具安全
3.1 多AI调度的动态策略
调度器在系统里扮演的角色,有点像一个繁忙的交通控制中心。它不关心每辆车要去哪,但必须保证道路不堵塞、事故能及时处理、优先级任务能插队通行。
我们采用任务队列 + 权重调度 + 超时熔断的组合策略。每个任务进入队列时会被打上priority标签,分为P0、P1、P2三档。P0任务(如生产环境故障排查)可以越过前面排队中的P2任务优先执行,但不能抢占正在执行中的任务,避免频繁中断导致上下文丢失。
超时和重试的参数是我们在压测中逐步调出来的。最初我们给所有任务统一设置30秒超时、3次重试,结果并发一高就会出现"超时风暴":A代理请求B代理超时后重试,重试又占用了B代理的处理容量,反过来导致B代理对其他请求响应更慢,系统雪崩。
后来我们改成动态超时 + 指数退避重试策略。动态超时的核心公式很简单:超时时间 = 预估执行时长 × 2 + 固定缓冲。预估执行时长来自对该代理近20次同类任务的加权平均耗时,初始值为系统默认15秒。这样,一个通常耗时5秒的任务,超时给到16秒左右;一个通常耗时40秒的任务,超时给到90秒左右,不再一刀切。重试则采用1秒、2秒、4秒的指数退避,最大重试次数限制为2次。
在降级策略上,我们为每个代理配置了模型路由的primary和fallback。当主力模型连续错误率达到阈值时,调度器自动把流量切到备用模型。连备用模型也不可用时,会进一步降级到规则引擎——用预设的关键词规则做一个兜底应答,至少保证接口有返回,而不是直接报错。
调度器的简化核心逻辑如下,这段代码我们在生产环境跑了很长一段时间:
class Scheduler: def __init__(self, registry, metrics): self.registry = registry self.metrics = metrics def dispatch(self, task_package): candidates = self.registry.match(task_package.capability_query) for agent in candidates: if self._is_overloaded(agent.agent_id): continue timeout_ms = self._dynamic_timeout(agent, task_package) try: result = agent.submit(task_package, route={ "timeout_ms": timeout_ms, "retry_policy": {"backoff": [1, 2], "max_retries": 2} }) task_package.attach_result(agent.agent_id, result) return result except TimeoutError: self.metrics.incr("dispatch_timeout", agent.agent_id) continue raise NoAvailableAgent(task_package.task_id)3.2 仲裁机制:多AI意见冲突怎么办
多人多AI协同和单AI对话最不一样的地方,在于同一个任务可能有多个代理产出不同答案。比如同时让两个代理分别做漏洞扫描,一个报了5个高危,一个报了7个高危,听谁的?
我们的仲裁机制分三层。第一层是规则评分,每类任务有独立的评分规则。漏洞扫描任务会比较结果集合的包含关系、扫描时间窗口、规则库版本号,然后得出一个可信度分数。第二层是置信度加权,每个代理在回传结果时会附带一个置信度级别(高/中/低),调度器会将置信度作为权重纳入结果合并。第三层是人工兜底,当两个代理的结果冲突严重且置信度均较高时,任务进入"待人工复核"状态,由业务负责人介入。
这套三层仲裁机制的落地比想象中要慢,主要难点在于规则评分的定义需要跟业务团队反复对齐。我们一开始写得太复杂,规则冲突反而造成误判;后来简化为"每个任务类型只保留三条最关键的评分规则",误判率明显下降。经验是:仲裁规则宁可少而准,不要多而杂。
3.3 工具调用与权限隔离
代理协同过程中最危险也最容易被忽视的环节,是工具调用。当一个代理拥有了调用外部API、读写文件的权限,而另一个代理能驱动它,这条调用链的权限边界就很难划清。
我们的做法是工具注册制:所有外部操作必须先在Tool Registry登记,声明功能、入参、出参、所属权、风险等级。代理在调工具时,携带自己的AgentID和任务包中的allowed_tools白名单。编排引擎会在执行前校验调用者的权限范围,白名单里没有的工具,直接拒绝执行。
工具执行本身跑在受限沙箱里。沙箱使用独立子进程,限制内存上限、无网络白名单以外的出网权限、禁止写系统目录。每个工具调用的完整记录——谁调的、调用的哪个工具、用的是什么参数、返回了什么结果、耗时多少——全部落到审计日志中。
有一次同事反馈说某个代理在生成周报时,竟然附带读取了服务器历史命令记录。排查后发现是工具注册时把"读取日志目录"配置成了可递归访问父目录,代理的能力声明里又没有限制allowed_tools路径。后来我们给工具注册加了路径白名单机制,所有文件读取类工具必须声明允许访问的根目录,沙箱在外面做了一层字符串前缀校验,堵住了这个洞。
3.4 可观测性:让协同过程可复盘
多AI协同系统最忌讳的就是"黑盒"。A代理说"我把任务发给B了",B代理说"我没收到",这种扯皮我们一开始经常遇到。
为了让整个过程可复盘,我们做了三件事。第一是在全链路注入TraceID。每一个跨代理交互的任务,在创建时生成一个trace_id,每经过一个环节就生成一个span_id,父子关系通过parent_span_id关联。第二是建设事件流,把关键动作按照"代理A发起了任务X""任务X被分发到代理B""代理B开始执行""代理B执行完成""仲裁通过"等事件序列写入事件库。第三是日志采样策略——正常请求按百分之一比例采样,失败和超时请求全量记录。
这套体系上线后,排查问题的效率提升非常明显。之前定位一个跨代理问题可能需要翻几十个文件凑线索,现在只需要拿到一个trace_id,在事件流页面就能看到整条链路的时间轴和执行记录。
4. 实操过程与踩坑实录
4.1 从脚本堆到编排框架的重构过程
这个项目的第一个版本其实很简陋:用一个Python脚本定时轮询消息队列,收到任务就按关键词匹配找到对应的模型函数,直接调。跑了不到两周,痛点全暴露出来了:任务路由靠if-else硬编码,新增一个代理要改20多行代码;超时重试逻辑散落各处,根本没法统一治理;最要命的是没有任何审计,出了事只能靠"猜"。
重构的方向,是先做代理注册中心,再做编排引擎。我们把所有代理的调用统一改成"标准任务包"接口,每个代理只需要实现handle(task_package)方法,内部怎么处理都行,外部不用关心。这个接口抽象是整个重构里最值得的一笔投入,它把"调度逻辑"和"代理实现"彻底解耦,后续加入新模型、新代理的边际成本大大降低。
重构过程中我们犯过一个非常低级的错误:改造期间新旧两套系统并行运行,新系统用了新的AgentID命名规则,旧系统还在用老的ID,同一个代理在两边各有一个身份,导致调度器把任务重复分发给"两个"看起来不同的代理。后来花了一周做数据清洗,把所有ID统一映射到Agent Registry的主键上。这个教训很直接:协同系统的身份必须从第一天就集中管理,任何分散的ID体系都是后患。
4.2 典型问题排查速查表
| 问题现象 | 根因 | 排查方法 | 解决方案 |
|---|---|---|---|
| B代理回答里出现A代理会话中的内容 | 上下文存储的Key缺少会话维度,查询时跨了Session边界 | 查事件流中B代理的上下文读取记录,确认Key前缀 | 全量改用TeamID+AgentID+SessionID三级前缀,存储层加前缀校验 |
| 多个代理同一时段接连超时,任务堆积 | 超时设置一刀切,重试策略没有退避 | 看指标面板中"平均执行耗时"和"超时率"相关性 | 动态超时=近期均值×2+缓冲,重试改指数退避 |
| 仲裁结果明显错误,选择了一个低置信度的结果 | 仲裁规则中置信度权重占比过高,忽略了规则分数 | 回放仲裁日志,观察评分明细 | 调整规则分数与置信度的加权比例,增加人工复核状态机 |
| 代理执行工具调用写入了越权目录 | 工具注册时未声明根目录限制 | 审计日志中定位到write syscall | 沙箱增加路径前缀白名单,子进程去掉root权限 |
| 一个Token耗尽后,备用模型返回风格突变 | 降级到备用模型后,没有同步调整提示词模板 | 对比两条链路的模板加载记录 | 模型路由策略中绑定专属提示词模板 |
4.3 性能与成本优化的几个土办法
这个架构跑起来之后,模型成本成了一个新的问题。多个代理频繁交互,上下文传送是很费Token的。我们做了三个优化,基本把成本压到了一半以下。
第一个是上下文裁剪。每个代理在处理任务包时,不会把历史对话全量塞给模型,而是按Token预算裁剪,超过预算的部分自动生成摘要,摘要再塞进提示词。这需要在代理内部维护一个裁剪器组件。刚开始担心丢了细节会影响回答质量,跑了半个月对比下来,质量几乎没有明显下降,但Token消耗减少了差不多三分之二。
第二个是语义缓存。对于重复性较高的任务(比如定时生成状态报告、周期性数据汇总),我们增加了一层语义缓存——按任务类型和输入特征做相似度匹配,命中后直接复用上次的结果,不再消耗模型推理资源。这个优化对日报、周报类任务效果极其明显。
第三个是并发限流。我们在每个代理的网关层配置了QPS上限,限制单代理每秒最多发起的请求数。这个机制不仅能防止模型API配额被瞬间打爆,还能让系统在突发流量下保持平稳——虽然任务排队等待时间变长了,但总吞吐量没有暴跌,用户体验反而更稳定。
写在最后的经验
这套多人多AI协同的架构方案,从设计到稳定运行大概花了四个月。我个人的体会是,多AI协同本质上面临的挑战不是模型能力,而是组织协作问题——两个智能体之间怎么信任、怎么交接、怎么划清边界,跟两个同事之间配合工作并无二致。技术架构能解决的是通道问题,让信息无损、可控、可追溯地流动;而真正让整个系统顺畅运转的,其实是你给每个代理定义的那份能力声明,以及你为每次交接设定的那条规则。
最后分享一个非常小的实战技巧:给系统里的每个代理设置一个清晰命名的ID加一句能力摘要,比如agent.code-review-v1 | 负责代码审查、依赖检查、支持十分钟内返回。这句话不仅让人容易理解,还能在不改动代码的情况下,让编排引擎的路由匹配更准确少走弯路。我们后期路由准确率的提升,有一半功劳要归功于这些简单的命名规范。如果你正在规划类似的AI协同平台,建议先从规范和身份开始,再谈技术选型。