助手本体:会话引擎、LLM 路由、记忆、身份、语音适配

从 Obsidian 笔记库剥离为独立仓库。规划文档与 P0 报告留在笔记库,
代码(助手本体、TTS 服务、P0 基准脚本、ESP32 固件)在此。

架构:服务器是助手,本地是客户端
- 助手本体跑在 cadadmin-server,N5095 只做 USB 外设桥与网络桥接
- 起因:实测 N5095 无 AVX2,跑不动可用的语音模型

当前技术栈
- LLM:DeepSeek deepseek-flash(云端,必须关思考)
- TTS:Qwen3-TTS 1.7B(服务器 3090,独立 HTTP 服务)
- STT:Zipformer 中英双语 int8(CPU,中文识别率未测)

实测:端到端 16/16 通过,首音延迟 1545ms
(对比:本地 LLM + vits-zh-ll 是 179ms,但音色不满意——音质与延迟
在此硬件上此消彼长)

设计要点
- MemoryStore 接口按"可能远程"设计(全 async、可超时、可失败)
- user_id / session_id / track_id 三者分开,人脸只作候选不自动切身份
- 记忆查询强制带 owner_user_id,无按 id 单独取的口子
- 自动抽取的记忆是"候选",默认不参与检索
- 异步写记忆绑定创建时的身份,不读"当前用户"
- 引擎与传输解耦,只用文件音频即可端到端测试

模型与音频产物不进版本管理(1.1GB),由 download_models.sh 恢复
This commit is contained in:
ylhan
2026-09-15 11:05:09 +08:00
commit 35e107c290
46 changed files with 5976 additions and 0 deletions
+35
View File
@@ -0,0 +1,35 @@
"""语音层:STT / TTS。
TTS 有两个后端,接口一致(synthesize / synthesize_sentences),
切换只需改配置 AI_TTS_BACKEND:
local — sherpa-onnx vits-zh-ll,RTF 0.09,很快但音色用户不满意
remote — Qwen3-TTS 独立服务,RTF 0.55–0.94,音质是另一档
为什么 remote 要走 HTTP 而不是进程内:qwen-tts 与助手/vllm-omni 的依赖互斥
(transformers 4.57 vs 5.14、hf_hub 0.36 vs 1.31),同 venv 会互相破坏。
模型文件不随代码走(体积大、可重新下载),由 VoiceConfig.model_dir 指向。
缺失时构造对象直接报错并提示下载脚本,不静默降级——静默降级会让
"没声音"变成一个很难查的问题。
"""
from .stt import STTError, STTStream, StreamingSTT
from .tts import MAX_CHARS_PER_SEGMENT, LocalTTS, TTSError, split_sentences
from .remote_tts import RemoteTTS, RemoteTTSError
def create_tts(cfg):
"""按配置造 TTS。返回对象统一提供 synthesize / synthesize_sentences。"""
if cfg.tts_backend == "remote":
return RemoteTTS(cfg.tts_service_url, voice=cfg.tts_speaker,
instructions=cfg.tts_instructions,
language=cfg.tts_language)
return LocalTTS(cfg)
__all__ = [
"StreamingSTT", "STTStream", "STTError",
"LocalTTS", "TTSError", "split_sentences", "MAX_CHARS_PER_SEGMENT",
"RemoteTTS", "RemoteTTSError", "create_tts",
]