LangGraph从入门到精通

225 阅读14分钟

LangGraph从入门到精通

目录

  1. LangGraph概述
  2. 核心概念
  3. 安装和环境配置
  4. 基础用法
  5. 图结构设计
  6. 状态管理
  7. 节点和边的高级用法
  8. 条件路由

1. LangGraph概述

1.1 什么是LangGraph

LangGraph是LangChain生态系统中的一个核心组件,专门用于构建有状态的、多参与者的应用程序,特别是在大语言模型(LLM)应用中。它提供了一个基于图的框架,用于定义复杂的工作流程和状态转换。

1.2 核心特性

  • 有状态性:维护跨步骤的应用状态
  • 图结构:使用节点和边定义复杂的执行流程
  • 人工干预:支持在执行过程中进行人工审核和修正
  • 持久化:提供检查点机制,支持长时间运行的工作流
  • 流式处理:支持实时流式输出
  • 条件路由:基于状态或条件进行动态路由选择

1.3 适用场景

  • 多代理系统:协调多个AI代理协作完成任务
  • 复杂对话系统:处理多轮对话和上下文管理
  • 工作流自动化:构建复杂的业务流程自动化
  • 决策支持系统:需要多步骤分析和决策的应用
  • 代码生成和审查:自动化代码生成、测试和审查流程

1.4 与传统链式架构的对比

特性LangChain ChainLangGraph
结构线性链式图状结构
状态管理有限完整的状态管理
条件分支困难原生支持
人工干预不支持原生支持
持久化简单完整的检查点机制
复杂度简单场景复杂工作流

2. 核心概念

2.1 图(Graph)

图是LangGraph的基本结构,由节点(Node)和边(Edge)组成:

from langgraph.graph import StateGraph

# 创建一个状态图
workflow = StateGraph(State)

2.2 状态(State)

状态是在图执行过程中维护的数据结构:

from typing import TypedDict, List

class State(TypedDict):
    messages: List[str]
    current_step: str
    user_input: str
    result: str

2.3 节点(Node)

节点代表执行的具体操作或功能:

def process_node(state: State) -> State:
    # 处理逻辑
    state["current_step"] = "processing"
    return state

# 添加节点
workflow.add_node("process", process_node)

2.4 边(Edge)

边定义了节点之间的连接和转换条件:

# 无条件边
workflow.add_edge("start", "process")

# 条件边
workflow.add_conditional_edges(
    "process",
    condition_function,
    {
        "continue": "next_step",
        "end": END
    }
)

2.5 入口点和结束点

from langgraph.graph import START, END

workflow.set_entry_point("start")
workflow.add_edge("final", END)

3. 安装和环境配置

3.1 安装LangGraph

# 基础安装
pip install langgraph

# 完整安装(包含所有依赖)
pip install "langgraph[all]"

# 开发版本
pip install git+https://github.com/langchain-ai/langgraph.git

3.2 必要依赖

pip install langchain
pip install langchain-openai
pip install python-dotenv

3.3 环境变量配置

import os
from dotenv import load_dotenv

load_dotenv()

# 设置API密钥
os.environ["OPENAI_API_KEY"] = "your-openai-api-key"
os.environ["LANGCHAIN_API_KEY"] = "your-langchain-api-key"
os.environ["LANGCHAIN_TRACING_V2"] = "true"

3.4 验证安装

import langgraph
print(f"LangGraph version: {langgraph.__version__}")

# 简单测试
from langgraph.graph import StateGraph
print("LangGraph installed successfully!")

4. 基础用法

4.1 创建第一个LangGraph应用

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

# 定义状态
class BasicState(TypedDict):
    input: str
    output: str
    step_count: int

# 定义节点函数
def hello_node(state: BasicState) -> BasicState:
    state["output"] = f"Hello, {state['input']}!"
    state["step_count"] += 1
    return state

def goodbye_node(state: BasicState) -> BasicState:
    state["output"] += " Goodbye!"
    state["step_count"] += 1
    return state

# 创建图
workflow = StateGraph(BasicState)

# 添加节点
workflow.add_node("hello", hello_node)
workflow.add_node("goodbye", goodbye_node)

# 添加边
workflow.add_edge(START, "hello")
workflow.add_edge("hello", "goodbye")
workflow.add_edge("goodbye", END)

# 编译图
app = workflow.compile()

# 执行
result = app.invoke({
    "input": "World",
    "output": "",
    "step_count": 0
})

print(result)
# 输出: {'input': 'World', 'output': 'Hello, World! Goodbye!', 'step_count': 2}

4.2 流式执行

# 流式执行,获取中间结果
for step in app.stream({"input": "World", "output": "", "step_count": 0}):
    print(f"Step: {step}")

4.3 异步执行

import asyncio

async def async_example():
    # 异步调用
    result = await app.ainvoke({
        "input": "Async World",
        "output": "",
        "step_count": 0
    })
    print(result)

# 运行异步函数
asyncio.run(async_example())

5. 图结构设计

5.1 图的类型

5.1.1 状态图(StateGraph)

最常用的图类型,维护状态信息:

from langgraph.graph import StateGraph

class MyState(TypedDict):
    data: str
    counter: int

graph = StateGraph(MyState)
5.1.2 消息图(MessageGraph)

专门处理消息的图结构:

from langgraph.graph import MessageGraph
from langchain_core.messages import HumanMessage

def process_message(messages):
    return [HumanMessage(content="Processed: " + messages[-1].content)]

graph = MessageGraph()
graph.add_node("process", process_message)

5.2 复杂图结构设计

5.2.1 并行执行
from langgraph.graph import StateGraph, START, END

class ParallelState(TypedDict):
    input_data: str
    result_a: str
    result_b: str
    final_result: str

def task_a(state: ParallelState) -> ParallelState:
    state["result_a"] = f"Task A processed: {state['input_data']}"
    return state

def task_b(state: ParallelState) -> ParallelState:
    state["result_b"] = f"Task B processed: {state['input_data']}"
    return state

def combine_results(state: ParallelState) -> ParallelState:
    state["final_result"] = f"{state['result_a']} + {state['result_b']}"
    return state

workflow = StateGraph(ParallelState)
workflow.add_node("task_a", task_a)
workflow.add_node("task_b", task_b)
workflow.add_node("combine", combine_results)

# 并行执行task_a和task_b
workflow.add_edge(START, "task_a")
workflow.add_edge(START, "task_b")
workflow.add_edge("task_a", "combine")
workflow.add_edge("task_b", "combine")
workflow.add_edge("combine", END)

app = workflow.compile()
5.2.2 循环结构
class LoopState(TypedDict):
    counter: int
    max_iterations: int
    result: List[str]

def increment_node(state: LoopState) -> LoopState:
    state["counter"] += 1
    state["result"].append(f"Iteration {state['counter']}")
    return state

def should_continue(state: LoopState) -> str:
    if state["counter"] < state["max_iterations"]:
        return "continue"
    return "end"

workflow = StateGraph(LoopState)
workflow.add_node("increment", increment_node)

workflow.add_conditional_edges(
    "increment",
    should_continue,
    {
        "continue": "increment",  # 循环回自己
        "end": END
    }
)

workflow.set_entry_point("increment")
app = workflow.compile()

5.3 图的可视化

from IPython.display import Image, display

# 获取图的Mermaid表示
mermaid_code = app.get_graph().draw_mermaid()
print(mermaid_code)

# 在Jupyter中显示图形
try:
    display(Image(app.get_graph().draw_mermaid_png()))
except Exception:
    print("无法显示图形,需要安装相应依赖")

6. 状态管理

6.1 状态定义最佳实践

6.1.1 使用TypedDict
from typing import TypedDict, List, Optional, Dict, Any

class ComprehensiveState(TypedDict):
    # 基础数据
    user_id: str
    session_id: str
    timestamp: str
    
    # 处理数据
    input_text: str
    processed_text: Optional[str]
    
    # 结果数据
    analysis_results: List[Dict[str, Any]]
    confidence_scores: Dict[str, float]
    
    # 控制数据
    current_step: str
    error_message: Optional[str]
    retry_count: int
6.1.2 使用Pydantic模型
from pydantic import BaseModel, Field
from typing import List, Optional

class PydanticState(BaseModel):
    user_input: str = Field(description="用户输入")
    processing_steps: List[str] = Field(default_factory=list)
    current_agent: Optional[str] = None
    result: Optional[str] = None
    
    class Config:
        extra = "allow"  # 允许额外字段

6.2 状态更新策略

6.2.1 增量更新
def incremental_update_node(state: MyState) -> MyState:
    # 只更新需要的字段
    state["current_step"] = "processing"
    state["processing_steps"].append("data_validation")
    return state
6.2.2 条件更新
def conditional_update_node(state: MyState) -> MyState:
    if state.get("error_message"):
        state["retry_count"] += 1
        if state["retry_count"] > 3:
            state["current_step"] = "failed"
    else:
        state["current_step"] = "completed"
    return state

7. 节点和边的高级用法

7.1 节点的高级功能

7.1.1 异步节点
import asyncio
from langchain_openai import ChatOpenAI

async def async_llm_node(state: MyState) -> MyState:
    """异步LLM调用节点"""
    llm = ChatOpenAI(temperature=0)
    
    # 异步调用LLM
    response = await llm.ainvoke(state["input_text"])
    state["llm_response"] = response.content
    state["processing_steps"].append("llm_processing")
    
    return state

# 在图中使用异步节点
workflow.add_node("async_llm", async_llm_node)
7.1.2 带有错误处理的节点
import logging
from typing import Dict, Any

def robust_processing_node(state: MyState) -> MyState:
    """带有完整错误处理的节点"""
    try:
        # 主要处理逻辑
        result = complex_processing_function(state["input_text"])
        state["result"] = result
        state["current_step"] = "completed"
        
    except ValueError as e:
        logging.error(f"Validation error: {e}")
        state["error_message"] = f"Validation error: {str(e)}"
        state["current_step"] = "validation_error"
        
    except ConnectionError as e:
        logging.error(f"Connection error: {e}")
        state["error_message"] = f"Connection error: {str(e)}"
        state["current_step"] = "connection_error"
        state["retry_count"] = state.get("retry_count", 0) + 1
        
    except Exception as e:
        logging.error(f"Unexpected error: {e}")
        state["error_message"] = f"Unexpected error: {str(e)}"
        state["current_step"] = "unknown_error"
    
    return state

def complex_processing_function(text: str) -> str:
    # 模拟复杂处理
    if not text.strip():
        raise ValueError("Input text cannot be empty")
    return f"Processed: {text.upper()}"

8. 条件路由

8.1 基础条件路由

def basic_condition(state: MyState) -> str:
    """基础条件判断"""
    if state.get("user_input", "").lower() == "help":
        return "help"
    elif state.get("user_input", "").lower() == "quit":
        return "quit"
    else:
        return "process"

workflow.add_conditional_edges(
    "input_handler",
    basic_condition,
    {
        "help": "help_node",
        "quit": END,
        "process": "processing_node"
    }
)

8.2 多级条件路由

class AdvancedRouter:
    """高级路由器,支持多级条件判断"""
    
    def __init__(self):
        self.routing_rules = []
    
    def add_rule(self, condition_func, route_name, priority=0):
        """添加路由规则"""
        self.routing_rules.append({
            "condition": condition_func,
            "route": route_name,
            "priority": priority
        })
        # 按优先级排序
        self.routing_rules.sort(key=lambda x: x["priority"], reverse=True)
    
    def route(self, state: MyState) -> str:
        """执行路由判断"""
        for rule in self.routing_rules:
            if rule["condition"](state):
                return rule["route"]
        
        return "default"

# 创建高级路由器
router = AdvancedRouter()

# 添加路由规则
router.add_rule(
    lambda state: state.get("user_type") == "admin",
    "admin_handler",
    priority=100
)

router.add_rule(
    lambda state: state.get("task_type") == "urgent",
    "urgent_handler",
    priority=90
)

# 在图中使用
workflow.add_conditional_edges(
    "router_node",
    router.route,
    {
        "admin_handler": "admin_processing",
        "urgent_handler": "urgent_processing",
        "default": "standard_processing"
    }
)

9. 人工干预机制

9.1 基础人工干预

from langgraph.prebuilt import create_react_agent
from langgraph.checkpoint.memory import MemorySaver

# 创建带有检查点的应用
memory = MemorySaver()

class HumanInterventionState(TypedDict):
    messages: List[str]
    human_input: Optional[str]
    requires_human_review: bool
    intervention_reason: Optional[str]

def analysis_node(state: HumanInterventionState) -> HumanInterventionState:
    """分析节点,可能需要人工干预"""
    content = state["messages"][-1] if state["messages"] else ""
    
    # 检查是否需要人工干预
    sensitive_keywords = ["urgent", "critical", "emergency"]
    if any(keyword in content.lower() for keyword in sensitive_keywords):
        state["requires_human_review"] = True
        state["intervention_reason"] = "Sensitive content detected"
        return state
    
    # 正常处理
    state["messages"].append(f"Analyzed: {content}")
    return state

def human_review_node(state: HumanInterventionState) -> HumanInterventionState:
    """人工审核节点"""
    # 这里会暂停执行,等待人工输入
    if state.get("human_input"):
        state["messages"].append(f"Human reviewed: {state['human_input']}")
        state["requires_human_review"] = False
        state["human_input"] = None
    return state

def should_get_human_input(state: HumanInterventionState) -> str:
    if state.get("requires_human_review"):
        return "human_review"
    return "continue"

# 构建带人工干预的图
workflow = StateGraph(HumanInterventionState)
workflow.add_node("analysis", analysis_node)
workflow.add_node("human_review", human_review_node)

workflow.add_conditional_edges(
    "analysis",
    should_get_human_input,
    {
        "human_review": "human_review",
        "continue": END
    }
)

workflow.set_entry_point("analysis")
app = workflow.compile(checkpointer=memory)

9.2 高级人工干预策略

class InterventionManager:
    """人工干预管理器"""
    
    def __init__(self):
        self.intervention_rules = []
        self.escalation_levels = {
            "low": {"timeout": 300, "auto_approve": True},
            "medium": {"timeout": 600, "auto_approve": False},
            "high": {"timeout": 1800, "auto_approve": False}
        }
    
    def add_intervention_rule(self, condition_func, level="medium", reason=""):
        """添加干预规则"""
        self.intervention_rules.append({
            "condition": condition_func,
            "level": level,
            "reason": reason
        })
    
    def evaluate_intervention(self, state: Dict) -> Optional[Dict]:
        """评估是否需要人工干预"""
        for rule in self.intervention_rules:
            if rule["condition"](state):
                return {
                    "required": True,
                    "level": rule["level"],
                    "reason": rule["reason"],
                    "timeout": self.escalation_levels[rule["level"]]["timeout"],
                    "auto_approve": self.escalation_levels[rule["level"]]["auto_approve"]
                }
        return {"required": False}

# 使用示例
intervention_manager = InterventionManager()

# 添加干预规则
intervention_manager.add_intervention_rule(
    lambda state: state.get("confidence_score", 1.0) < 0.3,
    level="high",
    reason="Low confidence score"
)

intervention_manager.add_intervention_rule(
    lambda state: "delete" in state.get("user_input", "").lower(),
    level="medium",
    reason="Destructive operation detected"
)

10. 持久化和检查点

10.1 检查点基础

from langgraph.checkpoint.sqlite import SqliteSaver
from langgraph.checkpoint.memory import MemorySaver

# 内存检查点(仅用于开发和测试)
memory_saver = MemorySaver()

# SQLite检查点(用于生产)
sqlite_saver = SqliteSaver.from_conn_string("checkpoints.db")

# 使用检查点编译图
app = workflow.compile(checkpointer=sqlite_saver)

# 带有线程ID的执行
thread_id = "user_session_123"
config = {"configurable": {"thread_id": thread_id}}

# 执行并自动保存检查点
result = app.invoke(initial_state, config=config)

# 从检查点恢复执行
result = app.invoke(None, config=config)  # 继续之前的执行

10.2 自定义检查点存储

import redis
import json
from langgraph.checkpoint.base import BaseCheckpointSaver

class RedisCheckpointSaver(BaseCheckpointSaver):
    """Redis检查点存储实现"""
    
    def __init__(self, redis_url: str):
        self.redis_client = redis.from_url(redis_url)
    
    def put(self, config, checkpoint, metadata=None):
        """保存检查点"""
        thread_id = config["configurable"]["thread_id"]
        checkpoint_id = checkpoint["id"]
        
        key = f"checkpoint:{thread_id}:{checkpoint_id}"
        data = {
            "checkpoint": checkpoint,
            "metadata": metadata or {}
        }
        
        self.redis_client.set(key, json.dumps(data, default=str))
    
    def get(self, config):
        """获取最新检查点"""
        thread_id = config["configurable"]["thread_id"]
        
        # 查找最新的检查点
        pattern = f"checkpoint:{thread_id}:*"
        keys = self.redis_client.keys(pattern)
        
        if not keys:
            return None
        
        # 获取最新的检查点
        latest_key = sorted(keys)[-1]
        data = json.loads(self.redis_client.get(latest_key))
        
        return data["checkpoint"]
    
    def list(self, config, limit=10):
        """列出检查点历史"""
        thread_id = config["configurable"]["thread_id"]
        pattern = f"checkpoint:{thread_id}:*"
        keys = self.redis_client.keys(pattern)
        
        checkpoints = []
        for key in sorted(keys)[-limit:]:
            data = json.loads(self.redis_client.get(key))
            checkpoints.append(data["checkpoint"])
        
        return checkpoints

# 使用Redis检查点
redis_saver = RedisCheckpointSaver("redis://localhost:6379")
app = workflow.compile(checkpointer=redis_saver)

11. 流式处理

11.1 基础流式处理

def streaming_example():
    """流式处理示例"""
    
    # 流式执行图
    for chunk in app.stream(initial_state, config=config):
        print(f"收到数据块: {chunk}")
        
        # 实时处理每个节点的输出
        if "analysis" in chunk:
            print(f"分析结果: {chunk['analysis']}")
        elif "processing" in chunk:
            print(f"处理进度: {chunk['processing']}")

# 异步流式处理
async def async_streaming_example():
    async for chunk in app.astream(initial_state, config=config):
        print(f"异步接收: {chunk}")
        await asyncio.sleep(0.1)  # 模拟异步处理

11.2 流式处理与WebSocket集成

import asyncio
import websockets
import json

class StreamingServer:
    """流式处理WebSocket服务器"""
    
    def __init__(self, langgraph_app):
        self.app = langgraph_app
    
    async def handle_client(self, websocket, path):
        """处理客户端连接"""
        try:
            async for message in websocket:
                data = json.loads(message)
                
                # 开始流式执行
                config = {"configurable": {"thread_id": data.get("thread_id")}}
                
                async for chunk in self.app.astream(data["input"], config=config):
                    # 发送流式数据到客户端
                    await websocket.send(json.dumps({
                        "type": "chunk",
                        "data": chunk
                    }))
                
                # 发送完成信号
                await websocket.send(json.dumps({
                    "type": "complete"
                }))
                
        except websockets.exceptions.ConnectionClosed:
            print("客户端断开连接")
        except Exception as e:
            await websocket.send(json.dumps({
                "type": "error",
                "message": str(e)
            }))
    
    def start_server(self, host="localhost", port=8765):
        """启动WebSocket服务器"""
        start_server = websockets.serve(self.handle_client, host, port)
        print(f"流式服务器启动在 ws://{host}:{port}")
        asyncio.get_event_loop().run_until_complete(start_server)
        asyncio.get_event_loop().run_forever()

# 使用示例
server = StreamingServer(app)
server.start_server()

12. 实战案例

12.1 智能客服系统

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

class CustomerServiceState(TypedDict):
    messages: List[str]
    user_intent: Optional[str]
    confidence_score: float
    escalate_to_human: bool
    resolution_status: str
    customer_info: Dict[str, Any]

def intent_classification_node(state: CustomerServiceState) -> CustomerServiceState:
    """意图分类节点"""
    llm = ChatOpenAI(model="gpt-4")
    
    prompt = f"""
    分析以下客户消息的意图,返回JSON格式:
    {{
        "intent": "意图类别(complaint/inquiry/support/billing)",
        "confidence": 0.95,
        "urgency": "low/medium/high"
    }}
    
    客户消息: {state['messages'][-1]}
    """
    
    response = llm.invoke([HumanMessage(content=prompt)])
    result = json.loads(response.content)
    
    state["user_intent"] = result["intent"]
    state["confidence_score"] = result["confidence"]
    
    # 低置信度或高紧急度需要人工干预
    if result["confidence"] < 0.7 or result["urgency"] == "high":
        state["escalate_to_human"] = True
    
    return state

def automated_response_node(state: CustomerServiceState) -> CustomerServiceState:
    """自动回复节点"""
    llm = ChatOpenAI(model="gpt-4")
    
    # 基于意图生成回复
    intent_templates = {
        "billing": "我来帮您处理账单问题...",
        "support": "我来为您提供技术支持...",
        "inquiry": "很高兴为您解答...",
        "complaint": "非常抱歉给您带来不便,我来帮您解决..."
    }
    
    template = intent_templates.get(state["user_intent"], "我来为您提供帮助...")
    
    prompt = f"""
    作为客服代表,基于以下信息回复客户:
    - 客户消息: {state['messages'][-1]}
    - 意图类别: {state['user_intent']}
    - 回复模板: {template}
    
    生成专业、友好的回复:
    """
    
    response = llm.invoke([HumanMessage(content=prompt)])
    state["messages"].append(response.content)
    state["resolution_status"] = "automated_response_sent"
    
    return state

def routing_condition(state: CustomerServiceState) -> str:
    """路由条件判断"""
    if state["escalate_to_human"]:
        return "human_agent"
    elif state["user_intent"] in ["billing", "complaint"]:
        return "specialized_handling"
    else:
        return "automated_response"

# 构建客服系统图
customer_service_workflow = StateGraph(CustomerServiceState)

customer_service_workflow.add_node("intent_classification", intent_classification_node)
customer_service_workflow.add_node("automated_response", automated_response_node)
customer_service_workflow.add_node("human_agent", lambda state: state)  # 占位符

customer_service_workflow.add_conditional_edges(
    "intent_classification",
    routing_condition,
    {
        "automated_response": "automated_response",
        "human_agent": "human_agent",
        "specialized_handling": "automated_response"
    }
)

customer_service_workflow.set_entry_point("intent_classification")
customer_service_app = customer_service_workflow.compile()

12.2 代码生成和审查系统

class CodeGenerationState(TypedDict):
    requirements: str
    generated_code: str
    code_quality_score: float
    test_results: Dict[str, Any]
    review_comments: List[str]
    approved: bool

def code_generation_node(state: CodeGenerationState) -> CodeGenerationState:
    """代码生成节点"""
    llm = ChatOpenAI(model="gpt-4")
    
    prompt = f"""
    根据以下需求生成Python代码:
    {state['requirements']}
    
    要求:
    1. 代码要有完整的文档字符串
    2. 包含错误处理
    3. 遵循PEP 8规范
    4. 包含单元测试
    """
    
    response = llm.invoke([HumanMessage(content=prompt)])
    state["generated_code"] = response.content
    
    return state

def code_quality_analysis_node(state: CodeGenerationState) -> CodeGenerationState:
    """代码质量分析节点"""
    import ast
    import re
    
    code = state["generated_code"]
    quality_score = 1.0
    issues = []
    
    try:
        # 语法检查
        ast.parse(code)
    except SyntaxError:
        quality_score -= 0.5
        issues.append("语法错误")
    
    # 风格检查
    if not re.search(r'""".*?"""', code, re.DOTALL):
        quality_score -= 0.2
        issues.append("缺少文档字符串")
    
    if "try:" not in code:
        quality_score -= 0.1
        issues.append("缺少错误处理")
    
    state["code_quality_score"] = max(0, quality_score)
    state["review_comments"] = issues
    
    return state

def approval_condition(state: CodeGenerationState) -> str:
    """审批条件"""
    if state["code_quality_score"] >= 0.8:
        return "approve"
    elif state["code_quality_score"] >= 0.5:
        return "review"
    else:
        return "regenerate"

# 构建代码生成系统
code_workflow = StateGraph(CodeGenerationState)
code_workflow.add_node("generate", code_generation_node)
code_workflow.add_node("analyze", code_quality_analysis_node)

code_workflow.add_edge("generate", "analyze")
code_workflow.add_conditional_edges(
    "analyze",
    approval_condition,
    {
        "approve": END,
        "review": "human_review",
        "regenerate": "generate"
    }
)

code_workflow.set_entry_point("generate")
code_app = code_workflow.compile()

13. 最佳实践

13.1 性能优化

# 1. 使用异步操作
async def optimized_llm_node(state: MyState) -> MyState:
    tasks = [
        llm1.ainvoke(state["input1"]),
        llm2.ainvoke(state["input2"]),
        external_api_call(state["input3"])
    ]
    
    results = await asyncio.gather(*tasks)
    state["results"] = results
    return state

# 2. 缓存机制
from functools import lru_cache

@lru_cache(maxsize=128)
def cached_expensive_operation(input_text: str) -> str:
    # 昂贵的计算操作
    return f"processed: {input_text}"

# 3. 批处理
def batch_processing_node(state: MyState) -> MyState:
    batch_size = 10
    items = state["items_to_process"]
    
    # 分批处理
    for i in range(0, len(items), batch_size):
        batch = items[i:i + batch_size]
        process_batch(batch)
    
    return state

13.2 错误处理策略

class ErrorHandlingState(TypedDict):
    error_count: int
    max_retries: int
    error_log: List[str]
    circuit_breaker_open: bool

def circuit_breaker_node(state: ErrorHandlingState) -> ErrorHandlingState:
    """断路器模式"""
    if state.get("circuit_breaker_open", False):
        state["error_log"].append("Circuit breaker is open")
        return state
    
    try:
        # 执行可能失败的操作
        risky_operation()
        state["error_count"] = 0  # 重置错误计数
    
    except Exception as e:
        state["error_count"] = state.get("error_count", 0) + 1
        state["error_log"].append(str(e))
        
        # 如果错误次数过多,打开断路器
        if state["error_count"] >= state.get("max_retries", 3):
            state["circuit_breaker_open"] = True
    
    return state

13.3 监控和日志

import logging
import time
from functools import wraps

def monitor_node_performance(func):
    """节点性能监控装饰器"""
    @wraps(func)
    def wrapper(state):
        start_time = time.time()
        node_name = func.__name__
        
        try:
            result = func(state)
            execution_time = time.time() - start_time
            
            logging.info(f"Node {node_name} executed successfully in {execution_time:.2f}s")
            
            # 记录性能指标
            if "_metrics" not in result:
                result["_metrics"] = {}
            result["_metrics"][node_name] = {
                "execution_time": execution_time,
                "status": "success"
            }
            
            return result
            
        except Exception as e:
            execution_time = time.time() - start_time
            logging.error(f"Node {node_name} failed after {execution_time:.2f}s: {e}")
            
            # 记录错误信息
            if "_metrics" not in state:
                state["_metrics"] = {}
            state["_metrics"][node_name] = {
                "execution_time": execution_time,
                "status": "error",
                "error": str(e)
            }
            
            raise
    
    return wrapper

# 使用监控装饰器
@monitor_node_performance
def monitored_processing_node(state: MyState) -> MyState:
    # 节点逻辑
    return state

14. 总结

LangGraph作为构建复杂AI应用的强大工具,提供了丰富的功能和灵活的架构。通过本文档的深度解析,您应该能够:

  1. 掌握核心概念:理解图、状态、节点、边等基本概念
  2. 设计复杂工作流:构建包含条件路由、循环、并行处理的复杂图结构
  3. 实现高级功能:使用人工干预、持久化、流式处理等高级特性
  4. 优化性能:应用最佳实践进行性能优化和错误处理
  5. 构建实际应用:基于实战案例构建自己的AI应用系统

14.1 学习路径建议

  1. 初学者:从基础概念和简单示例开始
  2. 进阶者:重点学习状态管理和条件路由
  3. 高级用户:掌握人工干预、持久化和性能优化
  4. 架构师:关注系统设计模式和最佳实践

14.2 持续学习资源

LangGraph正在快速发展,建议关注官方更新,学习最新的功能和最佳实践。随着AI技术的不断进步,LangGraph将成为构建下一代智能应用的重要工具。