配置说明
配置系统概览
配置文件位置
py-xiaozhi 的配置文件存储在 用户数据目录 下(而非项目根目录),符合各平台规范:
| 平台 | 配置目录 |
|---|---|
| Windows | C:\Users\<用户名>\AppData\Local\py-xiaozhi\config\ |
| macOS | ~/Library/Application Support/py-xiaozhi/config/ |
| Linux | ~/.local/share/py-xiaozhi/config/ |
<用户数据目录>/
├── config/
│ ├── config.json # 主配置文件(运行时配置)
│ └── efuse.json # 设备身份文件(自动生成)
├── logs/ # 日志文件
└── cache/ # 缓存文件提示:二开开发者如需自定义应用名称,修改
src/constants/system.py的APP_NAME即可改变数据目录名称。
配置层次结构
默认配置模板
- 位置:
src/utils/config_manager.py中的DEFAULT_CONFIG - 作用:提供系统默认配置值
- 用途:首次运行时自动生成配置文件的模板
- 位置:
运行时配置文件
- 位置:
<用户数据目录>/config/config.json - 作用:存储用户自定义配置
- 用途:系统运行时读取的实际配置
- 位置:
设备身份文件
- 位置:
<用户数据目录>/config/efuse.json - 作用:存储设备唯一标识和激活状态
- 用途:设备激活和身份验证
- 位置:
配置访问方式
配置系统支持点分隔路径访问,便于获取和修改嵌套配置:
python
# 获取配置示例
from src.utils.config_manager import ConfigManager
config = ConfigManager.get_instance()
# 获取网络配置
websocket_url = config.get_config("SYSTEM_OPTIONS.NETWORK.WEBSOCKET_URL")
# 获取唤醒词配置
wake_words = config.get_config("WAKE_WORD_OPTIONS.WAKE_WORDS")
# 更新配置
config.update_config("WAKE_WORD_OPTIONS.USE_WAKE_WORD", True)
config.update_config("CAMERA.VLapi_key", "your_api_key_here")
# 重新加载配置
config.reload_config()系统配置 (SYSTEM_OPTIONS)
基础系统配置
json
{
"SYSTEM_OPTIONS": {
"CLIENT_ID": "自动生成的客户端ID",
"DEVICE_ID": "设备MAC地址",
"WINDOW_SIZE_MODE": "screen_100",
"NETWORK": {
"OTA_VERSION_URL": "https://api.tenclass.net/xiaozhi/ota/",
"WEBSOCKET_URL": "wss://api.tenclass.net/xiaozhi/v1/",
"WEBSOCKET_ACCESS_TOKEN": "访问令牌",
"MQTT_INFO": {
"endpoint": "mqtt.server.com",
"client_id": "xiaozhi_client",
"username": "your_username",
"password": "your_password",
"publish_topic": "xiaozhi/commands",
"subscribe_topic": "xiaozhi/responses"
},
"ACTIVATION_VERSION": "v2",
"AUTHORIZATION_URL": "https://xiaozhi.me/"
}
}
}配置项说明
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
CLIENT_ID | String | 自动生成 | 客户端唯一标识符 |
DEVICE_ID | String | MAC地址 | 设备唯一标识符 |
WINDOW_SIZE_MODE | String | "screen_100" | 窗口大小模式 |
OTA_VERSION_URL | String | 官方OTA地址 | OTA配置获取地址 |
WEBSOCKET_URL | String | 由OTA下发 | WebSocket服务器地址 |
WEBSOCKET_ACCESS_TOKEN | String | 由OTA下发 | WebSocket访问令牌 |
ACTIVATION_VERSION | String | "v2" | 激活协议版本 (v1/v2) |
AUTHORIZATION_URL | String | "https://xiaozhi.me/" | 设备授权地址 |
服务端配置更换
更换自部署服务端
- 如需使用自行部署的服务端,只需修改OTA接口地址,系统会自动从OTA服务器获取WebSocket连接信息:
- AUTHORIZATION_URL换成你们绑定设备的后台,例如xiaozhi.me这种,点击跳转时会自动打开这个网页
json
{
"SYSTEM_OPTIONS": {
"NETWORK": {
"OTA_VERSION_URL": "https://your-server.com/xiaozhi/ota/",
"AUTHORIZATION_URL": "https://xiaozhi.me/"
}
}
}配置自动更新机制
系统启动时会通过以下流程自动更新配置:
- OTA配置获取:向
OTA_VERSION_URL发送POST请求 - 配置自动更新:系统自动更新MQTT和WebSocket配置
- 连接建立:使用更新后的配置建立连接
相关代码位置:
- OTA配置获取:
src/core/ota.py的fetch_and_update_config()方法 - 配置更新:
src/core/ota.py的update_websocket_config()和update_mqtt_config()方法
禁用配置自动更新
如果不需要配置自动更新,可以在以下位置注释相关代码:
1. 禁用OTA配置获取
在 src/core/system_initializer.py 中注释第三阶段:
python
# async def stage_3_ota_config(self):
# """
# 第三阶段:OTA获取配置.
# """
# # 注释掉整个方法内容2. 禁用WebSocket配置更新
在 src/core/ota.py 中注释更新方法:
python
async def update_websocket_config(self, response_data):
"""
更新WebSocket配置信息.
"""
# 注释掉配置更新逻辑
return None3. 手动配置WebSocket连接
直接在配置文件中配置固定的连接信息:
json
{
"SYSTEM_OPTIONS": {
"NETWORK": {
"WEBSOCKET_URL": "wss://your-server.com/xiaozhi/v1/",
"WEBSOCKET_ACCESS_TOKEN": "your_fixed_token"
}
}
}唤醒词配置 (WAKE_WORD_OPTIONS)
Sherpa-ONNX 语音唤醒设置
json
{
"WAKE_WORD_OPTIONS": {
"USE_WAKE_WORD": true,
"MODEL_PATH": "models/zh",
"NUM_THREADS": 4,
"PROVIDER": "cpu",
"MAX_ACTIVE_PATHS": 2,
"KEYWORDS_SCORE": 1.8,
"KEYWORDS_THRESHOLD": 0.2,
"NUM_TRAILING_BLANKS": 1,
"WAKE_WORD": "你好小智",
"WAKE_WORD_LANG": "zh"
}
}配置项说明
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
USE_WAKE_WORD | Boolean | true | 是否启用语音唤醒 |
MODEL_PATH | String | "models" | Sherpa-ONNX模型文件目录 |
NUM_THREADS | Integer | 4 | 模型推理线程数,影响响应速度 |
PROVIDER | String | "cpu" | 推理引擎(cpu/cuda/coreml) |
MAX_ACTIVE_PATHS | Integer | 2 | 搜索路径数,影响准确性和速度 |
KEYWORDS_SCORE | Float | 1.8 | 关键词增强分数,影响检测灵敏度 |
KEYWORDS_THRESHOLD | Float | 0.2 | 检测阈值,越低越灵敏 |
NUM_TRAILING_BLANKS | Integer | 1 | 尾随空白token数量 |
WAKE_WORD | String | "你好小智" | 唤醒词文本 |
WAKE_WORD_LANG | String | "zh" | 唤醒词语言(zh/en) |
模型文件结构
bash
models/
├── encoder.onnx # 编码器模型(已内置高精度版本)
├── decoder.onnx # 解码器模型
├── joiner.onnx # 连接器模型
├── tokens.txt # 拼音token映射表
└── keywords.txt # 关键词配置文件自定义唤醒词
编辑 models/keywords.txt 添加唤醒词:
# 格式:拼音分解 @中文原文
n ǐ h ǎo x iǎo zh ì @你好小智
j iā w éi s ī @贾维斯
x iǎo zh ù sh ǒu @小助手
k āi sh ǐ g ōng z uò @开始工作性能调优
速度优先配置
json
{
"WAKE_WORD_OPTIONS": {
"NUM_THREADS": 6,
"MAX_ACTIVE_PATHS": 1,
"KEYWORDS_THRESHOLD": 0.15,
"KEYWORDS_SCORE": 1.5
}
}准确性优先配置
json
{
"WAKE_WORD_OPTIONS": {
"NUM_THREADS": 4,
"MAX_ACTIVE_PATHS": 3,
"KEYWORDS_THRESHOLD": 0.25,
"KEYWORDS_SCORE": 2.2
}
}摄像头配置 (CAMERA)
视觉识别设置
json
{
"CAMERA": {
"camera_index": 0,
"frame_width": 640,
"frame_height": 480,
"fps": 30,
"Local_VL_url": "https://open.bigmodel.cn/api/paas/v4/",
"VLapi_key": "your_zhipu_api_key",
"models": "glm-4v-plus"
}
}配置项说明
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
camera_index | Integer | 0 | 摄像头设备索引 |
frame_width | Integer | 640 | 画面宽度 |
frame_height | Integer | 480 | 画面高度 |
fps | Integer | 30 | 帧率 |
Local_VL_url | String | 智谱API地址 | 视觉模型API地址 |
VLapi_key | String | "" | 智谱API密钥 |
models | String | "glm-4v-plus" | 视觉模型名称 |
摄像头测试
bash
# 测试摄像头功能
python scripts/camera_scanner.py
# 在程序中测试视觉识别
语音询问,看看摄像头前有什么?快捷键配置 (SHORTCUTS)
全局快捷键设置
json
{
"SHORTCUTS": {
"ENABLED": true,
"MANUAL_PRESS": {
"modifier": "ctrl",
"key": "j",
"description": "按住说话"
},
"AUTO_TOGGLE": {
"modifier": "ctrl",
"key": "k",
"description": "自动对话"
},
"ABORT": {
"modifier": "ctrl",
"key": "q",
"description": "中断对话"
},
"MODE_TOGGLE": {
"modifier": "ctrl",
"key": "m",
"description": "切换模式"
},
"WINDOW_TOGGLE": {
"modifier": "ctrl",
"key": "w",
"description": "显示/隐藏窗口"
}
}
}快捷键说明
| 快捷键 | 功能 | 说明 |
|---|---|---|
Ctrl+J | 按住说话 | 按住期间录音,释放后发送 |
Ctrl+K | 自动对话 | 开启/关闭自动对话模式 |
Ctrl+Q | 中断对话 | 中断当前对话 |
Ctrl+M | 切换模式 | 在不同对话模式间切换 |
Ctrl+W | 显示/隐藏窗口 | 显示或隐藏主窗口 |
声学回声消除配置 (AEC_OPTIONS)
AEC音频处理设置
json
{
"AEC_OPTIONS": {
"ENABLED": false,
"BUFFER_MAX_LENGTH": 200,
"FRAME_DELAY": 3,
"FILTER_LENGTH_RATIO": 0.4,
"ENABLE_PREPROCESS": true,
"MODE": "voice_processing"
}
}配置项说明
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
ENABLED | Boolean | false | 是否启用AEC回声消除功能 |
BUFFER_MAX_LENGTH | Integer | 200 | 参考信号缓冲区大小(帧数) |
FRAME_DELAY | Integer | 3 | 延迟补偿帧数(暂未使用) |
FILTER_LENGTH_RATIO | Float | 0.4 | 滤波器长度比例(秒),影响回声消除强度 |
ENABLE_PREPROCESS | Boolean | true | 是否启用噪声抑制预处理 |
MODE | String | "voice_processing" | AEC处理模式 |
AEC功能说明
回声消除 (Echo Cancellation)
- 消除扬声器播放音频在麦克风中产生的回声
- 支持实时双向对话,避免回声干扰
噪声抑制 (Noise Suppression)
- 抑制背景噪声和环境干扰
- 提高语音识别准确性
对话模式影响
json
{
"AEC_OPTIONS": {
"ENABLED": true // 启用时:实时对话模式(ListeningMode.REALTIME)
// 禁用时:回合制对话模式(ListeningMode.AUTO_STOP)
}
}环境优化建议
小房间/办公室环境
json
{
"AEC_OPTIONS": {
"FILTER_LENGTH_RATIO": 0.2,
"BUFFER_MAX_LENGTH": 150
}
}大房间/会议室环境
json
{
"AEC_OPTIONS": {
"FILTER_LENGTH_RATIO": 0.6,
"BUFFER_MAX_LENGTH": 300
}
}嘈杂环境
json
{
"AEC_OPTIONS": {
"FILTER_LENGTH_RATIO": 0.8,
"ENABLE_PREPROCESS": true,
"BUFFER_MAX_LENGTH": 400
}
}AEC功能测试
bash
# 测试回声消除效果
# 1. 启用AEC,播放音乐同时说话
python main.py # AEC启用时应无回声
# 2. 禁用AEC对比效果
# 修改配置文件 "ENABLED": false
python main.py # AEC禁用时可能有回声性能参数说明
滤波器长度计算
实际滤波器长度 = 采样率(16000Hz) × FILTER_LENGTH_RATIO
例如:FILTER_LENGTH_RATIO = 0.4 → 滤波器长度 = 6400 样本 (0.4秒)参数影响
- 滤波器长度↑:回声消除效果↑,CPU消耗↑
- 缓冲区长度↑:稳定性↑,内存消耗↑
- 预处理启用:噪声抑制↑,轻微延迟↑
音频设备配置 (AUDIO_DEVICES)
音频输入输出设置
json
{
"AUDIO_DEVICES": {
"input_device_id": null,
"input_device_name": null,
"output_device_id": null,
"output_device_name": null,
"input_sample_rate": null,
"output_sample_rate": null,
"input_channels": 1,
"output_channels": 2,
"opus_output_sample_rate": 24000,
"frame_duration": 20
}
}配置项说明
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
input_device_id | Integer | null | 输入设备ID(自动检测) |
input_device_name | String | null | 输入设备名称 |
output_device_id | Integer | null | 输出设备ID(自动检测) |
output_device_name | String | null | 输出设备名称 |
input_sample_rate | Integer | null | 输入采样率(自动检测) |
output_sample_rate | Integer | null | 输出采样率(自动检测) |
input_channels | Integer | 1 | 输入声道数 |
output_channels | Integer | 2 | 输出声道数 |
opus_output_sample_rate | Integer | 24000 | Opus解码采样率:24000(官方) 或 16000(第三方) |
frame_duration | Integer | 20 | 音频帧长度(ms):20(低延迟) / 40(平衡) / 60(低CPU) |
采样率与帧时长说明
Opus 解码采样率
24000: 官方服务器使用,音质较好16000: 第三方服务器使用,兼容性更好
帧时长选择
帧时长主要影响输入编码和设备回调频率。服务端返回的音频帧时长由客户端自动检测(解析 Opus TOC 字节),无需手动匹配。
20ms: 低延迟,适合实时对话(x86 默认)40ms: 平衡模式,延迟与性能兼顾60ms: 低CPU占用,适合树莓派等性能受限设备
音频设备自动检测
系统启动时会自动检测可用的音频设备。如需手动指定设备,可以配置设备ID和名称:
json
{
"AUDIO_DEVICES": {
"input_device_id": 2,
"input_device_name": "MacBook Air麦克风",
"output_device_id": 1,
"output_device_name": "MacBook Air扬声器"
}
}日志配置 (LOGGING)
日志系统设置
json
{
"LOGGING": {
"LEVEL": "INFO",
"FORMAT_TYPE": "colored",
"ENABLE_CONSOLE": true,
"ENABLE_FILE": true,
"ENABLE_ERROR_FILE": true,
"ENABLE_JSON_FILE": false,
"ENABLE_ASYNC": false,
"ENABLE_SENSITIVE_FILTER": true,
"MAX_BYTES": 10485760,
"BACKUP_COUNT": 30,
"ROTATION_WHEN": "midnight",
"THIRD_PARTY_LEVELS": {
"urllib3": "WARNING",
"websockets": "WARNING",
"asyncio": "WARNING",
"paho": "WARNING",
"PIL": "WARNING"
}
}
}配置项说明
| 配置项 | 类型 | 默认值 | 说明 |
|---|---|---|---|
LEVEL | String | "INFO" | 日志级别:DEBUG/INFO/WARNING/ERROR/CRITICAL |
FORMAT_TYPE | String | "colored" | 输出格式:colored/json/simple |
ENABLE_CONSOLE | Boolean | true | 是否启用控制台输出 |
ENABLE_FILE | Boolean | true | 是否启用文件日志 |
ENABLE_ERROR_FILE | Boolean | true | 是否单独记录错误日志 |
ENABLE_JSON_FILE | Boolean | false | 是否启用JSON格式日志文件 |
ENABLE_ASYNC | Boolean | false | 是否启用异步日志 |
ENABLE_SENSITIVE_FILTER | Boolean | true | 是否过滤敏感信息 |
MAX_BYTES | Integer | 10485760 | 单个日志文件最大字节数(10MB) |
BACKUP_COUNT | Integer | 30 | 保留的日志备份数量 |
ROTATION_WHEN | String | "midnight" | 日志轮换时机:midnight/H/D |
THIRD_PARTY_LEVELS | Object | 第三方库日志级别配置 |
日志级别说明
| 级别 | 说明 |
|---|---|
| DEBUG | 详细调试信息,开发时使用 |
| INFO | 一般运行信息(默认) |
| WARNING | 警告信息 |
| ERROR | 错误信息 |
| CRITICAL | 严重错误 |
开发调试配置
json
{
"LOGGING": {
"LEVEL": "DEBUG",
"FORMAT_TYPE": "colored",
"ENABLE_CONSOLE": true,
"ENABLE_FILE": true
}
}生产环境配置
json
{
"LOGGING": {
"LEVEL": "WARNING",
"FORMAT_TYPE": "json",
"ENABLE_CONSOLE": false,
"ENABLE_FILE": true,
"ENABLE_JSON_FILE": true,
"ENABLE_ASYNC": true
}
}协议配置详解
WebSocket 协议配置
WebSocket连接信息通常由OTA服务器自动下发,无需手动配置:
json
{
"SYSTEM_OPTIONS": {
"NETWORK": {
"WEBSOCKET_URL": "wss://your-server.com/xiaozhi/v1/",
"WEBSOCKET_ACCESS_TOKEN": "your_access_token"
}
}
}配置要点:
- URL必须以
ws://或wss://开头 - 支持IP地址或域名
- 默认端口为8000,可根据服务器配置调整
- 访问令牌用于身份验证
- 通常由OTA服务器自动配置,无需手动设置
MQTT 协议配置
json
{
"SYSTEM_OPTIONS": {
"NETWORK": {
"MQTT_INFO": {
"endpoint": "mqtt.server.com",
"port": 1883,
"client_id": "xiaozhi_client_001",
"username": "your_username",
"password": "your_password",
"publish_topic": "xiaozhi/commands",
"subscribe_topic": "xiaozhi/responses",
"qos": 1,
"keep_alive": 60
}
}
}
}配置要点:
endpoint: MQTT服务器地址port: 通常为1883(非加密)或8883(TLS加密)client_id: 客户端唯一标识qos: 消息质量等级(0-2)keep_alive: 心跳间隔(秒)
设备激活配置
激活版本说明
json
{
"SYSTEM_OPTIONS": {
"NETWORK": {
"ACTIVATION_VERSION": "v2",
"AUTHORIZATION_URL": "https://xiaozhi.me/"
}
}
}版本差异:
- v1: 简化激活流程,无需验证码
- v2: 完整激活流程,包含验证码验证
设备身份文件 (efuse.json)
json
{
"serial_number": "SN-E3E1F618-902e16dbe116",
"hmac_key": "b5bf012dd518080532f928b70ed958799f34f9224e80dd4128795a70a5baca24",
"activation_status": false,
"mac_address": "00:11:22:33:44:55",
"device_fingerprint": {
"cpu_info": "...",
"memory_info": "...",
"disk_info": "..."
}
}字段说明:
serial_number: 设备序列号hmac_key: 设备验证密钥activation_status: 激活状态mac_address: 设备MAC地址device_fingerprint: 设备指纹信息
配置管理实用技巧
1. 查找配置文件位置
bash
# macOS
open ~/Library/Application\ Support/py-xiaozhi/config/
# Linux
xdg-open ~/.local/share/py-xiaozhi/config/
# Windows (在文件资源管理器地址栏输入)
%LOCALAPPDATA%\py-xiaozhi\config2. 配置文件生成
bash
# 首次运行自动生成配置
python main.py
# 重新生成默认配置(删除用户数据目录下的配置文件)
# macOS/Linux 示例:
rm ~/Library/Application\ Support/py-xiaozhi/config/config.json
python main.py3. 配置备份与恢复
bash
# macOS/Linux 示例:
CONFIG_DIR=~/Library/Application\ Support/py-xiaozhi/config
# 备份配置
cp "$CONFIG_DIR/config.json" "$CONFIG_DIR/config.json.bak"
# 恢复配置
cp "$CONFIG_DIR/config.json.bak" "$CONFIG_DIR/config.json"配置文件模板
完整配置示例
json
{
"SYSTEM_OPTIONS": {
"CLIENT_ID": "12345678-1234-1234-1234-123456789012",
"DEVICE_ID": "00:11:22:33:44:55",
"WINDOW_SIZE_MODE": "screen_100",
"NETWORK": {
"OTA_VERSION_URL": "https://api.tenclass.net/xiaozhi/ota/",
"WEBSOCKET_URL": "wss://api.tenclass.net/xiaozhi/v1/",
"WEBSOCKET_ACCESS_TOKEN": "your_access_token",
"MQTT_INFO": {
"endpoint": "mqtt.server.com",
"client_id": "xiaozhi_client",
"username": "your_username",
"password": "your_password",
"publish_topic": "xiaozhi/commands",
"subscribe_topic": "xiaozhi/responses"
},
"ACTIVATION_VERSION": "v2",
"AUTHORIZATION_URL": "https://xiaozhi.me/"
}
},
"WAKE_WORD_OPTIONS": {
"USE_WAKE_WORD": true,
"MODEL_PATH": "models/zh",
"NUM_THREADS": 4,
"PROVIDER": "cpu",
"MAX_ACTIVE_PATHS": 2,
"KEYWORDS_SCORE": 1.8,
"KEYWORDS_THRESHOLD": 0.2,
"NUM_TRAILING_BLANKS": 1,
"WAKE_WORD": "你好小智",
"WAKE_WORD_LANG": "zh"
},
"CAMERA": {
"camera_index": 0,
"frame_width": 640,
"frame_height": 480,
"fps": 30,
"Local_VL_url": "https://open.bigmodel.cn/api/paas/v4/",
"VLapi_key": "your_zhipu_api_key",
"models": "glm-4v-plus"
},
"SHORTCUTS": {
"ENABLED": true,
"MANUAL_PRESS": {
"modifier": "ctrl",
"key": "j",
"description": "按住说话"
},
"AUTO_TOGGLE": {
"modifier": "ctrl",
"key": "k",
"description": "自动对话"
},
"ABORT": {
"modifier": "ctrl",
"key": "q",
"description": "中断对话"
},
"MODE_TOGGLE": {
"modifier": "ctrl",
"key": "m",
"description": "切换模式"
},
"WINDOW_TOGGLE": {
"modifier": "ctrl",
"key": "w",
"description": "显示/隐藏窗口"
}
},
"AEC_OPTIONS": {
"ENABLED": false,
"BUFFER_MAX_LENGTH": 200,
"FRAME_DELAY": 3,
"FILTER_LENGTH_RATIO": 0.4,
"ENABLE_PREPROCESS": true,
"MODE": "voice_processing"
},
"AUDIO_DEVICES": {
"input_device_id": null,
"input_device_name": null,
"output_device_id": null,
"output_device_name": null,
"input_sample_rate": null,
"output_sample_rate": null,
"input_channels": 1,
"output_channels": 2,
"opus_output_sample_rate": 24000,
"frame_duration": 20
},
"LOGGING": {
"LEVEL": "INFO",
"FORMAT_TYPE": "colored",
"ENABLE_CONSOLE": true,
"ENABLE_FILE": true,
"ENABLE_ERROR_FILE": true,
"ENABLE_JSON_FILE": false,
"ENABLE_ASYNC": false,
"ENABLE_SENSITIVE_FILTER": true,
"MAX_BYTES": 10485760,
"BACKUP_COUNT": 30,
"ROTATION_WHEN": "midnight",
"THIRD_PARTY_LEVELS": {
"urllib3": "WARNING",
"websockets": "WARNING",
"asyncio": "WARNING",
"paho": "WARNING",
"PIL": "WARNING"
}
}
}