很多同学第一次搭 Swarm 系统,会这样设计:用一个总 Agent 做调度,接到需求就派发给对应子 Agent,子 Agent 干完就把结果返回给总 Agent,总 Agent 再决定下一步。
结果上线后发现:
- 总 Agent 变成了瓶颈——每次都得经过它,延迟高、token 消耗大
- Agent 之间的对话上下文丢了——子 Agent 不知道之前发生了什么
- 用户多轮追问时频繁"失忆"——“我刚才说要订上海的酒店,你怎么忘了?”
这些坑的根源,都是没搞懂 Swarm 里的 handoff 到底在做什么。
01 Swarm 的本质:接力赛,不是派单
Swarm 的名字来自蜂群行为——没有中央控制,每只蜂根据感知到的局部信息自主决策。映射到 Multi-Agent,就是:每个 Agent 自己决定"任务完成了,该交给谁继续"。
对比 Supervisor 模式:
| 维度 | Supervisor 模式 | Swarm 模式 |
|---|---|---|
| 控制权位置 | 中央 Supervisor | 当前活跃 Agent |
| 路由决策者 | Supervisor LLM | 当前 Agent 的 handoff 工具 |
| 上下文传递 | 通过 Supervisor 中转 | 共享 State 直接传递 |
| 适合场景 | 任务需要全局视角协调 | 任务可明确切割给专家 |
| token 消耗 | 高(每步都过 Supervisor) | 低(Agent 直接移交) |
整个 Swarm 系统只有三个核心角色:
- SwarmState:共享状态,
active_agent字段就是接力棒,谁持有谁执行 - Active Agent Router:挂在 START 后,读
active_agent决定去哪个 Agent - 专家 Agent:持有接力棒时执行任务,干完通过 handoff 工具把棒传给下一个
整个系统的数据流向:START → Router → Agent A → (handoff) → Agent B → END。active_agent在整个过程里就是那根被传递的接力棒。
02 handoff 机制:用工具调用触发控制权转移
Swarm 里的 handoff 不是什么神秘机制,本质就是一个返回Command对象的工具。
Command是 LangGraph 的特殊返回类型,同时做两件事:更新 State(把active_agent改成目标 Agent 名)+ 跳转到指定节点(goto: "hotel_agent")。这两件事同步发生,就是"状态更新 + 控制权转移"的原子操作。
整个 handoff 链路:LLM 判断"该移交了" → 调用 handoff 工具 →Command触发状态更新和节点跳转 → 目标 Agent 接管,带着完整对话历史继续干。
用createHandoffTool创建 handoff 工具,重点是description写成明确的触发条件:
importfrom"@langchain/langgraph/prebuilt"importfrom"@langchain/langgraph-swarm"importChatOpenAIfrom"@langchain/openai"constnewChatOpenAImodel"gpt-4o"// description 要写触发条件 + 动作动词,不能只写"酒店相关"constcreateHandoffToolagentName"hotel_agent"description"当用户需要查询、预订或取消酒店时,立即调用此工具移交给酒店专家"constcreateReactAgentllmtoolsname"flight_agent"prompt"你是航班预订专家。完成航班任务后,如果用户还需要酒店,移交给 hotel_agent。"03 SwarmState:为什么上下文不会丢
Swarm 上下文不丢的秘密在于SwarmState。它在MessagesState基础上增加了active_agent字段,Reducer 是直接替换(不像messages是追加),每次 handoff 就改这一个字段:
importAnnotationMessagesAnnotationfrom"@langchain/langgraph"constSwarmStateAnnotationRootMessagesAnnotationspecactive_agentAnnotationstringreducer(_, update) =>// 直接替换,不累加default() =>""移交前:{ messages: [完整对话历史], active_agent: "flight_agent" }
移交后:{ messages: [完整对话历史,原封不动], active_agent: "hotel_agent" }
Agent B 启动时拿到的是完整的对话历史——它知道用户要去上海,知道已经订好了 CA1234,不需要重新问一遍。Swarm 比 Supervisor 在上下文连贯性上更好,就是因为没有中转损耗,State 直接共享。
04 完整实战:旅行预订 Swarm 系统
一个真实可运行的旅行预订 Swarm,包含航班 Agent 和酒店 Agent:
importfrom"@langchain/langgraph/prebuilt"importfrom"@langchain/langgraph-swarm"importMemorySaverfrom"@langchain/langgraph"importChatOpenAIfrom"@langchain/openai"importfrom"@langchain/core/tools"importfrom"zod"constnewChatOpenAImodel"gpt-4o-mini"// 业务工具consttoolasyncfromJSONstringifyid"CA1234"airline"国航"fromprice980id"MU5678"airline"东航"fromprice850name"search_flights"description"查询航班"schemaobjectfromstringtostringdatestringconsttoolasyncJSONstringifyid"H001"name"和平饭店"price1200rating5id"H002"name"全季酒店"price450rating4name"search_hotels"description"查询酒店"schemaobjectcitystringcheckInstringcheckOutstring// Agent 名称常量——用枚举,不手写字符串(坑2的修复方案)constAGENTSFLIGHT"flight_agent"HOTEL"hotel_agent"asconst// handoff 工具:互相授权constcreateHandoffToolagentNameAGENTSHOTELdescription"用户需要预订酒店时调用"constcreateHandoffToolagentNameAGENTSFLIGHTdescription"用户需要预订航班时调用"// 创建专家 AgentconstcreateReactAgentllmtoolsnameAGENTSFLIGHTprompt`你是航班预订专家。必须完成航班查询或预订后,才能移交给其他 Agent。`constcreateReactAgentllmtoolsnameAGENTSHOTELprompt`你是酒店预订专家。必须完成酒店查询或推荐后,才能移交给其他 Agent。`// 组装 SwarmconstcreateSwarmagentsdefaultActiveAgentAGENTSFLIGHTcompilecheckpointernewMemorySaver// 运行——同一会话必须用同一 thread_id!constawaitinvokemessagesrole"user"content"帮我订明天北京到上海的机票,顺便订个外滩附近的酒店"configurablethread_id"user-123-trip-booking"// 固定 thread_id// 输出:航班 CA1234 已查到,外滩和平饭店推荐给您create_swarm内部自动完成了:校验defaultActiveAgent在列表里;把active_agent类型收窄为具体 Agent 名的Literal(IDE 能帮你检查拼写);注册 Active Agent Router 到 START;遍历 agents 调用getHandoffDestinations自动发现 handoff 目标并提前注册好所有跳转边。
05 active_agent Router:图的入口交通指挥
Active Agent Router 是 Swarm 的心脏,每次 Swarm 被调用都先经过它,逻辑很简单:读active_agent,为空就去defaultActiveAgent,否则去active_agent指向的节点。
三种情况:
- 第一轮:
active_agent为空 → 去入口 Agent - 后续轮:
active_agent保存着上次的 Agent → 直接恢复 - handoff 后:
active_agent更新为目标 → 去新 Agent
对用户的感知就是:无论中间 handoff 了几次,对话始终连贯。这比 Supervisor 的每步中转效率高得多,也不会因为中转丢失上下文细节。
06 自定义 handoff:完全掌控图结构
不想用create_swarm,想完全控制图结构?手写 handoff 工具,核心是返回Command对象,同时用ToolMessage关闭 tool_call(这一步很容易漏掉):
importStateGraphMessagesAnnotationCommandAnnotationfrom"@langchain/langgraph"importToolMessagefrom"@langchain/core/messages"importfrom"@langchain/core/tools"importfrom"zod"constMyStateAnnotationRootMessagesAnnotationspecactive_agentAnnotationstringreducer(_, n) =>default() =>"triage_agent"// 工厂函数:生成 handoff 工具functionmakeHandoffTooltargetAgent: string, description: stringreturntoolasyncnewCommandupdateactive_agent// ⚠️ 必须用 ToolMessage 关闭 tool_call,否则消息链非法!messagesnewToolMessagecontent`移交给 ${targetAgent}`tool_call_idtoolCallidgotoname`transfer_to_${targetAgent}`schemaobject// 手动构建图:可插入审批节点、限制跳转关系、加 Human-in-the-LoopconstnewStateGraphMyStateaddNode"triage_agent"addNode"billing_agent"addNode"tech_agent"addConditionalEdges"__start__"(s) =>active_agenttriage_agent"triage_agent"billing_agent"billing_agent"tech_agent"tech_agent"constcompilecheckpointernewMemorySaver手写 vscreate_swarm的选择:简单场景用create_swarm省事,需要审批拦截、限制 Agent 间跳转关系、复杂路由逻辑时选手写。
07 常见坑:5个让人崩溃的问题
坑 1:handoff 工具配了但 LLM 不调
description太模糊,LLM 判断不出"该移交了"。“酒店相关"改成"当用户需要查询、预订或取消酒店时,立即调用此工具”——触发条件 + 动作动词缺一不可。
坑 2:defaultActiveAgent 拼错,上线才报错
createSwarm在运行时才校验,不是编译期类型错误。用枚举常量管理 Agent 名(见第04节AGENTS常量模式),不在参数里手写字符串。
坑 3:多轮对话上下文丢失
每次invoke传了不同的thread_id,Checkpoint 匹配不上,上下文全断。同一会话必须用同一个固定thread_id。
坑 4:Agent 之间循环 handoff
两个 Agent 都没干完活就互相推,死循环。Prompt 里明确"必须完成本职任务后才能移交"。配合recursionLimit做保底,防止无限循环把 API 额度耗干:{ configurable: { thread_id: SESSION_ID }, recursionLimit: 10 }
坑 5:手写 handoff 忘记关闭 tool_call
移交后目标 Agent 报"messages 格式非法"。手写Command时,ToolMessage里的tool_call_id必须填对应 LLM 发出的 tool_call 的 id——这是关闭 tool_call 的钥匙,缺了消息链就断了。createHandoffTool自动处理,手写必须自己保证(见第06节代码注释)。
总结
Swarm 的接力棒是active_agent字段,谁持有它谁就在执行,handoff 工具改变它来转移控制权。
handoff 的本质是返回Command对象,一次原子操作同时更新 State 和跳转节点,不经过中间层。
SwarmState的 messages 全程共享,移交后目标 Agent 拿到完整历史,上下文不断。
create_swarm自动处理路由和边注册,手写图可以获得完全控制权,两者都可以用。
最容易出问题的是 handoff description、thread_id 管理和手写 tool_call_id,这三个细节认真写,能省掉90%的调试时间。
学AI大模型的正确顺序,千万不要搞错了
🤔2026年AI风口已来!各行各业的AI渗透肉眼可见,超多公司要么转型做AI相关产品,要么高薪挖AI技术人才,机遇直接摆在眼前!
有往AI方向发展,或者本身有后端编程基础的朋友,直接冲AI大模型应用开发转岗超合适!
就算暂时不打算转岗,了解大模型、RAG、Prompt、Agent这些热门概念,能上手做简单项目,也绝对是求职加分王🔋
📝给大家整理了超全最新的AI大模型应用开发学习清单和资料,手把手帮你快速入门!👇👇
学习路线:
✅大模型基础认知—大模型核心原理、发展历程、主流模型(GPT、文心一言等)特点解析
✅核心技术模块—RAG检索增强生成、Prompt工程实战、Agent智能体开发逻辑
✅开发基础能力—Python进阶、API接口调用、大模型开发框架(LangChain等)实操
✅应用场景开发—智能问答系统、企业知识库、AIGC内容生成工具、行业定制化大模型应用
✅项目落地流程—需求拆解、技术选型、模型调优、测试上线、运维迭代
✅面试求职冲刺—岗位JD解析、简历AI项目包装、高频面试题汇总、模拟面经
以上6大模块,看似清晰好上手,实则每个部分都有扎实的核心内容需要吃透!
我把大模型的学习全流程已经整理📚好了!抓住AI时代风口,轻松解锁职业新可能,希望大家都能把握机遇,实现薪资/职业跃迁~