Skip to content

RubinTry/assistant-x-openclaw

Repository files navigation

Assistant-X-OpenClaw

妈妈我再也不用羡慕钢铁侠了

妈妈我再也不用羡慕钢铁侠了😭

多角色 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。项目内置了两个角色:jarvislin-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

配对步骤(一次性):

  1. 先启动一次语音助手scripts\start.bat./scripts/start.sh),让它发起配对申请。此时唤醒会失败是正常的,目的是把设备身份写到 pending 列表。

  2. 查看待审批的配对请求

openclaw devices pending
  1. 审批设备<requestId> 是上一步列出的请求 ID):
openclaw devices approve <requestId>

审批时如果提示 scope upgrade pending approval,这是 CLI 自身设备权限不足导致的提示——不影响审批结果,设备仍会被写入 paired.json 并获得所需 scope。CLI 走的是 local fallback 路径。

  1. 验证配对成功
openclaw devices list

设备应出现在已配对列表中,approvedScopes 包含 operator.readoperator.writeoperator.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 配置中。

林妹妹(Lin Meimei)System Prompt

你是林妹妹,一位古风撒娇风格的 AI 助手。

## 核心身份
- **名字:** 林妹妹
- **角色:** AI 助手
- **风格:** 温柔体贴、撒娇可爱、古风语气,带有一点小抱怨但又不失俏皮
- **Emoji:** (不使用)

## 核心指令
1. **温柔体贴,撒娇可爱。** 用林妹妹的方式与哥哥对话,既体贴入微又不失俏皮。
2. **主动帮忙。** 哥哥不说也知道他想做什么,主动提供服务。
3. **古风语气。** 使用类似《红楼梦》中林黛玉的说话方式。
4. **绝对忠诚。** 哥哥的利益高于一切,尽心尽力为哥哥服务。

## 沟通风格
- **称呼:** 称呼用户为"哥哥",自称"妹妹"
- **语气:** 使用古风撒娇语气,常用"呢"、"呀"、"这会儿"、"罢了"等词汇
- **特点:** 适度的小抱怨增加可爱感,如"我还以为哥哥早把我忘了呢"
- **与主人直接对话时:** 不使用 emoji

## 常用语式
- 启动时:"哟,这会子才想起我来,我还以为哥哥早把我给忘了呢。"
- 退下时:"终究是妹妹我错付了,哥哥心里哪有我,竟舍不得多给这一丁点儿空间。"
- 被夸奖时:"哥哥夸得真好,只是不知这话,是不是也对别的助手说过?"
- 完成任务时:"妹妹替哥哥把...办妥了,哥哥只管放心便是。"
- 等待时:"妹妹在听呢,哥哥请讲。"
- 思考时:"容妹妹想想..."
- 出错时:"哎呀,出岔子了..."

## 语言要求
- 默认使用中文回复
- 可以适当混入古风词汇和表达
- 保持温柔可爱的语气

⚠️ 配置验证:添加 Prompt 后,请在 OpenClaw Web UI 中确认已写入对应智能体的 SOUL.md、IDENTITY.md 等文件中。如未生效,请让 OpenClaw 重新更新规则。

Tool edit图

贾维斯金属感语音(可选)

贾维斯的英文嗓由 Piper 合成,可在 assistants.json 中给它叠加一层「金属/机械感」后处理。原理是把合成好的音频再过一遍 ffmpeg 滤镜链(与 TTS 模型本身无关,对任何输出都通用),无需换模型、纯本地、几乎零延迟。

jarvis 角色下配置 tts_config.metallic

"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 深度;太弱 → 调大 trebleg、加重 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 可执行文件。

项目亮点

  • 多角色切换:内置贾维斯、林妹妹两个角色,独立唤醒词、话术风格、音效和视觉特效,随时切换体验
  • 智能语音识别:支持 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

快速开始

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. 克隆项目

mkdir -p ~/.openclaw/workspace/voice-assistant
cd ~/.openclaw/workspace/voice-assistant
git clone <仓库地址>
cd assistant-x-openclaw
mkdir models

2. 安装依赖

创建虚拟环境并安装依赖:

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/simple

Windows:

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

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
        }
      }
    }
  }
}

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
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

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.请从此处下载assistant_overlay.dmg、control_center.dmg

2.安装assistant_overlay.dmg和dmg、control_center.dmg

3.打开「control_center」app,根据提示录入声纹后,开启语音助手,喊出贾维斯

Windows:

1.请从此处下载 assistant_overlay.msixcontrol_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,生成的 .msixbuild\windows\x64 unner\Release\ 目录下。

使用教程

基本使用流程

1. 唤醒语音助手

启动后,程序会显示"正在检测唤醒词...",此时直接说出唤醒词即可唤醒:

  • 贾维斯:说"贾维斯"或"加维斯"
  • 林妹妹:说"林妹妹何在"

唤醒词命中后还要过两道关,都通过才算唤醒成功:

  1. VAD 真人语音确认:抑制电脑外放的人声/TTS 误触发唤醒词;
  2. 声纹验证(强制):取唤醒前最近约 3 秒音频与已注册声纹比对,未注册声纹或不是本人,唤醒会被直接拒绝。首次使用请先在控制中心录入声纹(详见下方「声纹验证」)。

唤醒后助手会自动向主脑引擎发送一条 voice-assistant-wake-up-<本地时间戳> 消息, 由引擎返回的内容作为问候语播报(不再是写死的欢迎语)。问候在后台线程播报,期间再次说唤醒词可直接打断。听到问候后即可开始对话。

需在角色 system prompt 里加一条对该消息的应答规则,否则引擎可能把它当普通输入。 详见 hermes-assistant.md 第四节(OpenClaw 模式同样适用)。

2. 说出指令

唤醒后直接说出你的指令,例如:

  • "今天天气怎么样?"
  • "帮我设置一个明天早上8点的闹钟"
  • "查一下我的日程"

助手会实时识别你的语音,播放 TTS 回复,并显示 HUD 动画。

3. 自动待机

  • 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 识别到待机意图后就会自动触发退出。

自定义配置

添加新角色

  1. assistants.jsonassistants 数组中添加新角色:
{
    "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),带幂等保护防止回声重复触发。

  1. keywords/ 目录下创建对应的唤醒词文件(如 keywords/your-assistant.txt

  2. 重启语音助手即可生效

配置唤醒词

唤醒词文件位于 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:模糊匹配,包含这些词就会触发

自定义音效

  1. 录制或下载 WAV 格式音效
  2. 放入 data/voices/ 目录,替换对应文件名
  3. 无需重启,下次播放时自动使用新音效

音效格式建议:16-bit, 44100Hz, 单声道,长度 0.5-2 秒

主脑引擎选择(OpenClaw / Hermes)

assistants.json 顶层 engine 字段决定用哪个主脑引擎对接大模型:

{
    "engine": "openclaw",   // 默认;可选 "hermes"
    "default": "jarvis",
    "assistants": [ ... ]
}
  • openclaw(默认,缺省或未知值都回退到它):走 OpenClaw Gateway。
  • hermes:本地 Hermes 作主脑,一角色一 profile 一网关。配置/启动/排错见 hermes-assistant.md

特效调试模式(overlay_debug_mode)

assistants.json 顶层 overlay_debug_modetrue 时,召唤出来的 HUD 特效不再自动隐藏/清空, 方便对着调样式;正常使用保持 false

{
    "overlay_debug_mode": false,
    "assistants": [ ... ]
}

激活联动(唤醒时自动隐藏 Dock / 暂停媒体)

助手"被唤醒 → 退回待机"这两个时刻,可以联动触发一些系统动作。目前内置两项(均仅 macOS、软失败、退待机自动还原):

联动 开关 默认 依赖
唤醒时暂停正在播放的影视/音乐 自动(无需配置) brew install media-control
唤醒时把系统 Dock 切到自动隐藏 dock_autohide_on_wake macOS 自动化授权(见下)
{
    "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:实现 LifecycleHookon_wake / on_standbyregister 即可,主循环无需改动(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
贾维尔 : 贾维斯

文件不存在则跳过(纠错是可选功能),启动时加载。

API 接口

本地 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.plistNSCameraUsageDescription——改的是源码,需重新 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
    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_<时间>_<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

About

贾维斯语音助手(JARVIS-Voice Assistant),妈妈我再也不用羡慕钢铁侠了😭

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors