用 LangGraph 搭建多 Agent 协作系统:从踩坑到跑通
起因
我已经用 n8n 搭了不少自动化流水线,但一直想试试 LangGraph 的多 Agent 协作——让多个专业 Agent 在 Supervisor 的统一调度下协同完成复杂任务。
手头的资源:
- VPS 没有 GPU,5.8Gi 内存
- 已经有 One API 作为 LLM 网关(配了 20+ 渠道)
- 已经装了 LangChain 生态
目标:跑通一个「调研 → 撰写 → 审核」的三 Agent 内容生产流水线。
整体架构
text
用户指令 → Supervisor(调度器)
↓
┌─────────┼─────────┐
↓ ↓ ↓
Researcher Writer Reviewer
(调研) (撰写) (审核)
Supervisor 根据任务进度决定下一步调用哪个 Agent,Agent 之间通过 LangGraph 的 State 传递信息。
第一步:安装依赖
bash
cd /opt/rag-nvidia source venv/bin/activate pip install langgraph langgraph-supervisor langchain-openai langchain
四个包缺一不可:
| 包 | 作用 |
|---|---|
langgraph | Agent 运行时,提供状态管理和持久化 |
langgraph-supervisor | 预置的 Supervisor 模式实现 |
langchain-openai | 兼容 OpenAI 接口的模型封装 |
langchain | Agent 创建的高级抽象 |
第二步:第一次尝试(失败)
最初的脚本用了 LangChain 1.x 的 create_agent:
python
from langchain.agents import create_agent
from langgraph_supervisor import create_supervisor
researcher = create_agent(
model=model,
tools=[search_topic],
name="researcher",
system_prompt="你是调研专家。",
)
结果:Supervisor 输出了「给 Researcher 的指令」,但没有真正调用 researcher。
text
[supervisor] 下一步调用:Researcher(调研员) 给 Researcher 的指令:请针对"AI 改变教育"进行深度调研... (然后就没有下文了)
第三步:定位根因
反复调试后发现,问题不在 Agent 创建方式,而在模型的 tool calling 支持。
langgraph-supervisor 依赖 function calling / tool use 来实现 Agent 之间的控制权转交(handoff)。Supervisor 通过调用 transfer_to_researcher 这样的工具来把控制权交给子 Agent。
如果模型不支持 tool calling,Supervisor 就无法真正执行 handoff,只能生成文字描述。
第四步:测试哪些模型支持 tool calling
写了一个脚本,向 NVIDIA NIM 的模型发送带 tools 参数的请求,看返回的 finish_reason:
python
TOOLS = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
}
}]
body = {
"model": model_id,
"messages": [{"role": "user", "content": "What is the weather in Tokyo?"}],
"tools": TOOLS,
"tool_choice": "auto",
"stream": False,
}
关键看 finish_reason:
| 返回 | 含义 |
|---|---|
finish_reason: "tool_calls" + tool_calls 字段有内容 | ✅ 支持 |
finish_reason: "stop" + 普通文本 | ❌ 不支持 |
测试结果
| 模型 | tool calling |
|---|---|
gemma4:31b | ❌ stop,直接文本回答 |
gpt-oss:120b | ❌ stop,直接文本回答 |
nvidia/nemotron-3-super-120b-a12b | ✅ tool_calls |
nvidia/nemotron-3-ultra-550b-a55b | ✅ tool_calls |
关键发现:推理模型(gemma4、gpt-oss)不支持 tool calling,而 NVIDIA 的 Nemotron 系列支持。
第五步:用正确的模型跑通
把模型换成 nvidia/nemotron-3-super-120b-a12b:
python
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from langgraph_supervisor import create_supervisor
from langchain_core.tools import tool
model = ChatOpenAI(
base_url="http://172.17.0.1:3000/v1",
api_key="sk-你的OneAPI令牌",
model="nvidia/nemotron-3-super-120b-a12b",
temperature=0.7,
timeout=300,
)
@tool
def search_topic(query: str) -> str:
"""搜索关于某个主题的信息。"""
return f"关于「{query}」的调研结果:这是热门话题,主要观点包括 A、B、C 三方面。"
@tool
def write_draft(topic: str, research: str) -> str:
"""根据调研结果撰写文章草稿。"""
return f"基于调研「{research}」,关于「{topic}」的草稿已完成。"
@tool
def review_content(draft: str) -> str:
"""审核文章草稿。"""
return f"审核意见:草稿「{draft}」质量合格。"
researcher = create_agent(
model=model,
tools=[search_topic],
name="researcher",
system_prompt="你是调研专家。使用 search_topic 工具查找信息。",
)
writer = create_agent(
model=model,
tools=[write_draft],
name="writer",
system_prompt="你是内容撰写专家。根据调研结果产出草稿。",
)
reviewer = create_agent(
model=model,
tools=[review_content],
name="reviewer",
system_prompt="你是审核专家。检查草稿质量。",
)
workflow = create_supervisor(
agents=[researcher, writer, reviewer],
model=model,
prompt="""你是内容生产团队的主管。
流程:先让 researcher 调研,再把结果交给 writer 撰写,最后让 reviewer 审核。""",
)
app = workflow.compile()
result = app.invoke({
"messages": [{"role": "user", "content": "写一篇关于 AI 改变教育的内容"}]
})
结果:完整跑通。
text
[transfer_to_researcher]
Successfully transferred to researcher
↓
[researcher] 调研 → [transfer_back_to_supervisor]
↓
[transfer_to_writer]
Successfully transferred to writer
↓
[writer] 撰写 → [transfer_back_to_supervisor]
↓
[transfer_to_reviewer]
Successfully transferred to reviewer
↓
[reviewer] 审核 → [transfer_back_to_supervisor]
↓
[supervisor] 输出最终结果
关键验证点
| 验证项 | 结果 |
|---|---|
| Supervisor 决策 | ✅ 依次调度三个 Agent |
transfer_to_* 工具调用 | ✅ 每次转交都成功 |
transfer_back_to_supervisor | ✅ 每个 Agent 完成后交回控制权 |
| 三个 Agent 都被执行 | ✅ researcher → writer → reviewer |
踩坑记录
1. 模型不支持 tool calling 是最常见的坑
多 Agent 协作必须依赖 tool calling。如果模型只返回文本、不返回 tool_calls,Supervisor 就无法转交控制权。
排查方式:用 curl 发送带 tools 参数的请求,看 finish_reason 是否是 tool_calls。
2. 推理模型通常不支持 tool calling
gemma4:31b、gpt-oss:120b 都是推理模型,它们会先生成思考过程再输出回答,但不支持 function calling。换非推理的 Nemotron 系列解决。
3. create_react_agent 已弃用
LangGraph 1.x 后,create_react_agent 被移到 langchain.agents.create_agent。如果用旧版会报 LangGraphDeprecatedSinceV10 警告。
4. 550B 模型太慢
nemotron-3-ultra-550b 虽然也支持 tool calling,但每次调用约 37 秒。多 Agent 协作涉及多次调用,总耗时可能 3-5 分钟。用 nemotron-3-super-120b 更快。
5. One API 能正常转发 tool calling
测试确认,通过 One API 调用 nemotron-3-super-120b 时,tools 参数被正确转发,tool_calls 响应也能正确返回。
当前状态
| 组件 | 状态 |
|---|---|
| LangChain + LangGraph | ✅ 已安装 |
| langgraph-supervisor | ✅ 已安装 |
| One API 转发 tool calling | ✅ 正常 |
nemotron-3-super-120b | ✅ 支持 tool calling |
| 多 Agent 协作 | ✅ 跑通 |
可优化的方向
1. 换真实工具
当前的 search_topic、write_draft、review_content 都是返回固定文本的模拟工具。可以换成:
- 真实搜索:接入 Tavily、SerpAPI
- 真实发布:接入 WordPress REST API
- 真实审核:接入 RAG,基于事实检查
2. 加更多 Agent
- SEO Agent:优化标题和关键词
- 配图 Agent:调用 Pollinations 生成特色图片
- 发布 Agent:上传到 WordPress
3. 持久化与可视化
LangGraph 支持 checkpoint,可以把每次协作的中间状态存到 SQLite,方便回溯和调试。
4. 接入 n8n
把整个多 Agent 协作封装成一个 Flask 服务,n8n 通过 HTTP 调用它。
一句话总结
多 Agent 协作的核心前提是模型支持 tool calling。 选对模型(Nemotron 系列),配好 One API,用 LangGraph + langgraph-supervisor 就能在 VPS 上跑通完整的协作流水线。
