AI图鉴

AI图鉴首页 › AI 资讯 › 别让 AI 客服把用户当猴耍:百来行 Python 把「转人工」做成一条高可用链

别让 AI 客服把用户当猴耍:百来行 Python 把「转人工」做成一条高可用链路

来源:掘金 · 发布时间:10-30 · 由 AI图鉴每小时自动聚合

9 月 1 日,GB/T 47746—2026《顾客联络服务 人工与智能客户服务协同要求》正式实施。这是国内第一个专门约束人机客服协同的国家标准,几条硬要求值得直接抄进需求文档: 必须设置清晰、醒目的

9 月 1 日,GB/T 47746—2026《顾客联络服务 人工与智能客户服务协同要求》正式实施。这是国内第一个专门约束人机客服协同的国家标准,几条硬要求值得直接抄进需求文档:

- 必须设置清晰、醒目的人工服务入口,严禁隐藏人工通道;

- 用户明确要求转人工时,必须及时转接;

- 切换后要同步客户信息,不得重复询问;

- 涉及价格、折扣、退款、赔偿、合同变更等事项,AI 可以解释规则、收集材料、生成工单,最终确认应由人工或规范化流程完成。

现实是落地两个月,媒体实测仍在翻车:某购票平台记者三次说「转人工」才接通,有人等 40 分钟未接通导致票作废,甚至有机器人在识别到用户坚持后直接挂断。中消协上半年数据里,售后服务投诉占 26.79%,「AI 客服不实承诺、人工接入困难」是新增热点。

这些问题跟模型能力关系不大,几乎全是会话状态管理和产品策略的问题。下面给一份能直接跑的骨架。

技术要点

四个约束,决定了实现方式:

1. 转人工必须是规则,不是模型判断。 意图识别交给人,兜底交给规则引擎。标准里写的「明确要求」「超时」「高风险场景」,本质都是可枚举的触发条件。 2. 会话要有状态计数。 兜底话术连续命中几次、总轮次到了几轮,都得记。大多数线上事故就是没有这两个计数器。 3. 风险词优先于业务词。 「投诉」「监管」「12315」「人身安全」这类词必须走独立通道,不能被「自助流程」吃掉。 4. 转接要带上下文。 转过去之后人工看不到历史记录,等于用户要把委屈再讲一遍,体验二次崩塌。

可运行示例

纯标准库,复制即可跑。核心是一个 route() 函数,返回「继续聊」还是「转人工」。

# 三段代码块按顺序拼接后可直接运行

from dataclasses import dataclass

from typing import Callable

# --- 明确要求转人工:命中即转(国标硬要求)---

ESCALATE_PATTERNS = ("转人工", "人工客服", "找真人", "真人客服", "我要人工")

# --- 风险词:命中即升级,优先级最高 ---

RISK_PATTERNS = ("投诉", "监管", "12315", "起诉", "曝光", "受伤", "人身", "诈骗")

MAX_TURNS = 4

MAX_REPEAT = 2

# --- 会话状态:三个计数器全在这儿 ---

@dataclass

class Session:

sid: str

turns: int = 0

fail_hits: int = 0 # 兜底话术连续命中次数

last_reply: str = ""

history: list = None

def __post_init__(self):

self.history = []

def route(session: Session, text: str, reply_fn: Callable[[str], str]):

"""返回 (action, 回复文本)。"""

text = (text or "").strip()

session.turns += 1

session.history.append(("user", text))

# 1. 风险词最高优先级,不做任何自助挽留

if any(k in text for k in RISK_PATTERNS):

return "escalate", "已为您转接人工,请稍候。"

# 2. 明确要求转人工:一次就转,不挽留

if any(k in text for k in ESCALATE_PATTERNS):

return "escalate", "正在为您转接人工客服。"

# 3. 正常业务链路:模型只负责生成回复,永远不决定要不要转

reply = reply_fn(text)

if reply == session.last_reply:

session.fail_hits += 1

else:

session.fail_hits = 0

session.last_reply = reply

session.history.append(("bot", reply))

# 4. 兜底:重复话术 / 轮次超限,两个计数器任一命中

if session.fail_hits >= MAX_REPEAT:

return "escalate", "这个问题我处理不了,已为您转接人工。"

if session.turns >= MAX_TURNS:

return "escalate", "已经为您尝试多次,转接人工继续处理。"

return "reply", reply

if __name__ == "__main__":

FALLBACK = "非常理解您的心情,请您耐心等待。"

def fake_llm(text: str) -> str:

# 模拟一个只会答非所问的机器人

if "退" in text:

return FALLBACK

return "您可以在订单详情页自助操作。"

def run(cases, label):

s = Session(sid=label)

print(f"--- {label} ---")

for i, q in enumerate(cases, 1):

action, msg = route(s, q, fake_llm)

print(f"[{i}] {q} -> {action}: {msg}")

if action == "escalate":

print(f" 升级时携带 {len(s.history)} 条上下文")

break

# 三条路径各跑一遍

run(["我要退两张电影票", "退不了", "还是退不了", "算了"], "兜底话术重复触发")

run(["这个优惠券怎么用不了", "我要投诉"], "风险词触发")

run(["这个优惠券怎么用不了", "转人工"], "明确要求触发")

三条路径各跑一遍:兜底重复那条在第 3 句升级,风险词和明确要求都在第 2 句升级。也就是说,不需要模型多聪明,只要三个计数器有一个响了,人就能被捞出来。

如果要接大模型生成兜底话术,建议把「生成」和「决策」拆开:模型只负责 reply_fn,升级与否永远由 route() 决定。我平时调这类多模型兜底,统一入口切换的,省掉给每家单独对接 SDK 的功夫,也不用为了几个备用模型各开一份订阅。关键路径上别用单一供应商,这点比选哪个模型重要。

踩坑提示

坑一:把「人工」「0」当触发词。 很多系统对单字识别不准,「人工」两个字经常被当成业务词吃掉。要么匹配完整短语,要么维护一张同义词表,别指望模糊匹配。

坑二:情绪识别做反了。 有团队上了情绪打分,用户越急越触发「安抚话术」分支,结果把人困得更久。正确做法是情绪升级直接降权自助流程、提权转人工,不是加一段安慰。

坑三:把「转人工率」当负向 KPI。 这是根子上的问题。一旦转人工率高要被扣绩效,产品经理就会去藏入口,工程侧再漂亮也白搭。指标至少要成对看:转人工率 + 转人工后一次解决率 + 平均接通时长。

坑四:转接丢上下文。 国标明确要求切换后同步客户信息、不重复询问。实现上给工单附一段结构化摘要就够:用户诉求、已尝试动作、订单号、情绪标记。别把整段对话原样丢过去,人工读不完。

坑五:AI 的承诺没留痕。 中消协的态度很明确,经营者自己部署的 AI 客服,输出内容属于服务的一部分,「AI 说的不算」这种甩锅站不住。会话记录必须可检索、可导出,退款赔偿类承诺要落工单。

总结

转人工难的解法,八分在工程,两分在决心。工程部分是这几个计数器和一个优先级队列,一个下午能写完;决心部分是愿不愿意在「省人工」和「别把人逼疯」之间选后者。标准已经给了标尺,接下来谁先改,谁少挨骂。

本文由 AI图鉴自动抓取并翻译,版权归原作者所有;如需查看原文请点下方链接。

相关 AI 工具

相关免费羊毛

同源资讯

阅读原文(juejin.cn)

标题、摘要与正文均来自该信源的公开页面,版权归原作者所有;本站自动聚合与翻译,仅作出处跳转。

← 返回 AI 资讯列表AI工具图鉴首页

返回 AI图鉴首页 · 提交工具 · 商务合作 · 关于本站 · 600 款 AI 工具分类导航 · 每日 AI 热门项目与动态