第2章 智能客服系统¶
学习目标¶
- 掌握智能客服 Agent 的需求分析方法与关键指标定义
- 理解 RAG + Agent + 工具调用三位一体的客服架构设计
- 学会构建领域知识库并实施多轮对话状态管理
- 掌握人工转接(human-in-the-loop)的触发条件与实现方式
- 能够设计客服系统的效果评估体系与持续优化闭环
问题导入¶
某电商平台日均客服会话量 12 万通,旺季翻倍。传统关键词客服机器人只能解决 30% 的常见问题,复杂咨询全靠人工,导致旺季排队严重、客诉激增。业务方提出新诉求:智能客服要能理解商品细节、查询订单状态、处理退换货、必要时优雅转人工。简单的 FAQ 匹配已无法满足,必须引入大模型 + RAG + 工具调用的 Agent 架构。但如何设计才能兼顾准确率、响应时延与成本?如何在自动回复与人工兜底之间找到平衡?这正是本章要解决的核心问题。
核心概念¶
1. 客服 Agent 的能力分层¶
智能客服通常分三层能力,逐级升级:
| 层级 | 能力 | 实现方式 | 典型问题 |
|---|---|---|---|
| L1 | FAQ 直答 | 关键词/向量检索 + 模板回复 | 退货政策、运费规则 |
| L2 | 知识问答 | RAG + LLM 生成 | 商品参数对比、使用方法 |
| L3 | 任务执行 | Agent + 工具调用 + 多轮 | 查询订单、发起退款、修改地址 |
2. 架构核心组件¶
- 意图路由:判断用户意图,分流到 FAQ、RAG、任务 Agent 或人工。
- 知识库:商品库、政策文档、FAQ 库,支持向量 + 关键词混合检索。
- 工具集:订单查询、物流查询、退款发起、地址修改、券码核销等。
- 对话状态管理:维护槽位(订单号、商品 SKU、退款原因)与上下文。
- 人工转接:当置信度低、情绪负面、敏感操作时触发转人工。
- 效果监控:一次解决率、转人工率、满意度、平均轮次。
3. 知识库构建要点¶
- 分块策略:政策文档按条款切分,FAQ 按问答对,商品按 SKU 字段。
- 元数据:标注类目、有效期、版本号,支持过滤检索。
- 混合检索:向量检索召回语义相似,BM25 捕捉关键词,加权融合。
- 更新机制:政策变更需热更新,商品上下架需与商品库同步。
4. 多轮对话与槽位填充¶
任务型对话需要从用户话语中提取关键信息(槽位),并在信息不全时主动追问。例如退款场景需订单号、退款原因、退款金额,缺失时按优先级反问。
5. 人工转接触发条件¶
- 置信度低:检索 top1 相似度低于阈值,或模型多次拒绝回答。
- 情绪负面:检测到愤怒、投诉词汇,立即转人工安抚。
- 敏感操作:大额退款、账户解绑、投诉升级等高风险动作。
- 反复失败:同一问题连续 2 轮未解决。
- 用户主动:用户直接要求"转人工"。
6. 效果评估指标¶
| 指标 | 定义 | 目标值参考 |
|---|---|---|
| 一次解决率 | 无需转人工即解决的比例 | ≥ 60% |
| 转人工率 | 转人工会话占比 | ≤ 30% |
| 平均轮次 | 单次会话平均对话轮数 | 3-5 轮 |
| 首响时延 | 首条回复平均延迟 | ≤ 2 秒 |
| 满意度 | 用户评价 4-5 星比例 | ≥ 85% |
| 幻觉率 | 事实错误占比 | ≤ 3% |
原理图¶
flowchart TB
U[用户消息] --> Router{意图路由}
Router -->|FAQ| FAQ[FAQ 检索]
Router -->|知识问答| RAG[RAG 检索+生成]
Router -->|任务执行| Agent[任务 Agent]
Router -->|转人工| Human[人工坐席]
RAG --> KB[(知识库<br/>政策/FAQ/商品)]
Agent --> Tools[工具集<br/>订单/物流/退款]
Agent --> Slots[槽位管理]
Agent --> Check{转接判定}
Check -->|低置信/负面情绪| Human
Check -->|继续| Agent
FAQ --> Reply[回复用户]
RAG --> Reply
Agent --> Reply
Human --> Reply
Reply --> Monitor[效果监控]
Monitor --> Router
图:智能客服 Agent 架构,含意图路由、RAG、任务 Agent、人工转接与监控闭环
示例代码¶
以下代码演示一个简化的客服 Agent 核心实现,包含意图路由、工具调用与人工转接判定。
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Callable
@dataclass
class Tool:
name: str
description: str
func: Callable[[dict], str]
# 模拟工具实现
def query_order(params: dict) -> str:
oid = params.get("order_id", "未知")
return f"订单 {oid} 状态:已发货,预计明日送达。"
def request_refund(params: dict) -> str:
oid = params.get("order_id", "")
reason = params.get("reason", "未说明")
return f"已为订单 {oid} 发起退款申请,原因:{reason},预计 1-3 工作日到账。"
TOOLS: dict[str, Tool] = {
"query_order": Tool("query_order", "查询订单状态", query_order),
"request_refund": Tool("request_refund", "发起退款申请", request_refund),
}
@dataclass
class CustomerServiceAgent:
"""简化版客服 Agent。"""
slots: dict = field(default_factory=dict)
turn_count: int = 0
require_human: bool = False
def route(self, message: str) -> str:
"""简易意图路由:基于关键词。"""
if "转人工" in message or "投诉" in message:
self.require_human = True
return "human"
if "退款" in message:
return "refund"
if "订单" in message or "物流" in message:
return "order"
return "rag"
def fill_slots(self, message: str, intent: str) -> None:
"""从消息中抽取槽位(演示用,实际应使用 LLM 抽取)。"""
if "订单" in message:
# 简化:假设订单号在消息中
for token in message.replace(",", " ").split():
if token.startswith("DD"):
self.slots["order_id"] = token
if intent == "refund":
self.slots.setdefault("reason", "商品问题")
def needs_human(self, intent: str, confidence: float) -> bool:
"""转人工判定。"""
if self.require_human:
return True
if confidence < 0.5:
return True
if self.turn_count >= 4 and intent == "rag":
return True
return False
def handle(self, message: str, confidence: float = 0.8) -> str:
self.turn_count += 1
intent = self.route(message)
if self.needs_human(intent, confidence):
return "正在为您转接人工客服,请稍候……"
self.fill_slots(message, intent)
if intent == "order":
return TOOLS["query_order"].func(self.slots)
if intent == "refund":
if "order_id" not in self.slots:
return "请提供您的订单号以便发起退款。"
return TOOLS["request_refund"].func(self.slots)
return "已为您检索相关帮助文档,请问还有其他问题吗?"
if __name__ == "__main__":
agent = CustomerServiceAgent()
print(agent.handle("我的订单 DD20240601 还没到"))
print(agent.handle("我想退款"))
print(agent.handle("我要投诉你们"))
企业案例¶
案例 1:某电商平台客服升级¶
该平台原使用关键词机器人,一次解决率仅 30%。引入 LangGraph 编排的客服 Agent 后:意图路由分流 50% FAQ 直答,RAG 解决 35% 知识问答,任务 Agent 处理 10% 订单退款,剩余 5% 转人工。整体一次解决率提升至 75%,人工坐席压力下降 60%,旺季排队时长从 8 分钟降至 1 分钟以内。
案例 2:某金融企业客服的合规红线¶
金融客服涉及产品风险提示,不能简单让 LLM 自由生成。该企业采用"Agent 草拟 + 合规模板校验"双层架构:Agent 生成回复后,必须命中预审模板的关键句才能发出,否则降级为模板回复或转人工。幻觉率从 8% 降至 1.2%,满足监管要求。
案例 3:某 SaaS 公司的客服知识库治理¶
初期客服效果不稳定,根因是知识库陈旧。后建立知识库治理流程:每周自动检测低召回 FAQ,由运营人员补充;政策变更 24 小时内热更新;新增"知识有效期"字段,过期内容自动下线。治理后检索准确率从 72% 提升至 91%。
常见问题¶
Q1:客服 Agent 用 GPT-4 还是开源小模型? A:建议分层。意图路由、槽位抽取用小模型(速度快、成本低);复杂知识问答与多轮推理用强模型;FAQ 直答可不走模型。整体成本可降 60% 以上。
Q2:如何避免 LLM 编造政策? A:三管齐下——RAG 限定上下文、Prompt 强约束"仅依据资料回答,不知则转人工"、关键问题加模板校验层。
Q3:转人工时如何无缝交接上下文?
A:在转接时把对话摘要、已填槽位、用户画像推送给坐席系统,避免用户重复描述。可在 Agent 中维护 session_summary 字段,每轮更新。
Q4:多轮对话上下文太长怎么办? A:采用"摘要 + 近 3 轮原文"策略:超过阈值后对早期对话做摘要压缩,保留近期原文,兼顾上下文与 token 成本。
面试题¶
1. 描述智能客服 Agent 的三层能力架构及各层实现要点。 参考答案:L1 FAQ 直答用检索+模板;L2 知识问答用 RAG+LLM 生成;L3 任务执行用 Agent+工具调用+槽位填充。层级越高对编排与状态管理要求越高,需配套人工转接与监控。
2. 什么情况下应该转人工?如何实现? 答题要点:触发条件包括低置信度、负面情绪、敏感操作、反复失败、用户主动。实现上在 Agent 流程中插入判定节点,命中条件时跳转人工节点并推送上下文摘要。
Q3:如何评估客服 Agent 上线后的真实效果? 参考答案:核心看一次解决率、转人工率、满意度、幻觉率;同时监控平均轮次、首响时延、token 成本。需 A/B 灰度上线,对比新旧版本,并建立每日 badcase 复盘机制。
练习题¶
- 槽位填充设计:为"修改收货地址"场景设计所需槽位(订单号、新地址、验证方式等),并写出信息缺失时的追问逻辑。
- 转接策略:给定一组历史会话日志,请设计转人工判定规则并评估转人工率与一次解决率的平衡点。
- 思考题:当用户情绪激动时,Agent 应先安抚还是直接转人工?请结合产品体验与成本给出你的方案。
小结¶
智能客服是 AI Agent 落地最广、价值最直接的场景。其核心在于"分层能力 + 混合检索 + 工具调用 + 人工兜底"的协同架构,以及围绕一次解决率与幻觉率的效果闭环。技术上,LangGraph 的状态图非常适合表达"路由→执行→转接判定→回退"的客服流程;业务上,知识库治理与持续 badcase 复盘是效果长青的关键。下一章我们将转向企业内部场景——AI 办公助理。