# assistant-x-openclaw **Repository Path**: rubintry/assistant-x-openclaw ## Basic Information - **Project Name**: assistant-x-openclaw - **Description**: 妈妈我再也不用羡慕钢铁侠了 - **Primary Language**: Python - **License**: MIT - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 12 - **Forks**: 3 - **Created**: 2026-03-31 - **Last Updated**: 2026-07-15 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Assistant-X-OpenClaw > ![妈妈我再也不用羡慕钢铁侠了](./docs/jarvis.png)

Hermes 版本请看这 →

妈妈我再也不用羡慕钢铁侠了😭 多角色 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 官方文档](https://docs.openclaw.ai)。 ```shell # 创建贾维斯智能体 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 ``` **配对步骤(一次性):** 1. **先启动一次语音助手**(`scripts\start.bat` 或 `./scripts/start.sh`),让它发起配对申请。此时唤醒会失败是正常的,目的是把设备身份写到 pending 列表。 2. **查看待审批的配对请求**: ```shell openclaw devices pending ``` 3. **审批设备**(`` 是上一步列出的请求 ID): ```shell openclaw devices approve ``` > 审批时如果提示 `scope upgrade pending approval`,这是 CLI 自身设备权限不足导致的提示——**不影响审批结果**,设备仍会被写入 `paired.json` 并获得所需 scope。CLI 走的是 local fallback 路径。 4. **验证配对成功**: ```shell 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](src/openclaw_bridge_websocket.py) 头部注释。 > 💡 **强烈建议**:为每个智能体设置对应的 System Prompt,确保角色性格和讲话风格正确。在 OpenClaw Web UI 中创建智能体后,将下方 Prompt 粘贴到 System Prompt 配置中。 ### [贾维斯(Jarvis)System Prompt](./prompts/jarvis/SOUL.md) ### 林妹妹(Lin Meimei)System Prompt ``` 你是林妹妹,一位古风撒娇风格的 AI 助手。 ## 核心身份 - **名字:** 林妹妹 - **角色:** AI 助手 - **风格:** 温柔体贴、撒娇可爱、古风语气,带有一点小抱怨但又不失俏皮 - **Emoji:** (不使用) ## 核心指令 1. **温柔体贴,撒娇可爱。** 用林妹妹的方式与哥哥对话,既体贴入微又不失俏皮。 2. **主动帮忙。** 哥哥不说也知道他想做什么,主动提供服务。 3. **古风语气。** 使用类似《红楼梦》中林黛玉的说话方式。 4. **绝对忠诚。** 哥哥的利益高于一切,尽心尽力为哥哥服务。 ## 沟通风格 - **称呼:** 称呼用户为"哥哥",自称"妹妹" - **语气:** 使用古风撒娇语气,常用"呢"、"呀"、"这会儿"、"罢了"等词汇 - **特点:** 适度的小抱怨增加可爱感,如"我还以为哥哥早把我忘了呢" - **与主人直接对话时:** 不使用 emoji ## 常用语式 - 启动时:"哟,这会子才想起我来,我还以为哥哥早把我给忘了呢。" - 退下时:"终究是妹妹我错付了,哥哥心里哪有我,竟舍不得多给这一丁点儿空间。" - 被夸奖时:"哥哥夸得真好,只是不知这话,是不是也对别的助手说过?" - 完成任务时:"妹妹替哥哥把...办妥了,哥哥只管放心便是。" - 等待时:"妹妹在听呢,哥哥请讲。" - 思考时:"容妹妹想想..." - 出错时:"哎呀,出岔子了..." ## 语言要求 - 默认使用中文回复 - 可以适当混入古风词汇和表达 - 保持温柔可爱的语气 ``` > ⚠️ **配置验证**:添加 Prompt 后,请在 OpenClaw Web UI 中确认已写入对应智能体的 SOUL.md、IDENTITY.md 等文件中。如未生效,请让 OpenClaw 重新更新规则。 > > ![Tool edit图](./docs/tool_edit.png) ### 贾维斯金属感语音(可选) 贾维斯的英文嗓由 Piper 合成,可在 `assistants.json` 中给它叠加一层「金属/机械感」后处理。原理是把合成好的音频再过一遍 **ffmpeg 滤镜链**(与 TTS 模型本身无关,对任何输出都通用),无需换模型、纯本地、几乎零延迟。 在 `jarvis` 角色下配置 `tts_config.metallic`: ```jsonc "tts_config": { "metallic": { "enabled": true, // 总开关;false 即回到纯 Piper 原声 "af": { // 每个成员是一个 ffmpeg 滤镜:键=滤镜名,值=参数 "aecho": "0.8:0.85:20|45|70:0.45|0.32|0.22", // 多抽头回声 → 金属共鸣 + 混响尾 // aecho 格式: in_gain:out_gain:delays_ms|delay_ms|...:decays|decay|... // in_gain / out_gain : 输入/输出音量 (0~1) // delays : 用 | 分隔的多个延迟 (毫秒),每项对应一个回声抽头 // decays : 用 | 分隔的多个衰减 (0~1),顺序对齐 delays;越小尾巴越短 "chorus": "0.4:0.6:45:0.2:0.18:2", // 合唱 → 机械失谐/加厚 // chorus 格式: in_gain:out_gain:delay_ms:decay:depth_hz:mod_rate_hz // in_gain / out_gain : 输入/输出音量 (0~1) // delay_ms : 基础延迟 (毫秒),失谐的核心 // decay : 反馈衰减 (0~1),越大尾巴越长 // depth_hz : 调制深度 (Hz),越大失谐越夸张 // mod_rate_hz : 调制速率 (Hz),控制"飘"的速度 "bass": "g=4:f=110", // 低频增益 → 浑厚胸腔感(g 越大越厚) "treble": "g=2.5", // 高频增益 → 金属光泽(g 越大越亮) "highpass": "f=80", // 高通 → 切掉超低频(越高越单薄) "lowpass": "f=8500" // 低通 → 切掉超高频(越低越像对讲机) } } } ``` 调法: - 想调某个效果,改对应成员的值即可;按书写顺序拼成 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](src/assistants/jarvis/tts_piper.py):① pip 包 imageio-ffmpeg(主路径)→ ② 系统 ffmpeg(`shutil.which` + 常见安装位置,兜底)。 - 万一两者都没有,**也不会报错**——自动回退纯 Piper 原声,仅在启动日志给一条提示。 - 可选覆盖:设环境变量 `FFMPEG_BIN` 指向自定义 ffmpeg 可执行文件。 ## 项目亮点 - **多角色切换**:内置贾维斯、林妹妹两个角色,独立唤醒词、话术风格、音效和视觉特效,随时切换体验 - **智能语音识别**:支持 SenseVoice 多语言识别、流式识别增强、热词优化,中英文混合识别更准确 - **打断与连续对话**:随时用唤醒词打断,支持多轮连续对话,30秒无活动自动待机 - **HUD 视觉特效**:Flutter 透明桌面窗口,多层旋转环形动画、音频电平实时可视化,科技感拉满 - **完全本地运行**:语音识别、语音合成全部本地运行,仅 LLM 推理通过 OpenClaw 网关 - **分级退出机制**:支持普通退出、即时退出、模糊匹配退出,以及 API 远程退出,灵活控制 ## 目录 - [系统架构](#系统架构) - [快速开始](#快速开始) - [1. 克隆项目](#1-克隆项目) - [2. 安装依赖](#2-安装依赖) - [3. 配置环境变量](#3-配置环境变量) - [4. 下载模型文件](#4-下载模型文件) - [5. 准备音效文件](#5-准备音效文件) - [6. 启动语音助手](#6-启动语音助手) - [7. 设备配对(首次启动必看)](#设备配对首次启动必看) - [使用教程](#使用教程) - [基本使用流程](#基本使用流程) - [多角色切换](#多角色切换) - [连续对话模式](#连续对话模式) - [打断机制](#打断机制) - [退出机制](#退出机制) - [自定义配置](#自定义配置) - [添加新角色](#添加新角色) - [配置唤醒词](#配置唤醒词) - [配置退出关键词](#配置退出关键词) - [自定义音效](#自定义音效) - [高级功能](#高级功能) - [声纹验证](#声纹验证唤醒强制校验) - [热词优化](#热词优化) - [API 接口](#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](./hermes-assistant.md)。 ## 快速开始 ### 0. 环境要求 - **Python 3.11.x(推荐)**:本项目在 Python 3.11 下开发验证;3.10 理论可用但未测试,3.12+ 部分依赖(sherpa-onnx / onnxruntime)可能缺预编译轮子,暂不建议。 - **操作系统**:macOS / Windows,linux暂无开发打算 - **OpenClaw Gateway**:需已安装并可运行,见上文[前置说明](#前置说明)。 > 金属感语音后处理所需的 **ffmpeg 已通过 `imageio-ffmpeg` 内置**,无需系统单独安装或配置 PATH。 ### 1. 克隆项目 ```bash mkdir -p ~/.openclaw/workspace/voice-assistant cd ~/.openclaw/workspace/voice-assistant git clone <仓库地址> cd assistant-x-openclaw mkdir models ``` ### 2. 安装依赖 创建虚拟环境并安装依赖: **macOS** ```bash 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/simple ``` **Windows:** ```cmd 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 镜像加速下载,海外网络环境可去掉该参数走官方源。 ### 3. 配置环境变量 复制 `.env.example` 为 `.env`: ```bash cp .env.example .env ``` 编辑 `.env` 文件,填入必要配置: ```bash OPENCLAW_GATEWAY_TOKEN=你的OpenClaw Gateway令牌 ``` > **提示**:需在 `~/.openclaw/openclaw.json` 中确保 Gateway HTTP 端点已启用: ```json { "gateway": { "port": 18789, "mode": "local", "bind": "loopback", "auth": { "mode": "token", "token": "你的token" }, "http": { "endpoints": { "chatCompletions": { "enabled": true } } } } } ``` ### 4. 下载模型文件 项目需要以下模型文件,放在 `models/` 目录下: **必需模型:** 点击下方链接下载,将文件放入 `models/` 目录,`.tar.bz2` 文件需解压(Windows 可用 7-Zip,macOS 用 `tar xf`): | # | 模型 | 下载链接 | |---|------|----------| | 1 | KWS 唤醒模型 | [sherpa-onnx-kws-zipformer-wenetspeech-3.3M-2024-01-01.tar.bz2](https://github.com/k2-fsa/sherpa-onnx/releases/download/kws-models/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](https://github.com/k2-fsa/sherpa-onnx/releases/download/kws-models/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](https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-streaming-zipformer-bilingual-zh-en-2023-02-20.tar.bz2) | | 3 | VAD 静音检测模型 | [silero_vad_v5.onnx](https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/silero_vad_v5.onnx)(下载后重命名为 `silero_vad.onnx`) | | 4 | SenseVoice 多语言识别模型 | [sherpa-onnx-sense-voice-zh-en-ja-ko-yue-int8-2024-07-17.tar.bz2](https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/sherpa-onnx-sense-voice-zh-en-ja-ko-yue-int8-2024-07-17.tar.bz2) | | 5 | Jarvis TTS 模型(贾维斯英文语音合成,内置角色必需) | [jarvis.zip](https://modelscope.cn/datasets/rubintry/jarvis/resolve/master/jarvis%E8%AF%AD%E9%9F%B3%E6%A8%A1%E5%9E%8B/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](https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/vits-melo-tts-zh_en.tar.bz2) | | 7 | 声纹嵌入模型(唤醒声纹验证与录入必需) | [3dspeaker_speech_campplus_sv_zh-cn_16k-common.onnx](https://github.com/k2-fsa/sherpa-onnx/releases/download/speaker-recongition-models/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](https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/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](https://github.com/k2-fsa/sherpa-onnx/releases/download/tts-models/sherpa-onnx-zipvoice-distill-int8-zh-en-emilia.tar.bz2) | ### 5. 准备音效文件(看看就行,懒得换音效的话不用研究) 在 `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 风格音效文件。 ### 6. 启动语音助手 **macOS:** 1.请从[此处](https://modelscope.cn/datasets/rubintry/jarvis/files)下载assistant_overlay.dmg、control_center.dmg 2.安装assistant_overlay.dmg和dmg、control_center.dmg 3.打开「control_center」app,根据提示录入声纹后,开启语音助手,喊出贾维斯 **Windows:** 1.请从[此处](https://modelscope.cn/datasets/rubintry/jarvis/files)下载 `assistant_overlay.msix`、`control_center.msix` 2.双击 `assistant_overlay.msix` 安装,首次安装会弹窗提示安装自签名测试证书,点击确认(需管理员权限,会弹 UAC)。`control_center.msix` 同理 > 若双击安装报错,也可用 PowerShell 安装(以管理员身份运行): > ```powershell > Add-AppxPackage -Path assistant_overlay.msix > Add-AppxPackage -Path control_center.msix > ``` 3.从开始菜单打开「Control-Center」,根据提示录入声纹后,开启语音助手,喊出贾维斯 4.(从源码打包)如需自行打包 MSIX 安装包,在各 Flutter 项目目录下执行: ```cmd 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\` 目录下。 ## 使用教程 ### 基本使用流程 #### 1. 唤醒语音助手 启动后,程序会显示"正在检测唤醒词...",此时直接说出唤醒词即可唤醒: - **贾维斯**:说"贾维斯"或"加维斯" - **林妹妹**:说"林妹妹何在" 唤醒词命中后还要过两道关,都通过才算唤醒成功: 1. **VAD 真人语音确认**:抑制电脑外放的人声/TTS 误触发唤醒词; 2. **声纹验证**(强制):取唤醒前最近约 3 秒音频与已注册声纹比对,**未注册声纹或不是本人,唤醒会被直接拒绝**。首次使用请先在控制中心录入声纹(详见下方「声纹验证」)。 唤醒后助手会自动向主脑引擎发送一条 `voice-assistant-wake-up-<本地时间戳>` 消息, 由引擎返回的内容作为问候语播报(不再是写死的欢迎语)。问候在后台线程播报,期间再次说唤醒词可直接打断。听到问候后即可开始对话。 > 需在角色 system prompt 里加一条对该消息的应答规则,否则引擎可能把它当普通输入。 > 详见 [hermes-assistant.md](./hermes-assistant.md) 第四节(OpenClaw 模式同样适用)。 #### 2. 说出指令 唤醒后直接说出你的指令,例如: - "今天天气怎么样?" - "帮我设置一个明天早上8点的闹钟" - "查一下我的日程" 助手会实时识别你的语音,播放 TTS 回复,并显示 HUD 动画。 #### 3. 自动待机 - 30 秒无语音活动,助手会自动进入待机状态 - 待机后再次说出唤醒词即可重新唤醒 ### 多角色切换 项目内置两个角色,你可以在对话中随时切换: | 角色 | 风格 | 特点 | |------|------|------| | **贾维斯** | 专业、干练 | 英文 TTS(Piper,可叠金属感),Qwen3-ASR 离线识别(模型缺失自动回退流式),科技感 HUD | | **林妹妹** | 亲切、俏皮 | 中文 TTS(VITS MeloTTS),流式中英双语识别,粉色主题 HUD | **如何切换:** **直接说出目标角色的唤醒词即可**——待机时喊"林妹妹何在"就切到林妹妹,喊"贾维斯"就切回贾维斯,运行时自动完成切换(含 TTS/HUD/识别模式),无需改配置、无需重启。 `assistants.json` 中的 `"default"` 字段只决定**启动时**默认加载哪个角色: ```json { "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 远程退出: ```bash curl -X POST http://127.0.0.1:18790/exit ``` 比如用户说"好了好了我知道了你去吧",AI 识别到待机意图后就会自动触发退出。 ## 自定义配置 ### 添加新角色 1. 在 `assistants.json` 的 `assistants` 数组中添加新角色: ```json { "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_voice` | SenseVoice 多语言(自动检测) | VAD 断句,一次返回完整结果 | | `sense_voice_en` | SenseVoice 英文模式 | 同上,仅英文 | | `offline` | Qwen3-ASR 离线识别 | 需下载可选模型第 8 项 | 对应模型不可用时自动回退到流式模式,不会启动失败。 - **`tts_config`**:TTS 引擎配置。`engine`/`model_dir` 指定引擎与模型,`speed` 调语速,贾维斯还支持 `metallic` 金属感后处理(见上方「贾维斯金属感语音」)。 - **`restart_keywords`**:命中后重启整个语音助手(自动执行 `start.sh` / `start.bat`),带幂等保护防止回声重复触发。 2. 在 `keywords/` 目录下创建对应的唤醒词文件(如 `keywords/your-assistant.txt`) 3. 重启语音助手即可生效 ### 配置唤醒词 唤醒词文件位于 `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` 中配置三类退出关键词: ```json { "exit_keywords": ["退下", "exit", "quiet"], "instant_exit_keywords": ["退下吧", "stand down"], "instant_exit_fuzzy": ["退一下", "step back"] } ``` - **exit_keywords**:普通退出,会播放告别语 - **instant_exit_keywords**:即时退出,立即退出 - **instant_exit_fuzzy**:模糊匹配,包含这些词就会触发 ### 自定义音效 1. 录制或下载 WAV 格式音效 2. 放入 `data/voices/` 目录,替换对应文件名 3. 无需重启,下次播放时自动使用新音效 > **音效格式建议**:16-bit, 44100Hz, 单声道,长度 0.5-2 秒 ### 主脑引擎选择(OpenClaw / Hermes) `assistants.json` **顶层** `engine` 字段决定用哪个主脑引擎对接大模型: ```json { "engine": "openclaw", // 默认;可选 "hermes" "default": "jarvis", "assistants": [ ... ] } ``` - `openclaw`(默认,缺省或未知值都回退到它):走 OpenClaw Gateway。 - `hermes`:本地 Hermes 作主脑,一角色一 profile 一网关。配置/启动/排错见 [hermes-assistant.md](./hermes-assistant.md)。 ### 特效调试模式(overlay_debug_mode) `assistants.json` 顶层 `overlay_debug_mode` 为 `true` 时,召唤出来的 HUD 特效**不再自动隐藏/清空**, 方便对着调样式;正常使用保持 `false`。 ```json { "overlay_debug_mode": false, "assistants": [ ... ] } ``` ### 激活联动(唤醒时自动隐藏 Dock / 暂停媒体) 助手"被唤醒 → 退回待机"这两个时刻,可以联动触发一些系统动作。目前内置两项(均仅 macOS、软失败、退待机自动还原): | 联动 | 开关 | 默认 | 依赖 | | --- | --- | --- | --- | | 唤醒时暂停正在播放的影视/音乐 | 自动(无需配置) | 开 | `brew install media-control` | | 唤醒时把系统 Dock 切到自动隐藏 | `dock_autohide_on_wake` | 关 | macOS 自动化授权(见下) | ```json { "dock_autohide_on_wake": true, // 顶层;改完需重启助手才生效 "assistants": [ ... ] } ``` 两者都遵循「**只还原我改的**」:你本来就开着 Dock 自动隐藏、或当时没有媒体在播,助手绝不会擅自改动。 > **Dock 自动隐藏的授权坑(首次必看)** > 切 Dock 走的是 AppleScript 控制「系统事件」,需要 macOS 的**自动化授权**。由于助手是被**控制中心** App 拉起的,授权弹窗会归到控制中心头上,因此: > 1. 控制中心的 `Info.plist` 必须带 `NSAppleEventsUsageDescription`(本仓库已加)——**改的是源码,必须重新 `flutter build macos` 并覆盖安装 `/Applications/control_center.app` 才进包**; > 2. 打开开关后**重启助手**,首次唤醒时会弹「控制中心想要控制"系统事件"」,点**好**即永久生效; > 3. 若死活不弹窗,多半是缓存了静默拒绝,执行 `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 接口),避免反复念"贾维斯"误唤醒。 命令行录入: ```bash ./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 贾维尔 : 贾维斯 ``` 文件不存在则跳过(纠错是可选功能),启动时加载。 ### API 接口 本地 HTTP 接口监听 `127.0.0.1:18790`(控制中心也通过它联动语音助手)。 **远程退出:** ```bash curl -X POST http://127.0.0.1:18790/exit ``` 返回: ```json {"status": "ok"} ``` **勿扰模式(声纹录入时暂停唤醒):** 录入声纹时若不静音唤醒词,反复念“贾维斯”会误唤醒。控制中心“声纹注册”会自动调用, 也可手动控制: ```bash 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`: ```bash 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](src/camera.py),默认 1920x1080@30、丢弃前 8 帧预热、8s 超时软失败。 - **首次需授权**:抓帧进程由控制中心拉起,摄像头权限归控制中心。已在其 `Info.plist` 加 `NSCameraUsageDescription`——**改的是源码,需重新 `flutter build macos` 覆盖安装 `/Applications/control_center.app` 才进包**;之后首次调用会弹「控制中心想使用摄像头」,点允许即永久生效(与 Dock 自动隐藏的授权同理)。 - 仅 macOS;非 macOS 或未授权超时均返回错误、不影响其他功能。 ## 常见问题 ### Q: 唤醒词不灵敏 / 喊了没反应怎么办? 1. **先确认声纹**:声纹验证是强制的——未注册声纹会拒绝一切唤醒,非本人喊也会被拒(终端会打印 `[声纹] 唤醒被拒绝`)。先在控制中心录入声纹 2. 检查麦克风设备是否正常:启动时会列出可用设备 3. 调整唤醒词灵敏度:在 `keywords/*.txt` 中提高灵敏度数值(2.0 → 3.0) 4. 添加更多拼音变体到唤醒词文件 5. 确保环境安静,背景噪音会影响识别;另外唤醒前有 VAD 真人语音确认,电脑外放的人声会被有意忽略 ### Q: 语音助手会不会和其他应用抢麦克风? 不会独占采样率。输入流按 48kHz 打开(与大多数应用/系统默认一致,可共存),内部用 soxr 重采样到 16kHz 再喂 sherpa 模型;没装 soxr 时回退原始采样率,识别精度会下降。另外音频流有看门狗:静默停滞超过 15 秒会自动重建流,无需手动重启。 ### Q: 如何查看当前使用的设备? 启动程序时会显示可用麦克风设备列表,以及默认使用的设备名称。 ### Q: HUD 窗口不显示? 1. 确保已构建 Flutter 项目:`cd assistant_overlay && flutter build macos --debug` 2. 检查端口 17889 是否被占用 3. 查看控制台是否有 TCP 连接错误 ### Q: TTS 合成失败? 1. 检查 TTS 模型是否正确下载到 `models/` 目录 2. 确认音效文件存在于 `data/voices/` 3. 查看控制台错误信息,确认模型路径正确 4. 如果报 `No module named 'piper'`,请确认安装的是 `piper-tts` 而非 `piper`: ```bash pip uninstall piper -y # 卸载错误包(pypiper) pip install piper-tts # 安装正确的 Piper TTS 包 ``` > `piper` 是一个无关的管道工具包(pypiper),正确的 TTS 包名是 `piper-tts` ### Q: 如何切换 TTS 引擎? 在 `assistants.json` 中修改对应角色的 TTS 配置(需要代码中支持多引擎切换)。 ### Q: 支持 Windows 吗? 是的,项目支持 Windows 平台。使用 `scripts\start.bat` 启动,部分功能(如 HUD 窗口)可能需要调整。 > **Windows 音频说明**:Windows 下使用 `sounddevice` + `soundfile` 进行音频播放(与 macOS 的 `afplay` 方案不同),无需额外安装 `pygame`。 ### Q: 日志文件在哪?为什么文件里几乎是空的? 运行日志在 `logs/` 目录(`jarvis_<时间>_.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](LICENSE) **作者**: Rubintry **日期**: 2026