第四章:用户意图理解——多模态输入下的意图识别、槽位填充与上下文管理

好,咱们进入第四章。这一章我打算聊聊多模态交互里最核心、也最让人头疼的部分——用户意图理解。

你想想看,用户可能一边说话一边比划,或者打字时突然插入一张图片。系统得搞明白他到底想干嘛。这比纯文本的意图识别复杂多了。我当年刚接触多模态时,就踩过不少坑。今天我把这些经验掰开揉碎,讲给你听。

4.1 多模态意图识别:不只是“听懂”那么简单

单模态的意图识别,说白了就是分类问题。用户说“帮我订个机票”,系统识别出“订票”意图。但多模态下,情况就变了。

用户可能指着屏幕上的商品图片说:“这个,我要买。” 语音里没有“买”这个动词吗?有。但图片提供了关键实体信息。系统需要把语音的“买”意图和图片的“商品”实体结合起来。

我个人的习惯是,把多模态意图识别拆成两个层面:

  1. 主模态意图:哪个模态承载了核心动作意图?通常是语音或文本。
  2. 辅助模态实体:其他模态提供了哪些关键实体或约束?比如图片、手势、面部表情。

举个例子。用户对着摄像头皱眉说:“这个颜色我不喜欢。” 语音意图是“否定/不满”,但“这个颜色”具体指什么?需要结合视觉模态——用户目光注视的区域,或者他手指的屏幕位置。

核心原则:多模态意图识别 = 主模态意图分类 + 跨模态实体对齐。

别试图让一个模型同时处理所有模态。先分后合,效果更稳。

我在项目中遇到过一种情况:用户语音说“帮我查一下”,同时用手在平板上画了个圈。语音意图是“查询”,但圈选的内容是“区域内的所有店铺”。如果只识别语音,系统会问“查什么?” 体验就断了。正确的做法是,把圈选手势当作“查询范围”的实体输入。

4.2 槽位填充:多模态下的“拼图游戏”

槽位填充,就是提取用户指令中的关键参数。单模态下,我们做序列标注就行。多模态下,槽位可能分散在不同模态里。

比如用户说:“我想去这个地方。” 同时用手指了指地图上的一个点。语音槽位是“目的地”,但值(具体坐标)来自手势模态。

常见的多模态槽位类型:

槽位类型 可能来源模态 示例
目标实体 语音、图片、手势 “这个”(手指图片)→ 商品ID
数量/范围 语音、手势(画圈) “这些”(圈选区域)→ 坐标范围
时间/日期 语音、文本、日历截图 “下周三”(语音)+ 截图中的日期
情感/态度 语音语调、面部表情 皱眉(视觉)+ 语气(语音)→ 否定

这里有个避坑指南:我曾经设计过一个系统,用户语音说“两个”,同时伸出三根手指。系统直接取了语音的“2”,忽略了手势。结果用户要的是“3”。后来我加了模态置信度机制——当语音和手势冲突时,优先采用更具体、更明确的模态。手势通常比语音更精确,尤其是数字。

我的小技巧:设计槽位填充时,给每个模态的槽位值加一个“置信度分数”。最终填充时,取置信度最高的那个。如果两个模态置信度都高但值冲突,触发澄清对话。

4.3 上下文管理:多模态的“记忆宫殿”

上下文管理,说白了就是让系统记住之前说过什么、做过什么。多模态下,上下文不只是文本历史,还包括视觉历史、交互历史。

举个例子。用户先指着一张照片说:“帮我修掉这个瑕疵。” 系统记住了“照片A”和“瑕疵位置”。然后用户又说:“再调亮一点。” 这里的“再”字,依赖的是上一轮的“修图”上下文。但“调亮”是针对整张照片,还是只针对瑕疵区域?

多模态上下文的关键维度:

  • 对话轮次:第几轮交互?当前是延续还是新话题?
  • 模态引用:用户是否在引用之前展示过的图片、视频或界面元素?
  • 操作历史:用户之前做过哪些操作?比如缩放、旋转、选择。
  • 视觉焦点:用户当前在看什么?手指在什么位置?

我建议用“上下文槽位”来管理。每个对话轮次,系统维护一个上下文槽位列表。比如:

{
  "current_image": "photo_001.jpg",
  "last_action": "retouch",
  "last_region": {"x": 100, "y": 200, "w": 50, "h": 50},
  "user_gaze": {"x": 120, "y": 210},
  "active_tool": "brush"
}

当用户说“再调亮一点”时,系统检查上下文:当前图片是photo_001.jpg,上一轮操作是retouch,用户目光在瑕疵区域附近。所以“调亮”应该作用于瑕疵区域,而不是整张图。

注意:上下文不是无限保留的。我见过一些系统,上下文越积越多,最后模型都不知道该参考哪个。我的经验是:保留最近3-5轮交互的完整上下文,更早的只保留摘要。比如“用户之前修过图”这个事实,而不是具体坐标。

4.4 常见失败模式:这些坑我都踩过

做多模态产品,失败是常态。我总结了几种最常见的失败模式,你遇到了别慌。

模式一:模态冲突

用户语音说“删除”,但手势是“保存”。系统该听谁的?

我曾经遇到过这种情况,用户一边说“不要了”,一边把文件拖到“回收站”图标上。语音和手势一致,没问题。但有一次用户说“留着”,手却滑到了“删除”按钮上。系统执行了删除,用户暴怒。

解决方案:对关键操作(删除、提交、支付),采用“模态确认”机制。至少两个模态一致才执行。或者,让用户通过一个模态确认另一个模态的操作。

模式二:模态缺失

用户只用了语音,没用手势。或者只用了手势,没说话。系统却等着另一个模态的输入。

说白了,就是系统太“贪心”了。我设计过一个系统,默认用户会同时使用语音和手势。结果用户只是说了句“下一页”,系统却等着手势确认翻页方向。体验极差。

解决方案:每个意图定义“最小模态集”。比如“翻页”只需要语音或手势之一即可。只有“删除”这种高风险操作,才需要双模态确认。

模式三:上下文漂移

用户聊着聊着,突然切换了话题。系统还傻傻地沿用之前的上下文。

比如用户先问“今天天气怎么样?”,系统回答后,用户又说“帮我订个餐厅”。如果系统还认为上下文是“天气”,就会问“餐厅的天气怎么样?” 这就尴尬了。

解决方案:引入“话题边界检测”。当用户意图发生明显变化时(比如从“查询”变成“预订”),重置上下文。或者,让用户显式地切换话题,比如说“换个事,帮我订餐厅”。

模式四:模态过载

用户同时使用了太多模态,系统处理不过来。

你想想看,用户一边说话,一边做手势,一边还打字,甚至还在摇头。系统如果试图融合所有模态,很容易出错。

解决方案:设定“模态优先级”。我一般用这个顺序:语音 > 手势 > 文本 > 面部表情。语音通常承载了最明确的意图。手势和文本作为补充。面部表情只用来判断情感,不用于意图识别。

总结一下:多模态意图理解,不是把多个模态简单拼在一起。而是要让它们互相补充、互相验证。设计时,多想想“如果这个模态出错了怎么办?”、“如果用户只用了一个模态怎么办?”

这些问题的答案,就是你的产品体验的底线。

嗯,这一章就到这里。下一章我们聊聊多模态交互的反馈设计——怎么让用户知道系统“听懂”了。那也是个有意思的话题。