0Pricing
AI Engineering Academy · 课时

使用 LangGraph 构建多智能体流程

使用 LangGraph 在有向图中定义智能体节点、条件边和共享状态,从而支持包含循环、分支和人在回路检查点的复杂多智能体工作流。

使用 LangGraph 构建多智能体流程 是 CoddyKit 上的免费 AI Engineering Academy 课时。 这是第 3 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 AI Engineering Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 AI Engineering Academy 课程共包含 4 节课。

什么是 LangGraph

LangGraph 是一个构建于 LangChain 之上的库,可让您将多代理工作流定义为有向图。图中的节点表示代理或处理步骤,边表示状态在节点之间的流动,条件边则允许根据当前状态进行动态路由。LangGraph 负责执行引擎、状态持久化以及人在回路中的检查点。

# pip install langgraph
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator

# Define your shared state schema
class AgentState(TypedDict):
    messages: Annotated[list, operator.add]  # append-only list
    research: str
    draft: str
    status: str

在 LangGraph 中定义状态

每个 LangGraph 工作流都基于一个共享的状态对象运行,所有节点都可以读取和写入该对象。状态是一个类型化字典(TypedDict),负责在图中传递数据。节点运行时会接收当前状态,执行相应工作,然后返回一个更新字典,将其合并到状态中。这种共享状态模型使代理能够在不直接耦合的情况下进行通信。

from typing import TypedDict

class ResearchState(TypedDict):
    query: str           # input from user
    research_notes: str  # filled by researcher node
    written_draft: str   # filled by writer node
    review_feedback: str # filled by reviewer node
    final_output: str    # filled by synthesizer node
    iteration_count: int # tracks how many revision loops occurred

# Each node returns a PARTIAL update - only the keys it modifies
def researcher_node(state: ResearchState) -> dict:
    notes = do_research(state['query'])
    return {'research_notes': notes}  # only update this key

创建代理节点

在 LangGraph 中,每个代理都是一个节点函数:它接收当前状态,执行 LLM 调用和工具操作,然后返回状态更新。节点是纯函数——不会存储内部状态。所有状态都保存在共享图状态对象中,因此工作流易于检查、恢复和调试。

from langchain_openai import ChatOpenAI
from langchain_core.messages import SystemMessage, HumanMessage

llm = ChatOpenAI(model='gpt-4o')

def researcher_node(state: ResearchState) -> dict:
    messages = [
        SystemMessage(content='You are a research specialist. Find accurate information.'),
        HumanMessage(content=f'Research this topic: {state["query"]}')
    ]
    response = llm.invoke(messages)
    return {'research_notes': response.content}

def writer_node(state: ResearchState) -> dict:
    messages = [
        SystemMessage(content='You are a technical writer. Write clear, engaging prose.'),
        HumanMessage(content=f'Write a draft using these notes:\n{state["research_notes"]}')
    ]
    response = llm.invoke(messages)
    return {'written_draft': response.content}

使用 StateGraph 构建图

定义节点函数后,您可以使用 StateGraph 将它们连接起来。使用 graph.add_node() 添加节点,使用 graph.add_edge() 添加节点之间的边,使用 graph.set_entry_point() 设置入口点,并使用 graph.compile() 将图编译为可执行对象。编译后的图是一个可运行对象,接受初始状态并返回最终状态。

from langgraph.graph import StateGraph, END

# Build the graph
workflow = StateGraph(ResearchState)

# Add nodes
workflow.add_node('researcher', researcher_node)
workflow.add_node('writer', writer_node)
workflow.add_node('reviewer', reviewer_node)

# Add edges (sequential pipeline)
workflow.set_entry_point('researcher')
workflow.add_edge('researcher', 'writer')
workflow.add_edge('writer', 'reviewer')
workflow.add_edge('reviewer', END)

# Compile into an executable
app = workflow.compile()

# Run it
result = app.invoke({'query': 'What is RAG?', 'iteration_count': 0})
print(result['written_draft'])

用于动态路由的条件边

条件边允许图根据当前状态路由到不同节点。您无需提供固定的边,而是提供一个路由函数,由它检查状态并返回下一个节点的名称。这样便可实现修订循环、质量检查关卡、人工审批步骤,以及根据代理输出内容进行分支。

def should_revise(state: ResearchState) -> str:
    '''Router function: returns the name of the next node.'''
    if state['iteration_count'] >= 3:
        return 'finalize'  # Too many revisions - accept as is
    if 'insufficient' in state.get('review_feedback', '').lower():
        return 'researcher'  # Need more research
    if 'rewrite' in state.get('review_feedback', '').lower():
        return 'writer'  # Needs rewriting
    return 'finalize'  # Looks good

# Add conditional edge from reviewer
workflow.add_conditional_edges(
    'reviewer',                    # from node
    should_revise,                 # routing function
    {
        'researcher': 'researcher', # route name -> node name
        'writer': 'writer',
        'finalize': 'finalizer'
    }
)

LangGraph 中的循环与迭代

LangGraph 原生支持循环——同一个代理可以被多次重新访问。这对于修订周期、失败重试模式和迭代式改进至关重要。请始终在状态中加入循环终止条件(例如迭代计数器或质量分数阈值),并在条件边路由器中强制执行该条件,以防止无限循环。

def researcher_node(state: ResearchState) -> dict:
    notes = do_research(state['query'])
    return {
        'research_notes': notes,
        'iteration_count': state['iteration_count'] + 1  # always increment
    }

def should_continue_research(state: ResearchState) -> str:
    # Terminate loop after 3 iterations regardless of quality
    if state['iteration_count'] >= 3:
        return END
    # Continue if research is incomplete
    if len(state.get('research_notes', '')) < 500:
        return 'researcher'  # loop back
    return 'writer'  # proceed to next stage

并行执行节点

LangGraph 支持使用节点内的 RunnableParallel,或通过向多个节点分发任务来实现并行分支。当独立的子任务需要同时运行时,您可以让一个节点向多个并行节点分发任务,再设置一个汇入节点等待所有并行节点完成,并将它们的结果合并到共享状态中。

# Fan-out: one node triggers multiple parallel ones
workflow.add_edge('planner', 'researcher_a')
workflow.add_edge('planner', 'researcher_b')
workflow.add_edge('planner', 'researcher_c')

# Fan-in: aggregator waits for all three
workflow.add_edge('researcher_a', 'aggregator')
workflow.add_edge('researcher_b', 'aggregator')
workflow.add_edge('researcher_c', 'aggregator')
workflow.add_edge('aggregator', 'writer')

# Aggregator merges parallel results
def aggregator_node(state: ResearchState) -> dict:
    combined = state.get('notes_a', '') + '\n' + state.get('notes_b', '') + '\n' + state.get('notes_c', '')
    return {'research_notes': combined}

检查点与人在回路中

LangGraph 可以通过集成检查点后端(SQLite、Redis 或 PostgreSQL)来支持检查点。启用检查点后,图状态会在每个节点执行后持久化。这样,长时间运行的工作流就可以暂停、检查并恢复。它还支持人在回路中的模式:图在特定节点暂停,等待人工批准或提供输入后再继续。

from langgraph.checkpoint.sqlite import SqliteSaver

# Use SQLite for persistent checkpoints
checkpointer = SqliteSaver.from_conn_string(':memory:')
app = workflow.compile(checkpointer=checkpointer, interrupt_before=['human_review'])

# First run - pauses at human_review node
thread = {'configurable': {'thread_id': 'my-workflow-1'}}
result = app.invoke({'query': 'Analyze competitors'}, config=thread)
# result.next == 'human_review' -- waiting for human input

# Human provides feedback and resumes
app.update_state(thread, {'review_feedback': 'Good research, proceed with writing'})
final = app.invoke(None, config=thread)  # resume from checkpoint

流式输出 LangGraph 结果

LangGraph 支持流式模式:每个节点完成时就发出中间状态更新,而不是等整个工作流结束。对于希望向用户显示部分进度的长流水线,这一功能非常有用。使用 app.stream() 可获取一个迭代器,从每个步骤中取得状态快照。

# Stream intermediate results as each node completes
for event in app.stream({'query': 'What is RAG?'}):
    for node_name, node_output in event.items():
        print(f'Node completed: {node_name}')
        if 'research_notes' in node_output:
            print('Research done:', node_output['research_notes'][:100])
        if 'written_draft' in node_output:
            print('Draft done:', node_output['written_draft'][:100])

可视化图

LangGraph 可以将图绘制为 Mermaid 图表,这对于理解包含大量节点和条件边的复杂工作流非常有帮助。调用 app.get_graph().draw_mermaid_png() 可获取 PNG 图片,调用 app.get_graph().draw_mermaid() 可获取 Mermaid 语法,您可以将其粘贴到任意 Mermaid 渲染器中。

# Visualize the workflow graph
graph_image = app.get_graph().draw_mermaid_png()
with open('workflow.png', 'wb') as f:
    f.write(graph_image)

# Or print Mermaid syntax
print(app.get_graph().draw_mermaid())
# Outputs:
# graph TD
#    __start__ --> researcher
#    researcher --> writer
#    writer --> reviewer
#    reviewer -->|Good| finalize
#    reviewer -->|Needs work| researcher

端到端 LangGraph 代理示例

将所有内容结合起来:完整的 LangGraph 多代理流水线会定义一个 TypedDict 状态,为每个代理创建节点函数,使用 StateGraph 将它们连接起来,为修订循环添加条件边,使用检查点编译,并以初始状态调用。这样,您只需编写极少的样板代码,就能获得可靠、可观测且可恢复的多代理工作流。

快速检查

测试您对本课所学 LangGraph 多代理流水线的理解。

课程回顾

本课中,您学到了:LangGraph 将多代理工作流表示为有向图,其中节点是代理,边表示流转;条件边可根据当前状态实现动态路由、循环和修订周期;检查点允许长时间运行的工作流暂停,并在获得人在回路中的审批后恢复。接下来,我们将探索共享内存和代理间通信。

常见问题解答

「使用 LangGraph 构建多智能体流程」课时是免费的吗?

是的 — 「使用 LangGraph 构建多智能体流程」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 AI Engineering Academy 课程的其余内容,请升级到 CoddyKit PRO。 AI Engineering Academy 课程共包含 4 节课。

「使用 LangGraph 构建多智能体流程」这节课中我会学到什么?

使用 LangGraph 在有向图中定义智能体节点、条件边和共享状态,从而支持包含循环、分支和人在回路检查点的复杂多智能体工作流。 你通过在浏览器中直接运行的动手代码来练习 AI Engineering Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 AI Engineering Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 AI Engineering Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 3 节课,共 4 节。

「使用 LangGraph 构建多智能体流程」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 AI Engineering Academy 课中编写并运行代码吗?

能。每节 AI Engineering Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 单智能体为何会遇到瓶颈
  2. 编排器-子智能体模式
  3. 使用 LangGraph 构建多智能体流程
  4. 共享记忆与智能体间通信
← 返回 AI Engineering Academy