操作指南

如何在 Mac 上用语音写代码:Cursor、VS Code 和 Claude Code 完整指南

标识符拼写正确,commit message 自动符合 conventional 格式,PR 描述保留你平时会写出来的语气。这里有 6 个完整示例,以及我们每天都在用的快捷键设置。

TL;DR

这是一份用 Loqua 在 Mac 上语音写代码的实用指南,面向在 Cursor、VS Code 和 Claude Code 里工作的程序员。要让程序员语音输入真正可用,三件事必须同时成立:技术标识符能识别,输出能按目标位置格式化,延迟低到不会打断思路。Loqua 就是为这种 Mac 工作流设计的:代码注释、commit、PR 描述、终端命令、Cursor prompt、Claude Code 指令都能覆盖。这篇会从设置讲到完整示例,但不会假装每一行代码都最适合用语音写。

Loqua 是一款面向 Mac 的上下文感知语音输入工具。它会判断你当前是在 IDE、终端、PR 描述框,还是聊天面板里,并据此调整输出。它在 Apple Silicon 上通过 Neural Engine 运行,按应用格式化输出,也能识别技术词汇,不需要你先手动加载词典。

说实话:语音写代码和语音写普通文字不是同一种技能。第一小时你会更慢。到了第二小时,你会开始写出更长的注释和更好的 commit message,因为语音没有键盘输入的摩擦。我们已经连续几个月每天这样用,下面是具体设置。

90 秒完成设置

五个步骤,如果你装过 Mac app,应该都不陌生:

  1. 从首页下载 Loqua,然后拖到 /Applications
  2. 首次启动时,授予麦克风权限和辅助功能权限。(辅助功能权限让 Loqua 能看到当前活动 app 和选中的文本;如果想了解这里的 Accessibility 含义,可以看 Apple 的 Privacy & Security 指南。)
  3. 打开 Loqua 的 Settings,确认你的 push-to-talk 快捷键。默认是 Fn + Space。我们自己用 Karabiner-ElementsCaps Lock 重映射过来,因为不离开主键区就能按到。
  4. 打开任意文本编辑器:TextEdit、VS Code、Cursor、Notes 都可以,把光标放进文本输入区域。
  5. 按住快捷键,说话,松开。文字会出现在光标位置。

就这样。不需要按 app 单独配置。Loqua 在 Mac 上是系统级可用的。

第一次语音写代码

打开 VS Code 或 Cursor,把光标放到一个 Python 文件的函数体里。自然地说:

你说
"add a comment saying this caches the response for fifteen minutes and on auth failure just redirect to login don't retry"
Loqua 写出(在 VS Code 的 Python 文件中)
# Cache response for 15 min.
# On auth failure (401): redirect to /login — do not retry.

注意这里发生了三件事:它识别出你在代码里,所以输出成注释而不是普通段落;它格式化了明确的值("fifteen minutes" → "15 min",并推断出标准的 401 状态码);它还把第二个分句收紧成结构化指令。这些都不需要配置,背后的多模态上下文引擎会读取文件扩展名和相邻代码来判断。

适合代码场景的语音表达模式

你不需要学习新的语法。但你确实需要知道哪些说法更容易得到干净的输出。下面这些模式,是我们几个月每天使用后沉淀下来的。

  • 名称 + 格式提示:说 "function name fetch user profile" 会得到 fetchUserProfile;说 "function name underscore fetch user profile" 会得到 fetch_user_profile。默认格式会跟随当前文件的语言约定。
  • 用描述表达类型签名:说 "async function that takes a user id and returns a promise of user" 可以得到完整签名;Loqua 会从上下文推断类型。
  • 先明确注释意图:说 "add a comment saying X" 会按当前文件语法生成注释;在代码文件里只说 X 通常也会产出注释,但显式 framing 能减少歧义。
  • Commit message:说清改了什么:在 commit 场景(Source Control 面板、终端 git commit)里,Loqua 会生成 conventional 格式的消息,不需要你自己说前缀。
  • PR 描述:先讲为什么:如果仓库里有 PR template,Loqua 会读取并按它组织内容。
  • 结构切换时停顿:半秒左右的停顿,在普通文字里会被理解为段落分隔,在代码块里会被理解为逻辑步骤分隔。

6 个完整示例

下面每个例子都是真实的:我们实际怎么说,Loqua 实际怎么写。语音是你的,输出由 Loqua 组织:

你说(在 Cursor 中,请求重构)
"move the rate limiter into its own middleware file and update the imports"
Loqua 写出(作为 Cursor prompt
Refactor: extract the rate-limiter logic into a new middleware/rateLimit.ts module. Update imports across handlers. Preserve current behavior; no API changes.
你说(staging changes 之后)
"this fixes the race condition in session cleanup when two logout requests hit at the same time added a mutex on the session store also added a regression test"
Loqua 写出(作为 git commit message
fix(auth): handle concurrent session cleanup race condition

Two simultaneous /logout requests could both attempt to invalidate the same token. Added mutex lock on the session store write path. Tests: auth_test.go — TestConcurrentLogout
你说(在 PR 描述框里)
"this PR adds support for partial responses on the search endpoint clients can request specific fields and get back a smaller payload covered by tests and the changelog is updated"
Loqua 写出(在 GitHub PR 中)
## Summary
Adds field-selection support to the search endpoint. Clients can request a subset of fields and receive a smaller payload.

## Changes
- Search endpoint accepts a fields query param
- Response serializer respects field selection
- Tests cover selection, omission, and invalid-field handling
- CHANGELOG.md updated

## Test plan
- [ ] Unit tests pass
- [ ] Manual smoke against staging
你说(在 Terminal 中)
"use ripgrep to find all usages of the old auth client in the api folder excluding tests"
Loqua 写出(在 Terminal 中)
rg "OldAuthClient" api/ --glob '!**/*_test.go'
你说(在 DBeaver 里写 SQL 查询)
"select user id email and last login from users where last login is more than 90 days ago and account status equals active"
Loqua 写出(在 DBeaver 中)
SELECT user_id, email, last_login
FROM users
WHERE last_login < NOW() - INTERVAL '90 days'
  AND account_status = 'active';
你说(写 regex)
"regex for matching email addresses but allowing plus signs in the local part"
Loqua 写出(在 VS Code 的 JavaScript 文件中)
const emailWithPlus = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;

IDE 上下文如何影响输出

Loqua 不只是知道你在 VS Code 或 Cursor 里。它还知道文件类型、当前选区、周围代码,以及(如果你允许)打开的聊天面板。同一句语音,会因为这些线索而产生不同输出:

上下文输出形态
Python 文件的函数体内代码或行内注释,并匹配当前文件语言
docstring 或文件顶部注释中普通说明文字,按 docstring 格式输出
Source Control 的 commit message 输入框Conventional commit 格式
GitHub 的 PR 描述中结构化 PR 模板(Summary / Changes / Test plan)
Cursor 的聊天面板带上下文的 prompt 型指令
Claude Code 的终端界面直接指令;如果上下文明确,通常会带文件路径

这些都不需要你告诉 Loqua。它会读取当前 app 和光标周围文本并做判断。如果输出形态不对,你可以用更明确的说法再说一遍,比如 "add a comment saying..." 或 "the commit message is...",它就会调整。

如果想了解标识符保留背后的屏幕上下文机制,可以看 building a listener that sees what you see

多语言标识符与中英混说

我们遇到过一个真实场景:代码库里有一个中文命名的 feature flag,而它出现在一条英文 commit message 的中间。Loqua 不需要切换模式也能处理;更多 EN+中 模式可以看 我们的 voice + AI coding 指南。简短版如下:

你说
"add a fallback when 用户画像 service is down so the page still renders with the default state"
Loqua 写出(在 VS Code 的代码注释中)
// Fallback: if the 用户画像 service is down, render the page with the default state.

常见问题

  • 标识符识别错了:用自然英文重新说一遍这个标识符,比如说 "fetch user profile",不要逐个字母拼读。Loqua 的 NER 是为自然表达训练的,不是为逐字母拼写训练的。
  • 想要代码却输出成普通文字:用 "add a comment saying..." 或 "as code:..." 明确 framing。光标位置通常足够消歧,但显式 framing 更稳。
  • 语言命名约定错了(camelCase vs snake_case):Loqua 会跟随当前文件语言的默认约定。要覆盖默认值,可以直接说 "camel case" 或 "snake case"。
  • 语音没有被接收:看菜单栏图标:灰色表示缺少麦克风权限,红色表示正在收听,绿色表示空闲。麦克风权限在 System Settings → Privacy & Security → Microphone。
  • 快捷键冲突:如果 Fn + Space 和 Spotlight 或其他 app 冲突,可以在 Settings → Shortcut 里改。我们很多人用 Karabiner 把 Caps Lock 重映射过来,因为 Caps Lock 平时基本被浪费了。

我们每天实际怎么用

这部分比功能列表更重要。我们的日常工作流大概是这样:

  • 代码注释:几乎总是用语音。语音写出来通常更长、更解释性,团队也更愿意读。
  • Commit messages:语音生成,再快速编辑一遍。因为没有键盘输入成本,正文内容会更完整。
  • PR 描述:语音,通常一边看 diff 一边说。Loqua 能看到 GitHub template,所以结构会比较准确。
  • Cursor / Claude Code prompts:除了非常短的 "fix this" prompt,其他基本都用语音。长重构描述是语音最划算的场景。
  • Slack / Discord 工程讨论:语音。更快,也更容易把想法说完整。
  • 标识符和代码主体:混合使用。简单代码(CRUD、胶水代码)适合语音;复杂算法代码通常打字更快,因为真正的工作在结构本身。

粗略算下来:写代码里的文字内容(注释、文档、消息、prompt)大约有 4× 速度提升;写纯代码时大致和打字持平。放到一整天看,累积效果很明显,而且认知负担会下降,因为你不再频繁在思考模式和打字模式之间切换。

如果想看更深的架构说明,可以读 我们关于 three-model voice typing stack 的文章。如果想把这个模式扩展到 AI coding 工具,可以读 AI coding 的语音输入指南

给正在评估这个工作流的程序员再补一句:如果你搜索如何在 Mac 上语音写代码,大多数结果会停在“用 Apple 内置听写”。那是一个不错的起点,但它只是音频输入,不知道你的 IDE、你的标识符,也不知道你的结构约定。Loqua 想做的是下一层:面向程序员的语音输入,让输出一开始就匹配目标位置。

常见问题

Loqua 对 Cursor 有专门支持吗?
有。Loqua 把 Cursor 当作一等 IDE 场景处理:它会检测聊天面板、文件上下文和选区状态,并据此调整输出。Prompt 进入聊天面板,代码进入编辑器,注释保留在当前文件语言内。
我可以把 Loqua 和 Claude Code 一起用吗?
可以。Claude Code 会被识别为终端型开发工具;Loqua 会输出 Claude Code 更容易理解的直接指令和文件路径。长重构描述或规格草稿尤其适合用语音。
如果变量名里混用中文和英文怎么办?
Loqua 可以处理中途 code-switching,不需要切换模式。说 "add a check for the 用户画像 service" 会生成包含中文词的注释或标识符,并保留原始字符。
大括号、括号、等号这些符号怎么说?
通常不需要说。Loqua 会从上下文推断结构;比如说 "function name fetch user with id and return a user",它会生成带 parens、types 和 braces 的完整签名。少数需要显式输入符号时,可以说 "open paren" / "close paren" / "equals sign" 等。
Loqua 怎么处理很长的语音输入?
没有单次语音长度上限。按住快捷键,想说多久就说多久,松开即可。流式输出会边说边出现;TTFT 低于 200ms,所以你还没说完,前几个词就已经显示了。
学习成本高吗?
IDE 工作流大约一小时能上手。最大的心智切换,是学会哪些 framing 最容易得到干净输出(见上面的模式部分)。之后,写代码里的文字内容会比打字更快,IDE 上下文感知会替你处理大部分格式决策。

今天就试试 Loqua

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

下载

更多 Loqua 博客文章

教程
AI coding 的语音输入指南:不用打字,用语音 prompt Cursor 和 Claude Code
效率
语音生产力栈:我们实际用来写作、交付和思考的 9 个工具
教程
Mac 会议语音笔记:从语音到笔记、行动项和完成
工程
全模态语音输入:多模态理解、MoE 与流式文本输出