当我第一次在生产环境部署 LLM 应用时,被一个实际问题困扰:用户输入五花八门,有的要求简单问答,有的需要复杂分析,还有的触发了风控规则需要人工审核。硬编码的 if-else 逻辑让代码越来越臃肿,直到我深入使用了 LangGraph 的 conditional edges(条件边)——这个看似简单的功能,实际上是构建智能 AI 工作流的核心枢纽。

先看一个让我震惊的成本计算:假设你的 AI 应用每月处理 100 万 output token,主流模型费用差异巨大:GPT-4.1 输出 $8/MTok(¥58.4)、Claude Sonnet 4.5 输出 $15/MTok(¥109.5)、Gemini 2.5 Flash 输出 $2.50/MTok(¥18.25)、DeepSeek V3.2 输出仅 $0.42/MTok(¥3.07)。如果你选择 HolySheep AI 中转站,按 ¥1=$1 无损汇率结算,同样 100 万 DeepSeek token 费用是 ¥4,200,对比官方通道 ¥22,411,节省超过 85%。这还没算上国内直连 <50ms 的延迟优势——这正是我在生产环境中逐步将简单查询路由到 DeepSeek、复杂推理保留给 GPT-4 的契机。

一、Conditional Edges 基础概念

在 LangGraph 中,conditional edges(条件边)是连接节点的有向边,但边的选择不是固定的,而是由一个函数动态决定。想象一个客服系统:用户发送消息 → AI 判断意图 → 如果是退货请求走「退货流程」节点,如果是技术问题走「技术支持」节点,如果是紧急投诉走「人工介入」节点——这种「根据状态选择下一个节点」的能力,就是 conditional edges 解决的问题。

二、环境配置与依赖

# 安装 LangGraph(稳定版)
pip install langgraph langgraph-cli

验证版本

python -c "import langgraph; print(langgraph.__version__)"

预期输出示例:0.0.45 或更高版本

安装 LangChain 用于 LLM 调用

pip install langchain-openai langchain-anthropic

配置环境变量(使用 HolySheep API)

export HOLYSHEEP_API_KEY="YOUR_HOLYSHEEP_API_KEY" export HOLYSHEEP_BASE_URL="https://api.holysheep.ai/v1"

或者在代码中直接配置(推荐)

import os os.environ["HOLYSHEEP_API_KEY"] = "YOUR_HOLYSHEEP_API_KEY" os.environ["OPENAI_API_BASE"] = "https://api.holysheep.ai/v1/openai" # OpenAI 兼容格式

三、实战:构建意图分类路由系统

这是我在实际项目中实现的电商客服路由系统,完整展示了 conditional edges 的核心用法。系统会根据用户输入判断意图,然后路由到对应的处理节点。

"""
LangGraph 条件路由实战:电商智能客服
核心场景:根据用户意图路由到不同处理节点
"""
from typing import TypedDict, Literal
from langgraph.graph import StateGraph, END
from langchain_openai import ChatOpenAI
import os

============ 1. 定义状态结构 ============

class CustomerServiceState(TypedDict): """客服系统状态""" user_input: str intent: str response: str need_human: bool confidence: float

============ 2. 配置 LLM(使用 HolySheep API) ============

HolySheep 支持 OpenAI 兼容格式,国内直连延迟 <50ms

os.environ["OPENAI_API_KEY"] = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY") os.environ["OPENAI_API_BASE"] = "https://api.holysheep.ai/v1" llm = ChatOpenAI( model="gpt-4.1", # 或 "claude-sonnet-4.5", "deepseek-v3.2" 等 temperature=0.3, api_key=os.environ["OPENAI_API_KEY"], base_url="https://api.holysheep.ai/v1" )

============ 3. 定义处理节点 ============

def classify_intent(state: CustomerServiceState) -> CustomerServiceState: """节点1:意图分类""" user_input = state["user_input"] # 使用 LLM 进行意图分类 prompt = f"""分析用户输入,判断其意图类别: 用户输入:{user_input} 只能返回以下类别之一(直接返回类别名称): - refund(退货退款) - technical(技术支持) - complaint(投诉建议) - inquiry(商品咨询) - human(需要人工介入)""" intent = llm.invoke(prompt).content.strip().lower() # 简单分类时置信度设为 0.8,实际可用更复杂方法 return { "intent": intent, "confidence": 0.8, "need_human": intent == "human" } def handle_refund(state: CustomerServiceState) -> CustomerServiceState: """节点2:处理退货请求""" return { "response": "您好,我们已收到您的退货申请,正在处理中,预计 1-3 个工作日完成退款。" } def handle_technical(state: CustomerServiceState) -> CustomerServiceState: """节点3:技术支持""" return { "response": "感谢您联系我们技术团队,请问您遇到的具体问题是什么?我来帮您排查。" } def handle_complaint(state: CustomerServiceState) -> CustomerServiceState: """节点4:投诉处理""" return { "response": "非常抱歉给您带来不好的体验,我们会立即跟进处理,请留下您的联系方式。" } def handle_inquiry(state: CustomerServiceState) -> CustomerServiceState: """节点5:商品咨询""" return { "response": "您好,请问您想了解哪款商品的详细信息?" } def escalate_to_human(state: CustomerServiceState) -> CustomerServiceState: """节点6:转人工""" return { "response": "正在为您转接人工客服,请稍候..." }

============ 4. 定义条件路由函数(核心) ============

def route_intent(state: CustomerServiceState) -> Literal["handle_refund", "handle_technical", "handle_complaint", "handle_inquiry", "escalate_to_human"]: """ 条件路由函数:根据分类结果返回下一个节点名称 这是 conditional edges 的核心逻辑 """ intent = state.get("intent", "inquiry") # 使用置信度阈值:低置信度自动转人工 if state.get("confidence", 1.0) < 0.6: return "escalate_to_human" # 根据意图路由 intent_map = { "refund": "handle_refund", "technical": "handle_technical", "complaint": "handle_complaint", "inquiry": "handle_inquiry", "human": "escalate_to_human" } return intent_map.get(intent, "escalate_to_human")

============ 5. 构建图 ============

def build_routing_graph(): """构建条件路由图""" # 创建图构建器 workflow = StateGraph(CustomerServiceState) # 添加节点 workflow.add_node("classify_intent", classify_intent) workflow.add_node("handle_refund", handle_refund) workflow.add_node("handle_technical", handle_technical) workflow.add_node("handle_complaint", handle_complaint) workflow.add_node("handle_inquiry", handle_inquiry) workflow.add_node("escalate_to_human", escalate_to_human) # 设置入口点 workflow.set_entry_point("classify_intent") # 添加条件边(关键语法) workflow.add_conditional_edges( source_node="classify_intent", # 源节点 condition=route_intent, # 路由函数 path_map={ # 路径映射表 "handle_refund": "handle_refund", "handle_technical": "handle_technical", "handle_complaint": "handle_complaint", "handle_inquiry": "handle_inquiry", "escalate_to_human": "escalate_to_human" } ) # 所有处理节点都连接到结束 for node in ["handle_refund", "handle_technical", "handle_complaint", "handle_inquiry", "escalate_to_human"]: workflow.add_edge(node, END) # 编译图 return workflow.compile()

============ 6. 执行示例 ============

if __name__ == "__main__": # 构建图 app = build_routing_graph() # 测试用例 test_cases = [ {"user_input": "我想退货,上周买的衣服不合适", "intent": "refund"}, {"user_input": "App 闪退了,怎么回事", "intent": "technical"}, {"user_input": "等了一周还没发货,差评", "intent": "complaint"}, {"user_input": "这件衬衫有几种颜色", "intent": "inquiry"} ] print("=" * 60) print("LangGraph 条件路由测试") print("=" * 60) for i, case in enumerate(test_cases, 1): result = app.invoke({"user_input": case["user_input"]}) print(f"\n【测试 {i}】输入:{case['intent']}") print(f" 识别意图:{result['intent']}") print(f" 路由节点:{case['intent']}") print(f" 系统回复:{result['response']}")

四、进阶:多条件复合路由

在实际生产中,我遇到更复杂的场景:不仅要看意图,还要看用户等级、问题紧急程度、置信度等多个维度。下面这个例子展示了如何实现「多条件复合路由」。

"""
进阶场景:多条件复合路由
考虑因素:意图 + 用户等级 + 紧急程度 + 置信度
"""
from typing import Literal
from enum import Enum

class UserLevel(Enum):
    VIP = "vip"
    REGULAR = "regular"
    NEW = "new"

class UrgencyLevel(Enum):
    LOW = "low"
    MEDIUM = "medium"
    HIGH = "high"

class AdvancedState(TypedDict):
    user_input: str
    intent: str
    user_level: UserLevel
    urgency: UrgencyLevel
    confidence: float
    response: str
    routing_reason: str

def advanced_route(state: AdvancedState) -> Literal[
    "vip_fast_track", "normal_process", "priority_escalation", 
    "auto_resolve", "force_human"
]:
    """
    多条件复合路由函数
    
    路由决策逻辑(按优先级):
    1. VIP 用户 + 高紧急度 → 优先通道
    2. 置信度 < 0.5 → 强制转人工
    3. 新用户 + 低紧急度 → 自动解决
    4. 投诉/技术问题 + 低置信度 → 优先升级
    5. 默认 → 正常流程
    """
    intent = state["intent"]
    user_level = state["user_level"]
    urgency = state["urgency"]
    confidence = state["confidence"]
    
    # 条件1:VIP + 高紧急度直接优先处理
    if user_level == UserLevel.VIP and urgency == UrgencyLevel.HIGH:
        return "priority_escalation"
    
    # 条件2:置信度过低,转人工
    if confidence < 0.5:
        return "force_human"
    
    # 条件3:新用户 + 简单咨询,自动解决
    if user_level == UserLevel.NEW and intent in ["inquiry", "simple_question"]:
        return "auto_resolve"
    
    # 条件4:VIP 用户走快速通道
    if user_level == UserLevel.VIP:
        return "vip_fast_track"
    
    # 条件5:投诉/技术问题且置信度不高,优先升级
    if intent in ["complaint", "technical"] and confidence < 0.75:
        return "priority_escalation"
    
    # 默认:正常流程
    return "normal_process"

路由理由说明(用于调试和日志)

def get_routing_explanation(state: AdvancedState, route: str) -> str: """生成路由决策说明,用于日志和调试""" explanations = { "vip_fast_track": f"VIP 用户({state['user_level'].value})优先处理", "normal_process": f"标准流程,意图={state['intent']}", "priority_escalation": f"优先升级,置信度={state['confidence']:.2f}", "auto_resolve": f"新用户自动解决,intent={state['intent']}", "force_human": f"强制转人工,置信度过低={state['confidence']:.2f}" } return explanations.get(route, "未知路由")

使用示例

advanced_workflow = StateGraph(AdvancedState) advanced_workflow.add_node("classify", classify_intent) # 复用之前的分类函数 advanced_workflow.add_node("vip_fast_track", vip_handler) advanced_workflow.add_node("normal_process", normal_handler) advanced_workflow.add_node("priority_escalation", priority_handler) advanced_workflow.add_node("auto_resolve", auto_resolve_handler) advanced_workflow.add_node("force_human", force_human_handler) advanced_workflow.set_entry_point("classify") advanced_workflow.add_conditional_edges( source_node="classify", condition=advanced_route, path_map={ "vip_fast_track": "vip_fast_track", "normal_process": "normal_process", "priority_escalation": "priority_escalation", "auto_resolve": "auto_resolve", "force_human": "force_human" } )

添加结束节点

for node in ["vip_fast_track", "normal_process", "priority_escalation", "auto_resolve", "force_human"]: advanced_workflow.add_edge(node, END) advanced_app = advanced_workflow.compile()

测试

test_state = { "user_input": "我的订单还没到,已经等了10天了", "intent": "complaint", "user_level": UserLevel.VIP, "urgency": UrgencyLevel.HIGH, "confidence": 0.65 } result = advanced_app.invoke(test_state) print(f"路由决策:{result['routing_reason']}")

五、成本优化:模型动态路由策略

这是我在生产环境中使用的核心优化策略。通过条件边,根据查询复杂度动态选择模型——简单问题用 DeepSeek V3.2(¥0.42/MTok),复杂推理用 GPT-4.1(¥8/MTok),每月节省超过 85% 成本。

"""
成本优化:基于查询复杂度的动态模型路由
策略:
- 简单问答/翻译 → DeepSeek V3.2(¥0.42/MTok)
- 标准对话/总结 → Gemini 2.5 Flash(¥2.5/MTok)
- 复杂推理/代码 → GPT-4.1(¥8/MTok)
"""
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from typing import Literal
import os

配置 HolySheep API(¥1=$1 无损汇率)

HOLYSHEEP_API_KEY = os.getenv("HOLYSHEEP_API_KEY", "YOUR_HOLYSHEEP_API_KEY") BASE_URL = "https://api.holysheep.ai/v1"

初始化多模型客户端

models = { "deepseek": ChatOpenAI( model="deepseek-v3.2", api_key=HOLYSHEEP_API_KEY, base_url=f"{BASE_URL}/openai" # OpenAI 兼容格式 ), "gemini": ChatOpenAI( model="gemini-2.5-flash", api_key=HOLYSHEEP_API_KEY, base_url=f"{BASE_URL}/openai" ), "gpt4": ChatOpenAI( model="gpt-4.1", api_key=HOLYSHEEP_API_KEY, base_url=f"{BASE_URL}/openai" ) } class CostOptimizedState(TypedDict): user_input: str complexity: str # "simple" | "medium" | "complex" selected_model: str response: str estimated_cost: float # 本次调用预估成本(¥) def analyze_complexity(state: CostOptimizedState) -> CostOptimizedState: """分析查询复杂度""" user_input = state["user_input"] # 简单任务关键词 simple_keywords = ["翻译", "改写", "问候", "简单", "什么", "几个"] # 复杂任务关键词 complex_keywords = ["分析", "代码", "实现", "设计", "解释原理", "详细"] simple_score = sum(1 for k in simple_keywords if k in user_input) complex_score = sum(1 for k in complex_keywords if k in user_input) if complex_score > simple_score: complexity = "complex" elif simple_score > complex_score: complexity = "simple" else: complexity = "medium" return {"complexity": complexity} def select_model(state: CostOptimizedState) -> CostOptimizedState: """根据复杂度选择最优模型""" complexity = state["complexity"] user_input = state["user_input"] # 估算 token 数量(简单估算:中文约 2 token/字) estimated_tokens = len(user_input) * 2 model_map = { "simple": ("deepseek", 0.42, estimated_tokens), # ¥0.42/MTok "medium": ("gemini", 2.50, estimated_tokens), # ¥2.5/MTok "complex": ("gpt4", 8.00, estimated_tokens) # ¥8/MTok } model_name, price_per_mtok, tokens = model_map[complexity] estimated_cost = (tokens / 1_000_000) * price_per_mtok return { "selected_model": model_name, "estimated_cost": round(estimated_cost, 4) } def generate_response(state: CostOptimizedState) -> CostOptimizedState: """使用选定模型生成响应""" model_name = state["selected_model"] user_input = state["user_input"] llm = models[model_name] # 根据模型调整 prompt if model_name == "deepseek": prompt = f"简洁回答:{user_input}" elif model_name == "gemini": prompt = f"详细回答:{user_input}" else: prompt = f"深入分析并给出建议:{user_input}" response = llm.invoke(prompt).content return {"response": response} def route_by_complexity(state: CostOptimizedState) -> Literal["select_model", "generate_response"]: """条件路由:根据复杂度决定是否需要模型选择""" # 如果复杂度已确定,直接生成 if state.get("selected_model"): return "generate_response" # 否则进入模型选择 return "select_model"

构建图

cost_graph = StateGraph(CostOptimizedState) cost_graph.add_node("analyze", analyze_complexity) cost_graph.add_node("select_model", select_model) cost_graph.add_node("generate_response", generate_response) cost_graph.set_entry_point("analyze") cost_graph.add_conditional_edges( source_node="analyze", condition=route_by_complexity, path_map={ "select_model": "select_model", "generate_response": "generate_response" } ) cost_graph.add_edge("select_model", "generate_response") cost_graph.add_edge("generate_response", END) cost_app = cost_graph.compile()

测试

print("=" * 60) print("成本优化路由测试") print("=" * 60) test_queries = [ "你好,今天天气怎么样?", "帮我翻译成英文:你好世界", "请分析为什么人工智能很重要,以及它将如何改变未来十年" ] for query in test_queries: result = cost_app.invoke({"user_input": query}) print(f"\n输入:{query}") print(f" 复杂度:{result['complexity']}") print(f" 选用模型:{result['selected_model']}") print(f" 预估成本:¥{result['estimated_cost']}")

六、调试与监控:查看路由轨迹

我在生产环境中发现,条件路由最大的挑战不是实现,而是调试——你很难知道「为什么走了这条路径」。LangGraph 提供了可视化工具,可以完整追踪每个节点的输入输出和路由决策。

"""
调试工具:查看条件路由的执行轨迹
使用 LangGraph 内置的检查点功能
"""
from langgraph.checkpoint.memory import MemorySaver

创建带检查点的图(用于调试)

checkpointer = MemorySaver() debug_app = build_routing_graph(checkpointer=checkpointer)

执行并获取完整轨迹

def debug_route(user_input: str): """执行并返回完整调试信息""" # 配置线程(用于状态持久化) config = {"configurable": {"thread_id": "test-123"}} # 收集中间步骤 steps = [] # 使用 stream 模式获取每一步 for event in debug_app.stream( {"user_input": user_input}, config=config ): node_name = list(event.keys())[0] node_output = event[node_name] steps.append({"node": node_name, "output": node_output}) print(f"📍 节点: {node_name}") if node_name == "classify_intent": print(f" 输出: intent={node_output.get('intent')}, confidence={node_output.get('confidence')}") elif "response" in str(node_output): print(f" 输出: {node_output.get('response', '')[:50]}...") print() return steps

执行调试

print("=" * 60) print("路由轨迹调试") print("=" * 60) debug_route("我的订单丢了,怎么处理?")

导出为 Mermaid 图表(用于文档)

print("\n📊 图结构(Mermaid 格式):") print(debug_app.get_graph().draw_mermaid())

常见错误与解决方案

在我使用 LangGraph 条件路由的过程中,遇到了不少坑。以下是最常见的 3 个错误及其解决方案,都是生产环境中的真实经验:

错误 1:path_map 键值不匹配导致 KeyError

# ❌ 错误写法:路由函数返回值不在 path_map 中
def route_intent(state):
    return "refund"  # 直接返回字符串

workflow.add_conditional_edges(
    source_node="classify",
    condition=route_intent,
    path_map={
        "handle_refund": "handle_refund"  # ❌ 键应该是 "refund"
    }
)

✅ 正确写法:path_map 的键必须与路由函数返回值匹配

workflow.add_conditional_edges( source_node="classify", condition=route_intent, path_map={ "refund": "handle_refund", # ✅ 键="refund",值=实际节点名 "technical": "handle_technical", "complaint": "handle_complaint", "inquiry": "handle_inquiry", "human": "escalate_to_human" } )

错误 2:状态字典未正确更新导致数据丢失

# ❌ 错误写法:返回字典会替换整个状态
def bad_node(state):
    return {"response": "Hello"}  # ❌ 这会丢失 user_input, intent 等字段

✅ 正确写法:只更新需要修改的字段

def good_node(state: CustomerServiceState): return { "response": "Hello", # 只添加/修改 response # 其他字段自动保留 }

或者使用 @tool 装饰器 + 合并状态

from langchain_core.tools import tool @tool def bad_tool(user_input: str) -> str: return f"Response to: {user_input}"

注意:@tool 会替换状态,需要额外处理

错误 3:循环依赖导致无限循环

# ❌ 错误写法:节点 A 路由到节点 B,节点 B 路由回节点 A
workflow.add_conditional_edges("A", route_a_to_b, path_map={...})
workflow.add_conditional_edges("B", route_b_to_a, path_map={...})

❌ 可能导致无限循环

✅ 正确写法:确保有终止条件

def safe_route(state): # 添加循环计数器 loop_count = state.get("loop_count", 0) if loop_count >= 3: return END # 超过3次循环强制结束 return "next_node"

或者使用普通边 + END 确保有出口

workflow.add_edge("B", END) # 确保 B 有明确的结束路径

性能对比与选型建议

在实际生产中,我对比了不同路由策略的性能表现。以下数据基于 HolySheep API 的实测结果(国内直连 <50ms):

总结

LangGraph 的 conditional edges 是构建智能 AI 工作流的核心能力。从基础的意图路由,到复杂的多维度决策,再到成本优化的模型动态选择,条件边让「根据状态选择路径」变得优雅且可维护。我在多个项目中实践后发现:条件路由的真正价值不在于代码本身,而在于设计良好的路由策略——这需要结合业务需求、用户画像、成本控制综合考量。

如果你正在构建类似的 AI 应用,建议先从简单路由开始,逐步增加复杂度。同时,借助 HolySheep AI 的无损汇率和国内低延迟优势,可以在保证体验的同时显著降低成本。

完整的示例代码已在上文给出,你可以直接复制运行。建议从第一个「意图分类路由系统」开始,理解核心概念后再尝试进阶用法。

👉 免费注册 HolySheep AI,获取首月赠额度