你的语音智能体将每一个转录错误都视为事实
一名用户拨打你的保险语音代理,询问关于其免赔额(deductible)的问题。语音识别器听到了 "the duck tibble"。你的语言模型接收到了字符串 "the duck tibble",发现它逻辑不通,于是要么提出了一个令人生疑的后续问题,要么——更糟糕的是——胡编乱造了一个关于并不存在的产品答案。用户挂断了电话。你的日志显示了一次成功的交互:音频输入,生成转录,产生回应,没有抛出错误。
这就是几乎每个生产环境中的语音代理都存在的隐蔽失败。语音转文本系统完成了它的工作——它产生了一个最优的猜测。语言模型完成了它的工作——它对收到的文本进行了推理。而 Bug 就存在于它们之间的鸿沟中,存在于一个将概率猜测重新标记为事实的交接过程中。
文本代理不会遇到这种程度的问题。当用户在聊天框中输入 "the duck tibble" 时,他们可以看到错别字并在按回车键之前纠正它。语音代理的用户则没有这种机会。他们说对了单词。机器听错了。而当错误识别传达到模型时,每一丝怀疑的痕迹都已被丢弃。
抛弃误差范围的交接
每个现代语音识别器在内部本质上都是一个“不确定性机器”。它并不直接决定单词;它为假设评分。在任何时刻,它都在跟踪数十个候选转录——一个 n-best 列表,或者更丰富的格点(lattice)——每个都附带一个概率。"Deductible" 可能得分 0.62。"The duck tibble" 可能得分 0.31。其余的一小部分候选者瓜分了剩余的概率。
接着 API 调用返回,几乎所有的这些结构都被丢弃了。识别器将其整个概率分布压缩到单一的最高分路径——即 1-best 假设——并交给你的应用程序一个纯字符串。0.62 消失了。亚军也消失了。这曾是一个势均力敌的选择这一事实也消失了。
现在,你的语言模型收到的 "the duck tibble",其认识论状态(epistemic status)与精明用户在机械键盘上敲出的查询完全相同。提示词中没有字段说明“置信度低”。没有标记说明“这段文字存在争议”。模型无从得知它是在基于猜测进行推理,因此它将其视为真理进行推理。不确定性恰恰在最需要保留它的边界处被摧毁了。
这并不是任何单一组件的缺陷。识别器被允许返回其最佳猜测;对于常见的听写场景(即人类阅读输出并进行纠正)来说,这是一个合理的默认设置。这个缺陷是架构层面的:一个为“人工参与(human-in-the-loop)”转录而设计的流水线被重新利用为一个自主代理的前端,却没有人重新审视接口应该携带什么信息。
为什么词错误率会欺骗你
当你听说转录错误时,本能反应是寻求一个词错误率(WER)更低、更好的识别器。WER 是行业标准指标:相对于参考转录,被替换、插入或删除的单词百分比。专业系统的目标是 5% 到 10%。这听起来很让人放心,直到你观察这些错误落在哪些单词上。
WER 平等对待每一个单词。将 "the" 误认为 "a" 的得分,与将 "15,000" 或将 "allergic"(过敏)误认为 "a little"(一点)是一样的。但这些错误并不对等。前者是修饰性的;而后者则改变了含义、数据库查询或医疗决策。一份转录文本可能拥有极佳的 6% WER,但在决定通话结果的关键单词上依然可能是错误的。
在 2025 年衡量语音代理的从业者发现,这一差距巨大到需要一个专门的指标。行动错误率(Action Error Rate)——即代理采取错误行动的比率——通常比同一转录文本的原始 WER 高出 10 到 30 个百分点。即使整体转录看起来很 干净,语义关键的错误依然主导着下游的失败。识别器的平均准确率根本不是一个值得优化的数字,因为代理并不基于平均值行动。它基于特定的 Token 行动:金额、日期、姓名、账号、否定词。
否定词是最残酷的情况。"It is now" 对比 "it is no"。"I can make that payment" 对比 "I can't make that payment"。一个丢失或听错的音节就会完全反转意图,而且它是无声地反转,并带有极高的识别置信度,因为两种表述都是完美的流利英语。下游的流利度检查无法发现它。转录文本读起来就像人说的话,因为它确实是——只是不是这个人在这次通话中说的话。
你的用户没有逃生舱
值得仔细思考与文本输入的这种不对称性,因为它解释了为什么这个 Bug 在演示中很容易被忽略,而在生产环境中却极具破坏性。
在文本界面中,用户看到的输入和模型收到的输入是同一个产物。用户是最后一道错误纠正防线,而且是非常有效的一道——他们会重新阅读,抓住那些把 "deductible" 变成荒谬词汇的自动纠错,并修复它。界面为他们提供了一个窗口,让他们确切地看到系统将处理什么。
语音界面打破了这一循环。用户知道他们说了什么。他们完全不知道机器听到了什么。没有渲染后的转录文本在他们眼前滚动,没有机会插话喊道“不,我说的是免赔额”。错误识别变成了代理现实的一部分,而用户只有在代理的回答变得不知所云时才会发现——到那时,对话已经偏离轨道,而修复对话所需耗费的用户耐心,是你的产品很少能负担得起的。
这意味着语音代理不能像文本代理依赖用户吸收拼写错误那样,依赖用户去吸收识别错误。文本界面悄悄外包给人类的错误纠正责任,必须被重新设计回系统中。如果你不明确地承担这一责任,就没有人会承担。
将不确定性传递给下游,而不是将其平坦化
修复工作从接口开始。如果识别器知道某个片段存在冲突,这种知识应该在交付过程中保留下来,而不是被压缩掉。
最直接的做法是:停止只使用排名第一(1-best)的字符串。大多数识别 API 都能返回 n-best 列表(即排名靠前的几个候选转录)以及每个词或片段的置信度评分。关于利用 ASR 不确定性的研究表明,通过 n-best 列表而非仅用排名第一的假设来提示语言模型,可以显著改善意图检测和设备定向语音检测等下游任务。模型可以看到 "deductible"(免赔额)和 "the duck tibble" 是两个领先的候选结果,识别出一个是连贯的保险术语,另一个是噪音,并据此进行协调。你并不是在要求模型成为更好的识别器,而是在为它提供证据,让它去完成它原本就擅长的消除歧义工作。
以下是几个由此衍生出的实践模式:
- 将置信度带入提示词。 明确标注低置信度片段——即使是像
[uncertain: deductible|duck tibble]这样粗略的标记——这样模型就会将猜测视为猜测,而不是事实。 - 进行协调,而不是盲目重打分。 当你拥有多个假设时,评估它们在哪里一致,在哪里分歧,以及分歧是否涉及高风险的 Token。在平淡的词语上达成一致而在金额上产生分歧,是一个精确且可操作的信号。
- 记录分布,而不仅仅是胜出者。 为每一次交互存储 n-best 输出、每个词的置信度、时间戳和模型版本。你无法从单个折叠的字符串中调试级联故障,而观察置信度分布随时间的变化,是音频质量或识别器本身发生改变的预警信号。
这些都不需要统一的原生语音模型,尽管这种模型因为从一开始就不会折叠为文本而更有帮助。它主要需要将识别器的输出视为其本质——一组带概率的排序假设——而不是为了方便而将其视为某种单一结果。
设计 Agent 先询问再行动
只有当 Agent 利用不确定性做点什么时,保留它才有用。修复的后半部分是行为上的:Agent 应该在置信度低或风险高时请求确认,且仅在此时请求。
这里的原则是将团队倾向于混淆的两个维度分开。一个维度是识别器的置信度——系统对自己听到内容的确定程度。另一个维度是后果(consequence)——出错的代价有多大。当其中任何一个维度令人担忧时,你进行确认;而当两者都没问题时,你保持沉默。
在一个无关紧要的词上出现低置信度片段不需要确认;打断用户重新确认 "the" 本身就是一种失败,会让 Agent 变成那个连问四遍 “对不起,你能重复一遍吗?” 直到拨打者放弃的糟糕产品。但账号上的低置信度片段始终值得确认。而对于高风险片段——支付金额、药物、取消、预订日期——即使识别器非常自信,也值得进行显式确认,因为识别器的自信恰恰可能是错误所在。传统的划分方法依然适用:对高风险操作进行显式确认,对低风险操作进行隐式确认,而当有争议的片段与重要的槽位重叠时,则提出澄清问题。
好的确认也是具体的。“我不确定我是否听清了,你能把整件事重复一遍吗?” 会让用户重复工作并感到沮丧。“我收到了你关于免赔额的问题——是 1500 美元,还是 15000 美元?” 这精准定位了有争议的 Token,只需一秒钟即可回答,并向用户展示了系统正在关注。对于电子邮件地址或确认码等输入,将槽位拆分为更小的部分并逐一确认,或者要求用户拼读,虽然会增加几秒钟成本,但却消除了一整类无声的失败。
将转录视为证据,而不是用户的原话
值得从这一切中汲取的心理转变虽小却至关重要。转录并不是用户说的话。它是识别器对用户所说话语的最佳估计,无论你的系统是否去查看,这种估计都带有误差范围。
将转录视为基本事实(ground truth)的语音 Agent 是在无法核查的基础上构建推理。而将转录视为证据(排序的、打分的、有时有争议的、偶尔甚至是错误的)的语音 Agent,可以像谨慎的人类听众一样行事:注意到不匹配的单词,根据上下文权衡听起来奇怪的短语,并在对重要事项采取行动前进行询问。
