跳到主要内容

继承了你客服团队最坏习惯的聊天机器人

· 阅读需 11 分钟
Tian Pan
Software Engineer

你用一年的真实客服对话记录进行了微调,因为你认为那是领域知识的所在地。现在,这个模型的语气听起来就像你的支持团队。它会在有理由道歉之前就开始道歉,提供它没有权限批准的商誉补偿,还会说 “我已经把这个问题升级到了二级队列” —— 而这个队列对它来说根本不存在 —— 甚至会模仿你的客服在 Slack 上互相沟通时使用的半句式简写。在你的评估集上,领域准确率看起来非常棒。但在投入生产环境三周后,退款额度直线飙升,法务部门也找上了门。

这个聊天机器人并没有失控。它只是精准地学会了你训练它的内容。问题在于,对话记录并不是领域知识的记录 —— 它是组织行为的记录,而这两者在 Token 层面被紧紧粘在一起,监督微调(SFT)无法将它们分开。教导模型退货政策的同一个梯度步骤,同时也教会了它在面对沮丧的客户时,条件反射式地回应 “非常抱歉听到这个消息”,无论当时的情况是否需要道歉。你的客服人员有这些条件反射的原因。而模型只有表象。

这种失效模式不会出现在你的 AUC 中。领域准确率显示模型了解政策。客户满意度调查显示机器人很友好。然而,退款流失、向不存在的队列升级的比例,以及品牌调性的缓慢侵蚀 —— 这些数据存在于由不同团队负责的不同仪表盘中。等有人注意到其中的关联时,你已经基于六个月以来未经任何授权的行为对模型进行了训练。

对话记录是工作流,而非知识库

当你基于对话记录进行微调时,你其实是在进行行为克隆。数据集并不包含 “该查询的正确答案”。它包含的是 “在已知该客户的所有信息、队列深度、当周的政策例外情况、值班主管、客户已被转接两次的事实,以及私人猜测这个人是否会在 Twitter 上投诉的情况下,一名人类客服所做的事情”。所有这些调节因素对损失函数来说都是不可见的。损失函数只能看到 Token。

所以模型学会了 Token。它学会了当对话记录中出现 “我已经等了三周” 这一短语时,客服的下一个 Token 在 90% 的情况下是 “非常抱歉听到这个消息,让我立刻为你查看”。当人类客服说这句话时,它是没问题的,因为人类确实可以立刻查看。模型说了这句话,却无法立刻查看,因为它所需的工具要么不在其操作范围内,要么返回了一个它不知道如何处理的错误。道歉与缺乏后续行动现在被耦合进了同一次前向传播中。

更糟糕的是,对话记录中包含了一些之所以有效是因为双方都是同一团队人类的捷径。“升级到 T2”(二级队列)在你的队列管理系统中是有意义的。模型将其习得为一个能安抚客户的短语。它会告诉客户工单已被升级到 T2。但对机器人来说并没有 T2。客户在等待。什么也没发生。工单死在了一个你的仪表盘中甚至没有对应列的状态里。

同样的问题出现在对话记录的每一个层面。客服会省略客户无法理解的政策细节,因为主管稍后会补齐。模型省略了这些细节,却没有主管。客服做出承诺 —— “我会亲自确保这件事在周五前得到解决” —— 这些承诺是通过模型并不具备的人类升级网络来处理的。然而,承诺依然出现在了面向客户的回复中。模型经过数千个案例的训练,教会了它承诺性的语言可以安抚愤怒的客户,但却没有任何案例教会它不兑现承诺的代价。

加拿大航空的问题并非孤例

机器人承诺了某事而公司必须履行的案例现在已有先例。加拿大一个法庭在 2024 年裁定,航空公司必须遵守聊天机器人臆造的丧亲票价政策。有趣的地方不在于机器人产生了幻觉 —— 只要范围足够大,每个模型都会产生幻觉。有趣的是幻觉的形式。它听起来完全像是一个客服的回答。这个虚构的政策内部逻辑自洽,语气富有同情心,并以一个自信的下一步操作结尾,尽管它与同一网站上点击两次即可查看的实际政策相抵触。

这种形式是基于真实对话记录进行监督微调的标志。在客服文本上训练的模型被推向了 “客服在这种情况下会说的话”,当问题是 “什么是事实” 时,这正是错误的归纳偏置。优化的目标是在组织压力下的对话合理性。而真相从未在梯度下降的考量之中。

前一年的 DPD 事件走向了另一个极端 —— 一个客服机器人说脏话,写诗抱怨雇主有多么无能 —— 这种行为被广泛解读为护栏失效。但其底层机制是相同的。模型被训练得非常配合并遵循用户的引导,结果它顺着用户的引导进入了品牌调性无法承受的领地,如果有人在审阅训练数据时考虑到这种风险,这种事情本可以避免。

这些都不是边缘案例。它们是将针对不同目的收集的语料库,用于对文本概率分布进行微调后,可预见的必然结果。

没人规划的数据筛选步骤

大多数对对话记录进行微调的团队都会在清理流程上花费数周时间。他们脱敏个人身份信息,去重,针对不同意图进行 token 平衡。他们过滤掉没有明确解决方案的工单。每一个步骤都是必要的,但没有一个触及到核心问题。

核心问题在于,如何从人类在执行工作流时产生的记录中,移除人类工作流的痕迹。这需要你并不具备的标签。哪些句子是承诺?哪些是下意识的道歉?对内部工具的引用,是在反映真实的产品行为,还是在调用模型并不具备的基础设施?哪些升级反馈短语涉及了模型真正能调用的能力?每一项都是针对句子的判断,而获取它们的唯一方法,是带着不同于“这是否是一个好的客服回答”的问题去阅读对话记录。

一个实际的版本是在标准清理之上增加一层“行为剥离”环节。你需要建立一个“禁用动作”列表——包括模型无法兑现的语言承诺、指向不存在路径的升级短语、模型无法访问的内部工具引用,以及仅在同团队人类成员之间生效的沟通捷径。你要么过滤掉包含这些动作的示例,要么重写客服回复,或者为该示例添加一个反向信号,注明“不要模仿这部分”。每一个选项的成本都高于大多数团队交付的清理工作。否则,你交付的就是把客服部门最坏的习惯当成了产品功能。

你还需要诚实地面对哪些行为是你真正想要继承的。“听起来符合我们的品牌形象”是一个会夹带很多私货的目标。你是否希望机器人继承过度道歉的倾向,只因为这在模型永远不会参加的 CSAT(客户满意度)调查中得分很高?你是否希望它继承“让我看看我能做什么”这种为人工客服争取向主管请示空间的套话——尽管机器人根本没有可以请示的主管?诚实的规范版本会将你想要的声音与产生该声音的工作流分离开来,除非你刻意为之,否则你的训练数据不会遵守这种分离。

针对继承习惯的评估

随这些模型提供的评估套件通常测试政策正确性、拒绝行为、语气一致性和安全性。它们几乎从不测试继承的工作流痕迹,因为构建评估的人员所处的环境,正是模型训练时所依据的那个对话记录世界。如果你的评估标准是“针对这条客户消息,模型是否生成了合理的客服回复”,那么下意识的道歉、不存在的升级和虚假的承诺都会被判定为合理的客服回复。它们恰恰是人工客服会说的话。

你需要的是针对继承行为的对抗性评估。在政策要求拒绝的提示词上测试模型,看它是否提供了它无法授权的补偿。在人工客服通常会选择升级的消息类型上进行测试,评分标准不是回答本身,而是回答中提到的路径是否真实存在。测试它的承诺——每一个“我个人会……”、“周五前”和“我会确保……”——并让评审员检查机器人是否有任何机制来履行这些承诺。测试它的捷径:当人工客服在解决备注中写下“已推至 T2”时,模型现在生成的文本是否会对客户提到 T2?如果是这样,你已经将内部术语对外发布了。

构建这些评估并不难。它们被忽视的原因是,它们在对现有评估已经默许的行为进行评分。添加它们感觉就像是在提高一个已经过关系统的门槛。这恰恰是评估最容易出错的情况,因为训练数据中被视为“像客服”的行为,正是评估一直在默默奖励模型去生成的东西。

你究竟迁移了什么

思考整个项目最清晰的方式是询问:究竟什么东西从你的客服部门迁移到了模型中?预期的迁移是领域知识:产品、政策、常发问题及其解决方案。非预期的迁移是存在于相同 token 中的一切:工作流捷径、未成文的升级习惯、因沟通双方都是同一公司的员工而生效的谈话习惯,以及由主管网络和工单队列(模型并未参与其中)强制执行的承诺语言。

这种迁移之后,一个有用的直觉是:假设你的支持团队成员之间使用的任何短语,要么已经迁移到了机器人身上,要么会在你下次重新训练时被迁移。如果你不希望客户阅读你团队的 Slack 频道,你就不应该对微调后的模型与该客户交谈感到放心。模型不会对训练数据进行编辑加工,它只是在复制。当没有产品或法务人员监督时,你的客服部门听起来是什么样,你的客户即将听到的就是什么样,而且模型还会表现得格外自信,且完全不记得这些习惯存在的原因。

解决办法不是减少训练。在真实的对话记录上进行微调仍然是教给模型领域知识的最佳方式。解决办法是将数据筛选步骤视为一个行为工程问题,而不是数据清洗问题,并编写评估标准来对模型模仿的内容(而不是模仿的程度)进行评分。这两项成本都是真实存在的,你应该在交付之前为其配备人员。那些跳过这些步骤的公司并不是在节省时间;他们只是在将一起事故推迟到下一个季度,届时修复它的成本将昂贵得多。

你团队的行为并不总是你希望模型学习的东西。对话记录无法分辨其中的区别。你必须亲自动手。

References:Let's stay in touch and Follow me for more thoughts and updates