LangGraph 工作流中可以使用的核心策略,这些策略能帮助你更灵活、高效地设计和运行基于 LangGraph 的智能体或工作流应用。
LangGraph 作为专门为构建多步骤、有状态、可循环的 LLM 应用设计的框架,其核心价值就体现在灵活的工作流策略上。以下是最常用且实用的核心策略,我会结合场景和代码示例来解释:
一、核心工作流策略
1. 条件分支策略(Conditional Branching)
这是最基础也最常用的策略,根据节点执行的结果动态决定下一步执行哪个节点,实现 "决策树" 式的工作流。
- 适用场景:智能体判断是否需要调用工具、是否需要追问用户、是否完成任务等。
示例:
python
from langgraph.graph import StateGraph, END
from typing import TypedDict, Annotated
import operator
# 定义状态
class AgentState(TypedDict):
query: str
need_tool: bool
tool_result: str
final_answer: str
# 定义节点
def check_need_tool(state: AgentState) -> AgentState:
# 模拟判断是否需要调用工具
state["need_tool"] = "calculator" in state["query"].lower()
return state
def call_tool(state: AgentState) -> AgentState:
# 模拟调用工具
state["tool_result"] = "计算结果:100"
return state
def direct_answer(state: AgentState) -> AgentState:
# 直接回答
state["final_answer"] = f"无需工具,回答:{state['query']}"
return state
# 定义分支逻辑(核心策略)
def decide_next_step(state: AgentState) -> str:
if state["need_tool"]:
return "call_tool" # 走工具调用分支
else:
return "direct_answer" # 走直接回答分支
# 构建工作流
graph_builder = StateGraph(AgentState)
graph_builder.add_node("check_need_tool", check_need_tool)
graph_builder.add_node("call_tool", call_tool)
graph_builder.add_node("direct_answer", direct_answer)
# 设置入口和分支
graph_builder.set_entry_point("check_need_tool")
graph_builder.add_conditional_edges(
"check_need_tool",
decide_next_step, # 分支判断函数
{
"call_tool": "call_tool",
"direct_answer": "direct_answer",
},
)
# 分支节点最终都指向结束
graph_builder.add_edge("call_tool", END)
graph_builder.add_edge("direct_answer", END)
# 编译并运行
graph = graph_builder.compile()
result = graph.invoke({"query": "计算1+99的结果"})
print(result["final_answer"] if "final_answer" in result else result["tool_result"])
2. 循环 / 迭代策略(Loop/Iteration)
让工作流在满足特定条件前重复执行某组节点(核心是 "自环" 或 "循环边"),是智能体 "思考 - 执行 - 反思" 的核心实现方式。
- 适用场景:工具调用后检查结果是否满足需求、多轮对话追问、任务分步执行直到完成。
关键逻辑:
python
# 新增:检查工具结果是否满足要求
def check_tool_result(state: AgentState) -> str:
# 模拟判断:如果结果为空/错误,重新调用工具;否则结束
if not state["tool_result"] or state["tool_result"] == "错误":
return "call_tool" # 循环:重新调用工具
else:
state["final_answer"] = f"最终答案:{state['tool_result']}"
return "end" # 结束
# 调整工作流:call_tool 后先检查结果,再决定循环或结束
graph_builder.add_conditional_edges(
"call_tool",
check_tool_result,
{
"call_tool": "call_tool", # 自环:循环调用工具
"end": END,
},
)
3. 并行执行策略(Parallel Execution)
让多个节点同时执行(而非串行),提升工作流效率,LangGraph 提供并行边能力。
- 适用场景:同时调用多个工具(如同时查天气和查汇率)、并行处理多份数据、多维度分析同一个问题。
示例:
python
# 新增并行节点
def check_weather(state: AgentState) -> AgentState:
state["weather"] = "北京:25℃,晴"
return state
def check_exchange_rate(state: AgentState) -> AgentState:
state["exchange_rate"] = "1美元=7.2人民币"
return state
# 构建并行工作流
graph_builder.add_node("check_weather", check_weather)
graph_builder.add_node("check_exchange_rate", check_exchange_rate)
# 设置并行边:入口节点后同时执行两个节点
graph_builder.add_parallel_edges(
"check_need_tool", # 上游节点
["check_weather", "check_exchange_rate"], # 并行执行的节点列表
)
# 并行节点执行完后汇总结果
def summarize_parallel_results(state: AgentState) -> AgentState:
state["final_answer"] = f"天气:{state['weather']};汇率:{state['exchange_rate']}"
return state
graph_builder.add_node("summarize", summarize_parallel_results)
graph_builder.add_edge("check_weather", "summarize")
graph_builder.add_edge("check_exchange_rate", "summarize")
graph_builder.add_edge("summarize", END)
4. 状态持久化策略(State Persistence)
LangGraph 核心特性之一,通过持久化工作流的状态(如使用 MemorySaver),实现 "断点续跑" 或 "多轮对话记忆"。
- 适用场景:长对话智能体、分步执行的复杂任务(如中途中断后继续)、多用户会话隔离。
关键配置:
python
from langgraph.checkpoint.memory import MemorySaver
# 初始化内存存储(也可使用 Redis、SQL 等持久化存储)
memory = MemorySaver()
# 编译时传入 checkpointer,开启状态持久化
graph = graph_builder.compile(checkpointer=memory)
# 运行时指定会话 ID,实现状态隔离和续跑
config = {"configurable": {"thread_id": "user_123"}} # 会话ID
# 第一次调用
graph.invoke({"query": "先查天气"}, config=config)
# 第二次调用:复用之前的状态
result = graph.invoke({"query": "再查汇率"}, config=config)
print(result["final_answer"])
5. 回退 / 重试策略(Fallback/Retry)
当某个节点执行失败(如工具调用超时、LLM 报错)时,自动回退到备选节点或重试当前节点。
- 适用场景:工具调用容错、LLM 服务不稳定时的降级处理、用户输入格式错误时的重试。
关键逻辑:
python
from langgraph.errors import NodeError
# 带重试的工具调用节点
def call_tool_with_retry(state: AgentState) -> AgentState:
try:
# 模拟工具调用失败
raise Exception("工具调用超时")
state["tool_result"] = "计算结果:100"
return state
except Exception as e:
# 记录错误,触发重试
state["error"] = str(e)
raise NodeError(f"工具调用失败:{e}") from e
# 定义回退逻辑
def handle_tool_error(state: AgentState) -> str:
# 重试次数小于 3 则重试,否则降级
state["retry_count"] = state.get("retry_count", 0) + 1
if state["retry_count"] < 3:
return "call_tool"
else:
state["final_answer"] = "工具调用失败,无法回答"
return "end"
# 配置错误处理
graph_builder.add_conditional_edges(
"call_tool",
handle_tool_error,
{
"call_tool": "call_tool", # 重试
"end": END, # 降级结束
},
)
# 捕获节点错误
graph = graph_builder.compile(catch_exceptions=True)
6. 子图嵌套策略(Subgraph Nesting)
将一组相关节点封装为一个独立的子图,再将子图作为 "节点" 嵌入主工作流,实现工作流的模块化。
- 适用场景:复杂工作流的模块化拆分(如 "数据分析子图""报告生成子图")、复用通用工作流片段。
核心逻辑:
python
# 定义子图
subgraph_builder = StateGraph(AgentState)
subgraph_builder.add_node("step1", step1_func)
subgraph_builder.add_node("step2", step2_func)
subgraph_builder.set_entry_point("step1")
subgraph_builder.add_edge("step1", "step2")
subgraph_builder.add_edge("step2", END)
subgraph = subgraph_builder.compile()
# 主图中添加子图作为节点
graph_builder.add_node("subgraph_node", subgraph)
graph_builder.add_edge("check_need_tool", "subgraph_node")
graph_builder.add_edge("subgraph_node", END)
二、进阶策略(补充)
- 优先级策略:在并行节点中设置执行优先级,或在分支逻辑中优先选择更优路径(如优先使用缓存结果而非调用工具)。
- 中断 / 手动干预策略:通过
interrupt_before/interrupt_after配置,让工作流在指定节点暂停,等待人工输入后再继续(适用于需要人工审核的场景)。 - 缓存策略:对重复的节点执行结果(如相同的工具调用)进行缓存,避免重复计算,提升效率。
总结
LangGraph 工作流的核心策略可归纳为以下关键点:
- 条件分支是基础,实现 "决策式" 流程;循环策略是核心,支撑智能体的迭代思考。
- 并行执行提升效率,状态持久化实现会话记忆和断点续跑。
- 回退 / 重试保障鲁棒性,子图嵌套实现复杂流程的模块化管理。
这些策略可以组合使用(如 "循环 + 条件分支 + 并行"),满足从简单问答到复杂智能体的几乎所有工作流设计需求。