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(评估迭代)
- 落地策略:任务可拆分、需要多轮迭代、能力需求差异大时适合引入多代理
如果你觉得这篇文章有用,欢迎在评论区分享你的实践经验,咱们一起交流多代理系统的更多玩法!