LangGraph多Agent图编排与状态机工作流深度实战:从节点定义到持久化检查点的复杂推理网络构建全解析

举报
江南清风起 发表于 2026/08/31 22:01:17 2026/08/31
【摘要】 LangGraph多Agent图编排与状态机工作流深度实战:从节点定义到持久化检查点的复杂推理网络构建全解析 引言LangChain作为最早的LLM应用框架,其核心抽象Chain(链式调用)在简单场景中高效,但面对多Agent协作、条件分支、循环推理、人机协作(Human-in-the-loop)等复杂需求时捉襟见肘。LangGraph作为LangChain团队2024年推出的图编排框架,...

LangGraph多Agent图编排与状态机工作流深度实战:从节点定义到持久化检查点的复杂推理网络构建全解析

引言

LangChain作为最早的LLM应用框架,其核心抽象Chain(链式调用)在简单场景中高效,但面对多Agent协作、条件分支、循环推理、人机协作(Human-in-the-loop)等复杂需求时捉襟见肘。LangGraph作为LangChain团队2024年推出的图编排框架,以有向图(StateGraph)为核心抽象,节点是处理单元,边定义控制流,共享State在节点间传递与演化,天然支持循环、条件路由、并行分支、持久化检查点与中断恢复。这一范式让构建"研究助手"(多轮搜索-分析-综合)、“代码生成Agent”(规划-编码-测试-修复循环)、“多专家协作系统”(分工+汇总+质疑)等复杂AI应用成为可能。本文将从LangGraph的核心抽象讲起,覆盖StateGraph定义、条件路由、子图与并行、检查点持久化、Human-in-the-loop中断、多Agent架构模式(Supervisor与Swarm)、工具集成、流式输出与可观测性,并提供完整可运行的Python代码。

一、LangGraph核心抽象:StateGraph

1.1 状态、节点与边

LangGraph的三个基石:State(所有节点共享的可变状态,TypedDict或Pydantic定义)、Node(接收state返回更新,纯函数)、Edge(定义节点间控制流,包括固定边与条件边)。以下定义一个基础研究Agent的状态与图:

# langgraph_research/state.py - 共享状态定义
from __future__ import annotations
from typing import Annotated, TypedDict, Literal
from langgraph.graph.message import add_messages
from pydantic import BaseModel, Field

class SearchResult(BaseModel):
    title: str
    url: str
    snippet: str
    relevance: float = 0.0

class ResearchState(TypedDict):
    # 消息历史(add_messages追加而非覆盖)
    messages: Annotated[list, add_messages]
    # 检索到的信息
    search_results: list[SearchResult]
    # 子问题分解
    sub_questions: list[str]
    # 当前处理的子问题索引
    current_sub_index: int
    # 各子问题的部分答案
    partial_answers: list[str]
    # 综合答案
    final_answer: str
    # 控制流标志
    iteration: int
    max_iterations: int
    # 检索质量自评估
    needs_more_research: bool
    # 引用
    citations: list[dict]

1.2 构建第一个图

# langgraph_research/graph.py - 研究Agent图
from langgraph.graph import StateGraph, END, START
from langgraph.checkpoint.memory import MemorySaver
from .state import ResearchState

# ===== 节点定义 =====
async def plan_node(state: ResearchState) -> dict:
    """将用户问题分解为子问题"""
    from langchain_openai import ChatOpenAI
    from langchain_core.messages import HumanMessage, SystemMessage
    llm = ChatOpenAI(model="gpt-4o", temperature=0)
    user_question = state["messages"][-1].content
    response = await llm.ainvoke([
        SystemMessage(content="""将用户的研究问题分解为2-4个子问题。
        每个子问题应能独立检索回答。输出JSON:{"sub_questions": [...]}"""),
        HumanMessage(content=user_question),
    ])
    import json
    plan = json.loads(response.content)
    return {
        "sub_questions": plan["sub_questions"],
        "current_sub_index": 0,
        "partial_answers": [""] * len(plan["sub_questions"]),
        "max_iterations": len(plan["sub_questions"]),
        "iteration": 0,
    }

async def search_node(state: ResearchState) -> dict:
    """对当前子问题执行搜索"""
    idx = state["current_sub_index"]
    sub_q = state["sub_questions"][idx]
    # 调用搜索工具(示例用模拟)
    results = await web_search(sub_q, top_k=5)
    return {"search_results": results}

async def analyze_node(state: ResearchState) -> dict:
    """分析检索结果,生成部分答案"""
    from langchain_openai import ChatOpenAI
    llm = ChatOpenAI(model="gpt-4o", temperature=0.2)
    idx = state["current_sub_index"]
    sub_q = state["sub_questions"][idx]
    context = "\n".join(
        f"[{i}] {r.title}: {r.snippet}" for i, r in enumerate(state["search_results"])
    )
    response = await llm.ainvoke([
        {"role": "system", "content": "基于检索结果回答子问题。标注来源[编号]。"},
        {"role": "user", "content": f"子问题:{sub_q}\n\n检索结果:\n{context}"},
    ])
    partial = state["partial_answers"]
    partial[idx] = response.content
    return {"partial_answers": partial}

async def reflect_node(state: ResearchState) -> dict:
    """反思:当前部分答案是否充分"""
    from langchain_openai import ChatOpenAI
    llm = ChatOpenAI(model="gpt-4o-mini", temperature=0)
    idx = state["current_sub_index"]
    sub_q = state["sub_questions"][idx]
    partial = state["partial_answers"][idx]
    response = await llm.ainvoke([
        {"role": "system", "content": "评估部分答案是否充分回答了子问题。输出JSON:{\"sufficient\": true/false, \"gap\": \"缺失信息描述\"}"},
        {"role": "user", "content": f"子问题:{sub_q}\n答案:{partial[:500]}"},
    ])
    import json
    eval = json.loads(response.content)
    return {"needs_more_research": not eval["sufficient"]}

async def synthesize_node(state: ResearchState) -> dict:
    """综合所有部分答案为最终回答"""
    from langchain_openai import ChatOpenAI
    llm = ChatOpenAI(model="gpt-4o", temperature=0.3)
    parts = "\n\n---\n\n".join(
        f"子问题{i+1}: {state['sub_questions'][i]}\n答案: {state['partial_answers'][i]}"
        for i in range(len(state["sub_questions"]))
    )
    user_question = state["messages"][-1].content
    response = await llm.ainvoke([
        {"role": "system", "content": "综合各子问题的回答,给出对原始问题的完整回答。保持引用编号。"},
        {"role": "user", "content": f"原始问题:{user_question}\n\n子问题与答案:\n{parts}"},
    ])
    return {"final_answer": response.content,
            "messages": [{"role": "assistant", "content": response.content}]}

# ===== 条件路由 =====
def should_continue_research(state: ResearchState) -> str:
    """反思后决定:补充检索 or 下一个子问题 or 综合"""
    if state["needs_more_research"] and state["iteration"] < 2:
        return "search_again"
    if state["current_sub_index"] < len(state["sub_questions"]) - 1:
        return "next_sub"
    return "synthesize"

def route_after_plan(state: ResearchState) -> str:
    if not state["sub_questions"]:
        return "synthesize"
    return "search"

# ===== 构图 =====
def build_research_graph():
    graph = StateGraph(ResearchState)
    graph.add_node("plan", plan_node)
    graph.add_node("search", search_node)
    graph.add_node("analyze", analyze_node)
    graph.add_node("reflect", reflect_node)
    graph.add_node("synthesize", synthesize_node)

    graph.add_edge(START, "plan")
    graph.add_conditional_edges("plan", route_after_plan, {
        "search": "search",
        "synthesize": "synthesize",
    })
    graph.add_edge("search", "analyze")
    graph.add_edge("analyze", "reflect")
    graph.add_conditional_edges("reflect", should_continue_research, {
        "search_again": "search",
        "next_sub": "advance_index",
        "synthesize": "synthesize",
    })

    # 子问题推进节点
    def advance_index(state: ResearchState) -> dict:
        return {"current_sub_index": state["current_sub_index"] + 1,
                "iteration": 0}
    graph.add_node("advance_index", advance_index)
    graph.add_edge("advance_index", "search")

    graph.add_edge("synthesize", END)

    checkpointer = MemorySaver()
    return graph.compile(checkpointer=checkpointer)

async def web_search(query: str, top_k: int = 5) -> list:
    """模拟搜索工具"""
    return [
        type("S", (), {
            "title": f"Result {i} for {query}",
            "url": f"https://example.com/{i}",
            "snippet": f"Snippet about {query}...",
            "relevance": 0.8 - i * 0.1,
        })() for i in range(top_k)
    ]

二、条件路由与并行分支

2.1 条件边的Map模式

LangGraph的条件边用dict映射返回值到节点名,清晰且可测试。复杂路由逻辑(如基于LLM的意图分类)封装为纯函数:

# langgraph_code_agent/router.py - 代码Agent的意图路由
def route_intent(state: CodeAgentState) -> str:
    """根据用户意图路由到不同处理节点"""
    last_message = state["messages"][-1].content.lower()
    if any(kw in last_message for kw in ["实现", "创建", "写一个"]):
        return "implement"
    if any(kw in last_message for kw in ["修复", "bug", "错误"]):
        return "diagnose"
    if any(kw in last_message for kw in ["重构", "优化", "简化"]):
        return "refactor"
    if any(kw in last_message for kw in ["解释", "分析", "为什么"]):
        return "explain"
    return "clarify"

graph.add_conditional_edges("intent_classifier", route_intent, {
    "implement": "plan_implementation",
    "diagnose": "diagnose_bug",
    "refactor": "plan_refactor",
    "explain": "explain_code",
    "clarify": "ask_clarification",
})

2.2 并行扇出与汇聚

LangGraph通过Send API实现动态并行:一个节点扇出多个子任务并行执行,结果汇聚后继续。以下实现多文件分析并行扇出:

# langgraph_parallel/fanout.py - 并行文件分析
from langgraph.graph import StateGraph, START, END
from langgraph.constants import Send
from typing import Annotated
import operator

class AnalysisState(TypedDict):
    files: list[str]
    results: Annotated[list, operator.add]   # 并行结果追加合并
    summary: str

async def dispatch_analyses(state: AnalysisState) -> list[Send]:
    """为每个文件创建并行分析任务"""
    return [
        Send("analyze_file", {"file": f, "results": []})
        for f in state["files"]
    ]

async def analyze_file(state: dict) -> dict:
    """单个文件分析(并行执行)"""
    file = state["file"]
    # 实际调用LLM分析
    result = f"分析结果: {file} 包含3个函数,复杂度中等"
    return {"results": [result]}

async def summarize(state: AnalysisState) -> dict:
    """汇聚并行结果生成摘要"""
    all_results = "\n".join(state["results"])
    return {"summary": f"共分析{len(state['results'])}个文件:\n{all_results}"}

graph = StateGraph(AnalysisState)
graph.add_node("analyze_file", analyze_file)
graph.add_node("summarize", summarize)
graph.add_conditional_edges(START, dispatch_analyses, ["analyze_file"])
graph.add_edge("analyze_file", "summarize")
graph.add_edge("summarize", END)
compiled = graph.compile()

三、检查点持久化与中断恢复

3.1 持久化后端

MemorySaver仅存内存,生产环境需要数据库后端。LangGraph支持PostgreSQL、Redis等:

# langgraph_persistence/checkpoint.py - PostgreSQL检查点
from langgraph.checkpoint.postgres import PostgresSaver
from psycopg_pool import ConnectionPool

pool = ConnectionPool(
    conninfo="postgresql://user:pass@localhost:5432/langgraph",
    max_size=20,
)
checkpointer = PostgresSaver(conn=pool)
checkpointer.setup()  # 创建表结构

graph = build_research_graph().compile(checkpointer=checkpointer)

3.2 Human-in-the-loop中断

LangGraph的interrupt_before/interrupt_after让图在指定节点暂停,等待人工介入后继续。典型场景:代码修改前需要人工确认、危险操作需要审批:

# langgraph_hitl/human_approval.py - 人机协作中断
from langgraph.graph import StateGraph, START, END
from langgraph.checkpoint.memory import MemorySaver

class DeployState(TypedDict):
    change_description: str
    proposed_code: str
    test_results: dict
    approved: bool
    deployed: bool

async def propose_change(state: DeployState) -> dict:
    return {"proposed_code": "diff --git a/...", 
            "change_description": "Add rate limiting"}

async def run_tests(state: DeployState) -> dict:
    return {"test_results": {"passed": 42, "failed": 0}}

async def deploy(state: DeployState) -> dict:
    return {"deployed": True}

graph = StateGraph(DeployState)
graph.add_node("propose", propose_change)
graph.add_node("test", run_tests)
graph.add_node("deploy", deploy)

graph.add_edge(START, "propose")
graph.add_edge("propose", "test")
# 关键:在deploy前暂停,等待人工审批
graph.add_edge("test", "deploy")
graph.add_edge("deploy", END)

# interrupt_before让图在进入deploy前暂停
compiled = graph.compile(
    checkpointer=MemorySaver(),
    interrupt_before=["deploy"],
)

# 使用示例:第一次运行到deploy前暂停
config = {"configurable": {"thread_id": "deploy-001"}}
result = await compiled.ainvoke(
    {"change_description": "Add rate limiting"}, config,
)
# 此时图暂停在deploy节点前

# 人工审核proposed_code后,更新state并恢复
state = await compiled.aget_state(config)
if human_approves(state.values["proposed_code"]):
    # 恢复执行
    result = await compiled.ainvoke(None, config)  # 传None继续

3.3 动态更新状态

人工介入时可更新State再恢复,实现"修改计划后继续":

# 人工修改代码后恢复
await compiled.aupdate_state(
    config,
    {"proposed_code": revised_code, "approved": True},
)
result = await compiled.ainvoke(None, config)

四、多Agent架构模式

4.1 Supervisor模式

Supervisor作为中心调度器,决定调用哪个专家Agent、何时汇总、何时结束。适合任务边界清晰、需要中央控制的场景:

# langgraph_multiagent/supervisor.py - Supervisor编排
from langgraph.graph import StateGraph, START, END
from langchain_openai import ChatOpenAI
import json

class TeamState(TypedDict):
    messages: Annotated[list, add_messages]
    team_members: list[str]
    next_speaker: str
    task_complete: bool
    final_report: str

EXPERTS = {
    "researcher": "负责信息检索与事实核查",
    "analyst": "负责数据分析与统计建模",
    "writer": "负责撰写报告与文案",
    "reviewer": "负责质量审核与逻辑检查",
}

async def supervisor(state: TeamState) -> dict:
    """Supervisor:决定下一个发言者与是否完成"""
    llm = ChatOpenAI(model="gpt-4o", temperature=0)
    conversation = "\n".join(
        f"{m['role']}: {m['content'][:200]}" for m in state["messages"][-6:]
    )
    response = await llm.ainvoke([
        {"role": "system", "content": f"""你是团队主管,协调以下专家完成任务:
{json.dumps(EXPERTS, ensure_ascii=False, indent=2)}

决定下一步:调用某专家 or 完成任务(输出"FINISH")。
输出JSON:{{"next": "expert_name 或 FINISH", "instruction": "给该专家的指令"}}"""},
        {"role": "user", "content": f"对话历史:\n{conversation}\n\n原始任务:{state['messages'][0]['content']}"},
    ])
    decision = json.loads(response.content)
    if decision["next"] == "FINISH":
        return {"task_complete": True, "next_speaker": "FINISH"}
    # 将supervisor指令注入为消息
    return {
        "next_speaker": decision["next"],
        "messages": [{"role": "supervisor", "content": decision["instruction"]}],
    }

async def expert_node_factory(expert_name: str):
    """创建专家节点:每个专家有不同系统提示"""
    llm = ChatOpenAI(model="gpt-4o", temperature=0.3)
    system_prompt = EXPERT_SYSTEMS[expert_name]
    async def expert_node(state: TeamState) -> dict:
        last_msg = state["messages"][-1]
        response = await llm.ainvoke([
            {"role": "system", "content": system_prompt},
            {"role": "user", "content": f"指令:{last_msg['content']}\n\n对话上下文:{[m['content'][:100] for m in state['messages'][-3:]]}"},
        ])
        return {"messages": [{"role": expert_name, "content": response.content}]}
    return expert_node

def route_from_supervisor(state: TeamState) -> str:
    if state["task_complete"]:
        return "finalize"
    return state["next_speaker"]

# 构图
graph = StateGraph(TeamState)
graph.add_node("supervisor", supervisor)
for name in EXPERTS:
    graph.add_node(name, await expert_node_factory(name))
graph.add_node("finalize", finalize_node)

graph.add_edge(START, "supervisor")
graph.add_conditional_edges("supervisor", route_from_supervisor, {
    "finalize": "finalize",
    **{name: name for name in EXPERTS},
})
for name in EXPERTS:
    graph.add_edge(name, "supervisor")  # 专家完成后回supervisor
graph.add_edge("finalize", END)

async def finalize_node(state: TeamState) -> dict:
    llm = ChatOpenAI(model="gpt-4o", temperature=0.2)
    response = await llm.ainvoke([
        {"role": "system", "content": "综合团队讨论,生成最终报告。"},
        {"role": "user", "content": "\n".join(m["content"] for m in state["messages"])},
    ])
    return {"final_report": response.content}

4.2 Swarm模式

Swarm模式中Agent间直接传递控制权(handoff),无中心调度。适合对话式场景,Agent根据消息内容自主决定交接:

# langgraph_multiagent/swarm.py - Swarm handoff
from langgraph.graph import StateGraph, START, END

class SwarmState(TypedDict):
    messages: Annotated[list, add_messages]
    current_agent: str
    context: dict

HANDOFF_TOOLS = {
    "triage": {
        "name": "transfer_to_billing",
        "description": "转交账单问题专家",
        "target": "billing",
    },
    "billing": {
        "name": "transfer_to_tech",
        "description": "转交技术支持专家",
        "target": "tech",
    },
}

async def triage_agent(state: SwarmState) -> dict:
    llm = ChatOpenAI(model="gpt-4o", temperature=0)
    # Agent可用handoff工具决定交接
    response = await llm.ainvoke([
        {"role": "system", "content": "你是分流Agent。判断问题类型并转交。"},
        {"role": "user", "content": state["messages"][-1]["content"]},
    ])
    # 简化:基于内容判断是否需要交接
    if "账单" in response.content or "付款" in response.content:
        return {"current_agent": "billing",
                "messages": [{"role": "triage", "content": "转交账单专家"}]}
    return {"messages": [{"role": "triage", "content": response.content}]}

async def billing_agent(state: SwarmState) -> dict:
    # 处理账单问题,必要时转交tech
    ...

def route_swarm(state: SwarmState) -> str:
    return state["current_agent"]

五、工具集成与ReAct循环

5.1 工具节点与错误恢复

LangGraph的工具调用通过ToolNode封装,自动处理工具调用与结果回传。错误恢复是生产关键:

# langgraph_tools/react_agent.py - ReAct Agent with error recovery
from langgraph.graph import StateGraph, START, END
from langgraph.prebuilt import ToolNode
from langchain_core.tools import tool
from langchain_openai import ChatOpenAI

@tool
def execute_sql(query: str) -> str:
    """执行只读SQL查询"""
    # 实际执行
    return f"Query result for: {query}"

@tool
def search_docs(query: str) -> str:
    """搜索内部文档"""
    return f"Docs for: {query}"

@tool
def run_tests(file_path: str) -> str:
    """运行测试文件"""
    return f"All tests passed in {file_path}"

tools = [execute_sql, search_docs, run_tests]
tool_node = ToolNode(tools)

llm = ChatOpenAI(model="gpt-4o", temperature=0).bind_tools(tools)

async def agent_node(state: dict) -> dict:
    response = await llm.ainvoke(state["messages"])
    return {"messages": [response]}

def should_use_tools(state: dict) -> str:
    last_msg = state["messages"][-1]
    if hasattr(last_msg, "tool_calls") and last_msg.tool_calls:
        return "tools"
    return END

async def tool_error_handler(state: dict) -> dict:
    """工具执行失败时的恢复节点"""
    last_msg = state["messages"][-1]
    if hasattr(last_msg, "status") and last_msg.status == "error":
        # 向模型报告错误让它自行修正
        error_msg = f"工具执行失败:{last_msg.content}。请修正查询后重试。"
        return {"messages": [{"role": "tool", "content": error_msg,
                               "tool_call_id": last_msg.tool_call_id}]}
    return {}

graph = StateGraph({"messages": Annotated[list, add_messages]})
graph.add_node("agent", agent_node)
graph.add_node("tools", tool_node)
graph.add_node("error_handler", tool_error_handler)

graph.add_edge(START, "agent")
graph.add_conditional_edges("agent", should_use_tools, {
    "tools": "tools", END: END,
})
# 工具结果回到error_handler检查,再回agent
graph.add_edge("tools", "error_handler")
graph.add_edge("error_handler", "agent")

compiled = graph.compile()

六、流式输出与可观测性

6.1 流式Token输出

LangGraph支持节点级流式,让用户实时看到Agent的推理过程:

# langgraph_streaming/stream.py - 流式输出
async def stream_research(graph, question: str):
    config = {"configurable": {"thread_id": "research-001"}}
    # astream提供三种流模式
    async for mode, chunk in graph.astream(
        {"messages": [{"role": "user", "content": question}]},
        config, stream_mode="updates",
    ):
        # updates模式:每个节点的状态更新
        for node_name, update in chunk.items():
            print(f"[{node_name}] 更新: {list(update.keys())}")
            if "messages" in update:
                for msg in update["messages"]:
                    print(f"  {msg.get('role', 'system')}: {msg['content'][:100]}...")

    # values模式:获取每步完整状态快照
    async for chunk in graph.astream(
        {"messages": [{"role": "user", "content": question}]},
        config, stream_mode="values",
    ):
        print(f"当前子问题索引: {chunk.get('current_sub_index', 0)}")

    # messages模式:逐token流式LLM输出
    async for msg, metadata in graph.astream(
        {"messages": [{"role": "user", "content": question}]},
        config, stream_mode="messages",
    ):
        if msg.content:
            print(msg.content, end="", flush=True)

6.2 LangSmith可观测性

LangGraph与LangSmith深度集成,自动追踪每个节点的输入输出、LLM调用、工具执行:

import os
os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = "ls__..."
os.environ["LANGSMITH_PROJECT"] = "research-agent-prod"

# 设置后所有graph.invoke/astream自动上报到LangSmith
# 在LangSmith UI可看到:
# - 节点执行时间线
# - 每个节点的输入输出state diff
# - LLM调用的prompt/completion/token数
# - 工具调用的参数与返回
# - 条件路由的决策路径

七、生产部署与运维

7.1 长时运行与并发管理

生产LangGraph服务需要管理长时运行的图执行(多轮Agent可能运行数分钟),关键设计:异步非阻塞(FastAPI + async),检查点让任意中断可恢复,线程/会话隔离(thread_id),超时与熔断。以下是一个生产级API服务:

# server/main.py - LangGraph生产API
from fastapi import FastAPI, BackgroundTasks
from pydantic import BaseModel
from langgraph.checkpoint.postgres import PostgresSaver
from contextlib import asynccontextmanager
import asyncio

app = FastAPI()
graph = None

@asynccontextmanager
async def lifespan(app: FastAPI):
    global graph
    pool = ConnectionPool(...)
    checkpointer = PostgresSaver(conn=pool)
    checkpointer.setup()
    graph = build_research_graph().compile(checkpointer=checkpointer)
    yield
    pool.close()

app = FastAPI(lifespan=lifespan)

class QueryRequest(BaseModel):
    thread_id: str
    question: str
    stream: bool = False

@app.post("/research")
async def research(req: QueryRequest):
    config = {"configurable": {"thread_id": req.thread_id}}
    if req.stream:
        return StreamingResponse(
            stream_graph(req, config),
            media_type="text/event-stream",
        )
    result = await asyncio.wait_for(
        graph.ainvoke(
            {"messages": [{"role": "user", "content": req.question}]},
            config,
        ),
        timeout=300,  # 5分钟超时
    )
    return {"answer": result.get("final_answer", ""),
            "citations": result.get("citations", [])}

async def stream_graph(req, config):
    async for mode, chunk in graph.astream(
        {"messages": [{"role": "user", "content": req.question}]},
        config, stream_mode="updates",
    ):
        yield f"data: {json.dumps({'node': list(chunk.keys())})}\n\n"
    yield f"data: [DONE]\n\n"

@app.get("/research/{thread_id}/state")
async def get_state(thread_id: str):
    """获取会话当前状态(支持前端恢复中断的会话)"""
    config = {"configurable": {"thread_id": thread_id}}
    state = await graph.aget_state(config)
    return {
        "values": state.values,
        "next": state.next,  # 下一个要执行的节点
        "interrupted": state.next is not None and len(state.tasks) > 0,
    }

总结

LangGraph代表了LLM应用编排范式的成熟:从线性的Chain走向图状的StateGraph,节点是处理单元、边是控制流、共享State在节点间演化,条件路由实现意图分发,Send API实现并行扇出汇聚,检查点持久化让任意中断可恢复,Human-in-the-loop让图在关键节点暂停等待人工审批,Supervisor与Swarm两种多Agent模式分别覆盖中心调度与对等交接场景,工具节点与ReAct循环连接外部能力,流式输出与LangSmith可观测性让Agent推理过程透明可调试。工程实践的核心原则:节点保持纯函数(便于测试与重放),State用TypedDict明确定义(类型安全+减少隐式依赖),条件路由函数可独立测试,长时图必须配检查点(崩溃恢复是生产底线),Human-in-the-loop中断点要前置设计(而非事后补丁),多Agent模式按任务结构选择(Supervisor适合流程化任务,Swarm适合对话式交接)。当Agent应用从单轮问答走向多步推理、从单体走向多Agent协作、从一次性走向可中断可恢复的长期任务,LangGraph的图编排抽象正是支撑这一跃迁的工程基础设施。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。