LangGraph Multi-Agent 实战:让智能体像团队一样协作

80 阅读12分钟

1. 导读

真实业务里,一个 Agent 往往不够

  • 有的任务需要“拆分 → 并行执行 → 汇总决策”;
  • 有的任务需要“一个总控来分配工作,多个 worker 去各自执行”;
  • 有的场景要“一个模型来生成,一个模型来评估 / 修改 / 打回重做”。

这就是多代理系统(Multi-Agent)要搞定的事儿:

❝不再只依赖一个“大而全”的智能体,而是让多个有分工的 Agent 协同完成复杂任务。

咱们从能直接落地的角度,一起搭一个简单但靠谱的多代理系统,看看它是怎么让智能体像团队一样协作的。

2. 读完你能学到

  • 理解角色划分:Orchestrator(总控)、Worker(执行)、Evaluator(评估)、Specialist(领域专家)
  • 掌握核心思路:共享 State、条件边/路由、子图封装
  • 实现经典模式:Orchestrator-Worker(任务分配执行)、Evaluator-Optimizer(评估迭代)
  • 学会取舍:判断何时需要多代理,何时单 Agent + 工具足够

3. Multi-Agent 是什么 & 什么时候该用?

3.1 一个直观的类比

可以把多代理系统类比为一个小型团队:

  • Orchestrator:产品经理 / 项目经理,负责拆解任务、分配工作、整合结果;
  • Worker:各路开发 / 运营 / 销售,负责完成各自的子任务;
  • Evaluator:测试 / 质检 / 审核,负责挑错和把关质量。

在 LangGraph 视角下:

  • 每个 Agent 本质上就是一个"带有自己 Prompt + 工具 + 状态视角"的节点子图
  • 它们通过共享的全局 State读写信息;
  • 图结构(节点 + 边)定义了"谁先说、谁后说、谁有权打回重做"。

❝重要说明:本讲介绍的是"多节点编排"模式,而非"分布式多智能体"本讲:所有 Agent 节点在同一个进程内运行,通过 LangGraph 的状态机编排,共享同一个State。这种方式适合: ✅ 快速原型验证(代码少、部署快) ✅ 中小规模应用(任务复杂度适中) ✅ 本地开发调试(可观测性强)第 9 讲:我们将讲解真正的分布式多智能体系统,每个 Agent 可以独立部署在不同进程/服务器上,通过消息队列、API 等方式异步通信,适合大规模、高可用、需要独立扩展的场景。为什么先讲单进程?:单进程模式是分布式模式的基础,理解了状态共享和节点编排,再学分布式会更轻松。

3.2 什么时候值得上 Multi-Agent?

适合场景特征:

  • 任务可拆分:子任务职责清晰、边界明确
  • 需要多轮迭代:形成"生成 → 评估 → 优化"的闭环
  • 能力需求差异大:创作型、审查型、执行型能力并存

示例:智能代码审查系统(需求 → 生成代码 → 审查 → 测试用例)

4. 实战一:Orchestrator-Worker 模式

聊完概念,咱们直接上实战——用代码审查工作流来看看多代理怎么玩。

这一节,我们用代码审查工作流来实现最典型的 Orchestrator-Worker 模式:

❝一个 Orchestrator 负责拆解任务、分配给不同 Worker(开发者、审查者、测试者),最后收集和总结结果。

4.1 设计一个简单的任务:代码审查工作流

需求:

❝用户提交一个功能需求(比如"实现一个用户登录功能"),系统自动完成:代码生成 → 代码审查 → 测试用例生成。

我们可以设计 4 个 Agent:

  • orchestrator:理解用户需求,拆解任务,决定调用哪些 Worker;
  • developer_agent:负责根据需求生成代码;
  • reviewer_agent:负责审查代码质量、安全性、性能;
  • tester_agent:负责生成测试用例。

4.2 定义共享状态 State

from typing import TypedDict, List
from langgraph.graph import StateGraph, START, END


class CodeReviewState(TypedDict):
    # 用户的原始需求
    user_request: str
    # Orchestrator 拆解出的任务计划
    plan: str
    # 开发者生成的代码
    generated_code: str
    # 审查者发现的问题列表
    review_issues: List[str]
    # 测试者生成的测试用例
    test_cases: List[str]
    # 最终汇总的结果
    final_report: str

这里的关键点是:

❝所有 Agent 都在读 / 写同一个CodeReviewState,各自只关心自己负责的那一块。

4.3 定义 Orchestrator 节点

from langchain.chat_models import init_chat_model

model = init_chat_model(model="deepseek-chat", model_provider="deepseek")


def orchestrator_node(state: CodeReviewState) -> CodeReviewState:
    """
    - 读 user_request
    - 生成一个简单的开发计划说明,写入 plan
    - 决定后续应该调用哪些 Worker(这里先简化:固定三个 Worker 都走一遍)
    """
    prompt = f"""
你是一个技术负责人。下面是用户的功能需求,请你从"整体开发计划"的角度,
用简洁中文写出一个开发任务拆解,重点说明需要做什么:

用户需求:
{state["user_request"]}

请说明:
1. 需要实现哪些功能模块
2. 需要注意哪些技术要点
3. 需要做哪些测试
"""
    resp = model.invoke(prompt)

    state["plan"] = resp.content
    return state

4.4 定义三个 Worker 节点

def developer_agent(state: CodeReviewState) -> CodeReviewState:
    """
    开发者 Agent:根据需求和计划生成代码
    """
    prompt = f"""
你是一个经验丰富的 Python 开发者。根据以下需求和计划,生成完整的代码实现:

【用户需求】
{state["user_request"]}

【开发计划】
{state.get("plan", "")}

请生成:
1. 完整的代码实现(包括必要的导入、类、函数)
2. 代码注释要清晰
3. 遵循 Python 最佳实践
"""
    resp = model.invoke(prompt)
    state["generated_code"] = resp.content
    return state


def reviewer_agent(state: CodeReviewState) -> CodeReviewState:
    """
    审查者 Agent:审查代码质量、安全性、性能
    """
    prompt = f"""
你是一个严格的代码审查专家。请审查以下代码,找出所有问题:

【用户需求】
{state["user_request"]}

【生成的代码】
{state.get("generated_code", "")}

请检查:
1. 代码逻辑是否正确
2. 是否有安全漏洞(SQL注入、XSS等)
3. 是否有性能问题
4. 是否符合代码规范
5. 是否有潜在的 Bug

请列出所有发现的问题(如果没有问题,请说明"代码质量良好")。
"""
    resp = model.invoke(prompt)
    state.setdefault("review_issues", [])
    # 简单处理:把审查结果按行分割,每行作为一个问题
    issues = [line.strip() for line in resp.content.split("\n") if line.strip()]
    state["review_issues"] = issues
    return state


def tester_agent(state: CodeReviewState) -> CodeReviewState:
    """
    测试者 Agent:生成测试用例
    """
    prompt = f"""
你是一个测试专家。根据以下代码和需求,生成完整的测试用例:

【用户需求】
{state["user_request"]}

【生成的代码】
{state.get("generated_code", "")}

【审查发现的问题】(如有)
{state.get("review_issues", [])}

请生成:
1. 正常场景的测试用例
2. 边界条件的测试用例
3. 异常情况的测试用例
4. 使用 pytest 格式编写测试代码
"""
    resp = model.invoke(prompt)
    state.setdefault("test_cases", [])
    # 简单处理:把测试用例按块分割
    test_blocks = resp.content.split("\n\n")
    state["test_cases"] = [block.strip() for block in test_blocks if block.strip()]
    return state

4.5 汇总结果的节点

def summarize_report(state: CodeReviewState) -> CodeReviewState:
    """
    汇总所有结果,生成最终报告
    """
    prompt = f"""
你是技术负责人,请根据以下代码审查结果,生成一份完整的报告:

【用户需求】
{state["user_request"]}

【开发计划】
{state.get("plan", "")}

【生成的代码】
{state.get("generated_code", "")}

【审查发现的问题】
{state.get("review_issues", [])}

【测试用例】
{state.get("test_cases", [])}

请生成一份面向技术团队的汇报,包括:
1. 功能实现总结
2. 代码质量评估
3. 发现的问题和建议
4. 测试覆盖情况
"""
    resp = model.invoke(prompt)
    state["final_report"] = resp.content
    return state

4.6 用 StateGraph 串起来:Orchestrator-Worker 流程

builder = StateGraph(CodeReviewState)

builder.add_node("orchestrator", orchestrator_node)
builder.add_node("developer", developer_agent)
builder.add_node("reviewer", reviewer_agent)
builder.add_node("tester", tester_agent)
builder.add_node("summarize", summarize_report)

# 流程:总控 → 开发者 → 审查者 → 测试者 → 汇总
builder.add_edge(START, "orchestrator")
builder.add_edge("orchestrator", "developer")
builder.add_edge("developer", "reviewer")
builder.add_edge("reviewer", "tester")
builder.add_edge("tester", "summarize")
builder.add_edge("summarize", END)

graph = builder.compile()

使用示例:

config = {"configurable": {"thread_id": "code-review-1"}}

result = graph.invoke(
    {"user_request": "实现一个用户登录功能,包括用户名密码验证和 JWT token 生成"},
    config
)

print("最终报告:")
print(result["final_report"])

❝这里的例子刻意保持"结构清晰 + 易懂",实际项目可以结合条件边,让 Orchestrator 根据需求动态决定调用哪些 Worker,或者让审查者发现问题时触发开发者重写。

5. 实战二:Evaluator-Optimizer 模式

看完任务分配执行模式,咱们再来看看另一种经典模式——评估迭代模式。

第二种常见模式,是让一个 Agent 负责生成,另一个 Agent 负责评估 / 找问题 / 打回重写

❝在代码审查场景中,开发者 Agent 负责写代码,审查者 Agent 负责找问题,发现问题就让开发者重写。

5.1 典型场景:代码审查迭代

  • 开发者 Agent:根据需求生成代码
  • 审查者 Agent:审查代码质量、安全性、性能,发现问题就要求重写
  • 循环迭代:直到审查通过,或者达到最大迭代次数

这种模式特别适合代码审查,因为:

  • 代码质量需要严格把关,不能一次通过就结束
  • 审查者发现的问题需要开发者真正修复,而不是"假装修复"
  • 每次迭代都可以看到代码的改进过程

5.2 定义状态结构

from typing import Literal


class CodeReviewIterState(TypedDict):
    request: str              # 用户的原始需求
    code: str                # 当前版本的代码
    review_feedback: str     # 审查者的反馈意见
    status: Literal["pending", "approved", "rejected"]  # 审查状态
    iterations: int         # 已重写次数
    all_reviews: list        # 历史所有审查意见(可选,用于追踪)

5.3 生成 Agent:developer_node

MAX_ITER = 3


def developer_node(state: CodeReviewIterState) -> CodeReviewIterState:
    """
    开发者 Agent:根据需求和审查意见生成/重写代码
    """
    prompt = f"""
你是一个经验丰富的 Python 开发者。根据以下需求生成代码。
如果有之前的审查意见,请在新代码中修复所有问题。

【用户需求】
{state["request"]}

【之前审查意见】(如有)
{state.get("review_feedback", "无,这是第一次生成代码")}

请生成:
1. 完整的代码实现(包括必要的导入、类、函数)
2. 代码注释要清晰
3. 遵循 Python 最佳实践
4. 如果之前有审查意见,请确保所有问题都已修复
"""
    resp = model.invoke(prompt)
    state["code"] = resp.content
    state["status"] = "pending"
    state["iterations"] = state.get("iterations", 0) + 1
    
    # 记录历史审查意见(可选)
    if"review_feedback"in state and state["review_feedback"]:
        state.setdefault("all_reviews", [])
        state["all_reviews"].append(state["review_feedback"])
    
    return state

5.4 评估 Agent:reviewer_node

def reviewer_node(state: CodeReviewIterState) -> CodeReviewIterState:
    """
    审查者 Agent:严格审查代码,发现问题就要求重写
    """
    prompt = f"""
你是一个严格的代码审查专家。请审查以下代码:

【用户需求】
{state["request"]}

【当前代码】
{state["code"]}

【已重写次数】
{state.get("iterations", 0)}

请检查:
1. 代码逻辑是否正确,是否满足需求
2. 是否有安全漏洞(SQL注入、XSS、密码明文存储等)
3. 是否有性能问题(N+1查询、未使用索引等)
4. 是否符合代码规范(命名、注释、结构等)
5. 是否有潜在的 Bug(边界条件、异常处理等)

请给出审查结果:
- 如果代码质量良好,可以直接使用,请回答:"APPROVED: 代码质量良好,可以直接使用"
- 如果发现问题,请回答:"REJECTED: [具体问题列表,每个问题一行]"

请严格按照上述格式回答。
"""
    resp = model.invoke(prompt)
    content = resp.content

    state["review_feedback"] = content

    # 解析审查结果:包含 "APPROVED" 就视为通过
    if"APPROVED"in content.upper():
        state["status"] = "approved"
    else:
        state["status"] = "rejected"

    return state

5.5 条件边:继续重写还是结束?

from langgraph.graph import StateGraph, START, END

builder = StateGraph(CodeReviewIterState)
builder.add_node("developer", developer_node)
builder.add_node("reviewer", reviewer_node)


def should_rewrite(state: CodeReviewIterState) -> str:
    """
    判断是否需要重写:
    - 审查通过 → 结束
    - 审查不通过 + 未达最大迭代次数 → 重写
    - 达到最大迭代次数 → 结束(即使未通过)
    """
    if state["status"] == "approved":
        return"end"
    
    if state.get("iterations", 0) >= MAX_ITER:
        print(f"已达到最大迭代次数 {MAX_ITER},停止重写")
        return"end"
    
    return"rewrite"


builder.add_edge(START, "developer")
builder.add_edge("developer", "reviewer")
builder.add_conditional_edges(
    "reviewer",
    should_rewrite,
    {
        "rewrite": "developer",  # 回到开发者重写
        "end": END,              # 结束流程
    },
)

graph = builder.compile()

使用示例:

config = {"configurable": {"thread_id": "code-review-iter-1"}}

result = graph.invoke(
    {
        "request": "实现一个用户登录功能,包括用户名密码验证和 JWT token 生成",
        "code": "",
        "review_feedback": "",
        "status": "pending",
        "iterations": 0,
    },
    config
)

print(f"最终状态:{result['status']}")
print(f"迭代次数:{result['iterations']}")
print(f"\n最终代码:\n{result['code']}")
print(f"\n最后审查意见:\n{result['review_feedback']}")

输出示例:

最终状态:approved
迭代次数:2

最终代码:
[生成的代码...]

最后审查意见:
APPROVED: 代码质量良好,可以直接使用

❝这个模式的关键点在于:让"评估 / 修正"成为图的一等公民节点,而不是写在 Prompt 里一句"请自己检查并修正"。这样每次迭代都可观测、可计数、可打断、可调参与优化。在实际项目中,你还可以在审查者节点中加入更多检查工具(如静态代码分析、安全扫描等),让审查更严格、更可靠。

6. Multi-Agent 里的几个实践建议

聊完两种经典模式,咱们来聊聊多代理系统的工程实践建议。

6.1 核心实践原则

控制代理数量和调用深度

  • 多一个 Agent,就多一层调用和心智负担;
  • 开发早期从**2 个 Agent(如 Orchestrator + 一个 Worker 或 Evaluator)**开始;
  • 只有当一个 Agent 职责明显过重时,再拆分出新的 Agent。

明确输入/输出责任

  • 每个 Agent只读/写自己负责的那部分字段
  • 不要所有 Agent 都随意往同一个大字段里塞内容;
  • 可以用命名空间风格的字段:planning_*execution_*review_*

6.2 性能与成本优化

并行执行

  • 对独立任务(如代码审查和测试用例生成),使用add_edge实现多 Worker 并行运行,缩短总耗时。

成本控制

  • 按需调用:用条件边判断是否需要触发某个 Worker;
  • 模型差异化:不同 Agent 使用不同能力的模型;
  • 缓存机制:对重复任务的中间结果进行缓存;
  • 迭代限制:设置最大迭代次数,防止无限循环。

7. Multi-Agent vs. 强化单 Agent:如何选择?

很多人会问:“我到底应该做多代理,还是继续增强一个大 Agent?”

可以参考下面几条经验:

  • 如果问题主要是能力不够 / 工具不够→ 先补工具、补记忆、补路由,而不是马上上多代理;
  • 如果问题主要是职责太杂 / Prompt 难以维护→ 倾向于拆成多个 Agent,各司其职;
  • 如果你发现:

一句话总结:

❝用多代理解决“结构化协作”的问题,不要用多代理硬抗“模型能力不足”。

8. 小结

核心要点:

  • 角色划分:Orchestrator(总控)、Worker(执行)、Evaluator(评估)各司其职
  • 技术核心:通过共享 State、条件边和子图搭建多代理系统
  • 经典模式:Orchestrator-Worker(任务分配执行)和 Evaluator-Optimizer(评估迭代)
  • 落地策略:任务可拆分、需要多轮迭代、能力需求差异大时适合引入多代理

如果你觉得这篇文章有用,欢迎在评论区分享你的实践经验,咱们一起交流多代理系统的更多玩法!