第 3 篇:让 Agent 学会分工,LangGraph 构建多 Agent系统

系列简介 :从零搭建一个多 Agent AI 助手,覆盖原理、实现、部署全链路。不讲空话,每篇都有可运行的代码。
项目地址github.com/CodeMomentY...
本篇目标:用 LangGraph 搭建一个多 Agent 协作系统,支持意图识别、动态路由、串行/并行执行。

前言

大家好,我是一名前端工程师。都说前端"已死",那与其担心被 AI 替代,不如打入敌人内部,于是我开始折腾 Agent 开发。

折腾下来发现,Agent 的核心不是算法,而是"工程能力"(怎么设计架构、怎么串联服务、怎么把 LLM 的能力落地成产品)。这些恰好是我们擅长的事。

这个系列记录我从零搭建多 Agent 系统的完整过程。只聊技术知识和设计思路,代码交给 AI 写。如果你也想从应用层切入 AI,希望这个系列对你有帮助。

读完本篇你将学到:

  • 为什么需要多 Agent,单 Agent 的瓶颈在哪;
  • LangGraph 是什么,为什么选它;
  • 多 Agent 架构设计:Dispatcher + 专业 Agent;
  • 串行和并行两种执行模式的实现;

背景与动机

上两篇我们用 30 行代码实现了单 Agent,也了解了三种范式。但当你想让 Agent 同时具备"查天气"、"写文章"、"闲聊"这些能力时,那么问题来了:

全塞到一个 Agent 里,Prompt 会越来越臃肿。 你得在一个 System Prompt 里描述所有工具、所有规则、所有场景。LLM 看到一大坨指令,容易搞混,该调工具的时候不调,不该调的时候乱调。

这就像一个人同时当厨师、服务员、收银员------忙得过来,但质量堪忧。

解决方案很自然:分工。让不同的 Agent 各管一摊,再加一个"调度员"决定把任务交给谁。

但分工带来了新问题:多个 Agent 之间怎么传递数据执行顺序怎么控制什么条件走哪条路?如果还用前两篇的原生写法(手写 for 循环 + if-else),代码会迅速变成一团意大利面。

这就是为什么我们需要一个框架来管理流程------不是因为原生写法不行,而是当节点多了、路由复杂了,框架能帮你把"流程控制"这件事做得更清晰。

核心概念

单 Agent vs 多 Agent

我们看一下两者对比:

单 Agent 多 Agent
Prompt 一个巨大的 System Prompt 每个 Agent 一个精简 Prompt
职责 什么都干 各司其职
调试 出错不知道哪个环节的问题 哪个 Agent 出错一目了然
扩展 加功能就改 Prompt(越改越乱) 加功能就加一个新 Agent
速度 还行 多了 Dispatcher 的开销

设计多 Agent 架构

架构图:

三个专业 Agent:

  • tools 路径:需要调工具的任务(查天气、获取网页、查语雀文档),内部是 ReAct 循环;
  • writer 路径:写作类任务(邮件、文案、翻译),纯 LLM 生成,temperature 调高一点增加创造力;
  • chat 路径:闲聊和知识问答,纯 LLM 对话,会从知识库检索相关内容(RAG);

使用 LangGraph 来构建

为什么选 LangGraph 而不是 LangChain?很多人分不清 LangChain 和 LangGraph 的关系。简单来说:

  • LangChain:工具箱。提供了调 LLM、解析输出、连接向量库等基础能力,像是一堆零件。
  • LangGraph:施工图。在 LangChain 的零件基础上,定义了"谁先执行、谁后执行、什么条件走哪条路"的流程控制。

感兴趣的可以看看这篇文章:www.datacamp.com/tutorial/la...

LangChain 本身也能做 Agent(AgentExecutor),但它的问题是:流程是黑盒的。你把工具和 Prompt 丢进去,它内部自己循环,你很难控制"什么时候该停"、"中间结果怎么传递"、"多个 Agent 怎么协作"。

LangGraph 把流程显式化了------你画一张图,节点是什么、边怎么连、条件是什么,一目了然。对于多 Agent 协作这种需要精确控制流程的场景,LangGraph 比 LangChain 的 AgentExecutor 好用得多。

LangChain AgentExecutor LangGraph
流程控制 黑盒,框架内部循环 白盒,你画图定义
多 Agent 不原生支持 天然支持(多节点)
条件路由 难实现 一行代码
状态管理 手动传递 自动维护
调试 难(看不到中间过程) 易(逐节点 stream)
适合场景 简单单 Agent 复杂多 Agent 协作

其实在项目里,LangChain 的东西还是在用的(消息格式、工具定义、OpenAI SDK),只是不用它的 AgentExecutor,改用 LangGraph 来编排流程。

动手实现

LangGraph 基础用法

很多小伙伴不熟悉 LangGraph,所以在搭建多 Agent 之前,先看一个最简单的 LangGraph 示例,理解它的三个核心概念:State(状态)、Node(节点)、Edge(边)

其实就是把代码调度更具体化了,像是在画"流程图"。

python 复制代码
from langgraph.graph import StateGraph, END
from typing_extensions import TypedDict

# 1. 定义状态:所有节点共享的数据
class MyState(TypedDict):
    message: str
    count: int

# 2. 定义节点:就是普通函数,接收 state,返回要更新的字段
def say_hello(state):
    return {"message": f"你好!你已经来了 {state['count']} 次"}

def add_count(state):
    return {"count": state["count"] + 1}

# 3. 构建图:注册节点 + 连接边
graph = StateGraph(MyState)
graph.add_node("counter", add_count)
graph.add_node("greeter", say_hello)

graph.set_entry_point("counter")          # 入口
graph.add_edge("counter", "greeter")      # counter → greeter
graph.add_edge("greeter", END)            # greeter → 结束

app = graph.compile()

# 4. 运行
result = app.invoke({"message": "", "count": 0})
print(result)  # {"message": "你好!你已经来了 1 次", "count": 1}

就这么简单:定义状态 → 写几个函数 → 用边连起来 → Compile → Invoke(调用)

LangGraph 真正强大的地方在于条件边------根据状态动态决定下一步走哪:

python 复制代码
# 条件边:根据 count 决定走哪条路
def should_continue(state):
    if state["count"] >= 3:
        return "done"
    return "again"

graph.add_conditional_edges("greeter", should_continue, {
    "again": "counter",   # count < 3 → 回到 counter(循环)
    "done": END,          # count >= 3 → 结束
})

有了条件边,就能实现循环、分支、路由------这正是多 Agent 系统需要的能力。

Step 1:定义状态

LangGraph 的核心是 State------所有节点共享的数据结构。每个节点读取 state、处理、写回 state。

python 复制代码
from typing import Annotated, Sequence
from typing_extensions import TypedDict
from langchain_core.messages import BaseMessage
import operator

class AgentState(TypedDict):
    """所有节点共享的状态"""

    # 对话历史(自动追加)
    messages: Annotated[Sequence[BaseMessage], operator.add]

    # 意图列表(dispatcher 填写)
    intents: list[str]

    # 执行模式:sequential 或 parallel
    mode: str

    # 当前执行到第几个意图
    current_step: int

关键设计:messagesoperator.add 标注,意味着每个节点返回的消息会追加到列表里,而不是覆盖,这样对话历史自动累积。

Step 2:实现 Dispatcher(意图分类)

Dispatcher 是整个系统的入口,负责判断用户想干什么:

python 复制代码
DISPATCHER_PROMPT = """你是一个意图分类器。

分类规则:
- tools:需要调用工具的请求(查天气、获取网页、查文档)
- writer:写作类(写邮件、文案、翻译)
- chat:其他(闲聊、知识问答)

如果需要多个步骤,按顺序列出。
回复格式:意图1,意图2|模式(sequential 或 parallel)

示例:
- "上海天气" → tools|sequential
- "查天气然后写文案" → tools,writer|sequential
- "翻译hello,顺便查天气" → tools,writer|parallel
"""

def dispatcher_node(state):
    last_user_msg = ...  # 取最后一条用户消息
    response = invoke_llm([SystemMessage(DISPATCHER_PROMPT), ...])

    # 解析:intents + mode
    intents, mode = parse_response(response)

    return {"intents": intents, "mode": mode, "current_step": 0}

Dispatcher 的输出决定了后续走哪条路。注意它支持多意图 。比如:"查天气然后写文案"会被拆成 ["tools", "writer"],串行执行。

Step 3:构建 LangGraph 图

这是最关键的部分------把所有节点和路由规则组装成一张图,我们先看流程设计:

最终代码实现:

python 复制代码
from langgraph.graph import StateGraph, END

def build_graph():
    graph = StateGraph(AgentState)

    # 注册节点
    graph.add_node("dispatcher", dispatcher_node)
    graph.add_node("mode_router", lambda state: {})  # 路由跳板
    graph.add_node("step_router", lambda state: {})  # 串行步骤跳板
    graph.add_node("router", router_node)            # 工具决策
    graph.add_node("tool_executor", tool_executor_node)
    graph.add_node("writer_agent", writer_agent_node)
    graph.add_node("chat_agent", chat_agent_node)
    graph.add_node("advance_step", advance_step)     # 推进到下一步
    graph.add_node("parallel_executor", parallel_executor_node)

    # 入口
    graph.set_entry_point("dispatcher")

    # dispatcher → mode_router
    graph.add_edge("dispatcher", "mode_router")

    # 根据 mode 分流
    graph.add_conditional_edges("mode_router", route_mode, {
        "sequential": "step_router",
        "parallel": "parallel_executor",
    })

    # 串行:根据当前 intent 路由
    graph.add_conditional_edges("step_router", route_current_step, {
        "tools": "router",
        "writer": "writer_agent",
        "chat": "chat_agent",
        "done": END,
    })

    # tools 路径:ReAct 循环
    graph.add_conditional_edges("router", should_use_tools, {
        "tools": "tool_executor",
        "next": "advance_step",
    })
    graph.add_edge("tool_executor", "router")

    # writer/chat 完成后推进
    graph.add_edge("writer_agent", "advance_step")
    graph.add_edge("chat_agent", "advance_step")

    # 检查是否还有下一步
    graph.add_conditional_edges("advance_step", has_next_step, {
        "continue": "step_router",
        "done": END,
    })

    # 并行路径
    graph.add_edge("parallel_executor", END)

    return graph.compile()

Step 4:串行 vs 并行

串行:有依赖关系的任务。"查天气然后写文案"------writer 需要天气结果才能写。

并行:互不依赖的任务。"翻译hello world,顺便查天气"------两个任务没关系。

并行模式用 ThreadPoolExecutor 同时执行多个 Agent,最后让 LLM 把结果整合成一个连贯的回答。

Step 5:验证效果

bash 复制代码
# 单意图
curl -X POST /api/chat -d '{"message": "你好"}'
# → dispatcher: chat → chat_agent → "你好!有什么可以帮你的?"

# 单意图 + 工具
curl -X POST /api/chat -d '{"message": "上海天气"}'
# → dispatcher: tools → router → get_weather → router → "上海晴天24°C"

# 多意图串行
curl -X POST /api/chat -d '{"message": "查上海天气,写个朋友圈文案"}'
# → dispatcher: [tools, writer] sequential
# → tools(查天气)→ writer(基于天气写文案)→ 最终回复

# 多意图并行
curl -X POST /api/chat -d '{"message": "翻译hello world,顺便查北京天气"}'
# → dispatcher: [tools, writer] parallel
# → 并发执行 → 整合回复

刨根问底

序号 问题
1️⃣ Q:Dispatcher 的意图分类准确吗?模糊场景怎么办?
A:不一定准。"帮我写个出行计划"到底是 tools 还是 writer?靠 Prompt 里的规则和示例来约束。模糊时兜底到 chat(最安全的路径)。后续可以加 few-shot 示例提升准确率。
2️⃣ Q:并行模式怎么整合多个 Agent 的结果?
A:用 LLM 整合。把多个 Agent 的输出拼在一起,让 LLM 生成一个连贯的最终回答。类似于"你有两段信息,请合并成一段自然的回复"。
3️⃣ Q:LangGraph 和直接写 Python 函数调用有什么区别?
A:小项目没区别。但当图变复杂(10+ 节点、多种条件路由、需要流式输出)时,LangGraph 的状态管理和条件边比手写 if-else 清晰得多。而且它内置了 stream 模式,后面做 SSE 推送时直接用。

本篇小结

  • 多 Agent 的核心是分工------Dispatcher 做路由,专业 Agent 各管一摊;
  • LangGraph 用来描述 Agent 的执行流程,节点是函数,边是条件;
  • 支持串行 (有依赖)和并行(无依赖)两种多意图执行模式;
  • dispatcher 的意图分类质量决定了整个系统的上限;

写在最后

多 Agent 架构看起来复杂,但核心思想很朴素:把大问题拆成小问题,让专业的人做专业的事。这和微服务架构的理念一模一样------单体应用拆成多个服务,每个服务职责单一,通过 API 协作。

如果你做过前端的组件化拆分,多 Agent 的设计思路你一定不陌生。

下一篇预告:核心服务架构搭好了,接下来让它真正能完整跑起来------Web 界面 + SSE 流式输出,把 Agent 从命令行变成一个能用的产品。

相关推荐
程序员Jelena4 小时前
Python 代码是什么?—— 从字节到执行的完整解析
python
初心未改HD4 小时前
深度学习之Transformer架构详解
人工智能·深度学习·transformer
拾年2754 小时前
一个项目教你玩转Claude Code 常用命令
人工智能
阿里云云原生4 小时前
QECon2026 深圳站丨云原生专家团拆解 AI Agent 工程化落地的 4 个关键环节
agent
阿里云大数据AI技术4 小时前
PAI-FA|突破 TMEM 瓶颈:FlashAttention-4 大 Head Dimension (256) 高性能算子实现与优化
人工智能
Mr数据杨4 小时前
【CanMV K210】传感器实验 MPU6050 六轴数据与四元数姿态融合
人工智能·硬件开发·canmv k210
Das14 小时前
MCP Is Dead
人工智能
测试员周周4 小时前
【Appium 系列】第13节-混合测试执行器 — API + UI 的协同执行
开发语言·人工智能·python·功能测试·ui·appium·pytest
莽夫搞战术4 小时前
【Google Stitch】AI原生画布重新定义设计,让想法变成可交互界面
前端·人工智能·ui