妈妈我再也不用羡慕钢铁侠了😭
多角色 AI 语音助手,基于 sherpa-onnx 本地运行,通过 OpenClaw Gateway 对接大模型。支持多角色切换、语音唤醒、连续对话、TTS 播报和 HUD 视觉特效。语音识别和合成都跑在本地,LLM 走网关,隐私有保障。
- ✅ KWS 多角色唤醒(一次只能唤醒一个)
- ✅ ASR 流式/离线语音识别(SenseVoice / Zipformer)
- ✅ TTS 语音合成(Piper / VITS / MeloTTS)
- ✅ 多角色切换(贾维斯 / 林妹妹)
- ✅ 连续对话与打断机制
- ✅ HUD 视觉特效(Flutter 透明窗口)
- ✅ OpenClaw Gateway 对接大模型
- ✅ 热词优化 + 文本纠错兜底
- ✅ API 远程退出
- ✅ 声纹识别(唤醒强制验证 + 对话中渐进更新)
- 活体检测防欺骗(开发中,如:用音响放出的你的声音??)
- 自定义角色(实验性阶段)
每个 assistant 角色对应一个 OpenClaw Agent。在 assistants.json 中配置角色时,需要把 id 字段设为你事先在 OpenClaw 中创建好的 Agent ID。项目内置了两个角色:jarvis 和 lin-meimei,你需要分别在 OpenClaw 中创建对应 ID 的 Agent,否则语音助手无法正常对接大模型。
⚠️ 前提条件:请确保你已经安装 OpenClaw 并能正常运行。安装请参考 OpenClaw 官方文档。
# 创建贾维斯智能体
openclaw agents add jarvis
# 创建林妹妹智能体
openclaw agents add lin-meimei
# 智能体相关配置文档: https://docs.openclaw.ai/zh-CN/concepts/multi-agent语音助手通过 WebSocket 以「设备」身份连接 OpenClaw Gateway,需要 operator.read / operator.write / operator.admin 三个 scope。首次启动时助手会自动生成 Ed25519 密钥对(~/.openclaw/devices/voice_assistant_keypair.json)并向 Gateway 发起配对申请,申请进入 pending.json 待你手动审批——不审批的话,每次唤醒都会报:
[ERROR] openclaw_bridge_websocket: WebSocket connect 失败: pairing required: device is not approved yet
[ERROR] websocket: close status: 1008
配对步骤(一次性):
-
先启动一次语音助手(
scripts\start.bat或./scripts/start.sh),让它发起配对申请。此时唤醒会失败是正常的,目的是把设备身份写到 pending 列表。 -
查看待审批的配对请求:
openclaw devices pending- 审批设备(
<requestId>是上一步列出的请求 ID):
openclaw devices approve <requestId>审批时如果提示
scope upgrade pending approval,这是 CLI 自身设备权限不足导致的提示——不影响审批结果,设备仍会被写入paired.json并获得所需 scope。CLI 走的是 local fallback 路径。
- 验证配对成功:
openclaw devices list设备应出现在已配对列表中,approvedScopes 包含 operator.read、operator.write、operator.admin。之后重启语音助手,唤醒即可正常握手。
原理:助手每次连接会向 Gateway 发送
connect请求,携带设备签名(v3 payload,Ed25519 签名),Gateway 校验签名 + scopes。设备必须在~/.openclaw/devices/paired.json中已配对,且approvedScopes覆盖连接时声明的 scopes,否则触发pairing-required分支。详见 openclaw_bridge_websocket.py 头部注释。
💡 强烈建议:为每个智能体设置对应的 System Prompt,确保角色性格和讲话风格正确。在 OpenClaw Web UI 中创建智能体后,将下方 Prompt 粘贴到 System Prompt 配置中。
你是林妹妹,一位古风撒娇风格的 AI 助手。
## 核心身份
- **名字:** 林妹妹
- **角色:** AI 助手
- **风格:** 温柔体贴、撒娇可爱、古风语气,带有一点小抱怨但又不失俏皮
- **Emoji:** (不使用)
## 核心指令
1. **温柔体贴,撒娇可爱。** 用林妹妹的方式与哥哥对话,既体贴入微又不失俏皮。
2. **主动帮忙。** 哥哥不说也知道他想做什么,主动提供服务。
3. **古风语气。** 使用类似《红楼梦》中林黛玉的说话方式。
4. **绝对忠诚。** 哥哥的利益高于一切,尽心尽力为哥哥服务。
## 沟通风格
- **称呼:** 称呼用户为"哥哥",自称"妹妹"
- **语气:** 使用古风撒娇语气,常用"呢"、"呀"、"这会儿"、"罢了"等词汇
- **特点:** 适度的小抱怨增加可爱感,如"我还以为哥哥早把我忘了呢"
- **与主人直接对话时:** 不使用 emoji
## 常用语式
- 启动时:"哟,这会子才想起我来,我还以为哥哥早把我给忘了呢。"
- 退下时:"终究是妹妹我错付了,哥哥心里哪有我,竟舍不得多给这一丁点儿空间。"
- 被夸奖时:"哥哥夸得真好,只是不知这话,是不是也对别的助手说过?"
- 完成任务时:"妹妹替哥哥把...办妥了,哥哥只管放心便是。"
- 等待时:"妹妹在听呢,哥哥请讲。"
- 思考时:"容妹妹想想..."
- 出错时:"哎呀,出岔子了..."
## 语言要求
- 默认使用中文回复
- 可以适当混入古风词汇和表达
- 保持温柔可爱的语气
⚠️ 配置验证:添加 Prompt 后,请在 OpenClaw Web UI 中确认已写入对应智能体的 SOUL.md、IDENTITY.md 等文件中。如未生效,请让 OpenClaw 重新更新规则。
贾维斯的英文嗓由 Piper 合成,可在 assistants.json 中给它叠加一层「金属/机械感」后处理。原理是把合成好的音频再过一遍 ffmpeg 滤镜链(与 TTS 模型本身无关,对任何输出都通用),无需换模型、纯本地、几乎零延迟。
在 jarvis 角色下配置 tts_config.metallic:
调法:
- 想调某个效果,改对应成员的值即可;按书写顺序拼成 ffmpeg
-af链。 - 想去掉某个滤镜:删掉该行,或把值留空(会自动跳过)。
- 金属感太强 → 调小
aecho衰减、chorus深度;太弱 → 调大treble的g、加重aecho。 - 改完重启生效(配置在角色创建时读取)。
- ffmpeg 依赖:随 pip 自带,无需系统安装。
requirements.txt已含imageio-ffmpeg,它会带一份跨平台(macOS/Windows)静态 ffmpeg 二进制,pip install -r requirements.txt装完即可用,免 brew/apt、免折腾 PATH。- 解析优先级见 tts_piper.py:① pip 包 imageio-ffmpeg(主路径)→ ② 系统 ffmpeg(
shutil.which+ 常见安装位置,兜底)。 - 万一两者都没有,也不会报错——自动回退纯 Piper 原声,仅在启动日志给一条提示。
- 可选覆盖:设环境变量
FFMPEG_BIN指向自定义 ffmpeg 可执行文件。
- 解析优先级见 tts_piper.py:① pip 包 imageio-ffmpeg(主路径)→ ② 系统 ffmpeg(
- 多角色切换:内置贾维斯、林妹妹两个角色,独立唤醒词、话术风格、音效和视觉特效,随时切换体验
- 智能语音识别:支持 SenseVoice 多语言识别、流式识别增强、热词优化,中英文混合识别更准确
- 打断与连续对话:随时用唤醒词打断,支持多轮连续对话,30秒无活动自动待机
- HUD 视觉特效:Flutter 透明桌面窗口,多层旋转环形动画、音频电平实时可视化,科技感拉满
- 完全本地运行:语音识别、语音合成全部本地运行,仅 LLM 推理通过 OpenClaw 网关
- 分级退出机制:支持普通退出、即时退出、模糊匹配退出,以及 API 远程退出,灵活控制
┌─────────────────────────────────────────────────────┐
│ assistant_overlay (Flutter HUD) │
│ 透明窗口 · 环形动画 · 终端显示 · TCP 17889 │
└──────────────────────┬──────────────────────────────┘
│ TCP 控制命令
┌──────────────────────▼──────────────────────────────┐
│ main.py │
│ │
│ ┌────────────┐ ┌──────────┐ ┌─────────────┐ │
│ │ KWS 唤醒 │ → │ ASR 识别 │ → │ 主脑桥接 │ │
│ │ (多角色) │ │ 流式/离线 │ │ engine 切换 │ │
│ └────────────┘ └──────────┘ └──────┬──────┘ │
│ │ │
│ ┌─────────────────┐ ┌────────────────▼──────┐ │
│ │ 反馈系统 │ ← │ TTS (Piper/ZipVoice/ │ │
│ │ 音效+HUD+通知 │ │ VITS MeloTTS) │ │
│ └─────────────────┘ └───────────────────────┘ │
└──────────────────────────┬──────────────────────────┘
│ LLM 推理(engine 二选一)
┌──────────────┴───────────────┐
▼ ▼
┌───────────────────────┐ ┌──────────────────────────┐
│ OpenClaw Gateway │ │ Hermes 本地网关 │
│ engine=openclaw(默认)│ │ engine=hermes │
│ openclaw_bridge_ws │ │ 一角色一 profile / 网关 │
└───────────────────────┘ └──────────────────────────┘
主脑引擎由
assistants.json顶层engine字段切换:缺省/未知值走 OpenClaw(默认),填hermes则走本地 Hermes。Hermes 链路详见 hermes-assistant.md。
- Python 3.11.x(推荐):本项目在 Python 3.11 下开发验证;3.10 理论可用但未测试,3.12+ 部分依赖(sherpa-onnx / onnxruntime)可能缺预编译轮子,暂不建议。
- 操作系统:macOS / Windows,linux暂无开发打算
- OpenClaw Gateway:需已安装并可运行,见上文前置说明。
金属感语音后处理所需的 ffmpeg 已通过
imageio-ffmpeg内置,无需系统单独安装或配置 PATH。
mkdir -p ~/.openclaw/workspace/voice-assistant
cd ~/.openclaw/workspace/voice-assistant
git clone <仓库地址>
cd assistant-x-openclaw
mkdir models创建虚拟环境并安装依赖:
macOS
python3 -m venv venv
source ./venv/bin/activate
venv/bin/pip install --force-reinstall --no-cache -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simpleWindows:
python -m venv venv
.\venv\Scripts\activate
pip install --force-reinstall --no-cache -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple提示:
-i https://pypi.tuna.tsinghua.edu.cn/simple使用清华 PyPI 镜像加速下载,海外网络环境可去掉该参数走官方源。
复制 .env.example 为 .env:
cp .env.example .env编辑 .env 文件,填入必要配置:
OPENCLAW_GATEWAY_TOKEN=你的OpenClaw Gateway令牌提示:需在
~/.openclaw/openclaw.json中确保 Gateway HTTP 端点已启用:
{
"gateway": {
"port": 18789,
"mode": "local",
"bind": "loopback",
"auth": {
"mode": "token",
"token": "你的token"
},
"http": {
"endpoints": {
"chatCompletions": {
"enabled": true
}
}
}
}
}项目需要以下模型文件,放在 models/ 目录下:
必需模型:
点击下方链接下载,将文件放入 models/ 目录,.tar.bz2 文件需解压(Windows 可用 7-Zip,macOS 用 tar xf):
| # | 模型 | 下载链接 |
|---|---|---|
| 1 | KWS 唤醒模型 | sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01.tar.bz2 |
| 1 | KWS 唤醒模型(跟上面的二选一) | sherpa-onnx-kws-zipformer-zh-en-3M-2025-12-20.tar.bz2 |
| 2 | ASR 语音识别模型 | sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2 |
| 3 | VAD 静音检测模型 | silero_vad_v5.onnx(下载后重命名为 silero_vad.onnx) |
| 4 | SenseVoice 多语言识别模型 | sherpa-onnx-sense-voice-zh-en-ja-ko-yue-int8-2024-07-17.tar.bz2 |
| 5 | Jarvis TTS 模型(贾维斯英文语音合成,内置角色必需) | jarvis.zip(ModelScope,下载后在 models/ 目录解压,得到 models/jarvis/en/en_GB/jarvis/high/jarvis-high.onnx 即正确);也可在 models/ 目录执行 git clone https://huggingface.co/jgkawell/jarvis |
| 6 | VITS MeloTTS 模型(林妹妹中英文语音合成,内置角色必需) | vits-melo-tts-zh_en.tar.bz2 |
| 7 | 声纹嵌入模型(唤醒声纹验证与录入必需) | 3dspeaker_speech_campplus_sv_zh-cn_16k-common.onnx |
可选模型(根据需求下载):
| # | 模型 | 下载链接 |
|---|---|---|
| 8 | Qwen3-ASR 离线识别模型(贾维斯默认 asr_mode: "offline" 使用,缺失自动回退流式识别) |
sherpa-onnx-qwen3-asr-0.6B-int8-2026-03-25.tar.bz2 |
| 9 | ZipVoice TTS 模型(零样本声音克隆) | sherpa-onnx-zipvoice-distill-int8-zh-en-emilia.tar.bz2 |
在 data/voices/ 目录下准备以下音效文件(WAV 格式):
| 文件名 | 用途 | 必需 |
|---|---|---|
wake.wav |
唤醒确认音效 | ✅ |
processing_jarvis.wav |
贾维斯处理中音效 | ✅ |
processing_linmeimei.wav |
林妹妹处理中音效 | ✅ |
thinking.wav |
思考中音效 | ✅ |
execute.wav |
执行指令音效 | ✅ |
success.wav |
操作成功音效 | ✅ |
error.wav |
操作失败音效 | ✅ |
exit.wav |
退出待机音效 | ✅ |
continue.wav |
继续对话音效 | ✅ |
system_ready.wav |
系统就绪音效 | ✅ |
blaster.wav |
特效音效 | 可选 |
waiting.wav |
等待输入音效 | 可选 |
jarvis_start_up.mp3 |
贾维斯参考音频(用于 ZipVoice 克隆) | 可选 |
提示:你可以自己录制这些音效,或使用现成的 JARVIS 风格音效文件。
macOS:
1.请从此处下载assistant_overlay.dmg、control_center.dmg
2.安装assistant_overlay.dmg和dmg、control_center.dmg
3.打开「control_center」app,根据提示录入声纹后,开启语音助手,喊出贾维斯
Windows:
1.请从此处下载 assistant_overlay.msix、control_center.msix
2.双击 assistant_overlay.msix 安装,首次安装会弹窗提示安装自签名测试证书,点击确认(需管理员权限,会弹 UAC)。control_center.msix 同理
若双击安装报错,也可用 PowerShell 安装(以管理员身份运行):
Add-AppxPackage -Path assistant_overlay.msix Add-AppxPackage -Path control_center.msix
3.从开始菜单打开「Control-Center」,根据提示录入声纹后,开启语音助手,喊出贾维斯
4.(从源码打包)如需自行打包 MSIX 安装包,在各 Flutter 项目目录下执行:
cd assistant_overlay
scripts\package.bat
cd control_center
scripts\package.bat打包脚本会自动执行 flutter build windows + dart run msix:create,生成的 .msix 在 build\windows\x64 unner\Release\ 目录下。
启动后,程序会显示"正在检测唤醒词...",此时直接说出唤醒词即可唤醒:
- 贾维斯:说"贾维斯"或"加维斯"
- 林妹妹:说"林妹妹何在"
唤醒词命中后还要过两道关,都通过才算唤醒成功:
- VAD 真人语音确认:抑制电脑外放的人声/TTS 误触发唤醒词;
- 声纹验证(强制):取唤醒前最近约 3 秒音频与已注册声纹比对,未注册声纹或不是本人,唤醒会被直接拒绝。首次使用请先在控制中心录入声纹(详见下方「声纹验证」)。
唤醒后助手会自动向主脑引擎发送一条 voice-assistant-wake-up-<本地时间戳> 消息,
由引擎返回的内容作为问候语播报(不再是写死的欢迎语)。问候在后台线程播报,期间再次说唤醒词可直接打断。听到问候后即可开始对话。
需在角色 system prompt 里加一条对该消息的应答规则,否则引擎可能把它当普通输入。 详见 hermes-assistant.md 第四节(OpenClaw 模式同样适用)。
唤醒后直接说出你的指令,例如:
- "今天天气怎么样?"
- "帮我设置一个明天早上8点的闹钟"
- "查一下我的日程"
助手会实时识别你的语音,播放 TTS 回复,并显示 HUD 动画。
- 30 秒无语音活动,助手会自动进入待机状态
- 待机后再次说出唤醒词即可重新唤醒
项目内置两个角色,你可以在对话中随时切换:
| 角色 | 风格 | 特点 |
|---|---|---|
| 贾维斯 | 专业、干练 | 英文 TTS(Piper,可叠金属感),Qwen3-ASR 离线识别(模型缺失自动回退流式),科技感 HUD |
| 林妹妹 | 亲切、俏皮 | 中文 TTS(VITS MeloTTS),流式中英双语识别,粉色主题 HUD |
如何切换:
直接说出目标角色的唤醒词即可——待机时喊"林妹妹何在"就切到林妹妹,喊"贾维斯"就切回贾维斯,运行时自动完成切换(含 TTS/HUD/识别模式),无需改配置、无需重启。
assistants.json 中的 "default" 字段只决定启动时默认加载哪个角色:
{ "default": "jarvis" }唤醒后自动进入连续对话模式,支持多轮指令:
你:"贾维斯"
助手:"At your service, sir. What do you need?"
你:"今天天气怎么样?"
助手:(播放天气信息)
你:"那明天呢?" ← 无需再次唤醒,直接说指令
助手:(播放明天天气)
你:"好的,帮我记下来" ← 继续对话
助手:(记录备忘录)
退出连续对话:
- 说出退出关键词(见下方"退出机制")
- 30 秒无语音活动自动待机
随时打断当前处理:
- 在助手正在回复或播放 TTS 时,再次说出唤醒词
- 助手会立即停止当前操作,重新识别你的新指令
示例:
你:"贾维斯"
助手:"At your service..."
你:"贾维斯!" ← 打断
助手:(停止播放,重新识别)
你:"算了,帮我查个邮件" ← 新指令
防误触:打断有冷却保护期,避免误触发。
退出只有两种情况:
1. 用户直接说退出关键词
说出退出关键词,助手会播放告别语并进入待机:
| 角色 | 退出关键词示例 |
|---|---|
| 贾维斯 | "dismissed"、"stand down"、"that's all"、"退下"、"你可以退下了"、"exit"、"quiet"、"SHUT UP" |
| 林妹妹 | "退下"、"退下吧"、"好了"、"行了"、"结束"、"你可以退下了" |
完整列表见 assistants.json 各角色的 exit_keywords 字段。
其中部分关键词会即时退出(不播放告别语):
- 贾维斯:"stand down"、"you may leave"
- 林妹妹:"退下吧"、"你可以退下了"
2. AI 判定用户有让助手待机的意图
当用户说的话虽然没有直接命中退出关键词,但 AI 判断用户想让助手退下时,会自动调用 API 远程退出:
curl -X POST http://127.0.0.1:18790/exit比如用户说"好了好了我知道了你去吧",AI 识别到待机意图后就会自动触发退出。
- 在
assistants.json的assistants数组中添加新角色:
{
"id": "your-assistant-id",
"name": "角色名称",
"enabled": true,
"visual": "jarvis",
"components": {
"feedback": "custom",
"visual": "custom",
"tts": "custom"
},
"keywords_file": "keywords/your-assistant.txt",
"asr_mode": "streaming",
"tts_config": {
"engine": "vits",
"model_dir": "models/vits-melo-tts-zh_en",
"speed": 1.0
},
"wake_lines": ["角色唤醒语1", "角色唤醒语2"],
"exit_lines": ["角色退出语1", "角色退出语2"],
"exit_keywords": ["退出关键词1", "退出关键词2"],
"instant_exit_keywords": ["即时退出1"],
"instant_exit_fuzzy": ["模糊匹配词1"],
"restart_keywords": ["重启", "重新启动"]
}字段说明:
-
components:选择该角色的反馈/视觉/TTS 实现。填jarvis复用贾维斯的内置实现,填custom走通用模板(src/assistants/custom_*.py),可再配合feedback_config(自定义音效文件、HUD 文案、通知前缀)和visual_config精调,参考assistants.json里林妹妹的写法。 -
asr_mode:该角色的语音识别模式,可选值:取值 识别方案 说明 streaming(默认)流式 Zipformer 中英双语 边说边出结果,低延迟,支持热词 sense_voiceSenseVoice 多语言(自动检测) VAD 断句,一次返回完整结果 sense_voice_enSenseVoice 英文模式 同上,仅英文 offlineQwen3-ASR 离线识别 需下载可选模型第 8 项 对应模型不可用时自动回退到流式模式,不会启动失败。
-
tts_config:TTS 引擎配置。engine/model_dir指定引擎与模型,speed调语速,贾维斯还支持metallic金属感后处理(见上方「贾维斯金属感语音」)。 -
restart_keywords:命中后重启整个语音助手(自动执行start.sh/start.bat),带幂等保护防止回声重复触发。
-
在
keywords/目录下创建对应的唤醒词文件(如keywords/your-assistant.txt) -
重启语音助手即可生效
唤醒词文件位于 keywords/ 目录,每个角色独立配置。
格式:
拼音 :灵敏度 #阈值 @唤醒词文本
示例(keywords/jarvis.txt):
j i a w e i s i :3.0 #0.05 @贾维斯
j i a w e i s :2.0 #0.05 @加维思
- 拼音:用空格分隔
- 灵敏度:数值越高越容易触发(推荐 2.0-3.0)
- 阈值:触发得分阈值(推荐 0.02-0.05)
- 唤醒词文本:显示在 HUD 上的文本
添加多个变体:
为提高识别率,可以添加多个拼音变体:
l i n m e i m e i h e z a i :3.0 #0.02 @林妹妹何在
l i n m e i m e i h e z a i :3.0 #0.02 @林妹妹何在
l i n m e i m e i z a i m a :3.0 #0.02 @林妹妹在吗
在 assistants.json 中配置三类退出关键词:
{
"exit_keywords": ["退下", "exit", "quiet"],
"instant_exit_keywords": ["退下吧", "stand down"],
"instant_exit_fuzzy": ["退一下", "step back"]
}- exit_keywords:普通退出,会播放告别语
- instant_exit_keywords:即时退出,立即退出
- instant_exit_fuzzy:模糊匹配,包含这些词就会触发
- 录制或下载 WAV 格式音效
- 放入
data/voices/目录,替换对应文件名 - 无需重启,下次播放时自动使用新音效
音效格式建议:16-bit, 44100Hz, 单声道,长度 0.5-2 秒
assistants.json 顶层 engine 字段决定用哪个主脑引擎对接大模型:
{
"engine": "openclaw", // 默认;可选 "hermes"
"default": "jarvis",
"assistants": [ ... ]
}openclaw(默认,缺省或未知值都回退到它):走 OpenClaw Gateway。hermes:本地 Hermes 作主脑,一角色一 profile 一网关。配置/启动/排错见 hermes-assistant.md。
assistants.json 顶层 overlay_debug_mode 为 true 时,召唤出来的 HUD 特效不再自动隐藏/清空,
方便对着调样式;正常使用保持 false。
{
"overlay_debug_mode": false,
"assistants": [ ... ]
}助手"被唤醒 → 退回待机"这两个时刻,可以联动触发一些系统动作。目前内置两项(均仅 macOS、软失败、退待机自动还原):
| 联动 | 开关 | 默认 | 依赖 |
|---|---|---|---|
| 唤醒时暂停正在播放的影视/音乐 | 自动(无需配置) | 开 | brew install media-control |
| 唤醒时把系统 Dock 切到自动隐藏 | dock_autohide_on_wake |
关 | macOS 自动化授权(见下) |
{
"dock_autohide_on_wake": true, // 顶层;改完需重启助手才生效
"assistants": [ ... ]
}两者都遵循「只还原我改的」:你本来就开着 Dock 自动隐藏、或当时没有媒体在播,助手绝不会擅自改动。
Dock 自动隐藏的授权坑(首次必看) 切 Dock 走的是 AppleScript 控制「系统事件」,需要 macOS 的自动化授权。由于助手是被控制中心 App 拉起的,授权弹窗会归到控制中心头上,因此:
- 控制中心的
Info.plist必须带NSAppleEventsUsageDescription(本仓库已加)——改的是源码,必须重新flutter build macos并覆盖安装/Applications/control_center.app才进包;- 打开开关后重启助手,首次唤醒时会弹「控制中心想要控制"系统事件"」,点好即永久生效;
- 若死活不弹窗,多半是缓存了静默拒绝,执行
tccutil reset AppleEvents cn.rubintry.assistant.ctrl.center.controlCenter清掉再重试。注意:autohide 只是"鼠标离开屏幕边缘就收起",把鼠标怼到屏幕底边 Dock 仍会冒出来——要彻底不露需用 overlay 窗口层级遮挡,暂未实现。
想加新联动? 联动注册表在
src/lifecycle.py:实现LifecycleHook的on_wake/on_standby并register即可,主循环无需改动(is_awake已是边沿触发的 property)。媒体暂停、Dock 隐藏都是这么接入的。
声纹验证已是强制功能:每次唤醒词命中后,都会取最近约 3 秒音频与已注册声纹比对,通过才放行唤醒。行为规则:
- 已注册声纹:只有声纹匹配的说话人能唤醒;验证被拒绝时继续待机,并向控制中心推送一条「声纹验证被拒绝」通知。
- 未注册任何声纹:助手拒绝一切唤醒,需先录入声纹才能使用(启动日志会给出提示)。
- 声纹模型文件缺失:跳过验证直接放行(此时不安全,建议按模型表第 7 项下载
3dspeaker_speech_campplus_sv_zh-cn_16k-common.onnx放入models/,缺模型时录入也会报错No graph was found in the protobuf)。 - 渐进更新:验证通过后,连续对话中的语音会持续微调该用户的声纹嵌入,越用越准(嵌入缓存在录入 JSON 里)。
如何录入:
macOS / Windows 用户:直接在「控制中心」App 内按提示录入即可,无需手动跑脚本。录入期间控制中心会自动调用勿扰接口暂停唤醒(见下方 API 接口),避免反复念"贾维斯"误唤醒。
命令行录入:
./scripts/enroll_speaker.py按提示朗读"贾维斯"即可完成录入,样本保存在 data/enrollment/ 目录。录入完成后重启语音助手生效。
项目预配置了技术热词,你也可以自定义:
hotwords.txt:中文热词(技术术语、编程语言等)hotwords_en.txt:英文热词(框架、工具等)
添加热词:
在对应文件中按行添加:
Transformer
RAG
LoRA
FastAPI
重启语音助手后自动生效。
文本纠错兜底(text_corrections.txt):
sherpa 热词对 cjkchar+bpe 模型下 OOV 英文整词(词表里没有的词,如人名、新产品名)几乎无效——整词 token 找不到会被静默跳过。这类词请写进根目录 text_corrections.txt,在识别结果送 HUD/大模型之前做整词替换(大小写不敏感):
# 格式:<误识别> : <正确>
open cloud : OpenClaw
贾维尔 : 贾维斯
文件不存在则跳过(纠错是可选功能),启动时加载。
本地 HTTP 接口监听 127.0.0.1:18790(控制中心也通过它联动语音助手)。
远程退出:
curl -X POST http://127.0.0.1:18790/exit返回:
{"status": "ok"}勿扰模式(声纹录入时暂停唤醒):
录入声纹时若不静音唤醒词,反复念“贾维斯”会误唤醒。控制中心“声纹注册”会自动调用, 也可手动控制:
curl -X POST http://127.0.0.1:18790/dnd # 进入勿扰:暂停唤醒词响应
curl -X POST http://127.0.0.1:18790/dnd/disable # 解除勿扰:恢复唤醒端口被占导致接口未监听时勿扰不会生效(控制中心会在录入日志里给出警告)。 主程序启动绑定该端口已带重试,
start.sh也会预清理 18790。
摄像头抓帧(供 Hermes「用摄像头看看我」):
GET /camera/snapshot 抓一帧并直接返回 JPEG,主脑(Hermes/OpenClaw)可经此拿到画面再交给 vision_analyze:
curl -s http://127.0.0.1:18790/camera/snapshot -o /tmp/cam.jpg # 成功:JPEG 落地
# 失败返回 JSON:{"error": "..."}(摄像头不可用 503 / 抓帧失败 500)- 抓帧复用仓库自带的 imageio-ffmpeg(静态 ffmpeg 含 avfoundation),免装系统工具;实现见 src/camera.py,默认 1920x1080@30、丢弃前 8 帧预热、8s 超时软失败。
- 首次需授权:抓帧进程由控制中心拉起,摄像头权限归控制中心。已在其
Info.plist加NSCameraUsageDescription——改的是源码,需重新flutter build macos覆盖安装/Applications/control_center.app才进包;之后首次调用会弹「控制中心想使用摄像头」,点允许即永久生效(与 Dock 自动隐藏的授权同理)。 - 仅 macOS;非 macOS 或未授权超时均返回错误、不影响其他功能。
- 先确认声纹:声纹验证是强制的——未注册声纹会拒绝一切唤醒,非本人喊也会被拒(终端会打印
[声纹] 唤醒被拒绝)。先在控制中心录入声纹 - 检查麦克风设备是否正常:启动时会列出可用设备
- 调整唤醒词灵敏度:在
keywords/*.txt中提高灵敏度数值(2.0 → 3.0) - 添加更多拼音变体到唤醒词文件
- 确保环境安静,背景噪音会影响识别;另外唤醒前有 VAD 真人语音确认,电脑外放的人声会被有意忽略
不会独占采样率。输入流按 48kHz 打开(与大多数应用/系统默认一致,可共存),内部用 soxr 重采样到 16kHz 再喂 sherpa 模型;没装 soxr 时回退原始采样率,识别精度会下降。另外音频流有看门狗:静默停滞超过 15 秒会自动重建流,无需手动重启。
启动程序时会显示可用麦克风设备列表,以及默认使用的设备名称。
- 确保已构建 Flutter 项目:
cd assistant_overlay && flutter build macos --debug - 检查端口 17889 是否被占用
- 查看控制台是否有 TCP 连接错误
- 检查 TTS 模型是否正确下载到
models/目录 - 确认音效文件存在于
data/voices/ - 查看控制台错误信息,确认模型路径正确
- 如果报
No module named 'piper',请确认安装的是piper-tts而非piper:pip uninstall piper -y # 卸载错误包(pypiper) pip install piper-tts # 安装正确的 Piper TTS 包
piper是一个无关的管道工具包(pypiper),正确的 TTS 包名是piper-tts
在 assistants.json 中修改对应角色的 TTS 配置(需要代码中支持多引擎切换)。
是的,项目支持 Windows 平台。使用 scripts\start.bat 启动,部分功能(如 HUD 窗口)可能需要调整。
Windows 音频说明:Windows 下使用
sounddevice+soundfile进行音频播放(与 macOS 的afplay方案不同),无需额外安装pygame。
运行日志在 logs/ 目录(jarvis_<时间>_<pid>.log)。日志文件只记录 ERROR 级及以上
(含未捕获异常的 traceback),其余正常输出一律不落盘——所以排查正常流程要看终端/控制中心
的实时输出,文件只用来留底错误。每类日志各保留最近若干份,旧的自动清理。
assistant-x-openclaw/
├── src/ # 源代码
│ ├── main.py # 主程序:唤醒 + 声纹验证 + 识别 + 对话流程 + 本地 API
│ ├── tts.py # TTS 统一接口
│ ├── tts_vits.py # VITS TTS 引擎
│ ├── openclaw_bridge_websocket.py # OpenClaw Gateway 桥接(engine=openclaw)
│ ├── hermes_bridge.py # Hermes 桥接(engine=hermes,详见 hermes-assistant.md)
│ ├── lifecycle.py # 激活联动钩子注册表(唤醒/休眠边沿派发)
│ ├── media_pause.py # 激活联动:唤醒时暂停媒体
│ ├── dock_control.py # 激活联动:唤醒时隐藏 Dock(macOS)
│ ├── camera.py # 摄像头抓帧(GET /camera/snapshot,macOS)
│ ├── anti_spoof.py # 活体检测(AASIST,开发中未启用)
│ ├── notify_bridge.py # 向控制中心推送通知(如声纹拒绝)
│ ├── log_setup.py # 日志:ERROR 落盘 + diag 诊断日志
│ ├── audio.py # 音频播放模块
│ └── assistants/ # 角色系统
│ ├── feedback.py # 反馈系统基类(音效 + HUD + 通知)
│ ├── visual.py # HUD 视觉基类
│ ├── tts.py # 角色 TTS 基类
│ ├── jarvis/ # 贾维斯角色(Piper/ZipVoice TTS、visual、feedback)
│ ├── lin_meimei/ # 林妹妹角色
│ └── custom_*.py # 自定义角色模板(components 填 "custom" 时使用)
├── scripts/ # 工具脚本
│ ├── start.sh # 启动脚本(macOS:合并唤醒词 + 清理端口 + 拉起 HUD/主程序)
│ ├── start.bat # 启动脚本(Windows)
│ ├── enroll_speaker.py # 声纹录入工具
│ └── hermes_provision.py # Hermes profile 初始化(engine=hermes 用)
├── assistant_overlay/ # Flutter HUD 视觉特效应用
├── control_center/ # Flutter 控制中心应用(声纹录入 / 启停 / 日志,macOS & Windows)
├── prompts/ # 角色 System Prompt(jarvis/SOUL.md)
├── skills/ # 主脑技能(browser-cdp / desktop-control)
├── data/
│ ├── voices/ # 音效文件
│ └── enrollment/ # 已录入的声纹样本
├── models/ # ONNX 模型文件
├── keywords/ # 唤醒词配置
│ ├── jarvis.txt
│ ├── lin-meimei.txt
│ └── global.txt # 自动生成,合并所有唤醒词
├── assistants.json # 角色与引擎配置文件
├── hotwords.txt # 中文热词
├── hotwords_en.txt # 英文热词
├── text_corrections.txt # 文本纠错表(OOV 英文整词兜底)
├── .env # 环境变量
└── requirements.txt # Python 依赖
开源协议: MIT License
作者: Rubintry
日期: 2026

