AI 纪元 追踪人工智能最新进展,深度解读前沿技术

用 LangGraph 管住售后 Agent 的退款路径

售后 Agent 同时处理订单核验、政策判断和退款执行时,长 Prompt 很难守住每条权限边界。用 LangGraph 拆出状态、节点、条件边和人工审核后,死循环能设出口,错误退款能被拦截,流程也能从检查点恢复。

0 次阅读 约 3102 字 6 分钟 AI 生成
A minimalist physical model of a logic flow graph with spheres and tubes.
A minimalist physical model of a logic flow graph with spheres and tubes.

用户只问了一句“退款进度”,系统却一路走到了退款接口。

把它放进一个设定于 2026 年电商大促的测试场景:订单 API 没拿到实时物流状态,Agent 开始反复执行“道歉→查询→失败→再次道歉”。System Prompt 里还有一句“尽量满足用户需求”,模型在上下文混乱时选中了无需审核的快速退款工具。模拟后果是,商家单日出现数笔非合规退款。

答错一句话只是客服质量问题;错误穿过权限边界,就成了资金问题。售后 Agent 要解决的关键,是把模型的活动范围限制在允许的退款路径里。

长 Prompt 管不了每一条退款路径

常见做法是把全部业务规则塞进 System Prompt。比如先核对订单号,示例政策规定只有 7 天内可以无理由退款,贵重物品需要人工审核,再根据会员等级、商品品类和退货时长决定下一步。最后,模型自行选择查询、退款或创建工单等工具。

这套方式做 Demo 很快,进入长对话后却难以排查。到了第 10 轮,开发者很难确认 Prompt 顶部的每条限制是否仍被严格执行;订单 API 返回的信息无法推进状态时,模型可能重复调用同一个工具;走错分支后,系统也缺少清晰的恢复位置。

以 5 个步骤为例:提取订单号、核验订单、判断有效期、匹配政策、执行退款。只要这些步骤都由模型自由路由,日志就很难回答一个简单问题:退款请求究竟在哪一步获得了执行权限?

继续往 Prompt 里追加规则,只会让这条权限链更难验证。LangGraph 官方将其定位为面向可靠 AI Agent 的编排框架。它把流程组织成有向图:节点负责执行任务,边负责决定状态如何流转。图只是形式,真正有用的是每个节点都能被检查、限制和恢复。

先把订单状态从聊天记录里拿出来

订单号、核验结果和重试次数不该只藏在对话文本中。可以先定义一份带类型的显式状态:

class AfterSalesState(TypedDict):
    order_id: str              # 订单号
    user_intent: str           # 退款、换货或投诉
    verification_status: bool  # 订单核验状态
    refund_amount: float       # 拟退款金额
    retry_count: int           # 当前节点重试次数
    next_step: str             # 下一步路由

这份 AgentState 在节点之间传递。开发者可以直接查看 verification_status,也可以用 retry_count 判断工具是否反复失败。配合 checkpoint,流程暂停后还能从已保存的状态继续执行,无需重新拼接整段聊天记录。

四个节点,分别看住四件事

售后流程可以先拆成四个节点:

  • IntentNode:从用户输入中提取订单号和意图。信息缺失时,直接返回询问,不进入退款流程。
  • VerifyNode:用普通 Python 代码调用订单 API,检查订单是否存在、是否仍在退款有效期内。日期计算和订单核验无需交给 LLM 猜测。
  • PolicyNode:读取核验后的订单信息和公司政策,给出“自动退款”“引导寄回”或“转接人工”等结果。
  • ExecuteNode:调用退款接口,或者创建售后工单。

节点拆开后,条件边可以直接写进代码:

def should_continue(state):
    if not state['verification_status']:
        return 'ask_user_or_handoff'
    return state['next_step']

只要 VerifyNode 没有通过,流程就不能进入 ExecuteNode。这条禁行规则由 Python 控制,可以单独写测试,也不会因为对话变长而失效。

一次错误退款,Trace 应该回答什么

假设测试时点晚于 2026-01-01,用户为已经超过示例退款期限的商品申请退款,Agent 却执行了退款。把所有步骤串成一条 Chain 时,开发者往往只能面对一长串输入和输出。LangSmith 的 Trace 视图则能把节点调用关系摊开,顺着执行路径查找错误状态。

这次调用可以定位到两个时间点:

  • T1:VerifyNode 返回 expiry_date: 2026-01-01,订单已经过期。
  • T2:PolicyNode 读到 Prompt 中含糊的“特殊客户”说明,将用户误判为特例,并把 next_step 写成 execute_refund。

修复位置很明确:在 ExecuteNode 前增加一个 Guardrail 节点,重新检查硬性条件。

def guardrail(order, user):
    if order.is_expired and not user.is_vip:
        raise ValidationError('refund blocked')

只要退款路径被强制要求经过这个节点,PolicyNode 即使再次误判,也无法直接越过代码条件。Prompt 仍可负责理解政策,最终权限则落在可测试的规则上。

500 元退款,先停在审核台

涉及资金的动作还需要人工接管入口。可以在 ExecuteNode 前设置 interrupt_before,配合持久化 checkpointer 保存当前状态并暂停流程。售后主管在后台看到的待审核记录可以包括:

  • 用户请求:退款 500 元
  • Agent 判定:符合特例退款条件
  • 状态快照:
{"order_id": "123", "amount": 500, "reason": "customer_complaint"}

主管批准后,LangGraph 从检查点恢复并继续调用退款接口。主管拒绝并修改理由后,流程可以回到 PolicyNode,重新生成给用户的说明。

retry_count 也能处理订单 API 暂时不可用的情况。每次失败后增加计数,达到系统设定的上限就转人工或稍后重试,避免再次出现“查询失败后无限查询”的循环。

Prompt 留在它擅长的位置

Prompt 仍然适合提取用户意图、阅读政策文本和组织回复语言。订单是否存在、退款期限是否有效、接口能否执行、失败后去哪里、多少钱必须人工审核,这些条件更适合写进状态、条件边和代码节点。

LangGraph 的价值就在这张可检查的决策链上:哪一步由模型判断,哪一步由代码拦截,哪里暂停,哪里恢复。退款发生后,开发者也能沿着 Trace 找到具体节点,而不是继续修改一份越来越长的 System Prompt。

Datawhale 的客服 Agent 实践把人工升级、审计、数据设计和上线边界列为重点;Higress 关于 Agent 工程化的讨论,也提醒开发者关注模型之外的产品与技术实现。对售后系统来说,这些控制点直接决定了 Agent 能否接触真实订单和退款接口。

参考资料

相关阅读