唤醒词("Hey Hermes")
唤醒词把 Hermes 变成跨 CLI、TUI 和桌面应用的免手助手:打开一个开关,Hermes 就在后台监听一句口语触发词。说出它,Hermes 就开启一个新会话、打开麦克风,通过常规语音流水线捕获你的命令并作答——完全像 "Hey Siri" 或 "Alexa"。用 surface 选择由哪一个来听。
检测完全在设备端运行。常开监听器只盯唤醒词;在你真正向 agent 说出命令之前,没有任何音频离开你的机器。
工作原理
wake_word.enabled: true(或/wake on)后,一个轻量热词检测器在你配置的输入设备上监听;未设wake_word.input_device时使用进程默认麦克风。- 听到唤醒词时它暂停自身(释放麦克风),开启新会话,并用语音模式的静音检测录制一次语音。
- 你的语音被转写并发送给 agent。它回复后,监听器自动恢复,等待下一个唤醒词。
它默认关闭——在你打开之前什么都不听。
在桌面应用中,免手语音对话可直接说 "stop"(或 "never mind"、"goodbye"、"cancel"、"that's all")结束——这句口语命令结束对话,而非发给 agent。只有整句的停止命令才匹配,因此 "stop the docker container" 这样的真实请求仍正常通过。
远程桌面(客户端采集)
当桌面应用连接到远程 Hermes 后端(例如无头 Docker 主机或另一个房间的机器)时,后端往往没有麦克风。服务端 PortAudio 随即失败,报 "Failed to open the wake-word microphone."
为此 Hermes 支持客户端采集:
- 桌面以
capture: client布防唤醒(当后端无本地输入设备时 GUI 自动如此,或在下方显式设置)。 - 所选唤醒引擎仍运行在后端(相同引擎、相同模型)。
- 桌面打开本地 Mac/PC 麦克风,重采样为 16 kHz 单声道 int16,通过
wake.feedRPC 流式发送短帧。 - 检测到时后端照常发出
wake.detected;桌面在客户端麦克风上启动常规语音流水线。
wake_word:
enabled: true
capture: auto # auto | local | client
# auto — 本地 PortAudio,除非桌面以 client_capture 布防
# local — 始终打开后端麦克风(CLI/TUI 默认)
# client — 始终期待来自桌面的 wake.feed PCM(远程友好)
桌面 GUI 在 wake.start 时总是传 client_capture: true,因此无麦克风的远程后端自动以客户端模式布防。CLI 和 TUI 保持本地采集,除非你显式设 capture: client。
隐私提示:客户端采集时,唤醒 PCM 经过已鉴权的桌面↔后端 WebSocket(与会话其余部分同一通道)传输。检测仍不向第三方唤醒 API 发送音频;引擎在后端进程本地。
引擎
| 引擎 | 成本 | API 密钥 | 说明 |
|---|---|---|---|
| openWakeWord | 免费 | 无 | 经 pyopen-wakeword 的 TFLite。含 "hey hermes" 模型。自定义模型需 .tflite 文件。不支持 Intel macOS 或原生 Windows ARM64。 |
| sherpa | 免费 | 无 | 对键入短语的开放词表检测。首次使用时下载英文模型。支持原生 Windows ARM64。 |
| Porcupine | 免费档 / 付费 | PORCUPINE_ACCESS_KEY | Picovoice 引擎;内置关键词 + 自定义 .ppn 文件 |
默认提供商是 auto。它按此顺序选择第一个平台支持的引擎:openWakeWord → sherpa → Porcupine。平台指 Python 后端的平台,而非远程桌面客户端:
- 原生 Windows ARM64 和 Intel macOS: sherpa(免费,无密钥)。
- Windows x64、Apple Silicon 及支持的 Linux 目标: openWakeWord(免费,无密钥)。
显式指定的提供商保持选中,即便该平台不支持它。Hermes 报告需求错误,而非静默切换引擎。既有显式设置不迁移。要选择自动选择,运行 hermes config set wake_word.provider auto。唤醒检测在你启用前保持关闭。
默认短语标签是 "hey hermes"。对 openWakeWord,Hermes 附带其训练好的 TFLite 模型。pyopen-wakeword 包附带共享的特征提取模型,因此该引擎启动时不下载模型。
若所选引擎缺失,Hermes 在你启用唤醒词检测时请求其 PM extra。security.allow_lazy_installs 控制此安装。新依赖环境可能需要重启 Hermes 后引擎才加载。打包构建包含其目标平台支持的引擎依赖。
pyopen-wakeword 的 macOS wheel 虽标 universal2,实则只含 ARM64 库。Hermes 在 Intel Mac 和原生 Windows ARM64 上排除该引擎。Sherpa 在这两个目标上提供无密钥检测。
Porcupine 的默认关键词是 "jarvis",而非 "hey hermes"。其 phrase 设置只是显示标签;选择内置关键词或提供自定义 .ppn 模型才能改变它检测的内容。在 console.picovoice.ai 获取访问密钥,并把 PORCUPINE_ACCESS_KEY 存到你 profile 的 .env,而非 config.yaml。
受支持的 pyopen-wakeword wheel 面向 Apple Silicon(macOS 15 或更高)、glibc Linux 2.35 或更高、Windows x64。这些要求适用于该引擎,而非每个 Hermes 特性。Termux 的 core/ACP 包不含此唤醒栈。
快速开始
# 在交互式 `hermes` 会话中:
/wake on # 开始监听(首次使用时安装引擎)
/wake status # 显示短语、提供商和状态
/wake off # 停止监听
在桌面应用中,把鼠标悬停在输入框的麦克风上,点击从它展开的那只耳朵。唤醒词监听时耳朵为实心。
这个开关本身就是设置:通过 /wake 或桌面耳朵按钮开/关唤醒词,也会把 wake_word.enabled 写入 ~/.hermes/config.yaml,因此你的选择跨会话持久。你也可手动切换:
wake_word:
enabled: true
配置
wake_word:
enabled: false
surface: auto # 符合条件的界面:"auto" | "cli" | "tui" | "gui"
input_device: null # PortAudio 输入索引或设备名子串;null = 进程默认
capture: auto # auto | local | client——PCM 在哪里采集(见远程桌面)
provider: auto # auto | openwakeword | sherpa | porcupine(需访问密钥)
phrase: "hey hermes" # 仅装饰标签——检测由下方模型/关键词决定
sensitivity: 0.6 # 0.0-1.0——越高越严(误触发越少),三引擎一致
confirmation_frames: 3 # 仅 openWakeWord——触发所需的连续超阈帧数
start_new_session: true # 唤醒时开启新会话 vs. 继续当前会话
openwakeword:
model: hey_hermes # 内置默认,或自定义 .tflite 的绝对路径
porcupine:
keyword: jarvis # 内置关键词或自定义 .ppn 路径
sensitivity 和 start_new_session 适用于全部三个引擎。对 sherpa,phrase 选择检测短语。对 openWakeWord 和 Porcupine,phrase 是显示标签;由其模型或关键词选择检测短语。
input_device 直接传给唤醒监听器的 PortAudio(sounddevice)流。使用数字设备索引或无歧义的设备名子串。此设置只改变唤醒词采集;桌面端按鍵讲话仍使用桌面应用的麦克风路径。
减少环境语音的误触发
openWakeWord 每次给一个短(约 80ms)音频帧打分,因此背景对话中的一个零星音素偶尔会把单帧顶过阈值,无意触发唤醒词。两个旋钮控制它:
confirmation_frames(默认3,仅 openWakeWord)——唤醒触发前需要多少连续超阈帧。真实的 "hey hermes" 在数帧上保持高分;环境杂音只顶起一帧。若嘈杂房间里仍有误触发,调高它(如4–5);代价是几十毫秒额外延迟。1恢复旧的首帧即触发行为。sensitivity(默认0.6)——检测阈值,0.0–1.0。越高越严(误触发越少)。该方向在所有引擎上一致——对 openWakeWord 是原始逐帧分数阈值,对 sherpa 映射到关键词阈值,对 Porcupine 内部反转,使 "越高越严" 同样成立。0.6默认值位于 openWakeWord 宽松的0.5基线上方——后者会放过 "hey hor" 这类近似命中;若仍有误触发,向0.8调高;若真实 "hey hermes" 被漏检,则调低。
sherpa 和 porcupine 引擎在内部解码整个短语,因此没有单帧尖峰问题,并忽略 confirmation_frames(但仍遵循 sensitivity)。
openwakeword 提供商名现在选择 pyopen-wakeword。其 wheel 含 TFLite 库和共享特征模型。Hermes 默认使用内置的 hey_hermes.tflite 模型。ONNX 唤醒模型和 inference_framework 设置不再支持。
界面(CLI、TUI、GUI)
唤醒词在所有三个 Hermes 界面中工作,surface 选择哪一个拥有监听器、并在触发时开启新会话:
surface | 行为 |
|---|---|
auto(默认) | 所有本地界面符合条件;第一个布防的拥有监听器。 |
cli | 仅经典 hermes CLI。 |
tui | 仅 hermes --tui。 |
gui | 仅桌面应用。 |
检测器在设备端、单麦克风,因此同一时刻只有一个界面监听,包括 Hermes 界面运行在不同进程时。所有权是粘性的:第一个符合条件的认领者保持监听器,直到它停止、断开或进程退出。Hermes 不会静默故障转移到另一个已打开的界面。当你想固定所有权而非先到先得时,设置 surface。TUI 和桌面 GUI 共享同一 Python 后端(tui_gateway),它在服务端运行检测器服务器,并在命令录制时把麦克风让给语音采集。
使用不同短语
"Hey Hermes" 是 openWakeWord 和 sherpa 的默认检测短语。Porcupine 使用其配置的关键词(默认 "jarvis")。要唤醒别的东西,在受支持平台上最简单的路径是开放词表引擎:
方案 A——sherpa(任意短语,零训练)
键入你想要的短语;运行时分词——"hey coder"、"computer"、"wake up neo",任何都行:
wake_word:
enabled: true
provider: sherpa
phrase: "hey coder" # 检测键——直接键入你的短语
小的英文 KWS 模型(约 13 MB)首次使用时下载一次。每个 profile 可设自己的短语——为你运行的每个 profile 设 "hey <profile>"。
唤醒特定 profile(桌面端)
用 sherpa 引擎,一个监听器可唤醒任何 profile。配置中 wake_word.enabled: true 的每个 profile 自动登记;未设置时其短语默认为 hey <profile 名>。说出某 profile 的短语,桌面应用即实时切到该 profile、在那里开启新会话并启动免手语音:
- "hey hermes" → default profile
- "hey coder" →
coderprofile - "hey trader" →
traderprofile
在监听器所在 profile 上设 wake_word.profile_routing: false 可退出路由,只听自己的短语。CLI 和 TUI 是单 profile 进程:属于另一 profile 的唤醒短语会打印切换命令(hermes -p <profile>)而非路由。
名称按英文子词声音声学匹配:由两个词构成、音节 2+ 的独特短语效果最佳。极短名称、浓重的非英语音韵,或两个发音相近的 profile,都会降低准确率——必要时按 profile 调 sensitivity。
方案 B——openWakeWord(免费,训练好的模型)
要换短语,获取或训练一个兼容的 openWakeWord TFLite 模型。在配置中设其绝对路径。Hermes 不会为你解析 hey_jarvis 等内置名或下载其模型。
wake_word:
enabled: true
provider: openwakeword
phrase: "computer"
openwakeword:
model: /absolute/path/to/computer.tflite
训练参考:
与日常语音不冲突的唤醒词泛化最好。两个音节加一个不常见的词("hermes" 即符合)胜过 "hello" 或 "stop" 这类常见词。
方案 C——Porcupine(数秒内自定义关键词)
在 Picovoice Console 创建一个 "Hey Hermes" 关键词,下载 .ppn,然后:
wake_word:
enabled: true
provider: porcupine
phrase: "hey hermes"
porcupine:
keyword: ~/.hermes/wakewords/hey_hermes.ppn
在 ~/.hermes/.env 设置你的访问密钥:
PORCUPINE_ACCESS_KEY=your-key-here
要求
- 可用麦克风和
sounddevice+numpy音频栈(与语音模式共享)。 - 用于转写口语命令的 STT 提供商——本地
faster-whisper开箱即用;完整提供商列表见语音模式。 - 用于朗读回复的 TTS 提供商(默认
edge-tts无需密钥即可用)。唤醒流程完全免手,因此开关在 STT 和 TTS 都就绪前拒绝布防——hermes tools(Voice 区)会配置它们。 - 唤醒引擎依赖(自动安装,或
hermes-agent[wake])。
若监听器无法启动,/wake status 会精确报告缺什么。
"Listening" 但从不唤醒(macOS)
macOS 按进程授予麦克风访问权。桌面应用中 STT 正常证明渲染器有麦克风权限——唤醒监听器运行在 Python 后端,它需要自己的授权。没有它,CoreAudio 给后端一条"正常"却只产出静音的流,因此耳朵显示监听但短语从不触发。Hermes 检测到这一点(/wake status 显示 "mic delivers only silence";桌面折叠的语音菜单在其触发器上带同样提示)。修复:系统设置 → 隐私与安全性 → 麦克风 → 启用 Hermes 后端(它可能显示为你的终端、python 或 Hermes),然后把唤醒词关掉再开。
"Listening" 但收到静音(Windows)
桌面端按鍵讲话和唤醒词采集使用不同麦克风路径。按鍵讲话使用桌面应用的浏览器采集,而唤醒词监听器在 Python 后端打开 PortAudio 流。一个工作时,另一个可能选中了静音或不可用的 Windows 输入。
/wake status 报告所选输入设备和 Windows 音频主机 API。当它报告静音时,把 wake_word.input_device 设为工作 PortAudio 输入的数字索引或无歧义名称,然后切换唤醒词:
hermes config set wake_word.input_device "Microphone Array"
用 null 返回进程默认:
hermes config set wake_word.input_device null
注意与限制
- 仅本地界面。 唤醒词运行在 CLI、TUI 和桌面 GUI——凡有本地麦克风之处。它不在消息网关(Telegram、Discord……)运行,那里没有麦克风。
- 一次一个麦克风。 检测器在命令录制时释放麦克风,回合结束后重新收回,因此不会与语音采集争抢。
- 隐私。 热词检测是本地的。误触发多就调高
sensitivity,漏检你就调低。