上一篇文章聊了工单智能体,这次聊聊更进阶的一个:用LangGraph做一个能自主决策的客服智能体。所谓"自主决策",就是它不只是"查知识库回答",而是能根据对话进展自己决定下一步动作——继续追问、查订单、申请退款、还是转人工。这个项目从设计到上线花了三周,这篇把核心设计和踩坑过程记录下来。
普通LangChain的Chain是"线性管道":输入→处理→输出,一步到底。但真实的客服对话是有分支、有循环、有状态的:用户说"我要退款",智能体要判断——订单在途不能退?那就只能退部分?要不要问用户原因?这些逻辑用Chain写会变成一团if-else,可维护性极差。
LangGraph把流程建模成图:节点是动作(理解意图、查订单、生成回复),边是条件跳转。状态对象贯穿整个流程,每个节点都能读写状态。这正好符合客服场景"根据上下文动态决策"的需求。
from langgraph.graph import StateGraph, END
from typing import TypedDict, Literal
class State(TypedDict):
messages: list # 对话历史
intent: str # 当前意图: 查询/退换/投诉/闲聊
order_info: dict | None # 订单信息
need_escalate: bool # 是否需要转人工
# 节点1: 意图识别——判断用户要干什么
# 节点2: 信息补齐——信息不足时主动追问
# 节点3: 工具调用——查订单/查物流/申请售后
# 节点4: 兜底转人工——超范围或用户情绪激烈时
graph = StateGraph(State)
graph.add_node("understand", understand_intent)
graph.add_node("collect", collect_info)
graph.add_node("action", call_business_api)
graph.add_node("escalate", escalate_to_human)条件边的设计是灵魂:
graph.add_conditional_edges(
"understand",
route_by_intent, # 根据intent决定走哪个节点
{"query": "action", "refund": "collect", "complaint": "escalate"}
)用户说"查订单",直接走action查库;说"我要退"但没说订单号,走collect先追问;涉及投诉,直接转人工——每一个决策都清晰写在图里,比藏在一堆if-else里好维护十倍。
早期让模型直接输出意图标签,结果"帮我看看我昨天买的那个东西到哪了"被识别成"闲聊"。改成让模型从预设意图列表中选择并输出JSON,配合5个示例(few-shot),准确率从85%提到96%。
用户连续两次不提供订单号时,智能体应该判断"再问下去用户体验更差",直接转人工。我在collect节点里加了一个状态计数:同一信息追问超过2次,强制走escalate。自主决策必须有边界,无限追问就是灾难。
查完订单后,把订单状态写进state(比如"已签收"),后续的退款判断节点直接读这个字段决定能不能退。状态是贯穿全流程的,节点之间通过它传递信息,而不是每次重新查一遍——这也是LangGraph相比Chain的核心优势之一。
上线到企业微信客服通道后:
用LangGraph做这个智能体,最大的收获是:把"AI要自主决策"这件事,从玄学变成了工程。所谓自主,不是让模型自由发挥,而是把决策点拆成明确的节点和条件边,让模型在"受约束的选项"里做选择。模型的创造力用在理解对话上,流程的确定性交给图结构保证。
如果你要做客服、助手类的复杂智能体,强烈推荐LangGraph:画好状态、定好节点、明确边界,一个可靠可维护的自主决策智能体就立起来了。