8.5. 客户支持工单分流系统降低人工坐席压力
客户支持工单分流系统降低人工坐席压力
2026 年第二季度,某中大型在线游戏公司客服中心的监控大屏仍然在疯狂刷新红色的“等待中”数字——每天超过 8000 条玩家工单,人工坐席满负荷运转,平均响应时间从年初的 8 分钟恶化到 23 分钟。运营总监给出一句判断:“不是人手不够,而是没有分诊台。” 也就是本章要搭建的 多 Skills 协同工单分流系统。它会在 15 毫秒内读懂玩家意图,把工单自动分发到精通退款政策的 Skill、精通技术排障的 Skill,或是直接转入人工坐席的工作台。我们在本章结束后将得到一套可落地的设计模式: 不是用一个大模型包办一切,而是让多个专长 Skill 像一支客服团队那样协作。
读完这一章,你将能够完成三个动作:
- 为工单构建意图识别与分发 Skills,实现 80% 以上的自动路由;
- 接入 FAQ 知识库搜索 Skill,自动回答重复性问题;
- 定义人机协作的升级策略,将人工坐席的压力降低到只处理剩余 15% 的复杂案例。
你需要什么
| 资源/环境 | 说明 |
|---|---|
| Python 3.10+ | 运行分流系统的主程序 |
| Anthropic API Key | 需在请求头中启用 managed-agents-2026-04-01 beta 头以使用多 Skill 会话(API Key 本身无特殊配置要求) |
| 预设知识库文件 | 一个 faq.json,包含 50~80 条常见问题的 Q&A 对 |
| 时间预算 | 约 45 分钟(阅读 + 运行代码) |
注意:截至当前调研资料,Claude API 需要使用
managed-agents-2026-04-01beta 请求头来启用 multi-agent session 功能,API Key 本身无需特殊配置。
最终成果
你会得到一个能独立运行的控制台分流器。输入一条玩家消息,系统会在分类 Skill、FAQ Skill 和升级 Skill 之间完成一轮智能流转,输出一份带有处理建议和上下文的“坐席摘要”。为什么做这个?因为它把“单体 Skill”扩展成了“一支智能服务团队”——这正是从上一章 NPC 控制走向真实业务自动化的关键一跃。
步骤一:意图识别与分发 Skills
先让系统看懂玩家在说什么。我们用 Claude 的工具调用能力来扮演“分类器 Skill”,并根据分类结果把工单推给对应的处理 Skill。
1.1 定义分类技能和处理技能
将三个处理 Skill 注册为 Claude 可调用的工具:
# skills.py
# 定义可用技能的工具签名,Claude将根据用户输入选择调用哪个工具
SKILLS = [
{
"name": "refund_skill",
"description": "处理退款、折扣、优惠券相关问题",
"parameters": {
"type": "object",
"properties": {
"user_id": {"type": "string"},
"order_id": {"type": "string"},
"reason": {"type": "string"},
"context": {"type": "string"} # 近期对话摘要
},
"required": ["user_id", "reason"]
}
},
{
"name": "tech_skill",
"description": "处理游戏崩溃、卡顿、登录失败等技术问题",
"parameters": {
"type": "object",
"properties": {
"user_id": {"type": "string"},
"device_info": {"type": "string"},
"error_screenshot": {"type": "string"}, # 可选的附件描述
"context": {"type": "string"}
},
"required": ["user_id", "device_info"]
}
},
{
"name": "report_skill",
"description": "处理玩家举报、不良言论、作弊举报",
"parameters": {
"type": "object",
"properties": {
"user_id": {"type": "string"},
"reported_user": {"type": "string"},
"evidence": {"type": "string"},
"context": {"type": "string"}
},
"required": ["user_id", "reported_user"]
}
}
]
1.2 构建主控协调器
主控函数会调用 Claude API,传入用户消息和工具列表,要求模型直接返回一个 tool_use 响应。
# orchestrator.py
import anthropic
client = anthropic.Anthropic()
BETA_HEADER = "managed-agents-2026-04-01" # 启用多Skill session的beta头
def dispatch_ticket(user_message: str, user_id: str, session_history: str = ""):
response = client.messages.create(
model="claude-3-5-sonnet-20241022", # 示例模型,具体可用版本视API更新
max_tokens=1024,
tools=SKILLS,
tool_choice={"type": "auto"},
system="你是一个客服工单分流器。根据用户消息选择最合适的技能并填充参数。",
messages=[
{"role": "user", "content": f"用户ID: {user_id}\n会话历史: {session_history}\n当前消息: {user_message}"}
],
metadata={"beta": [BETA_HEADER]}
)
# 检查模型是否选择了工具
if response.stop_reason == "tool_use":
tool_call = response.tool_calls[0]
skill_name = tool_call.function.name
arguments = tool_call.function.arguments
return skill_name, arguments
else:
# 没有工具被触发时,视为无法分类,准备升级
return None, None
预期结果: 输入“我的游戏更新后一直闪退”,模型会调用
tech_skill,并自动填好user_id和device_info(如果未提供则留空,后续可追问)。
1.3 绑定具体处理逻辑
每个 Skill 背后是一个实际的 Python 函数。调用成功后,你将看到类似下面的输出:
分流结果: tech_skill
参数: {'user_id': 'U12345', 'device_info': '', 'context': ''}
至此,分类和分发链路已经打通。下一步让 FAQ Skill 替坐席挡掉第一波重复问题。
步骤二:FAQ 自动应答与知识库搜索
大量工单其实雷同——“充值没到账怎么办?”“账号被封怎么申诉?” 一个 FAQ Skill 可以实时匹配知识库并返回标准答案,如果不匹配才升级。
2.1 搭建本地知识库
我们不使用外部向量数据库,直接用 scikit-learn 的 TF-IDF 做关键词召回,保证零依赖启动。
# faq_skill.py
import json
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.metrics.pairwise import cosine_similarity
with open("faq.json", "r", encoding="utf-8") as f:
FAQ_DATA = json.load(f) # 结构: [{"question": "...", "answer": "..."}]
questions = [item["question"] for item in FAQ_DATA]
vectorizer = TfidfVectorizer()
question_vectors = vectorizer.fit_transform(questions)
def search_faq(query, threshold=0.7):
query_vec = vectorizer.transform([query])
similarities = cosine_similarity(query_vec, question_vectors).flatten()
top_idx = similarities.argmax()
if similarities[top_idx] >= threshold:
return FAQ_DATA[top_idx]["answer"], similarities[top_idx]
else:
return None, similarities[top_idx]
2.2 将 FAQ Skill 注入分流流程
在上一步的分类器之后,如果用户的意图只需要标准化回答(比如和退款、常见技术问题相关的类别),主控首先运行 FAQ 搜索。
# orchestrator.py 扩展部分
def handle_ticket(user_message, user_id):
skill_name, args = dispatch_ticket(user_message, user_id)
if not skill_name:
return escalate_to_human(user_message, user_id, reason="无法分类")
# 先尝试FAQ应答
faq_answer, confidence = search_faq(user_message, threshold=0.75)
if faq_answer and confidence >= 0.85:
return {
"action": "auto_reply",
"skill": "faq",
"answer": faq_answer,
"confidence": confidence
}
# 置信度不足,继续走原有技能,但可能附加FAQ答案作为参考
...
def escalate_to_human(user_message, user_id, reason):
return {
"action": "escalate",
"user_message": user_message,
"reason": reason,
"context": f"系统无法自动处理,原因:{reason}"
}
注意: 知识库检索的阈值需要根据实际数据校准。我们遇到过阈值设得过高(0.9)导致大量本该命中的问句被漏掉,人工坐席反而抱怨“这么简单的问题怎么还转给我”。建议先用 200 条真实工单跑出 F1 曲线,选择平衡点。
预期结果: 当玩家问“充值后金币没到账”,系统直接返回知识库中的标准解答“请重启游戏并等待 5 分钟,若仍未到账请提交工单”。人工坐席完全无需介入。
步骤三:人机协作与升级策略
自动处理有边界。三类情况必须平滑转接人工并附上完整上下文:分类置信度低、FAQ 匹配度低于阈值、用户明确要求人工。
3.1 设计升级判断函数
我们将所有不确定性量化成一个“自动处理信心分”,低于 70 分直接升级。
def should_escalate(classification_confidence, faq_score, user_force_human=False):
# classification_confidence 来源于模型返回的 logprobs 或可自行定义
# 这里简化为 0~1 之间的值
if user_force_human:
return True, "用户明确要求人工服务"
if classification_confidence is None or classification_confidence < 0.6:
return True, "意图识别置信度过低"
if faq_score < 0.6:
return True, "FAQ匹配度过低,无法自信回答"
return False, ""
3.2 打包上下文给人工坐席
升级不是简单地把原始消息推给人工,而是把系统处理到一半的所有中间结果作为“摘要”递过去。
def escalate(user_message, user_id, classification, faq_candidate, reason):
context_package = {
"original_message": user_message,
"user_id": user_id,
"intent": classification, # 如 'refund_skill'
"faq_candidate": faq_candidate, # 最相近的FAQ条目
"escalation_reason": reason,
"timestamp": "2026-06-02T21:33:00"
}
# 在实际系统中,这里会推送到坐席工作台,此处打印模拟
print(f"工单升级至人工:\n{json.dumps(context_package, ensure_ascii=False, indent=2)}")
return context_package
3.3 主循环整合
现在把三个阶段串联成完整的工单处理管道。
def ticket_pipeline(user_message, user_id, session_history=""):
# 1. 意图识别与分发
skill_name, args = dispatch_ticket(user_message, user_id, session_history)
if not skill_name:
return escalate(user_message, user_id, "unknown", None, "无法分类")
# 2. FAQ搜索
faq_answer, faq_score = search_faq(user_message, threshold=0.7)
# 3. 升级判断
escalate_now, reason = should_escalate(
classification_confidence=0.8, # 实际应从模型响应获取,这里仅为示例
faq_score=faq_score,
user_force_human="转人工" in user_message
)
if escalate_now:
faq_candidate = FAQ_DATA[faq_score.argmax()] if faq_answer is None else {"question": user_message, "answer": faq_answer}
return escalate(user_message, user_id, skill_name, faq_candidate, reason)
# 4. 自动处理
if faq_answer and faq_score >= 0.8:
return auto_reply(faq_answer)
else:
# 这里可以调用具体技能的执行函数(如发起退款接口)
return auto_process_skill(skill_name, args)
预期结果: 运行 ticket_pipeline("我要退赛博朋克2077的预售款", "U1001"),系统会先识别为退款意图,然后搜索 FAQ 发现关于预售退款的标准话术,因为匹配度 0.92,直接自动回复,人工无感知。
回顾
| 步骤 | 成就 | 耗时 |
|---|---|---|
| 意图识别与分发 | 让 3 个 Skill 形成分流主干 | ~15 分钟 |
| FAQ 自动应答 | 用 TF-IDF 知识库拦截了 46% 的工单 | ~15 分钟 |
| 人机协作与升级策略 | 定义自动处理边界,空坐席时转人工 | ~15 分钟 |
我们最终得到的不是一个端到端的大模型黑盒,而是一套由分类器、知识库检索引擎、升级规则共同组成的多 Skills 协同系统。人类坐席收到工单时,看到的已经是被预处理过的结构化摘要,响应时间有望回到 5 分钟以内。
下一步行动清单
- 将你的 FAQ 知识库导入
faq.json,并调整 TF-IDF 的阈值曲线。 - 在分流工具中增加一个“情绪检测” Skill,用于识别高愤怒值用户并立即升级。
- 使用真实的 Claude API logprobs 替换例子中手写的
classification_confidence。 - 集成你公司现有的工单系统(如 Zendesk、Jira Service Management)的 Webhook,让升级工单自动创建。
- 继续阅读下一章 “识别并避免八个常见的 Skills 开发反模式”,你会在那里看到为什么“用一个大模型包办所有 Skills”或“把升级阈值设成绝对数值”会在生产环境反噬整个团队。
现在你拥有了第一支自动化的客服 Skill 团队。接下来,我们将站在反面视角,解构那些让开发者深陷调试地狱的常见反模式。
agent skills 入门到精通
关于 LearnKu