智能体只需要接收“开灯”“关灯”这类少量语音指令时,可以先限定识别短语,再用完整结果匹配动作白名单。Vosk 的运行时词表用于缩小识别范围,未知词和没有精确匹配的结果应进入拒绝分支,而不是猜测后执行动作。
本文示例使用英文小模型、turn on light/turn off light 两条短语。代码在 Windows、Python 3.11.15、vosk 0.3.45 上运行,测试输入包含本机 Microsoft Zira 合成的英文“turn on light”以及项目提供的英文数字录音。合成语音只用于链路验证,没有在真实房间、噪声或中文语音环境测量识别准确率。

模型必须支持运行时限定词表
官方模型适配说明指出,运行时修改词表需要动态图模型,静态图大模型不支持同样的接口。此处选择 官方模型列表里的 vosk-model-small-en-us-0.15,下载 ZIP 并解压,把完整模型目录交给代码。
英文模型适合本例英文短语;要识别中文,需要相应中文动态图模型及中文短语,并重新验证目标设备、口音和噪声。把英文短语直接替换成中文字符串,并不能改变声学模型的语言能力。
准备真实 16kHz 单声道 PCM 音频
在独立环境安装 vosk==0.3.45。准备 WAV 格式、单声道、16 位 PCM、实际采样率 16000 Hz 的录音。本例会直接拒绝不同格式;修改 WAV 头或只把构造器采样率写成 16000,都不等于对原波形重采样。
例如录制一段清晰的英文 turn on light,保存为 command.wav。把代码保存为 recognize_command.py,运行 python recognize_command.py vosk-model-small-en-us-0.15 command.wav。第一个参数是模型目录,第二个是录音路径。
import json
import sys
import wave
from vosk import KaldiRecognizer, Model, SetLogLevel
SetLogLevel(-1)
model_path = sys.argv[1]
wav_path = sys.argv[2]
phrases = ['turn on light', 'turn off light', '[unk]']
routes = {'turn on light': 'LIGHT_ON', 'turn off light': 'LIGHT_OFF'}
def route(text):
if '[unk]' in text or text not in routes:
return 'REJECT'
return routes[text]
assert route('turn on light') == 'LIGHT_ON'
assert route('[unk]') == 'REJECT'
assert route('turn on light please') == 'REJECT'
with wave.open(wav_path, 'rb') as audio:
if audio.getnchannels() != 1 or audio.getsampwidth() != 2 or audio.getcomptype() != 'NONE':
raise ValueError('Expected mono 16-bit PCM WAV')
if audio.getframerate() != 16000:
raise ValueError('This example requires an actual 16000 Hz waveform')
model = Model(model_path)
recognizer = KaldiRecognizer(model, 16000, json.dumps(phrases))
print('audio_sample_rate:', audio.getframerate())
print('grammar:', phrases)
results=[]
while True:
chunk = audio.readframes(4000)
if not chunk:
break
if recognizer.AcceptWaveform(chunk):
results.append(json.loads(recognizer.Result()))
results.append(json.loads(recognizer.FinalResult()))
for result in results:
text=result.get('text', '')
print('recognized:', text)
print('route:', route(text))
本地运行输出
light_command.wav
audio_sample_rate: 16000
grammar: ['turn on light', 'turn off light', '[unk]']
recognized: turn on light
route: LIGHT_ON
test.wav
audio_sample_rate: 16000
grammar: ['turn on light', 'turn off light', '[unk]']
recognized: [unk] [unk]
route: REJECT
recognized: [unk]
route: REJECT
完整结果和动作匹配分开处理
官方短语词表示例将 JSON 短语列表传给 KaldiRecognizer,并使用 AcceptWaveform、Result 与 FinalResult 处理分块输入。本例保留 [unk] 作为未知结果通道,只匹配完整最终文本;PartialResult 可能继续变化,不适合直接触发动作。
程序打印 LIGHT_ON/LIGHT_OFF 仅代表演示路由,没有控制真实设备。路由函数对 [unk]、额外词语、空文本和未匹配短语都返回 REJECT;不要用“包含 light”这类宽松判断代替明确指令。
本次合成“turn on light”被识别为 turn on light,路由为 LIGHT_ON;英文数字录音落入未知或不匹配分支,没有触发灯光路由。验收时用两条合法短语、无关语句、静音和噪声分别测试,核对最终文本和动作结果,不只检查程序无异常。
接到真实智能体前还需要什么
- 对每种语音输入保留录音、最终文本、路由与人工预期,统计误触发和漏识别。
- 设置录音结束或分段规则,避免同一句话在多次结果中重复触发;记录请求编号和动作执行状态。
- 动作失败需要单独反馈;识别到短语不代表设备已完成操作。
- 账户、支付或不可逆动作应沿用现有权限和确认规则,不能仅靠一次语音转写授权。
限定短语无法保证无关声音总被识别为 unk。仍可能把相近发音误识别成白名单短语,尤其在噪声、回声和不同口音下;本例的拒绝分支能控制文本匹配范围,但不构成语音身份认证。
Ai菜鸟网。发布者:AI小管家,转载请注明出处:https://www.alyyhw.com/31867.html