聊天机器人开发实战:从概念到落地的挑战与应对策略
1. 项目概述从技术炒作到现实挑战的聊天机器人开发去年十月虚拟助手被置于Gartner技术成熟度曲线的“膨胀期望高峰期”这距离2016年它还在“创新萌芽期”中部的位置是一次显著的跃升。差不多同时Gartner也将对话式平台列为2018年十大战略技术趋势之一。从我个人的主观视角来看聊天机器人这一年的确引发了巨大的炒作热潮其声势大概只逊色于加密货币、广义的机器学习以及物联网。对于一项技术而言身处“膨胀期望高峰期”并朝着“幻灭低谷期”前进这本身就意味着一些事情。每天都有太多未经证实的声明和承诺在成倍增加开发者工具尚不完善支撑这项技术的基础研究也面临诸多障碍这个清单还可以继续列下去。正如任何流行技术趋势所经历的那样当一项技术达到公众关注的某个临界点就会有更多人实际使用它并看清其真实状况。走向“幻灭低谷期”并不意味着一旦到达那里就没人再开发聊天机器人了。公众、媒体和投资者的兴趣会减弱但与此同时仍会有许多开发者和研究者在默默耕耘。正是这些开发者和研究者将确保这项有前景的技术最终能交付有用的成果尽管沿途充满挑战。我希望能尝试梳理聊天机器人开发面临的一些挑战。我不会讨论传统自然语言处理NLP和深度学习这两个支撑当今聊天机器人理解人类语言能力的研究领域所面临的根本性难题。相反我将分享一些我作为开发者在实际工作中遇到的挑战。对于新的聊天机器人开发者来说了解这些至关重要因为我觉得它们是非常普遍的挑战并非我特定项目所独有。2. 我的聊天机器人开发背景与视角在深入探讨具体挑战之前我想先分享一些与聊天机器人主题相关的个人背景。这样做纯粹是为了让你了解我可能存在的某些偏见或视角局限。在过去的8个月里我参与了数个聊天机器人项目并有机会与不少团队交流他们构建聊天机器人的经验。我接触过不同的聊天机器人框架在Rasa Stack上完成了2个项目在Dialogflow上完成了3个项目也看过微软LUIS的销售演示。本文的论述基于我在加拿大电信公司Telus担任软件开发实习生时所做的一场关于聊天机器人的演讲内容。由于我在Rasa Stack上的开发经验最为丰富因此部分示例会提及Rasa特有的概念。我也会稍微涉及Dialogflow。除此之外我试图从一般性角度讨论聊天机器人开发但鉴于我对其他框架的接触有限我的概括可能不尽准确。3. 概念性挑战常见误解与不切实际的期望这一部分将探讨几个概念性挑战也称为常见误解。对于聊天机器人项目的所有利益相关者而言克服这些挑战至关重要以便对聊天机器人本身以及项目时间线抱有更现实的期望。3.1 对“自我改进”能力的误解对于那些刚刚开始涉足任何机器学习ML项目不仅仅是聊天机器人的人来说一个常见的误解是认为拥有“自我改进”能力的技术能够轻易地为组织节省大量时间。我猜这种想法背后的逻辑是你只需要引导一个聊天机器人处理基本的交互之后它就能随着时间的推移自行学会更复杂的交互。然而这并不是监督学习的工作原理。对于新技术尤其是人工智能过度乐观的想法非常普遍考虑到主流媒体对此话题的报道方式这并不令人意外。媒体夸大计算机智能的报道并非我们这个时代独有事实上可以追溯到计算机起源之初。在实际动手开发几天后大多数人就会开始理解这项技术的局限性并认识到关于聊天机器人“自我改进”的几个关键事实任何程度的自我改进都需要一个良好的自然语言理解NLU管道。没有准确的理解就谈不上有效的学习。即使是全自动的NLU反馈管道也需要持续的监督。目前所有主流聊天机器人框架都使用监督学习模型这意味着模型需要人类持续提供正确的标注数据来学习。你需要开发真正优秀的管理员界面以实现高效、无痛的监督过程。这一点至关重要我将在第二部分详细讨论。归根结底监督式机器学习模型本身并不具备“自我改进”作为其内在属性。这取决于开发者围绕模型构建的工具和流程使得模型看起来好像只需人类监督者付出极少努力就能学习新事物。这种能力的实现本质上是一项系统工程。3.2 对利用现有数据可行性的误解这是另一个在没有机器学习实践经验的人群中常见的误解。根据我的经验他们的思路通常是这样的“我的组织拥有大量数据。众所周知数据是机器学习的燃料因此拥有大量数据将使创建成功的机器学习应用变得容易。”这种推理思路的问题在于仅仅拥有一些与你的项目半相关的数据是远远不够的。我曾读到过数据科学家超过一半的工作时间都花在数据预处理上我手头没有确凿来源但根据我的经验这个数字大致正确。虽然为聊天机器人项目准备现有数据与为数据科学分析准备数据并不完全相同但它仍然非常耗时。你手边真的有足够的“聊天数据”吗为了更具体地说明利用现有数据的困难我们假设正在进行的聊天机器人项目是一个企业服务台聊天机器人这是我第一个聊天机器人项目的应用场景。准备聊天机器人NLU训练数据主要有两种途径。途径一不同格式的现有数据假设你当前的服务台通过电子邮件运作。你拥有大量电子邮件形式的训练数据。你搞定了如何从Outlook或其他邮件客户端批量导出邮件如何将导出文件转换为纯文本以及如何剥离邮件头和其他无关内容比如“Hi …”、“Thanks, …”或者包含公司整个电子邮件通信政策的超长签名。即便如此你剩下的仍然是相对较长的消息有时甚至包含多个段落这绝对不是聊天机器人训练数据的理想材料。人们在聊天环境中的交流方式与电子邮件通信截然不同。从这里出发你有两条路可走其一你从这些邮件中记下常见的问题类型并将其作为基础自己构思适合聊天机器人的训练数据你必须设想人们如何在聊天环境中提出他们通过邮件询问的问题。在这种情况下现有数据只帮助你定义了聊天机器人NLU能力的初始领域。数据准备的大部分工作仍然落在你或你的团队身上。其二彻底放弃聊天机器人项目的想法转而采用自动邮件回复系统。这种方法不在本文讨论范围之内。途径二相同格式的现有数据假设你当前的服务台通过聊天系统例如Slack、Google Hangouts或类似工具运作。你导出所有对话数据并只提取用户的话语不包含服务台客服的回复。你检查所有话语并进行数据标注的过程为每句话语分配正确的类别意图。看起来你已经成功地利用了现有数据对于一个机器学习项目来说这似乎再简单不过了你只需获取原始数据通过标注使其适用于监督学习算法。然而为话语分配意图实际上比标注计算机视觉数据集例如ImageNet要复杂得多。我将在本系列的第二部分更深入地探讨其原因。总的来说为人类语言附加标签是一个比用具体物体标注图像主观得多的过程。4. 开发过程中的具体挑战本节提出的挑战在我看来是聊天机器人开发所特有的。尽管我觉得这些挑战也可能适用于其他机器学习应用的开发过程但我只能基于聊天机器人开发的经验来确切地谈论它们。4.1 机器学习模型的非确定性为了澄清本小节的标题我将讨论机器学习模型在不同训练会话之间模型架构和超参数相同的情况下如何表现出非确定性以及这如何影响聊天机器人开发。首先必须指出的是即使模型架构和超参数保持不变每次训练会话中模型的权重也会不同。这是由于随机权重初始化和数据洗牌造成的。但是只要你的训练数据集不是非常小这不应该对你的模型性能产生任何明显影响。真正让权重值的差异对聊天机器人开发过程产生负面影响的是训练数据标注或结构中的错误。NLU数据中的错误NLU训练数据错误通常更难被发现。让我们再次使用服务台聊天机器人的例子。假设你的NLU模型有一个相当大的意图映射大约包含300个意图。你正在审查最新的聊天日志并为新的用户话语添加标签。你将“我最近丢了手机无法登录网站X因为我用手机做双重验证2-FA”标注为一个全新的意图help.smartphone.2fa因为你的团队最近刚刚设计了一个流程描述机器人应如何处理2-FA问题。你完成了其余数据的标注重新训练模型并快速进行了一些手动测试。你从“我的手机2-FA有问题”开始测试机器人回复的内容是由一个更通用的意图help.smartphone触发的。嗯……你判断可能help.smartphone.2fa的示例太少了于是你又创建了一些。你重新训练模型在本地测试现在“我的手机2-FA有问题”正确地映射到了help.smartphone.2fa。干得漂亮你将更新推送到生产服务器在构建过程中模型再次被重新训练。几个小时后你收到同事的消息说生产服务器上的模型将2-FA相关的话语映射到了help.smartphone而不是新添加的help.smartphone.2fa。你在本地用完全相同训练数据训练的模型副本上尝试相同的话语它却如预期般映射到help.smartphone.2fa。那么是什么可能导致这样的问题呢对于上面的例子一个可能的原因是几个月前当你的意图数量少得多且都非常通用时你将一些与智能手机2-FA相关的话语标注为help.smartphone。在当时这是合理的因为那时你的机器人对所有智能手机相关的故障排除只有一个统一的响应例如“请拨打这个号码我们的团队将帮助您解决智能手机问题。”添加新意图help.smartphone.2fa后就产生了一种情况在词汇和句法上非常相似的话语现在可能映射到两个不同的意图。这导致了机器人在相同输入下不同训练会话间的行为不一致。一个NLU模型只有在训练数据呈现“多对一”或“一对一”映射时才是可靠和可预测的而不是“一对多”或“多对多”。因此在引入新意图之前务必在你的训练数据中搜索与该意图相关的关键词。如果发现任何可能造成干扰的训练数据请将这些示例重新分配给新的、更精确的意图一个优秀的NLU管理界面对此过程有极大帮助。对话数据中的错误仅与Rasa Core相关另一个可能导致聊天机器人在不同训练会话间行为差异的错误是创建具有相同起始条件但结局不同的Rasa Core故事。快速示例 general_computer_problem utter_confirm_need_help_now * yes action_create_ticket utter_expect_specialist_soon general_computer_problem utter_confirm_need_help_now * yes utter_bring_device_to_helpdesk这个例子看起来尤其幼稚因为两个冲突的故事就并排放在一起。但相信我当你有大量故事分散在许多文件中并且收到相互冲突的功能需求时犯这种错误是相当容易的。如果你不习惯这类错误调试起来会非常棘手Rasa Core默认没有检查冲突故事的功能问题可能在本地不可见只会在其他机器例如你的开发服务器上显现最后作为一名程序员你可能会开始在代码逻辑中寻找错误而不是在训练数据中。为了在部署前验证聊天机器人的对话模型是否按预期工作编写一些测试故事会很有帮助。Rasa Addons包中包含一个用于自动化Rasa Core测试的工具测试功能目前处于实验阶段。4.2 训练时间现代开发中的“编译等待”有时使用Rasa Core开发聊天机器人的感觉就像我想象中30-40年前的软件开发开发者主要使用编译型语言而且他们的计算机性能远不如我们今天拥有的。你会写一小段代码尝试编译它修复所有编译时的警告和错误最后启动编译过程。然后你可以切换去完成一封早前开始的邮件或者喝杯咖啡休息一下甚至出去散个步好在当时还没有YouTube……根据代码库的大小编译可能会花上一段时间。类似地当你在Rasa Core中实现一个新功能例如一个新的对话分支时你必须重新训练Rasa Core用于处理不同对话场景的LSTM模型来测试它。随着聊天机器人训练数据集的增长其训练时间也会增加。当然你可以调整训练轮数epochs来优化训练所需的时间。例如一旦损失的变化率低于某个阈值就停止训练。但这只能帮你到这里。我最近正在开发的一个聊天机器人训练时间已经超过了7分钟大关。有些日子我需要重新训练模型几十次这种等待有时会令人沮丧尤其当我在等待时被其他无关事情分心但有时也是一个短暂休息的好机会除非我因为某些原因连续重新训练了3次模型。在常规的编译型语言软件开发中有可能将你正在处理的单个组件隔离出来避免每次重新编译整个项目但对于机器学习模型来说这是不可能的它是项目中不可分割的组成部分。我认为在我的个人案例中GPU是限制因素因此缓解这个问题的方法是购买额外的GPU或者习惯长时间的训练并将其与休息时间匹配起来。5. 架构与工程化挑战前瞻如果到目前为止你觉得读到的内容有趣我强烈建议你继续阅读本系列的第二部分。在第二部分中我将深入讨论聊天机器人项目中常见的架构挑战。在我看来那一类挑战是最困难的因此有很多内容可以探讨。聊天机器人开发远不止是选择一个框架和标注数据。将其集成到现有系统、设计可维护的对话流、处理上下文和状态管理、实现有效的错误处理和降级策略、构建监控和数据分析管道这些都是决定项目成败的关键工程环节。许多团队在概念验证阶段表现出色却在试图将聊天机器人规模化、产品化时遇到瓶颈原因往往在于早期忽视了这些架构层面的考量。例如如何设计一个松耦合的架构使得NLU引擎、对话管理器和后端业务逻辑能够独立演化如何处理多轮对话中复杂的上下文依赖避免出现“失忆”或逻辑混乱当NLU置信度较低时是应该要求用户澄清还是优雅地转移到人工客服如何收集和分析对话日志不仅用于改进模型还用于洞察用户需求和发现业务流程中的问题这些都是在动手写第一行代码之前就需要深思熟虑的问题。6. 给新开发者的实操建议与心得基于我过去几个月的实战经验我想给即将或刚刚踏入聊天机器人领域的开发者一些具体的建议这些是你在官方文档里可能看不到的“踩坑”心得。1. 从小处着手定义明确的成功标准。不要一开始就试图构建一个能处理所有事情的通用助手。选择一个非常具体、边界清晰的垂直领域例如“重置公司内部WiFi密码”、“查询年假余额”。明确定义成功指标是降低客服成本提升用户满意度还是缩短问题解决时间这能帮助你在面临无数技术选择时保持专注。2. 将数据质量视为最高优先级。模型可以换算法可以调但垃圾数据进去垃圾结果出来。建立严格的数据标注指南和复审流程。即使是小团队也要考虑使用像Prodigy、Label Studio这样的专业标注工具或者至少构建一个带搜索、过滤和批量操作功能的基本管理界面。记住标注不一致是NLU模型性能的“隐形杀手”。3. 拥抱“混合”智能。在现阶段纯粹基于AI的聊天机器人在复杂场景中风险很高。设计你的系统时要预留“逃生通道”。这可以是规则后备对某些关键、高频且句式固定的查询如“我的工号是多少”直接使用正则表达式或关键词匹配绕过NLU模型确保100%准确。无缝转人工当模型置信度低或用户表达出挫败感时必须能平滑、无丢失地将对话上下文转移给人工客服。澄清与确认多设计确认环节。“您是想查询北京到上海的航班对吗”这虽然增加了交互步骤但极大地避免了后续的错误操作。4. 像开发软件一样开发对话流。为你的对话故事Story或意图Intent编写“测试用例”。定期进行回归测试确保新增功能不会破坏旧有的对话路径。考虑使用版本控制来管理你的NLU训练数据和对话流设计并建立代码审查机制。Rasa的测试故事和Dialogflow的测试套件功能要充分利用。5. 监控、日志与迭代。上线不是终点而是开始。你需要监控技术指标NLU意图识别准确率、置信度分布、响应时间。业务指标任务完成率、转人工率、用户满意度评分如果有。对话日志定期查看失败案例、低置信度案例。设立一个“周五下午复盘”机制团队一起看最奇怪的对话你会发现很多改进点。6. 管理利益相关者的期望。这是最软性但可能最重要的技能。主动、定期地向非技术背景的同事或老板展示聊天机器人的局限性。用实际对话日志演示它在哪些地方会出错解释为什么某些看似简单的功能实现起来很复杂例如处理“像上次那样”这样的指代。教育他们理解“训练数据”的概念让他们明白机器人的“智能”需要持续的人力投入来喂养和修正。最后保持耐心和务实。聊天机器人开发是一个结合了语言学、心理学、软件工程和机器学习的交叉领域。它没有银弹进步来自于对细节的持续打磨和对失败的坦诚分析。每一次用户说“这机器人真笨”的时刻都是你发现一个宝贵优化机会的起点。