LangGraph从入门到精通
目录
1. LangGraph概述
1.1 什么是LangGraph
LangGraph是LangChain生态系统中的一个核心组件,专门用于构建有状态的、多参与者的应用程序,特别是在大语言模型(LLM)应用中。它提供了一个基于图的框架,用于定义复杂的工作流程和状态转换。
1.2 核心特性
- 有状态性:维护跨步骤的应用状态
- 图结构:使用节点和边定义复杂的执行流程
- 人工干预:支持在执行过程中进行人工审核和修正
- 持久化:提供检查点机制,支持长时间运行的工作流
- 流式处理:支持实时流式输出
- 条件路由:基于状态或条件进行动态路由选择
1.3 适用场景
- 多代理系统:协调多个AI代理协作完成任务
- 复杂对话系统:处理多轮对话和上下文管理
- 工作流自动化:构建复杂的业务流程自动化
- 决策支持系统:需要多步骤分析和决策的应用
- 代码生成和审查:自动化代码生成、测试和审查流程
1.4 与传统链式架构的对比
| 特性 | LangChain Chain | LangGraph |
|---|---|---|
| 结构 | 线性链式 | 图状结构 |
| 状态管理 | 有限 | 完整的状态管理 |
| 条件分支 | 困难 | 原生支持 |
| 人工干预 | 不支持 | 原生支持 |
| 持久化 | 简单 | 完整的检查点机制 |
| 复杂度 | 简单场景 | 复杂工作流 |
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应用的强大工具,提供了丰富的功能和灵活的架构。通过本文档的深度解析,您应该能够:
- 掌握核心概念:理解图、状态、节点、边等基本概念
- 设计复杂工作流:构建包含条件路由、循环、并行处理的复杂图结构
- 实现高级功能:使用人工干预、持久化、流式处理等高级特性
- 优化性能:应用最佳实践进行性能优化和错误处理
- 构建实际应用:基于实战案例构建自己的AI应用系统
14.1 学习路径建议
- 初学者:从基础概念和简单示例开始
- 进阶者:重点学习状态管理和条件路由
- 高级用户:掌握人工干预、持久化和性能优化
- 架构师:关注系统设计模式和最佳实践
14.2 持续学习资源
LangGraph正在快速发展,建议关注官方更新,学习最新的功能和最佳实践。随着AI技术的不断进步,LangGraph将成为构建下一代智能应用的重要工具。