生命不息,折腾不止。前三课你手里已经有个能调工具、记得住你、还能打包成 API 的 Agent 了;可什么活都塞给它一个人干,早晚要「精神分裂」。今天给它配一队专科专家,再请个「老板」专门派活、验收。

一、单打独斗的 Agent,卡在哪儿

前面三课的 Agent 本质是「全科大夫」:搜索、算数、写文案、查数据库,全塞给它一个。任务简单时挺顺,一上量就露三种病:

  1. 工具一多就选错。一个 Agent 挂上二三十个工具,让它挑对工具,跟让食堂阿姨同时背二十个菜价一样不靠谱;
  2. 上下文光速爆炸。每调一次工具,中间结果全进同一份对话历史,几十轮跑下来,光「过程记录」就把上下文塞满了;
  3. prompt 越写越长。为了让一个 Agent 啥都会,system prompt 只能一路加料,最后长得连模型自己都抓不住重点。

多智能体(Multi-Agent)就是来治这个的:把「全科大夫」拆成几个「专科医生」,每人只精一件事;再请一个「老板」Agent 负责派活、盯进度、验收成果。 这个「老板」,就是今天的主角 —— Supervisor。

二、Supervisor 模式:一个老板,管一队专家

Supervisor 模式的核心思想,一句话:专家之间不互相使唤,所有调度都经过老板。

  • 用户把任务丢给 Supervisor;
  • Supervisor 看当前状态,决定「这一步该谁干」,然后把活(handoff)出去;
  • 被选中的专家干完,控制权回到 Supervisor
  • Supervisor 再判断:活干完了没?没干完继续派下一个;干完了就把结果汇总给你。

那「派活」这一步在代码里怎么实现?靠的是 tool-based handoff:Supervisor 手上会自动多出几个「派活工具」,名字长这样 —— transfer_to_research_experttransfer_to_math_expert。它调哪个工具,就等于把控制权交给哪个专家。本质还是让模型调工具,只是这个工具的效果是「切换 Agent」。

官方把这些封装成了一个独立小包 langgraph-supervisor,不用你自己从零拼节点和边。

装它:

1
pip install langgraph-supervisor langchain-openai

注意:langgraph-supervisor 要求 Python >= 3.10,环境太老的先升一下。

⚠️ 官方还有个提醒值得知道:这个库现在主要定位成「帮你升级已有代码」,作者更推荐大多数新项目直接用工具调用(tool-calling)实现 supervisor 模式,理由是那样对上下文工程的控制更细。所以本课两条路都给你:先用这个库最快跑通手感,后面再揭开它底层其实就是一堆 handoff 工具,让你能徒手拼。

三、手把手:两个专家 + 一个老板,完整能跑

下面这段是照着官方 Quickstart 改的,跑之前把 OPENAI_API_KEY 填上就行:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
from langchain_openai import ChatOpenAI
from langgraph_supervisor import create_supervisor
from langgraph.prebuilt import create_react_agent

model = ChatOpenAI(model="gpt-4o", temperature=0)

# 1. 定义两个「专科工具」
def web_search(query: str) -> str:
"""联网搜索资料。真实项目里换成你的搜索 API。"""
return f"搜索「{query}」的结果:FAANG 2024 年员工数如下……"

def add(a: float, b: float) -> float:
"""两个数相加。"""
return a + b

# 2. 把工具各自包成一个专家 Agent
research_agent = create_react_agent(
model=model,
tools=[web_search],
name="research_expert",
prompt="你是资深研究员,只负责查资料,不做任何算术。",
)
math_agent = create_react_agent(
model=model,
tools=[add],
name="math_expert",
prompt="你是数学专家,只负责计算,不查资料。",
)

# 3. 请一个 Supervisor 来管这两位
workflow = create_supervisor(
[research_agent, math_agent],
model=model,
prompt=(
"你是团队主管,手下有一个研究专家和一个数学专家。"
"要查资料就派给 research_expert,要算数就派给 math_expert,"
"一次只派一个人,等他干完再决定下一步。"
),
)

# 4. 编译、跑起来
app = workflow.compile()
result = app.invoke({
"messages": [{
"role": "user",
"content": "帮我查一下 FAANG 几家 2024 年的员工数,然后算个总和。",
}]
})
print(result["messages"][-1].content)

跑起来你会看到它自动串了两步:先把「查资料」派给 research_expert,拿到数据后,再把「求和」派给 math_expert,最后汇总回答。你全程只提了一个问题。

几个关键点:

  • create_react_agentname 必须唯一且有意义。这个 name 会变成 handoff 工具名的一部分,也出现在消息历史里,起成 agent1agent2 你以后自己都看不懂;
  • prompt 是老板的「派活说明书」。写清「什么活派给谁」是它不瞎派的关键,含糊的话它会来回乱转;
  • 专家干完自动回老板。你不用手写「回来后干嘛」,这是这个包帮你处理掉的。

四、进阶:历史怎么记、层级怎么叠

4.1 消息历史:别让过程把上下文撑爆

每次专家干活的中间消息要不要全记进对话历史?output_mode 就是干这个的:

1
2
3
4
5
6
7
# 只保留每个专家的最终结论(默认)——省上下文,推荐
workflow = create_supervisor(agents=[research_agent, math_agent], model=model,
output_mode="last_message")

# 专家干活的全部消息都塞进来——调试时有用,生产环境慎用
workflow = create_supervisor(agents=[research_agent, math_agent], model=model,
output_mode="full_history")

默认是 last_message:老板只看到专家的「结论」,看不到中间那一堆工具调用。多专家 + 长任务时,这个选择直接决定你的 token 账单。

4.2 多层级:老板上面还有老板

一个 Supervisor 管的人太多也会乱。这时候就叠层级 —— 让 Supervisor 去管别的 Supervisor:

1
2
3
4
5
6
7
8
9
10
11
12
research_team = create_supervisor(
[research_agent, math_agent], model=model
).compile(name="research_team")

writing_team = create_supervisor(
[writing_agent, publish_agent], model=model
).compile(name="writing_team")

# 顶层老板管两个「小组长」
top_level = create_supervisor(
[research_team, writing_team], model=model
).compile(name="top_level_supervisor")

这就是「老板 → 组长 → 组员」的三级结构,跟真实公司的组织架构一个道理。

4.3 自定义「派活工具」

嫌自动生成的 transfer_to_xxx 太机械?可以用 create_handoff_tool 自己定制,甚至让老板在派活时附上详细任务说明

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from langgraph_supervisor import create_handoff_tool

workflow = create_supervisor(
[research_agent, math_agent],
model=model,
tools=[
create_handoff_tool(agent_name="math_expert",
name="assign_to_math_expert",
description="把计算任务派给数学专家"),
create_handoff_tool(agent_name="research_expert",
name="assign_to_research_expert",
description="把调研任务派给研究专家"),
],
)

如果你想要更彻底的控制(比如派活时顺带传一段「任务描述」给下一个 Agent),就得手写 handoff —— 用 LangGraph 的 Command(goto=..., graph=Command.PARENT) 把控制权连同状态一起交给目标 Agent。这是下一篇要展开的东西,先记个名字。

4.4 给老板配记忆

Supervisor 本质还是个 StateGraph,前面第二课那套记忆挂件照样能用:

1
app = workflow.compile(checkpointer=checkpointer, store=store)

再加上你已经有的人审门禁(interrupt),一套「多专家 + 长期记忆 + 人工把关」的完整架构就成了。

五、避坑清单

踩过的坑,替你记下了:

  1. Python 版本不够langgraph-supervisor>= 3.10,3.9 会直接装不上或导入报错;
  2. 专家 name 重名:两个 Agent 都叫 expert,handoff 工具就撞了,调度直接乱套;
  3. 让专家互相直接调用:Supervisor 模式的价值就在于「所有调度都过老板」,专家之间交叉调用来调用去,你会得到一团没人理得清的乱麻;
  4. output_mode 用错:生产环境还用 full_history,上下文和账单一起起飞。调试才用全量,上线切回 last_message
  5. 模型选便宜的就以为省钱:调度是最吃「判断力」的活,老板 Agent 的模型别太抠。模型接哪都行 —— OpenAI 兼容接口的都吃得下,想省点接入成本,用中转站 ai.aklibk.com 这种国内直连、按量付费的也行,接口格式跟官方一样,代码不用改;
  6. 一上来就叠三级:层级越深、延迟越高、越容易在某层卡死。先用「一个老板 + 两三个专家」跑通,真不够了再加层。

六、小结

到这一步,你的 LangGraph 技能树是这样的:

  • 第一课:会画图(State / Node / Edge);
  • 第二课:会调工具、会断点续跑、会人审、会给长期记忆;
  • 第三课:能打包成 API 对外服务;
  • 第四课:会带队 —— 一个 Supervisor 指挥一队专家并行干活。

单 Agent 到多 Agent,本质上是把「一个全科医生」升级成「一个会分诊的医院」。分工带来的不只是能力上限,还有可维护性 —— 每个专家单独调试、单独换模型、单独加工具,互不干扰。

生命不息,折腾不止。第四课先到这里。下一篇咱们聊怎么让专家们真正「并行」起来Send 把同一个任务拆成几份同时派出去、map-reduce 式汇总结果,再配上「子图」把每个专家各自打包成独立模块 —— 从「流水线」升级成「并发工厂」。仓库我都给你留着,下一篇见。