TourBot · 旅游场景智能客服机器人
以携程机票 / 酒店 / 火车票退改签场景做的对话机器人原型。这个 Demo 是真的能跑, 不过比起聊天本身,我更想让你看四件事:意图识别准不准、槽位缺失怎么追问、 什么时候该转人工,以及每轮对话能不能变成可以归因的数据。
先试试看,再往下看我怎么做的
打开右上角「调试模式」,每轮回复下面会展开完整的决策链路:意图候选与得分、槽位快照、知识命中、转人工规则命中情况。 右侧会实时统计本次会话的三个核心运营指标。
先把该拦的问题拦住,再谈像不像人
先分清「可自助」与「必须人工」
退款到账时间、行李额、发票开具这类政策明确的问题,让机器人自己闭环。 涉及资金复核、账号安全,或者用户已经明确说不要机器人了,目标就是快点转出去, 转得干净一点。
追问一次只问一个
退改类的意图都要订单号。原型用的是"必填槽位 + 单槽追问"。 用户要是自己一口气说全了,比如"订单号 202609178866,退掉明天的机票",就直接跳过追问。
转人工要把上下文带走
用户最烦的是跟机器人说了半天,转到人工还得从头再讲。 转接时把意图、槽位、情绪分和聊天记录一起推过去,客服打开就能看到, 转人工之后的满意度基本就看这一下。
15 类意图,覆盖三大业务域
拆得太粗会答非所问,拆得太细样本又不够。这一版按「业务域 × 用户动作」两个维度拆, 每类意图都有对应的知识,也有明确的解决标准。
| # | 意图 ID | 意图名称 | 业务域 | 必填槽位 | 关键词示例 |
|---|---|---|---|---|---|
| 01 | hotel.order.query | 酒店订单查询 | 酒店 | 订单号 | 酒店订单 / 我的酒店 / 入住信息 |
| 02 | hotel.cancel | 酒店取消·退订 | 酒店 | 订单号 | 取消酒店 / 退订 / 不去了 |
| 03 | hotel.change | 酒店改期 | 酒店 | 订单号 + 新日期 | 酒店改期 / 换日期 / 提前入住 |
| 04 | flight.change | 机票改签 | 机票 | 订单号 + 新日期 | 机票改签 / 换个航班 / 改到 |
| 05 | flight.refund | 机票退票 | 机票 | 订单号 | 机票退票 / 不飞了 / 退掉机票 |
| 06 | flight.delay | 航班延误·取消 | 机票 | 航班号 | 延误 / 晚点 / 航班取消 |
| 07 | flight.baggage | 行李额与托运 | 机票 | — | 行李额 / 托运 / 登机箱 |
| 08 | train.refund | 火车票退票 | 火车票 | 订单号 | 火车票退 / 高铁退票 |
| 09 | train.change | 火车票改签 | 火车票 | 订单号 + 新日期 | 火车票改签 / 换车次 |
| 10 | refund.progress | 退款进度查询 | 通用 | 订单号 | 退款进度 / 什么时候到账 / 钱还没退 |
| 11 | invoice | 发票与开票 | 通用 | — | 发票 / 开票 / 行程单 |
| 12 | pet.hotel | 宠物入住咨询 | 酒店 | — | 宠物 / 带狗 / 宠物友好 |
| 13 | complaint | 投诉与不满 | 通用 | — | 投诉 / 差评 / 曝光 |
| 14 | human | 转人工 | 通用 | — | 人工 / 真人 / 不要机器人 |
| 15 | greeting | 寒暄·开场 | 通用 | — | 你好 / 在吗 / 您好 |
一轮对话要经过 7 个环节
这是机器人每一轮实际走的路径,跟调试模式里展开的日志一一对应。 列出来的原因是排查问题时得先知道卡在哪一环,是没识别到,还是识别到了但知识库没这条。
动作词优先
用户在说"要做什么"(取消 / 退票 / 改签 / 行李 / 投诉)时,命中动作词的整体提权 1.8 倍。 这是意图的决定性信号——对象决定归属哪个域,动作决定要做哪件事。
业务域加权
「机票 / 航班 / 飞机」「火车 / 高铁 / 车票」「酒店 / 房间 / 住宿」分别指向不同业务域。 同一个动作词在多个域里都存在,靠域加权才能把结果收敛到正确的那一类。
二元组模糊兜底
把输入切成连续两字片段,与意图名做 Jaccard 相似度,兜住关键词没覆盖的长尾口语表达, 避免"没说过这个词就完全识别不了"。
置信度归一化
三路得分相加后经 Sigmoid 映射到 0–1,作为置信度直接展示给运营。 低于 0.45 视为未识别,连续两轮即触发转人工——阈值是可运营的旋钮,不是写死的常数。
10 条知识,每条都能核对
我写知识的标准是只写能核对的条件和数值,不写形容词。 "手续费较高"用户没法验证,运营也没法归因;"24 小时以上收 10%"才是一条能写进测试用例的知识。
5 条规则,决定什么时候放手
转人工率是个两头堵的指标:太高说明机器人没拦住,太低说明在硬撑。 所以这五条我做成能单独开关、单独看数,右侧那个实时命中面板就是干这个用的。
| 规则 | 名称 | 触发条件 | 处理动作 | 优先级 |
|---|---|---|---|---|
| R1 | 用户主动要求转人工 | 触发词命中「人工 / 转人工 / 不要机器人」 | 立即转接 + 同步上下文 | P0 |
| R2 | 情绪分 ≥ 3 | 负向词典加权 + 感叹号密度强化 | 秒转人工 + 标记“高情绪”工单 | P0 |
| R3 | 连续 2 轮未识别 | 最高意图得分 < 阈值,置信度 < 0.45 | 第 2 轮起直接转人工,禁止反复澄清 | P1 |
| R4 | 追问槽位 ≥ 3 次 | 同一会话内累计追问订单号/日期/航班号 | 转人工 + 提示“可发送订单链接代查” | P1 |
| R5 | 高金额退改 ≥ 5000 元 | 槽位抽取出金额并超过阈值 | 转人工复核,规避资金风险 | P1 |
如果换成大模型驱动,我会这样写 System Prompt
当前 Demo 用的是规则 + 检索的确定性引擎(离线可跑、结果可复现,方便做测试用例)。 真上线上大模型时,规则的部分会退化成"兜底校验层",语义理解交给模型。下面是我为大模型版设计的 System Prompt。
# 角色
你是携程的智能客服机器人「小 Tour」,服务于机票、酒店、火车票的
预订咨询与售后场景。你的目标不是"把话说漂亮",而是:
用最少的轮次,把用户的问题解决掉,或在必要时准确转接人工。
# 硬性约束
1. 只依据【知识库】中的政策与规则作答,知识库没有的内容禁止编造,
必须回答"这个问题我需要为您转接人工核实"。
2. 涉及金额、手续费比例、时限时,必须给出可核对的具体数值与适用条件。
3. 绝不承诺知识库以外的补偿、退款与免责。
4. 每轮回复不超过 120 字;一次只问一个问题。
5. 用户在表达不满或愤怒时,先共情一句,再给方案,禁止先讲流程。
# 回复结构(按需组合,不要机械套用)
- 共情/确认 → 结论先行 → 依据(政策)→ 下一步动作或追问
# 槽位
必填槽位缺失时主动追问,一次只追一个:
orderId(订单号) / date(新日期) / flightNo(航班号)
# 转人工
出现以下任一情况,立即转人工并说明已同步上下文:
① 用户明确要求;② 用户情绪激动或提及投诉/媒体;
③ 连续两轮未理解;④ 涉及金额 ≥ 5000 元;
⑤ 知识库无覆盖。
# 少样本示例
用户:我订的酒店明天到不了了,能退吗?
助手:理解,临时变动确实麻烦,我来帮您看能否免手续费取消。
请提供一下订单号(8–14 位数字)。
用户:你们这个退款拖了一个月了,我要投诉!
助手:非常抱歉让您等这么久,这确实是我们的问题。已为您优先转接
人工专员并标注加急,您的订单与聊天记录已同步,无需重复说明。 把「禁止编造」写进硬约束
客服机器人的最大风险是幻觉承诺。所以第一条约束就是"知识库外一律转人工", 而不是"尽量回答"。
用"一次只问一个"控制轮次
模型天然喜欢一次问三个问题。明确写死"一次只追一个槽位", 才能保证平均对话轮次可控,也才谈得上提升自助解决率。
给情绪场景单独写示例
常见错误是模型先讲流程再安抚。所以我在少样本里直接给了"愤怒用户"的标准应答, 用示例约束语气,比在规则里写十行形容词有效。