工程

多模态语音识别:打造一个能看见你所见的监听器

为什么只听音频的 ASR 在真实工作流里仍会失败,以及 Loqua 如何用本地屏幕上下文消解意图歧义。

要点速览

多模态语音识别是从“转写文本”走向“可用听写”的关键一层。Loqua 是一款 Mac 原生语音输入工具,会把音频、本地屏幕上下文、当前应用元数据和光标附近内容结合起来。这样,同一句话落到目标应用里时,才能变成正确的标识符、指令或格式化文本。

只依赖音频的语音识别已经足够好,以至于它剩下的问题很容易被低估。干净语音基准掩盖了真正的产品问题:用户是在应用里听写,在可见代码旁听写,在多语言混杂的环境里听写,也会说“这个函数”“上面那条 bullet”这类不完整引用。

ASR 仍会失败的地方

最经典的例子是同音或近音。"From foo import bar" 和 from foo import bar 听起来相似,却属于完全不同的语境。如果模型不知道光标在 TypeScript 文件里,"cache the auth client" 和 "cash the auth client" 也可能被混淆。单靠音频无法稳定推断目标输出场景。

代码标识符会把问题放大。用户可能说“fetch profile”,但可见函数名是 fetchProfile。转写模型听到的是词;听写模型应该保留标识符。多模态语音识别把可见文本当作证据,而不是装饰。

指示词是第三个尖锐边界。当用户说“把这个替换成 guard clause”时,语音本身看似完整,但“这个”到底指向什么,完全依赖选择区和光标位置。没有选择感知或稳定的光标参照,系统只能猜;而猜错一次,往往比重新输入更浪费时间。只听音频的 ASR 无法解析这种指示关系,只能把指示词转写出来,然后希望下游工具自己理解。

  • 同音歧义:普通英文与代码语法。
  • 实体:包名、类名、文件路径和命令参数。
  • 指示:“这个”“那个”“上面”“选中的部分”。
  • 格式:正文、列表、代码注释、commit message 或 prompt。

多模态监听器架构

Loqua 的监听器有三个本地输入:流式音频特征、屏幕派生上下文和应用元数据。音频路径提出“用户说了什么”的候选;上下文路径概括“文本将落在哪里”:应用、字段类型、选中文本、附近 token 和可见结构线索;应用路径补充约束,例如是否适合换行、Markdown 或代码语法。

监听器并不需要像人一样理解整块屏幕。它只需要对听写有用的最小证据。在 VS Code 里,这可能是可见标识符、语言模式和选中的代码;在 Slack 里,可能是线程主题和最近的语气;在 Notes 里,则可能是标题层级和列表上下文。

我们刻意不做什么

有些能力被我们有意排除在范围外。监听器不会对远程内容截图做 OCR,不会总结用户没有正在输入的窗口,也不会建立持久的视觉历史。它同样不会从图像里推断细粒度意图:图表、视频帧或设计画布本身不会被解释,只有周围文本会被使用。每一次删减都是产品选择:用能力换取可预测性和更清晰的隐私边界。

因此,我们只在狭义产品意义上称它为音频视觉听写:音频加上用于写作的视觉上下文。目标不是通用视觉推理,而是在光标处少写错词。

屏幕上下文如何消解歧义

屏幕上下文听写通过收窄可能性来改变输出。如果光标在 Python 文件里,且可见行已经包含 from fastapi import,用户说出的“router”更可能是一个符号,而不是普通名词。如果光标在 Gmail,同一句话就应该变成自然句子。

你说
"add a guard before fetch profile if auth client is missing"
Loqua 写入(在 VS Code 中)
if (!authClient) return null;
const profile = await fetchProfile(authClient);
你说
"can you take a look at the PR I just pushed and let me know if the retry logic looks right"
Loqua 写入(在 Slack 中)
Could you take a look at the PR I just pushed? Want to make sure the retry logic looks right.

监听器也支持选择感知编辑。如果有文本被选中,听写会默认被解释为作用在这段文本上的指令,除非用户明确要求插入新的正文。仅仅这个区分,就能消除一整类意外重复文本。

当上下文信号冲突时,我们会先信任最硬的证据。活动应用是最可靠的信号,因为它由操作系统结构性保证;选中文本排在其后;附近可见 token 是最软的信号,因为它们可能过时或只是偶然出现。两类信号不一致时,监听器会优先采用更硬的信号并降低置信度,而不是随便选一个然后提交。

隐私:屏幕上下文留在本地

上下文感知语音识别如果实现粗糙,会带来隐私代价。Loqua 的规则是:监听器需要的屏幕上下文默认留在本地。上下文摘要在设备上计算,用来塑造当前这次语音输入;它不会被保留成通用屏幕日志。

具体来说,进入设备端监听器的是一段短暂的上下文包:活动应用标识、语言和字段类型、选区范围,以及附近几百个字符的可见文本。默认永远不会离开设备的是更广泛的窗口内容、其他标签页、其他应用,以及上述任何内容的持久历史。用户开启可选云功能时,云端只会在我们混合隐私说明中描述的边界内接收听写音频或文本;它不会接收原始上下文包。

这个边界很重要,因为一个能看见你所见的监听器可能接触代码、消息和草稿。我们把它视作敏感数据。隐私架构在我们的混合隐私说明里有更详细的解释,简短版本是:屏幕上下文路径本地优先,可选云功能不会收到原始的周边屏幕内容。

开放研究背景

相关研究背景包括音频语言建模、视觉语言投影和多模态指令微调。可以从 Whisper 的稳健 ASR、LLaVA 的视觉指令微调模式,以及 ImageBind 的跨模态对齐开始了解。

这些论文是文献背景。Loqua 的多模态语音识别栈是面向 Mac 听写界面的原创工作:本地上下文、低延迟流式处理和应用感知输出。我们借用的是领域词汇,而不是依赖链。

路线图

下一步是更好的不确定性表达。如果上下文指向两个可能的标识符,系统应该保留这种歧义,而不是假装确信。我们也希望为终端、电子表格、IDE 聊天面板和设计工具做更细的应用适配,因为这些场景里“有用输出”的形状差异非常大。

终端适配器是最具体的近期工作。终端在结构上只是光标处的一行,但上下文上却是一长串历史命令和输出,它们都应该影响用户下一句要输入什么。电子表格适配器几乎相反:可见上下文窗口很小,但列语义非常刚性。两个适配器复用同一套监听器架构;差别在于什么算证据,以及文本渲染器从哪里获得格式线索。

长期方向不是“让模型看见一切”。方向更窄,也更安全:监听器只看足够的本地上下文,在你想写的位置写出你真正想表达的内容,并减少后续清理。这就是多模态语音识别的产品承诺。

常见问题

什么是多模态语音识别?
多模态语音识别会把音频与另一类信号结合起来,例如屏幕上下文或应用元数据,用来推断预期的书面输出。在 Loqua 里,这意味着系统不只是转写语音,还会考虑光标在哪里、附近有什么可见文本。
为什么只听音频的 ASR 在代码场景会失败?
代码包含标识符、包名、大小写、标点和语法,这些信息往往无法单靠声音判断。模型可能正确听到“fetch profile”,却仍然错过可见标识符 fetchProfile。屏幕上下文为识别器提供了音频缺失的证据。
Loqua 会录制我的屏幕吗?
按这里描述的产品意义,不会。Loqua 会读取当前听写事件所需的本地上下文,例如活动应用、选中文本和附近可见文本。它不是持续屏幕录制器,且上下文路径默认留在本地。
这和个人词典有什么不同?
个人词典把已知短语映射到偏好的写法。多模态上下文可以通过可见证据解析用户从未预先登记过的短语。如果某个标识符就在光标旁边出现,Loqua 可以保留它,而不要求你手动建词条。
屏幕上下文会不会出错?
会。如果可见上下文过时、含糊或无关,监听器可能过度依赖它。产品挑战在于校准:上下文强时使用上下文,不确定时保留原始语音,避免从薄弱证据里做出自信改写。
多模态语音识别只适合开发者吗?
不是。开发者最先感到痛点,是因为代码里充满标识符。同样的思路也能帮助邮件、笔记、电子表格、项目工具和聊天。即使说出的词很普通,目标应用也会改变这句话应该变成什么。
监听器收到的上下文包里具体有什么?
一段短暂载荷:活动应用标识、字段类型和语言模式、当前选区范围,以及附近可见文本的小窗口,通常是几百个字符。它按每次语音输入构建,在听写期间使用,不会被持久保存成通用屏幕日志。

今天就试试 Loqua

免费开始。Mac 原生。由每天都在使用它的算法研究者打造。

下载

更多 Loqua 博客文章

工程
全模态语音输入:多模态理解、MoE 与流式文本输出
教程
如何在 Mac 上用语音写代码:Cursor、VS Code 和 Claude Code 完整指南
对比
Loqua vs Typeless:面向上下文、编程和深度工作流的 Mac 原生 Typeless 替代品