news 2026/10/14 3:23:45

LangGraph多智能体协作实战:从框架选型到“研究员+写作者+审稿人”流水线

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
LangGraph多智能体协作实战:从框架选型到“研究员+写作者+审稿人”流水线

摘要

给一个智能体一项任务,它能完成得不错。给它三项任务,第二次交接就可能出问题:它会忘记第一步找到的内容,会慷慨地给自己的草稿打高分,会在输出仍未完成时宣布成功。多智能体系统通过专业化分工解决这一困境。本文系统梳理2026年Python多智能体编排的四大主流框架选型逻辑,深入解析Supervisor、Handoff、Network等核心协作模式,并以LangGraph 1.0为技术底座,从零构建一个可运行的“研究员+写作者+审稿人”三角色协作流水线,包含条件重试边与状态管理机制,帮助读者完成从单智能体思维到多智能体协作思维的跨越。

关键词

LangGraph、多智能体协作、Supervisor模式、框架选型、条件边、状态管理

一、框架选型:2026年Python多智能体编排格局

2026年,Python多智能体编排领域由四个框架主导:Microsoft Semantic Kernel、LangGraph、AutoGen和CrewAI。对于零基础学习者,选择第一个框架比同时学习多个更重要。

1.1 LangChain + LangGraph:主线选择

LangChain 1.0是核心框架,负责模型抽象、提示词管理、工具定义和RAG组件。LangGraph 1.0是官方编排运行时,将工作流建模为有向图,节点代表处理步骤,边代表控制流。两者的关系是:LangChain提供构建块,LangGraph决定这些构建块如何组织和流转。

LangGraph的核心能力在于条件分支、循环、并行等复杂控制流,并支持状态持久化、断点续跑和人工介入。智能体的标准入口是create_agent(即create_react_agent的正式版本),旧的AgentExecutor已废弃。推荐的学习顺序是:ChatModel → Prompt → Tool → RAG → LCEL → LangGraph → create_agent。

1.2 CrewAI:轻量补充

CrewAI是四个编排框架中设置成本最低的。声明角色(如researcher、writer、reviewer),选择协作模式即可跑起来,适合快速原型验证。但它的控制粒度不如LangGraph精细,不适合需要复杂条件逻辑的生产系统。

1.3 选型建议

以LangGraph为主线,CrewAI为补充。LangGraph的StateGraph模型让你能够像搭建流程图一样构建多智能体工作流,状态管理和条件边的能力是构建可靠多智能体系统的关键。

二、多智能体协作的四种核心模式

在动手写代码之前,需要理解多智能体系统中几种基本的协作架构。

2.1 Supervisor(监督者模式)

一个中心监督者负责任务分解、分配和进度决策,多个专业Agent各司其职,完成后向监督者反馈。监督者通过条件判断决定下一步由谁执行。优势是集中控制、流程清晰、易调试;劣势是监督者是单点瓶颈,且每次路由都需要一次LLM调用。适用场景:研究报告生成、代码审查等多步骤流程任务。

2.2 Handoff(交接模式)

Agent之间直接交接控制权,没有中间协调层。这是OpenAI Agents SDK的核心设计模式。优势是去中心化、通信延迟低;劣势是交接链易形成环路、调试困难。适用场景:客服、用户对话等需要动态任务流转的场景。

2.3 Network(网络模式)

智能体间可以直接通信,形成网状拓扑。灵活但复杂度高,适合小规模、强交互的场景。

2.4 本教程的选择:图结构流水线

本文采用显式图结构的方式:不依赖模型自行决定下一步,而是在代码中预先声明节点、边和共享状态。研究流程是确定的——先研究,再写作,最后审稿,不合格则退回修改。这种流水线模式最适合用图结构来表达。

三、实战项目:研究员+写作者+审稿人流水线

3.1 系统架构设计

整个系统的结构如下:

text

START → researcher → writer → reviewer ──(条件边)──→ END(通过) ↑ │ └──────────────────────┘ (不通过,退回修改)

三个命名节点、一条通过边和一条重试边,以及一个汇集topic、notes、draft、verdict的共享状态对象。

3.2 定义共享状态

所有智能体共享一个类型化的状态对象,这是它们之间传递信息的唯一通道:

python

from typing import TypedDict, List, Annotated from langgraph.graph.message import add_messages class ResearchState(TypedDict): topic: str # 研究主题 notes: List[str] # 研究员收集的原始笔记 draft: str # 写作者产出的草稿 verdict: str # 审稿人的判定:PASS 或 REWORK feedback: str # 审稿人的修改建议 revision_count: int # 修改次数(防止无限循环) messages: Annotated[list, add_messages] # 对话历史

状态中的所有字段都是可读写的,但不同的节点负责更新不同的字段。revision_count是防止无限循环的关键——当修改次数达到上限时,即使审稿人不通过也强制结束。

3.3 创建专业智能体

使用create_react_agent创建三个专业Agent。每个Agent有独立的系统提示词和工具集:

python

from langgraph.prebuilt import create_react_agent from langchain_openai import ChatOpenAI model = ChatOpenAI(model="gpt-4o", temperature=0.1) # 研究员:负责收集和分析资料 researcher = create_react_agent( model, tools=[web_search, arxiv_search], prompt="你是一个资深研究员,专注于收集和分析技术资料。" "根据给定的研究主题,收集3-5个关键信息点," "每个信息点包含来源和核心内容。" ) # 写作者:负责将研究笔记转化为文章 writer = create_react_agent( model, tools=[write_document, format_markdown], prompt="你是一个技术写作专家,擅长将复杂概念转化为清晰文章。" "基于研究员提供的笔记,撰写一篇结构完整的文章。" "如果收到审稿意见,根据意见修改草稿。" ) # 审稿人:负责质量把关 reviewer = create_react_agent( model, tools=[check_facts, grammar_check], prompt="你是一个严格的审稿人,确保内容的准确性和质量。" "评估文章是否满足以下标准:" "1. 事实准确,无编造内容" "2. 结构清晰,逻辑连贯" "3. 语言流畅,无语法错误" "输出JSON格式:{\"verdict\": \"PASS\" 或 \"REWORK\", \"feedback\": \"具体修改建议\"}" )

注意create_react_agent的prompt参数——它定义了Agent的角色和行为准则。审稿人的提示词中明确要求输出JSON格式,这是后续条件边能够正确解析判定的前提。

3.4 编写节点函数

每个节点是一个Python函数,接收状态对象,返回要更新的状态字段:

python

def researcher_node(state: ResearchState): """研究员节点:根据主题收集信息""" result = researcher.invoke({ "messages": [{"role": "user", "content": f"研究主题:{state['topic']}\n请收集相关信息。"}] }) return { "notes": [result["messages"][-1].content], "revision_count": 0 # 初始化修改次数 } def writer_node(state: ResearchState): """写作者节点:基于笔记撰写或修改草稿""" if state.get("feedback"): # 有审稿反馈,是修改场景 prompt = f"""研究主题:{state['topic']} 研究笔记:{state['notes']} 上一版草稿:{state['draft']} 审稿意见:{state['feedback']} 请根据审稿意见修改草稿。""" else: # 首次写作 prompt = f"""研究主题:{state['topic']} 研究笔记:{state['notes']} 请基于以上笔记撰写一篇结构完整的文章。""" result = writer.invoke({"messages": [{"role": "user", "content": prompt}]}) return {"draft": result["messages"][-1].content} def reviewer_node(state: ResearchState): """审稿人节点:评估草稿质量,输出PASS或REWORK""" prompt = f"""请审阅以下文章: 主题:{state['topic']} 草稿:{state['draft']} 请评估文章质量,输出JSON格式的审稿结果。""" result = reviewer.invoke({"messages": [{"role": "user", "content": prompt}]}) import json content = result["messages"][-1].content # 从模型输出中提取JSON try: parsed = json.loads(content) except json.JSONDecodeError: # 处理Markdown代码块包裹的情况 import re match = re.search(r'\{.*\}', content, re.DOTALL) parsed = json.loads(match.group(0)) if match else {"verdict": "PASS", "feedback": ""} return { "verdict": parsed.get("verdict", "PASS"), "feedback": parsed.get("feedback", ""), "revision_count": state.get("revision_count", 0) + 1 }

3.5 定义条件边

条件边是流水线的核心控制逻辑。审稿人返回结果后,系统根据verdict字段决定下一步:

python

def route_after_review(state: ResearchState) -> str: """审稿后的路由决策""" # 达到最大修改次数,强制通过 if state.get("revision_count", 0) >= 3: return "finish" # 审稿通过 if state.get("verdict") == "PASS": return "finish" # 审稿不通过,退回写作者修改 return "rework"

最大修改次数限制是必须的。没有这个限制,审稿人可能永远不满意,导致无限循环和Token浪费。

3.6 构建图

将所有节点和边组装成完整的图:

python

from langgraph.graph import StateGraph, START, END # 创建图,指定状态类型 workflow = StateGraph(ResearchState) # 添加节点 workflow.add_node("researcher", researcher_node) workflow.add_node("writer", writer_node) workflow.add_node("reviewer", reviewer_node) # 添加边:线性流程 workflow.add_edge(START, "researcher") workflow.add_edge("researcher", "writer") workflow.add_edge("writer", "reviewer") # 添加条件边:审稿后的分支 workflow.add_conditional_edges( "reviewer", route_after_review, { "rework": "writer", # 退回写作者修改 "finish": END # 审稿通过,结束 } ) # 编译图 app = workflow.compile()

条件边的三个参数分别是:源节点名称、路由函数、目标映射字典。路由函数返回映射中的键,LangGraph据此决定下一步走向哪个节点。

3.7 运行完整流水线

python

result = app.invoke({ "topic": "LangGraph在2026年的多智能体协作能力", "notes": [], "draft": "", "verdict": "", "feedback": "", "revision_count": 0, "messages": [] }) print(f"最终草稿:\n{result['draft']}") print(f"\n修改次数:{result['revision_count']}") print(f"审稿结果:{result['verdict']}")

运行后,如果审稿人判定为REWORK,图会自动回到writer节点,携带feedback状态,写作者据此修改草稿,然后再次进入reviewer节点。这个循环最多执行3次,之后强制结束。

四、状态管理与持久化

4.1 为什么需要持久化

上面的示例使用内存中的状态,进程结束后所有状态丢失。生产级系统需要Checkpointer来持久化状态,支持跨会话恢复和断点续跑。

python

from langgraph.checkpoint.sqlite import SqliteSaver # 使用SQLite作为持久化存储 memory = SqliteSaver.from_conn_string("checkpoints.db") app = workflow.compile(checkpointer=memory) # 运行时指定thread_id config = {"configurable": {"thread_id": "research_001"}} result = app.invoke(initial_state, config)

SqliteSaver将每一步的状态快照写入SQLite数据库,进程重启后可以通过相同的thread_id恢复会话。

4.2 消息历史的独立管理

在多智能体系统中,每个Agent可能需要独立的对话历史,而不是共享全部消息。LangGraph的子图(Subgraph)机制支持这一点:每个Agent可以作为子图运行,拥有自己的消息历史,只向父图暴露必要的输出。

五、常见问题与优化建议

5.1 无限循环

最常见的问题。审稿人永远不满意,写作者反复修改但无法达标。解决方案:在状态中记录修改次数,达到上限后强制通过。推荐上限为3次。

5.2 工具选择困难

给单个Agent配备过多工具会导致“选择恐惧症”。解决方案:让每个Agent只持有与其角色相关的工具。研究员只需要搜索工具,写作者只需要写作工具,审稿人只需要校验工具。

5.3 状态膨胀

随着修改次数增加,状态对象中的草稿和反馈会不断累积,导致上下文膨胀。解决方案:在写作者节点中,不将全部历史草稿传给LLM,只传上一版草稿和当前反馈。

5.4 成本控制

每次审稿和修改都是一次完整的LLM调用。优化方案:使用模型路由——研究员用轻量模型(如glm-4-flash)做并行检索,写作者和审稿人用高质量模型保证输出质量。

六、总结

本文从框架选型出发,系统梳理了LangGraph多智能体协作的核心概念与实践方法。关键要点可以归纳为五条:

  1. 框架选择:以LangGraph为主线,create_react_agent创建专业Agent,StateGraph组织流程。

  2. 协作模式:Supervisor适合集中控制,Handoff适合动态流转,显式图结构适合确定性流水线。

  3. 状态管理:所有Agent共享类型化状态对象,通过节点函数读写状态字段。

  4. 条件边:用路由函数决定下一步走向,实现“审稿不通过则退回修改”的循环逻辑。

  5. 防循环:在状态中记录修改次数,达到上限后强制结束,避免Token浪费。

从单Agent循环到多Agent图结构,是从“模型自行判断路径”到“代码显式控制流程”的转变。这个转变让你的Agent系统从不可预测的黑箱,变成可以在 diff 中读出的、可控可调试的工程结构。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/14 3:23:43

图邻接矩阵创建全解析:C语言结构体定义、初始化与常见坑

1. 为什么用邻接矩阵入门图的存储不管你是正在啃数据结构期末考试的大二学生,还是准备考研刷题的准研究生,肯定都被图这个章节卡过那么一下。图的存储方式那么多——邻接矩阵、邻接表、十字链表、邻接多重表——第一次接触时确实容易一头雾水。我自己的感…

作者头像 李华
网站建设 2026/10/14 3:23:10

心率变异性时域分析:核心指标与临床应用详解

1. 心率变异性(HRV)基础概念解析心率变异性(Heart Rate Variability, HRV)是指连续心跳间期(RR间期)存在的微小波动现象。这种看似"不规律"的心跳间隔变化,实际上是人体自主神经系统功…

作者头像 李华
网站建设 2026/10/14 3:23:08

【CS336】lecture7 多卡|通信架构|集合通信|NCCL|通信原语|torch.distributed

多GPU通信架构这讲开始,进入多GPU并行。整体结构如上,我们前几讲了解的是单GPU的结构,在此之上还有更高的层次:单节点多GPU之间通过NVLink和NVSwitch连接,这也被称为单机多卡。多节点之间通过以太网或Infiniband连接&a…

作者头像 李华
网站建设 2026/10/14 3:22:56

STM32F407与LAN8720嵌入式以太网方案:FreeRTOS+LWIP实现UDP通信

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/14 3:22:40

Hive数据清洗实战:数仓脏数据治理与SQL技巧详解

做大数据分析的人,十有八九都遇到过这种场景:数仓里同一张订单表,日期字段同一天既有2024-06-01,又有20240601,还有2024/06/01的写法;同一个用户ID,接口侧存的是userId_123,数据库侧…

作者头像 李华