最近闲着无聊随便做了一个windows的语音唤醒助手,主要是闲平常要出门,或者不方便的时候(比如运动、躺床上的时候),可以叫一声电脑就做我想让他做的内容(可以连接LLM/GUI agent/MCP等等)。
再加上现在GUIAgent发展的很快,网上还没有语音唤醒形式的链接,也就自己搭了一个出来。
下面是这个项目的readme。
WinAssistant – Windows 本地语音唤醒与自动化执行#一个在 Windows 上运行的本地语音助手:
说出唤醒词 → 识别你的语音 → 自动执行自定义动作(脚本、GUI Agent、MCP 等)。全离线(唤醒+识别均可离线),即插即用,优先使用耳机麦克风。演示视频#https://github.com/user-attachments/assets/a48b8e94-8b95-46eb-9aa5-a4085c2341c4
✨ 核心特性#多唤醒词可选 / 可自定义
内置多种常见唤醒词,也可替换为你训练的 .ppn 文件。
本地唤醒:Picovoice Porcupine
轻量、低延迟、可靠,离线运行。
语音识别:fast-whisper
内置去噪、VAD 端点检测,自动判断“用户是否说完”,可按需调节模型大小(速度/准确度权衡)。
自动音频设备选择
自动选择可用的输入/输出设备,优先耳机。
可插拔“处理态”
识别到文本后进入你的“处理态”(可自定义),例如:
调用 MCP / 工具调用触发 GUI Agent执行脚本、打开应用、查询信息等🧠 工作流 / 状态机#stateDiagram-v2
[*] --> 空闲态
空闲态 --> 唤醒态: 语音唤醒
唤醒态 --> 处理态: 用户语音结束
处理态 --> 空闲态
唤醒态 --> 空闲态: 用户长时间无应答
空闲态 --> 空闲态: (持续监听)
说明:唤醒后进入实时听写;若检测到长时间静音则回退到空闲态。
📦 目录结构#WINASSISTANT/
├─ model/
│ ├─ 小智.ppn # 自定义/内置唤醒词(Porcupine)
│ └─ porcupine_params_zh.pv # 中文参数
├─ music/ # 系统提示音
│ ├─ ok.wav
│ ├─ sorry.wav
│ └─ zai.wav
├─ utils/
│ ├─ player.py # 播放器:播放提示音/反馈
│ ├─ reader.py # 识别器:fast-whisper + VAD
│ ├─ rouser.py # 唤醒:Porcupine 推理
│ └─ UIoperator.py # 处理态模板(可自定义)
├─ .env # 环境变量(见下)
├─ main.py # 入口:python main.py
└─ requirements.txt # 依赖
🚀 快速开始#1) 环境准备#Windows 10/11Python 3.9+(建议 64-bit)麦克风 & 扬声器/耳机git clone https://github.com/wanghai673/WinAssistant
cd WINASSISTANT
# 建议:创建虚拟环境
python -m venv .venv
.\.venv\Scripts\activate
pip install -r requirements.txt
2) 申请 Picovoice Access Key#前往 https://picovoice.ai/ 免费获取 ACCESS_KEY。
3) 配置 .env#在项目根目录创建或修改 .env:
ACCESS_KEY=你的AccessKey
# 唤醒词(可选:小智, hey google, grasshopper, computer, americano,
# bumblebee, hey barista, ok google, pico clock, porcupine,
# picovoice, jarvis, terminator, grapefruit, blueberry, alexa, hey siri)
ROUSE_WORD=小智
想用自定义唤醒词?把训练好的 .ppn 文件放到 model/ 并在代码/ENV 中指向它即可。
4) 运行#python main.py
说出唤醒词(默认 “小智”)→ 说出命令 → 听到提示音并执行。
🧩 自定义“处理态”#识别结果会进入你的“处理态”模块(示例:utils/UIoperator.py)。
你可以在这里:
串接 MCP 工具调用通过 GUI Agent 操作桌面执行脚本 / 打开应用 / 系统自动化回放 music/ok.wav / sorry.wav 作为反馈建议将业务逻辑与语音管线解耦:保留 player / reader / rouser 作为通用能力层,处理态专注于“要做什么”。
⚙️ 常用调优点#VAD/静音阈值:在 reader.py 中调整 MAX_SILENCE_SECS 等参数,影响“说完就停”的敏感度。模型大小:根据机器性能切换 fast-whisper 模型(小模型更快,大模型更准)。提示音屏蔽:通过 realtime_zh(..., beep_guard=0.5) 吞掉前 0.5s 系统“滴”声,避免影响识别。音频设备:默认自动选择,优先耳机;如需固定设备,可在 player/reader 中指定设备索引。🔐 隐私与本地化#唤醒与识别均可离线完成;音频不会上传到云端。仅在你显式配置联网服务时才会产生外部调用。🧪 简单示例(伪代码)## 极简示例:监听唤醒 → 识别
from utils.player import Player
from utils.reader import Reader
from utils.rouser import Rouser
from pvrecorder import PvRecorder
from dotenv import load_dotenv
import os
load_dotenv()
ACCESS_KEY = os.getenv("ACCESS_KEY")
ROUSE_WORD = os.getenv("ROUSE_WORD", "小智")
DEVICE_INDEX = -1 # 使用系统默认输入设备
rouser = Rouser(access_key=ACCESS_KEY, device_index=DEVICE_INDEX, keyword=ROUSE_WORD)
player = Player()
reader = Reader(device_index=DEVICE_INDEX)
recorder = PvRecorder(device_index=DEVICE_INDEX, frame_length=rouser.porcupine.frame_length)
recorder.start()
print(f"正在监听唤醒词:『{ROUSE_WORD}』 (Ctrl+C 退出)")
while True:
pcm = recorder.read()
if rouser.process(pcm) >= 0: # 检测到唤醒
player.play_voice(block=True) # 提示音
text = reader.realtime_zh(rec_shared=recorder, beep_guard=0.0)
if text:
print("识别文本:", text)
player.play_voice(block=True, type="ok")
# 在这里根据 text 执行动作...
else:
player.play_voice(block=True, type="sorry")
🧯 故障排查#没有反应 / 设备占用:检查是否有其他应用占用麦克风;尝试在系统声音设置中启用设备。识别慢:试用更小的 fast-whisper 模型或关闭其他高占用程序。唤醒不灵敏:更换更清晰的唤醒词模型 .ppn,或在安静环境下测试。提示音被识别进去:增大 beep_guard(如 0.7)。🙌 致谢#Picovoice Porcupine(本地唤醒)fast-whisper(快速 ASR)