最近在帮团队搭一套多人多AI协同系统,第一道坎儿不是模型能力,而是"到底由谁来做交互"。我们最初的产品形态很简单:每个人一个AI代理助手,大家在同一套工作流里各干各的。但跑了一周之后就发现问题了——代理和代理之间根本不会好好说话,人也被无休止的确认消息淹没。标题里"基于AI代理代为交互"这个说法,意思就是让代理替人去完成协同过程中的信息传递、任务协调和决策支撑,而不是让代理继续扮演"对话框里的助手"。
这篇文章我想把"多人多AI协同系统"的架构研究思路完整写出来,包括我试图解决什么、怎么分层、代理之间怎么通信、冲突怎么仲裁、落地时踩了哪些坑。如果你最近也在折腾多智能体系统的架构设计,或者准备让AI代理真正介入团队协作流程,这篇应该能帮你省不少试错时间。
1. 为什么"代为交互"是多人协同里最难啃的骨头
1.1 传统协同工具的信息过载
先说一个让我很头疼的场景。团队五个人,项目群里有需求变更、技术方案、测试报告、客户反馈,一天能刷几百条。每个人都要花大量时间去做同一件事:把散落在各处的信息拼起来,搞清楚"现在到底进行到哪了"。更麻烦的是,上下文是断裂的。产品经理在群聊里发了一条需求变更,开发可能三天后才看到,而AI助手能做的只是把这条消息总结得更短,并没有真正解决"信息该往哪走、谁该关注什么"的问题。
这里的关键不是"信息太多",而是"信息与决策者的连接关系"没有被建模。传统协同工具把信息仓库做得很完善,但它默认"人会自己去看"。当参与者和信息量同时增长,人根本看不过来,协同效率就开始崩塌。
1.2 代理"代交"的三个层次
我后来把"代为交互"拆成了三个层次来理解,这样架构设计才有抓手:
- 第一层:信息代收代发。代理帮你盯着消息、筛选优先级、把相关变更转给对应的代理。这层只做路由,不做决策,最容易落地。
- 第二层:任务代接代转。代理能理解任务的状态,把需要他人配合的动作转交出去,比如"开发代理"把测试请求发给"测试代理",并跟踪结果。
- 第三层:决策代议代裁。代理在规则允许范围内,代表你参与讨论、谈判资源、甚至拍板。这层最难,因为你要面对信任和责任问题。
大多数团队做多AI协同,死在了第一层往第二层过渡的地方。因为一旦代理要"代接"任务,就必须有跨代理的状态协议,而这是传统AI应用没考虑过的事情。
1.3 我的实验场景:一个需求变更的跨代理流转
我用一个具体案例来说明这个区别。某次需求评审会上,产品经理的代理收到了变更指令,它生成了一份变更摘要,直接把消息推给了开发代理和测试代理。开发代理识别出涉及两个模块,自动生成工作量评估,回传给产品代理;测试代理则在开发确认后创建回归测试计划。
整个过程中,产品经理只需要在最后审批"变更是否上线",其他环节全是代理之间完成的。这个实验让我意识到,多人多AI协同系统的核心不是"每个人都有一个更聪明的助手",而是把人与人之间的交互协议——通知、确认、转办、催办、裁决——全部抽象成代理间的通信协议。
2. 把协同职责拆进五层架构:每一层都在解决什么问题
如果只做一个Demo,不需要分层,脚本编排就能跑通。但一旦要支撑真实业务流程,分层是必须的。我最后用的架构是五层,从下到上依次是:基础设施层、数据与记忆层、模型接入层、代理编排层、交互呈现层。
2.1 五层架构的职责边界
| 层级 | 核心职责 | 关键组件 |
|---|---|---|
| 交互呈现层 | 多媒体交互、消息通知、人工介入入口 | Web客户端、IM机器人、语音/白板接口 |
| 代理编排层 | 任务状态机、代理间路由、策略仲裁 | 编排引擎(LangGraph)、规则引擎 |
| 模型接入层 | 大模型统一网关、云+本地模型路由 | OpenAI兼容网关、Ollama/vLLM接入 |
| 数据与记忆层 | 短期上下文、任务状态、长期知识、审计日志 | Redis、PostgreSQL、向量数据库 |
| 基础设施层 | 通信总线、分布式部署、可观测性 | NATS/Kafka、Kubernetes、OpenTelemetry |
这张表是整个架构的骨架。我实际开发时的顺序恰好相反,先从基础设施层的通信总线开始,因为代理之间要对话,必须先把"路"修通。
2.2 交互呈现层:多媒体交互不是简单聊天窗口
交互层是人和系统接触的边界,也是"代为交互"安全感的第一来源。如果代理替人做了决定,但人看不到推理过程,信任感会迅速崩塌。所以这层不只是聊天界面,还包含:
- 操作回放与决策解释面板:每次代理动作都带"为什么这么做"的说明。
- 消息提醒策略:区分"需要你马上回应"和"记录一下即可",避免代理把人也卷入消息风暴。
- 多媒体接入:文本、语音、白板、文件批注要统一进消息协议。我们在白板标注上吃过亏——代理能读文字,但读到一张图画圈时,它需要转成结构化标注才能继续流转。
我的建议是,交互层设计一定要遵循一个原则:代理能处理的自动处理,不能处理的优雅升级给人。而不是反过来,把所有信息都推给人看。
2.3 代理编排层:状态机是协同的地基
代理编排层就是整个系统的大脑。我最初以为要做一个通用的"多Agent框架",后来发现最稳的思路是把它做成一个任务状态机,每个代理围绕任务状态来驱动。
一个任务流转的基本状态包括:
- pending:等待处理
- processing:代理正在处理
- waiting_external:等待其他代理或人
- negotiating:多个代理对结论有分歧,需要仲裁
- done:完成
- rejected:被驳回
以需求变更为例,产品代理创建任务后,状态变成processing;随后调开发代理,任务转为waiting_external;开发代理返回结果后,如果产品代理发现工作量超出预期,可以发起negotiating;最终达成一致后变为done。这套状态机用LangGraph实现非常合适,节点就是各种代理动作,边就是状态迁移。
我在代码里是这样组织的(伪代码):
graph = StateGraph(TaskState) graph.add_node("product_agent", product_agent_handler) graph.add_node("dev_agent", dev_agent_handler) graph.add_node("test_agent", test_agent_handler) graph.add_node("human_approval", human_approval_node) graph.add_edge("product_agent", "dev_agent", condition=is_requirement_change) graph.add_edge("dev_agent", "test_agent", condition=dev_finished) graph.add_edge("test_agent", "human_approval", condition=needs_approval)这里有个关键点:不是所有路径都由模型决定,很多路径是规则写死的。只有这样才能保证可控性。模型可以生成摘要、评估工作量、判断冲突等级,但它不能决定任务流去哪里,任务流由编排引擎决定。
2.4 模型接入层:云端模型与本地模型的混合路由
模型接入层解决的是"什么样的任务交给什么样的模型"。
大模型在各个代理间被共享调用,如果不做统一网关,会出现一个非常现实的问题:多个代理各自直连模型服务,来回切换上下文,成本失控。我做的模型网关支持两种路由策略:
- 按敏感度路由:涉及客户敏感数据、内部财务信息的内容,强制走本地模型,数据不出域;通用的总结、润色、创意文本走云端模型。
- 按延迟敏感度路由:实时决策类任务走低延迟本地小模型,复杂度高的深度推理走大参数云端模型。
这里我要强调一下本地模型的价值,热度很高的"ai代理助手加本地模型"这个方向,不是赶时髦。实测下来,用Ollama部署一套7B到14B的量化模型,处理日常的文本分类、意图识别、信息抽取,延迟能压到500毫秒以内,而且完全不受云端限流影响。多代理场景中会有大量"轻量级理解"请求,如果每个请求都坐等云端大模型,整个系统的吞吐会被按在地板上摩擦。
网关还要做一层协议统一。无论底层是OpenAI、Claude还是本地模型,对外暴露统一的接口,代理编排层不关心模型是谁。
2.5 数据与记忆层:跨代理的记忆不共享,协同就是空的
数据与记忆层包含三类存储:
- 短期上下文:一段对话周期内的消息,用Redis存,带TTL。
- 工作记忆:任务状态、审批流程、代理间的待办关系,用PostgreSQL持久化,支持事务。
- 长期记忆:从历史交互中沉淀的项目知识、团队偏好、用户画像,用向量数据库存。
这三类存储要严格区分。我见过一个项目把所有历史对话一股脑塞进上下文,结果token爆炸,每一个请求都慢得像爬。更合理的做法是:代理只携带与当前任务直接相关的短期上下文,其他信息通过检索获取。
数据层的另一个重点是记忆的归属。每个用户的代理有私有记忆,团队层有共享记忆,二者必须隔离。否则就会出现"你的代理把我之前的隐私对话当成了团队参考"这种社死级事故。
3. 代理间通信与状态同步:最容易翻车的地方
3.1 通信选型:消息队列不是可选项,是底线
代理之间交互采用什么通信方式,是我最先拍板的决定。一开始团队有同学说直接用HTTP调用不就行了吗——代理A调代理B的接口,拿到结果就返回。听起来简单,但真实跑起来全是坑。
HTTP同步调用的核心问题是强耦合和重试地狱。代理A调代理B,B卡住了,A也得卡住;B在重试,C也在重试,整个链路瞬间毛线团。多人多AI系统里代理数量一旦超过两三个,同步调用就是灾难。
我的选择是引入消息总线,用的是NATS,轻量、够快、部署简单。核心通信模式是异步的"发布-订阅"加"请求-应答"混合:
- 发布-订阅:代理广播任务状态变更、通知事件。
- 请求-应答:代理向另一个代理发起有返回的协作请求。
Kafka也可以,但如果是中小规模团队,Kafka的运维成本不低。NATS JetStream在持久化和消息回溯上已经够用。真正的核心不是选哪个中间件,而是建立统一的消息协议。
我定义的核心消息结构长这样(伪代码):
{ "protocol_version": "1.0", "message_id": "uuid-xxx", "sender": "product_agent", "recipient": "dev_agent", "task_id": "task-001", "msg_type": "request_review", "payload": { "requirement_id": "R-012", "change_summary": "...", "priority": "high" }, "created_at": 1719900000, "trace_id": "trace-abc" }trace_id是贯穿全链路的关键,没有它,分布式排查问题会累到怀疑人生。
3.2 状态同步:上下文要传增量,不要传全量
代理之间除了消息,还要同步状态。这块我踩过一次大坑。最初的设计是,代理B在收到任务时,代理A把"所有已知信息"打包发过去。结果每个任务的消息体积随流程推进线性膨胀,到后面一个简单的确认操作都要带几十KB上下文,模型输入成本飙升。
正确的做法是状态同步加增量上下文:
- 每次传递只携带"相对上一个版本的变化"。
- 新代理启动时,先向状态服务拉取任务快照,再订阅增量事件。
- 所有状态变更都带版本号,用乐观锁防止覆盖。
比如开发代理更新了任务状态为"开发完成,耗时2人日",这个变更本身就是增量信息,代理链路上只需要广播这一条JSON。想要全量视图?去PostgreSQL里查,别在消息里带。
3.3 消息风暴与代理死锁
通信架构搭好之后,还会有两个更隐蔽的问题。
第一个是消息风暴。我实测过,如果两个代理在协商一个未定义清晰的协议,比如"你觉得呢""我觉得可以""那你觉得呢",双方会无限互发消息。这不是模型的问题,是协议没有终止条件。解决方法是给消息链路加最大跳数。任何一个任务的消息流转深度超过预设阈值(我常用6跳),就强制转人工。
第二个是代理死锁。开发代理在等测试代理的确认,测试代理在等开发代理的测试报告,两边互相等,人也不知道。这种情况在分布式系统里叫死锁,处理方式也很经典:超时回退加人工唤醒。每个waiting状态都设置超时时间,超时后自动升级为"需要人处理"。
4. 仲裁、人机回权与安全边界:代理能替你拍板到什么程度
4.1 冲突类型与仲裁策略
多代理协同一旦进入真实业务,冲突是必然的。我遇到的冲突分两种:
- 资源冲突:两个代理同时要调用同一个外部工具。比如同一个数据库写连接,或者同一个执行任务的worker。这种冲突靠分布式锁解决,制定好锁的粒度就行。
- 决策冲突:产品代理说这个需求要做,开发代理说成本太高不建议。这是最棘手的。
我用过一套三层仲裁策略:
- 规则优先:如果冲突场景符合预设规则(比如安全问题一票否决),直接按规则执行。
- 投票协商:无明确规则时,让相关代理投一次票,各自附理由,系统汇总。
- 升级给人:如果投票仍没有结论,或者冲突影响面较大,直接升级到人。
这里有一个原则:升级给人的门槛要低,不要怕打扰人。代理协同的目标是减少低价值沟通,而不是在高风险决策上替人做主。
4.2 人在回路的notify、approve、override三级控制
我给每个代理配了三种控制级别,这是整个系统安全感的来源:
- notify级别:代理自主决策,但每个决策都记录日志,并推送摘要给人。适用于低风险操作,比如会议纪要整理、任务优先级建议。
- approve级别:代理可以提出方案,但执行必须等人工确认。适用于高风险或高成本操作,比如对外发送正式邮件、修改生产环境配置、批量删除数据。
- override级别:人可以直接接管代理,手动修改任务状态或流程走向。当代理卡死或乱来,人可以一键切换成"手动模式"。
实测中,最容易翻车的是approve边界划定。划得太宽,人不停点确认,协同效率为零;划得太窄,代理悄悄干了一件不该干的事。我的经验是划边界时多问一句:"这个动作如果错了,修复成本高不高?" 修复成本高的一律要approve。
4.3 权限即边界,代理权限永远不要超过主人
安全设计上,我的核心原则是:代理的权限永远不要超过主人。
每个代理携带一个权限令牌,令牌的权限集继承自所属用户,并且可以细化到功能模块。关键词之一是"最小化授权":开发代理只能读代码仓库,不能推送代码;产品代理只能读需求文档,不能访问财务数据。另一个是"时效性授权":某些权限只在任务周期内有效,任务结束自动撤销。
这一块没有太多可讨价还价的余地。做多人多AI系统,权限模型的复杂度会随人数和代理数线性上升,越早设计越省钱。
5. 从一个人两个代理开始:落地路径与踩坑报告
5.1 三个让我崩溃的坑
多智能体系统的坑,有一部分是分布式系统的通病,有一部分是AI特有的。我按"崩溃程度"排序,最值得一提的三个:
第一个坑是幻觉在代理链路上的放大。单代理的幻觉还只是自己答错,多代理链路上的幻觉是灾难式的。代理A在总结时说"需求已完成"(其实没完成),代理B直接引用这个结论往下走,后面所有环节都建立在一个不存在的事实上。解决办法是强制"事实回链":每个关键结论必须附引用来源编号,后续代理如果要引用,必须追溯到原始记录,源头没有可靠来源的,标记为待确认。
第二个坑是上下文膨胀。我一开始把"让代理多带点上下文"当作提高准确率的手段,结果每个请求慢得离谱。后来我才接受一个现实:模型的能力再强,也架不住在几十万token里翻找关键信息。现在我的做法是"摘要加召回"双通道:先给代理一个全局摘要,关键细节按需从向量库检索,检索不到才追加上下文。
第三个坑是框架选型锁死。团队一开始用了一个非常"高级"的多代理框架,后期发现很多底层行为不可控,想改又受限于框架封装。我的建议是:如果是做生产系统,优先选择可编程性强的编排框架(我选了LangGraph),框架只提供状态机骨架,决策逻辑全部自己写。看起来工作量多一点,但排障时有全栈的控制力,值。
5.2 中小规模团队的组件清单
按团队规模不同,我给出两套可以直接抄的组件组合:
- 小规模(5人以内,代理数小于10):PostgreSQL保存一切持久状态,Redis做短期缓存和分布式锁,NATS做消息总线,编排层用LangGraph,模型网关用自研轻量服务(或者直接接OpenAI兼容网关),UI端用现成IM机器人加Web面板。
- 中等规模(20人左右,代理数几十):把NATS升级为Kafka,引入完整向量数据库(比如Milvus或qdrant),加独立认证服务,所有代理动作走审计日志,再加一套OpenTelemetry链路追踪。
这里有一条经验:架构上预留升级路径,但实现上不要一上来就上重武器。先用一台机器跑通全流程,等真的发生性能瓶颈再扩容,比一开始就铺Kafka集群划算得多。
5.3 下一步:从办公协同到具身场景
多代理协同的架构不会只在聊天和文档场景止步。最近我比较关注的是"openclaw+ros为你的ai代理"这类方向——把AI代理的能力从软件交互延伸到硬件控制。本质架构没有变,依然是代理编排、消息通信、控制回权三件套,只是交互层变成传感器数据、机器人控制指令。
另外一个趋势是边缘部署。像"u盘安装麒麟系统arm架构"这种硬件适配需求,说明很多团队已经在考虑把整个系统跑到工控机或边缘设备上。本地模型加轻量消息总线,在ARM架构上完全跑得起来,资源占用可用性都不错。
我现在对这个方向的判断是:多处落地的通用组件还没有定型,但核心架构范式已经出现了。消息协议、状态机、权限模型、人机回权这四件事,无论将来底层模型怎么进化,都是绕不开的骨架。
写到这里,我更想说的是:架构图人人都能画,真正区分设计好坏的是边界的取舍——哪些交给代理自主决策,哪些必须升级给人;哪些上下文要传递,哪些要裁剪;哪些消息要实时等,哪些异步就行。这些决策没有标准答案,只能靠小步实验一点点调出来。
如果你正在搭这样的系统,我只有一个建议:别一上来就是五层架构、十几个代理。先让一个流程完整跑通,让两个代理真实协作完成一个任务,把通信、状态、回权这条链路走顺。等这条链路不再出错,再慢慢往里面加人、加代理、加场景。多代理系统的复杂度是指数增长的,但起步永远可以是从"一个人两个代理"开始。