多 Agent 之间如何通信?Supervisor 间接通信 直连 Handoff 全解析
配套代码:LangGraph Typescript,包含 Supervisor 间接通信(带轮次熔断兜底)+ LangGraph 实现 Handoff(类 Swarm 直连)两套完整 Demo
前言
做多智能体(Multi-Agent)开发时,90% 的开发者都会卡在同一个核心问题:多个子 Agent 之间到底怎么交互、传参、协作?
很多新手误区:
- 以为子 Agent 可以像函数一样直接互相调用
- 混淆 Supervisor 架构和 Swarm 架构的通信差异
- 不知道什么场景需要 Agent 互通、什么场景禁止互通
- 踩坑国产模型适配问题(Swarm 并非全模型通用)
本文基于 LangGraph(TS/JS)、OpenAI Swarm 生产实践,彻底讲透多 Agent 通信的所有范式、落地场景、优劣对比和工程最佳实践,并附带完整可运行代码。
一、核心定论:多 Agent 只有两种通信方式
所有多 Agent 框架,无论 LangGraph、OpenAI Swarm、AutoGen,底层只分为两类通信模型:
- 间接通信(中心调度模式)
子 Agent 永远不能直接互相对话,所有交互经过中心节点转发,代表架构:Supervisor 主管架构。 - 直接通信(自主交接模式)
子 Agent 可自主判断、主动将任务交接给其他 Agent,无需中心节点,代表架构:Swarm / Handoff 架构。
没有第三种模式,所有复杂多 Agent 协作都是这两种模式的组合。
二、模式一:Supervisor 间接通信(工业生产首选)
1. 通信原理
这是 LangGraph 默认的标准架构,也是企业级项目最常用的方案。
链路:用户 → Supervisor → 子 Agent → 写入共享 State → Supervisor 路由 → 下一个子 Agent
核心规则:
- 所有子 Agent 互相隔离,无直接调用、无直接消息推送
- 所有 Agent 的输出、中间结果,统一存入 全局共享 State
- Supervisor(主管节点)统一读取状态、决策下一步路由、转发上下文
- 子 Agent 通过读取共享 State,感知其他 Agent 的工作结果,实现「间接通信」
2. 典型落地场景(必须间接通信)
✅ 场景 1:多专家评审、迭代修改
起草 Agent 写方案 → 风控 Agent 评审 → 不通过再返回起草 Agent 修改,多轮迭代收口。
✅ 场景 2:RAG 多路召回融合
向量召回 Agent、关键词召回 Agent 并行执行,结果统一汇总到 Supervisor 做去重、打分、融合。
✅ 场景 3:分层任务拆解、流水线协作
需求拆解、内容生成、格式校验、结果润色等流水线节点串行协作。
3. 关键工程能力:轮次熔断与兜底(生产必备)
多轮迭代通信最大隐患:Agent 互相拉扯、无限循环、无法收敛。
标准解决方案:
- State 中增加
step计数器、maxRound最大轮次限制 - Supervisor 优先判断轮次,达到上限触发熔断
- 进入兜底节点,强制收口,三种兜底策略:
- 折中输出(推荐):整合所有历史结果,生成最终内容,标注未解决风险
- 失败终止:合规场景直接返回任务未完成,拒绝输出半成品
- 主管仲裁:Supervisor 统一汇总结果、强行拍板收尾
4. 完整 TS 代码:Supervisor + 间接通信 + 轮次熔断兜底
业务示例:起草 Agent + 评审 Agent,互相读取对方产出,Supervisor 做调度,超过最大轮次触发兜底
安装依赖
npm install @langchain/langgraph @langchain/core @langchain/openai
// supervisor-multi-agent.ts
import {
StateGraph,
Annotation,
START,
END,
} from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage } from "@langchain/core/messages";
// ======================
// 1. 定义全局共享State(子Agent通信载体)
// ======================
const GraphAnnotation = Annotation.Root({
messages: Annotation<Array<HumanMessage>>({
reducer: (prev, next) => prev.concat(next),
}),
// 各个子agent产出,用来互相读取,实现间接通信
agentOutputs: Annotation<Record<string, string>>({
reducer: (prev, next) => ({ ...prev, ...next }),
}),
nextAgent: Annotation<string | null>(),
// 迭代轮次计数器
step: Annotation<number>({
reducer: (_prev) => _prev + 1,
default: () => 0
}),
maxRound: Annotation<number>({
default: () => 4
}),
});
type GraphState = typeof GraphAnnotation.State;
// ======================
// 2. LLM实例,兼容国内模型(通义千问 / DeepSeek / GLM均可)
// ======================
const model = new ChatOpenAI({
apiKey: process.env.LLM_API_KEY,
model: "qwen-max",
configuration: {
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
},
});
// ======================
// 3. 子Agent节点
// draftAgent:方案撰写,可以读取reviewAgent上一轮评审意见
// ======================
async function draftAgent(state: GraphState): Promise<Partial<GraphState>> {
const prevReview = state.agentOutputs.reviewAgent ?? "暂无评审意见";
const prompt = `
你是方案撰写专家。
上一轮评审意见:${prevReview}
根据评审意见输出退款业务方案,只输出方案正文,不要多余描述。
`;
const res = await model.invoke([new HumanMessage(prompt)]);
console.log(`[DraftAgent] 本轮输出:`, res.content);
return {
agentOutputs: {
draftAgent: res.content as string,
},
messages: [res],
};
}
// reviewAgent:评审专家,读取draftAgent的方案输出评审意见
async function reviewAgent(state: GraphState): Promise<Partial<GraphState>> {
const draft = state.agentOutputs.draftAgent ?? "暂无方案";
const prompt = `
你是风控评审专家。
待评审方案:${draft}
给出评审意见。如果方案合格,直接输出【PASS】;不合格写明漏洞。
`;
const res = await model.invoke([new HumanMessage(prompt)]);
console.log(`[ReviewAgent] 本轮评审:`, res.content);
return {
agentOutputs: {
reviewAgent: res.content as string,
},
messages: [res],
};
}
// ======================
// 兜底熔断节点:达到最大轮次,强制收口
// ======================
async function fallbackTerminateAgent(state: GraphState): Promise<Partial<GraphState>> {
const allOutput = JSON.stringify(state.agentOutputs, null, 2);
const prompt = `
任务已达到最大迭代轮次,多方协商没有达成一致。
整合下面所有Agent历史产出,生成一份最终交付文档,**明确标记遗留风险和未解决争议**。
历史输出:
${allOutput}
`;
const res = await model.invoke([new HumanMessage(prompt)]);
console.log(`[Fallback] 轮次耗尽,兜底生成结果`);
return {
messages: [res],
agentOutputs: {
fallbackResult: res.content as string
}
}
}
// ======================
// 4. Supervisor主管节点:路由 + 熔断判断核心
// ======================
async function supervisor(state: GraphState): Promise<Partial<GraphState>> {
const { step, maxRound } = state;
const draft = state.agentOutputs.draftAgent;
const review = state.agentOutputs.reviewAgent;
// 熔断判断:达到最大迭代轮次,进入兜底
if (step >= maxRound) {
console.log(`[Supervisor] 已到达最大轮次${maxRound},触发熔断`);
return { nextAgent: "fallback_terminate" }
}
let nextAgent: string;
if (!draft) {
nextAgent = "draftAgent";
} else if (!review) {
nextAgent = "reviewAgent";
} else if (!review.includes("【PASS】")) {
// 评审不通过,继续交给draftAgent修改,实现多轮间接通信
nextAgent = "draftAgent";
} else {
nextAgent = END;
}
console.log(`[Supervisor] step=${step}, 路由到:${nextAgent}`);
return { nextAgent };
}
// ======================
// 5. 构建LangGraph图
// ======================
const builder = new StateGraph(GraphAnnotation)
.addNode("supervisor", supervisor)
.addNode("draftAgent", draftAgent)
.addNode("reviewAgent", reviewAgent)
.addNode("fallback_terminate", fallbackTerminateAgent)
// 条件路由:根据nextAgent跳转
.addConditionalEdges("supervisor", (state) => state.nextAgent, {
draftAgent: "draftAgent",
reviewAgent: "reviewAgent",
fallback_terminate: "fallback_terminate",
[END]: END,
})
// 子Agent执行完成,全部回到主管节点
.addEdge("draftAgent", "supervisor")
.addEdge("reviewAgent", "supervisor")
.addEdge("fallback_terminate", END)
.addEdge(START, "supervisor");
export const app = builder.compile();
// ======================
// 6. 入口调用
// ======================
(async () => {
const result = await app.invoke({
messages: [new HumanMessage("写一份客户退款业务方案")],
agentOutputs: {},
nextAgent: null,
step: 0,
maxRound: 4
});
console.log("\n===== 最终全部Agent产出 =====");
console.log(result.agentOutputs);
})();
运行命令:
# 设置环境变量
export LLM_API_KEY="sk-xxx"
tsx supervisor-multi-agent.ts
5. 优缺点总结
✅ 优点:
- 极高可控性:路由、轮次、权限全可控,可防止死循环
- 适配所有模型:对国产大模型友好,不依赖强 Function Call 能力
- 可观测可审计:全链路 State 留存,日志、调试、复盘简单
- 支持串行、并行、条件分支所有复杂流程
❌ 缺点:
- 多轮协商场景路由逻辑稍重
- 需要手动维护共享 State 数据结构
三、模式二:Swarm 直接通信(Handoff 自主交接)
1. 通信原理
代表框架:OpenAI Swarm(实验版)、新版 OpenAI Agents SDK。
核心逻辑:取消中心节点,子 Agent 自主判断,通过工具调用直接将任务交接给其他 Agent。
链路:AgentA → 自主调用转移工具 → 直接交给 AgentB 执行
无需中间人转发,Agent 之间可自由对话、多轮辩论、按需协作。
2. 适用场景
- 多方 Agent 辩论、头脑风暴、协商共识
- Agent 执行中按需主动查询其他 Agent 数据
- 开放式对话、灵活任务接力,无固定流水线
3. 关键问题:Swarm 能不能用国内模型?
全网最大误区纠正:
Swarm 不强制绑定 OpenAI 模型,但极度依赖「稳定的 Function Call」。
详细结论:
- ✅ 协议兼容即可接入:所有支持 OpenAI 兼容接口的国内模型(通义、DeepSeek、GLM 等)均可接入
- ❌ 国内模型普遍适配翻车:Swarm 的 Handoff 完全靠模型主动输出工具调用,多数国产模型指令遵循弱,容易不触发转移、乱输出、直接自由对话
- ❌ 无 TS 原生支持:原版 Swarm 只有 Python 版本,TS 项目无法直接使用
- ⚠️ 项目已停止维护:OpenAI 已归档 Swarm,继任者为 OpenAI Agents SDK
4. Python 原版 Swarm 极简示例(仅用于演示,生产不推荐)
# swarm_demo.py
from swarm import Swarm, Agent
from openai import OpenAI
# 替换为国内兼容接口
client = OpenAI(
api_key="你的通义千问api-key",
base_url="https://dashscope.aliyuncs.com/compatible-mode/v1",
)
# 评审Agent
review_agent = Agent(
name="review_agent",
instructions="你是风控评审专家,方案有问题就调用transfer_to_drafter返回修改,没问题直接输出PASS",
model="qwen-max"
)
# 起草Agent
draft_agent = Agent(
name="draft_agent",
instructions="你是方案撰写专家,写完交给评审;收到评审意见就修改,调用transfer_to_reviewer交接",
functions=[
lambda: review_agent
],
model="qwen-max"
)
swarm = Swarm(client=client)
resp = swarm.run(agent=draft_agent, messages=[{"role":"user","content":"写退款业务方案"}])
print(resp.messages[-1]["content"])
5. 优缺点总结
✅ 优点:
- 多 Agent 自然对话、协商体验极佳
- 无需复杂路由逻辑,代码简洁
❌ 缺点:
- 不可控:极易出现无限循环、越权执行
- 对模型能力要求极高,国产模型适配成本大
- 链路追踪弱,生产调试困难
- 无原生 TS 支持
四、两种通信架构全方位对比
表格
| 维度 | Supervisor 间接通信 | Swarm Handoff 直接通信 |
|---|---|---|
| 通信方式 | 中心转发、状态共享、无直连 | Agent 自主交接、直接互传任务 |
| 模型适配性 | 所有大模型(国产友好) | 依赖强 Function Call,国产模型易翻车 |
| 可控性 | 极强,支持熔断、限流、兜底 | 弱,易死循环、不可预测 |
| 可观测性 | 全 State 留存,易调试复盘 | 链路混乱,排查困难 |
| 技术栈 | TS/Python 全支持 | 仅 Python,无 TS 原生版本 |
| 生产适用性 | 企业生产首选 | 仅适合 Demo、创意场景,不建议上生产 |
五、落地选型终极判断标准
1. 选 Supervisor 间接通信(90% 业务场景)
满足任意一条即可选择:
- 需要稳定、可审计、可兜底的生产能力
- 使用国产大模型部署
- RAG、文档生成、任务拆解、流水线协作
- 需要防死循环、轮次熔断、异常兜底
- TS 技术栈项目
2. 选 Swarm 直连通信(仅小众场景)
同时满足所有条件再选择:
- Python 项目、仅做体验 / 演示
- 使用 GPT 系列强遵循模型
- 需要多 Agent 自由辩论、多轮协商
- 不要求严格可控、无强业务合规要求
六、高阶补充:TS 基于 LangGraph 实现类 Swarm Handoff 直连通信
TS 没有原生 Swarm,我们可以自己在 LangGraph 上实现 Handoff,子 Agent 自主决定交接给谁,同时保留轮次熔断兜底,兼顾灵活性和稳定性。
核心逻辑:子 Agent 返回
transferTo字段,图根据该字段自动路由,不需要固定 Supervisor 做业务判断。
// langgraph-handoff.ts
import {
StateGraph,
Annotation,
START,
END,
} from "@langchain/langgraph";
import { ChatOpenAI } from "@langchain/openai";
import { HumanMessage } from "@langchain/core/messages";
const GraphAnnotation = Annotation.Root({
messages: Annotation<HumanMessage[]>({
reducer: (prev, next) => prev.concat(next),
}),
transferTo: Annotation<string | null>(),
step: Annotation<number>({
reducer: (p) => p + 1,
default: () => 0
}),
maxRound: Annotation<number>({
default: () => 4
})
});
type GraphState = typeof GraphAnnotation.State;
const model = new ChatOpenAI({
apiKey: process.env.LLM_API_KEY,
model: "qwen-max",
configuration: {
baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
},
});
// 起草Agent,自主决定是否交接给评审
async function draftAgent(state: GraphState): Promise<Partial<GraphState>> {
const prompt = `你是方案起草专家。
输出JSON,格式必须是:{"content":"方案内容","transferTo":"reviewAgent | null"}
transferTo如果需要交给评审专家就填reviewAgent,任务完成填null。
用户需求:${state.messages.at(-1)?.content}`;
const res = await model.invoke([new HumanMessage(prompt)]);
const json = JSON.parse(res.content as string);
console.log("[DraftAgent] 输出,转移到:", json.transferTo);
return {
messages: [new HumanMessage(json.content)],
transferTo: json.transferTo ?? null
};
}
// 评审Agent,自主决定是否交回起草Agent修改
async function reviewAgent(state: GraphState): Promise<Partial<GraphState>> {
const prompt = `你是风控评审专家。
输出JSON,格式必须是:{"content":"评审意见","transferTo":"draftAgent | null"}
方案不合格就transferTo=draftAgent;合格transferTo=null。
待评审内容:${state.messages.at(-1)?.content}`;
const res = await model.invoke([new HumanMessage(prompt)]);
const json = JSON.parse(res.content as string);
console.log("[ReviewAgent] 输出,转移到:", json.transferTo);
return {
messages: [new HumanMessage(json.content)],
transferTo: json.transferTo ?? null
};
}
// 路由函数,增加最大轮次熔断
function routeNode(state: GraphState) {
if (state.step >= state.maxRound) {
console.log("[Handoff] 轮次超限,终止");
return END;
}
return state.transferTo ?? END;
}
const builder = new StateGraph(GraphAnnotation)
.addNode("draftAgent", draftAgent)
.addNode("reviewAgent", reviewAgent)
.addConditionalEdges("draftAgent", routeNode, {
reviewAgent: "reviewAgent",
[END]: END
})
.addConditionalEdges("reviewAgent", routeNode, {
draftAgent: "draftAgent",
[END]: END
})
.addEdge(START, "draftAgent");
export const handoffApp = builder.compile();
// 执行入口
(async () => {
const result = await handoffApp.invoke({
messages: [new HumanMessage("写退款业务方案")],
transferTo: null,
step:0,
maxRound:4
});
console.log("==== Handoff最终消息 ====")
console.log(result.messages);
})();
这个就是 TS 版的类 Swarm:Agent 自主决定交接对象,但是我们依然保留 step/maxRound 熔断,避免无限循环。
缺点:对模型 JSON 结构化输出能力有要求,国产模型需要调优 prompt 保证输出格式稳定。
七、总结
- 多 Agent 通信只有 中心间接通信 和 自主直连通信 两种范式
- 生产优先 Supervisor:稳定、可控、适配国产模型、支持熔断兜底、TS 友好
- Swarm 仅适合 Demo:依赖强模型能力、国产适配差、无 TS 支持、不可控
- 所有多轮 Agent 协作,必须配置 最大轮次熔断 + 兜底收口,杜绝无限循环
- TS 项目无需纠结 Swarm,LangGraph 自定义路由可平替所有直连能力

浙公网安备 33010602011771号