VoiceRouter 是一个统一的语音路由服务,向外提供一致的 ASR/TTS API,向内对接多个第三方语音平台,并按语种、能力和策略进行路由。
当前设计目标:
- 对外暴露统一的
ASR/TTS接口 - 按语种配置不同供应商
ASR支持“大模型润色”开关TTS支持音色、语速、音量、采样率等配置- 不同平台通过独立适配器封装,对内统一协议
- 提供轻量级后台管理系统,支持供应商和路由策略配置
- API 服务:
FastAPI - 数据模型:
Pydantic - ORM:
SQLAlchemy - 数据库:
PostgreSQL(开发环境可先用SQLite) - 后台管理:
FastAPI + Jinja2 + HTMX/Alpine.js - 异步任务:初期可同步执行,后续按需引入
Celery/RQ
- 音频转文字
- 按语种路由到不同 ASR 供应商
- 可选大模型润色
- 支持原始识别结果和润色后结果同时返回
- 支持供应商失败后的降级与切换
- 支持同一供应商多组认证 Key 的健康分调度、降权和冷却
- 文本转语音
- 按语种路由到不同 TTS 供应商
- 支持统一音色配置模型
- 支持供应商私有参数透传
- 支持不同供应商音色映射
router-api- 对外统一 API
domain- 领域模型、统一请求/响应协议
providers- 各家 ASR/TTS 适配器
routing- 语种、供应商、回退策略选择
llm-polish- ASR 后处理润色链路
admin- 轻量后台管理
storage- 配置、日志、审计、密钥引用
VoiceRouter/
├── README.md
├── docs/
│ └── system_design.md
├── app/
│ ├── main.py
│ ├── api/
│ │ ├── asr.py
│ │ ├── tts.py
│ │ └── admin.py
│ ├── core/
│ │ ├── config.py
│ │ ├── security.py
│ │ └── logging.py
│ ├── domain/
│ │ ├── enums.py
│ │ ├── schemas.py
│ │ └── entities.py
│ ├── services/
│ │ ├── asr_service.py
│ │ ├── tts_service.py
│ │ ├── routing_service.py
│ │ └── llm_polish_service.py
│ ├── providers/
│ │ ├── base/
│ │ │ ├── asr.py
│ │ │ └── tts.py
│ │ ├── openai/
│ │ ├── azure/
│ │ ├── aliyun/
│ │ └── volcengine/
│ ├── repositories/
│ ├── models/
│ ├── templates/
│ └── static/
└── tests/
- 已有统一
ASR/TTSAPI - 已有轻量后台
/admin/ - 已接入首家真实 ASR 供应商骨架:
Azure Speech ASR - 后台支持同一 Provider 多组凭证、多 Key 自动降权和冷却
- 支持手动测试某把凭证健康状态
要求:
- Python
3.11+
推荐命令:
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install -e ".[dev]"如果你不需要测试依赖,也可以:
python3 -m pip install -e .先复制环境变量模板:
cp .env.example .env当前支持的关键配置:
VOICEROUTER_DATABASE_URL- 默认值:
sqlite:///./voicerouter.db
- 默认值:
VOICEROUTER_API_KEY- 可选;如果设置了,调用
/api/v1/*时需要带请求头X-API-Key
- 可选;如果设置了,调用
VOICEROUTER_DEBUG- 开发环境可设为
true
- 开发环境可设为
推荐直接用 uvicorn:
python3 -m uvicorn app.main:app --reload --host 0.0.0.0 --port 8000或者用我加的 Makefile:
make run启动后访问:
- OpenAPI 文档:http://127.0.0.1:8000/docs
- 后台管理:http://127.0.0.1:8000/admin/
- 健康检查:http://127.0.0.1:8000/health
- 自动创建数据库表
- 自动写入默认 Provider、默认语言路由、默认 Voice Profile 和默认 Mock Credential
- 默认数据库文件会出现在项目根目录:
voicerouter.db
运行测试:
python3 -m pytest -q或者:
make test项目依赖里已经包含:
azure-cognitiveservices-speech
如果你是按上面的安装命令安装依赖,这个包会一起装好。
微软官方安装参考:
访问 /admin/,在 Provider Credentials 里新增一条:
Provider Code:azure_speech_asrLabel: 自定义,例如Azure East Asia Key 1Priority: 比如100Azure Region: 例如eastasiaAzure Subscription Key: 你的 Azure Speech Key
可选字段:
Azure EndpointAzure HostAzure Authorization TokenAzure Endpoint ID
说明:
- 表单会自动把这些 Azure 字段合并到
auth_config - 同一个
azure_speech_asr可以配置多把 Key - 系统会优先使用健康分高的 Key
- 某把 Key 鉴权失败或临时失败后,会自动降权并进入冷却期
在 /admin/ 的 Language Routes 中,把某个语言的:
ASR Primary改成azure_speech_asrASR Fallbacks可保留mock_asr_primary之类作为兜底
例如:
language_code:zh-CNasr_primary_provider:azure_speech_asrasr_fallbacks:mock_asr_primary
在 Provider Credentials 表格里点对应凭证的 Test 按钮。
测试结果会回写到数据库中的:
last_statuslast_errorpenalty_scorecooldown_until
如果 Azure SDK 没装好,或者认证参数缺失,测试会直接失败并显示状态。
curl -X POST "http://127.0.0.1:8000/api/v1/asr/transcribe" \
-H "Content-Type: application/json" \
-d '{
"language": "zh-CN",
"audio_url": "https://example.com/demo.wav",
"polish_text": true
}'如果设置了 VOICEROUTER_API_KEY,再加:
-H "X-API-Key: your-api-key"curl -X POST "http://127.0.0.1:8000/api/v1/tts/synthesize" \
-H "Content-Type: application/json" \
-d '{
"language": "en-US",
"text": "hello from VoiceRouter"
}'make install-dev
make test
make run我建议下一步优先做这两件事:
- 用真实 Azure Key 做一次本地联调,确认
audio_url和audio_base64都能正常识别 - 把 Azure credential 的
Test从“参数预检”升级成“真实短音频预检”,这样能更准确反映账号和区域是否可用
详细设计见 docs/system_design.md。