2 Commits 9fc1b405c2 ... f958bbaf4d

Author SHA1 Message Date
  wenhongquan f958bbaf4d feat(architecture): 添加声纹识别和记忆系统的详细说明,删除过时的架构总结文件 2 months ago
  wenhongquan 3957b633fc docs: update AGENTS.md with voiceprint, session, memory architecture 2 months ago
2 changed files with 62 additions and 175 deletions
  1. 62 0
      AGENTS.md
  2. 0 175
      ARCHITECTURE_SUMMARY.md

+ 62 - 0
AGENTS.md

@@ -7,6 +7,7 @@ asr/
 ├── asr_agent/                  # 服务端(Python)
 │   ├── dispatcher.py           # HTTP Dispatcher — 多房间调度
 │   ├── worker.py               # VAD → ASR → LLM → TTS 完整流水线
+│   ├── voiceprint.py           # 声纹识别 + 对话记忆(Zvec + JSON)
 │   ├── whisper_asr/            # ASR 核心引擎
 │   │   ├── audio_processor.py  # AudioBuffer 环形缓冲
 │   │   ├── qwen_engine.py      # Qwen3-ASR 本地引擎
@@ -111,6 +112,53 @@ sequenceDiagram
 | **LLM** | Mimo v2.5 / vLLM | `LLM_PROVIDER` 切换;流式 SSE + `<think>` 过滤 |
 | **TTS** | Mimo v2.5 API | 24kHz PCM,并行生成 + 顺序入队播放 |
 | **播放** | 单轨 `LocalAudioTrack` | `play_q` 队列 + `_player` 协程持续 drain |
+| **声纹** | scipy MFCC + Zvec | 自动注册 / 识别说话人,识别结果注入 LLM 上下文 |
+| **记忆** | Zvec + JSON | 声纹向量存 Zvec;对话历史存 JSON,按用户隔离 |
+
+## 声纹识别
+
+```mermaid
+flowchart LR
+    A[音频输入] --> B[MFCC 特征提取<br/>120维]
+    B --> C[Zvec 向量检索<br/>余弦相似度]
+    C -->|匹配 >0.65| D[返回已知用户]
+    C -->|无匹配| E[自动注册新用户]
+    D --> F[注入 LLM 上下文]
+    E --> F
+    F --> G[个性化回复]
+    
+    B --> H[对话记忆<br/>JSON 持久化]
+    H -->|同一说话人| I[恢复历史会话]
+    I --> F
+```
+
+## 会话管理
+
+```mermaid
+sequenceDiagram
+    participant A as App
+    participant D as Dispatcher
+    participant W as Worker
+    
+    Note over A,W: 首次连接
+    A->>D: POST /connect {identity}
+    D-->>A: {room: "room-xxx", token}
+    Note over A: 保存 room
+    
+    Note over A,W: 暂停 → 继续
+    A->>D: POST /connect {identity, room: "room-xxx"}
+    D->>D: 检测 room-xxx 存活
+    D-->>A: {room: "room-xxx", token}
+    Note over A,W: 同房间 → Worker 保持 → 上下文不丢
+```
+
+## 三层记忆系统
+
+| 层级 | 存储 | 键 | 生命周期 | 用途 |
+|------|------|-----|---------|------|
+| **房间会话** | `self.hist` (内存) | 房间号 | APP 暂停→继续 | 当前对话上下文 |
+| **声纹向量** | Zvec 嵌入式 DB | 声纹特征 | 永久 | 说话人识别 |
+| **对话记忆** | JSON 文件 | `speaker_id` | 永久 | 跨会话历史 |
 
 
 
@@ -131,6 +179,7 @@ python3 -m py_compile asr_agent/dispatcher.py
 # 2. 上传文件到服务器
 sshpass -p '123456' scp asr_agent/worker.py ubuntu@200.200.18.11:/tmp/asr_build/worker.py
 sshpass -p '123456' scp asr_agent/dispatcher.py ubuntu@200.200.18.11:/tmp/asr_build/dispatcher.py
+sshpass -p '123456' scp asr_agent/voiceprint.py ubuntu@200.200.18.11:/tmp/asr_build/voiceprint.py
 sshpass -p '123456' scp -r asr_agent/whisper_asr ubuntu@200.200.18.11:/tmp/asr_build/
 
 # 3. 服务器构建镜像
@@ -151,6 +200,7 @@ docker run -d --name asr-dispatcher --network host --restart unless-stopped \
   -e LLM_PROVIDER=mimo \
   -e ASR_PROVIDER=mimo \
   -v /data/models:/data/models:ro \
+  -v /data/voiceprints:/data/voiceprints \
   asr-dispatcher:v1
 '
 
@@ -176,6 +226,8 @@ curl -s -X POST http://localhost:10005/connect -H "Content-Type: application/jso
 | `MIMO_KEY` | — | Mimo API Key |
 | `MIMO_API_BASE` | `https://token-plan-cn.xiaomimimo.com/v1` | Mimo API 地址 |
 | `VAD_MODEL_PATH` | `whisper_asr/silero_vad.onnx` | Silero VAD 模型路径 |
+| `VP_DB_PATH` | `/data/voiceprints` | 声纹数据库目录 |
+| `VP_SIMILARITY_THRESHOLD` | `0.65` | 声纹匹配余弦相似度阈值 |
 
 ## 端口
 
@@ -196,6 +248,16 @@ curl -s -X POST http://localhost:10005/connect -H "Content-Type: application/jso
 5. App 断开 → Worker 退出 → 房间释放
 ```
 
+### 暂停 → 继续
+
+```
+1. App 暂停 → 保存 room 名称
+2. App 继续 → POST /connect {identity, room: "room-xxx"}
+3. Dispatcher 检测 room-xxx 是否存活
+4. 存活 → 返回相同 room,Worker 保持,上下文不丢
+5. 已释放 → 创建新 room + 新 Worker,声纹记忆恢复上下文
+```
+
 ## Flutter App 编译
 
 ```bash

+ 0 - 175
ARCHITECTURE_SUMMARY.md

@@ -1,175 +0,0 @@
-# ASR 项目架构总结
-
-## 概述
-
-该仓库包含一个实时语音识别和 AI 助手系统,主要由以下部分组成:
-
-1. `asr_agent/` - 后端 ASR + LLM + TTS Worker 逻辑。
-2. `flutter_asr_client/` - Flutter 移动客户端应用。
-3. `livekit-server/` - LiveKit 部署配置。
-
-系统使用 LiveKit 进行实时音频传输和数据通道消息传递,并结合本地 ASR 和可选的云服务备用方案。
-
----
-
-## 1. 后端 (`asr_agent/`)
-
-### 1.1 入口与服务层
-
-- `dispatcher.py`
-  - 提供 `POST /connect`:创建唯一房间、生成 LiveKit token,并启动对应房间的 `Worker`。
-  - 提供 `GET /health`:检查并清理已结束的 Worker。
-  - 使用 `aiohttp` 提供 HTTP 接口。
-
-### 1.2 Worker 运行时
-
-- `worker.py`
-  - `Worker` 作为机器人连接到 LiveKit 房间。
-  - 监听参与者的远端音频轨道。
-  - 执行管道:VAD -> ASR -> LLM -> TTS。
-  - 通过 LiveKit 数据通道发布实时转写和回复事件。
-  - 通过本地音频轨道发布合成语音。
-
-### 1.3 语音处理流水线
-
-- VAD:优先使用 Silero VAD ONNX 模型,否则回退到能量检测。
-- ASR:
-  - 默认使用本地 `Qwen3-ASR` 模型,封装在 `whisper_asr/qwen_engine.py`。
-  - 可通过 `ASR_PROVIDER=mimo` 切换为远程 Mimo ASR。
-- LLM:
-  - 默认使用本地 vLLM REST/SSE 接口(`VLLM_URL`)。
-  - 可通过 `LLM_PROVIDER=mimo` 切换为云端 Mimo LLM。
-- TTS:
-  - 使用 Mimo API 进行语音合成。
-  - `_TTSSegmenter` 实现二级分句,保证语音播放更流畅。
-
-### 1.4 支持模块
-
-- `whisper_asr/audio_processor.py`
-  - 负责音频缓冲、PCM 转换、语音活动检测、队列管理。
-- `whisper_asr/qwen_engine.py`
-  - 封装 Qwen3-ASR 模型加载和转写接口。
-
-### 1.5 关键技术
-
-- `livekit` Python RTC 客户端
-- `onnxruntime` + Silero VAD
-- `qwen_asr` 本地语音模型
-- `aiohttp` 异步 Web 服务器
-- `pyjwt` 生成 LiveKit token
-
----
-
-## 2. Flutter 客户端 (`flutter_asr_client/`)
-
-### 2.1 应用入口与路由
-
-- `lib/main.dart`
-  - 启动 `ProviderScope`,并注入 `LiveKitServiceImpl`。
-- `lib/app.dart`
-  - 使用 Riverpod 和 GoRouter 创建 `MaterialApp.router`。
-- `lib/router/app_router.dart`
-  - 定义主应用导航:
-    - `/tasks`
-    - `/records`
-    - `/reports`
-    - `/profile`
-    - `/recording`
-
-### 2.2 状态与业务逻辑
-
-- `lib/providers/livekit_providers.dart`
-  - 定义 `LiveKitService` 抽象。
-  - 暴露消息流和房间名提供者。
-- `lib/providers/settings_providers.dart`
-  - 提供应用设置和服务 URL。
-- `lib/pages/recording/notifiers/recording_notifier.dart`
-  - 管理录音生命周期。
-  - 请求 Dispatcher 房间信息。
-  - 连接 LiveKit 并订阅服务端消息流。
-  - 处理实时转写、AI 回复、暂停/恢复和结束录音。
-
-### 2.3 LiveKit 服务封装
-
-- `lib/services/livekit_service.dart`
-  - 实现 `LiveKitService`。
-  - 连接 LiveKit 并发布麦克风音频。
-  - 监听数据通道中的 `transcription` 消息。
-  - 包含开发环境下的 JWT 生成逻辑。
-
-### 2.4 音频采集服务
-
-- `lib/services/audio_capture_service.dart`
-  - 使用 `record` 插件采集 PCM16 音频。
-  - 暴露音量流和录音开始/停止方法。
-  - 注意:应用真实音频传输路径是通过 LiveKit 麦克风发布。
-
-### 2.5 UI 层
-
-- `lib/pages/shell/app_shell.dart`
-  - 底部导航壳,带中央 FAB 进入录音。
-- `lib/pages/recording/recording_page.dart`
-  - 录音页面,显示实时话语、AI 回复、连接状态和控制按钮。
-
-### 2.6 数据模型
-
-- `lib/models/websocket_message.dart`
-  - 定义客户端请求消息与服务端消息类型。
-  - 服务端消息包括 `connected`、`partial`、`utterance`、`reply`、`reply_partial`、`transcript`、`error`。
-
----
-
-## 3. LiveKit 部署
-
-- `livekit-server/docker-compose.yml`
-- `livekit-server/livekit.yaml`
-
-这些文件配置了应用和后端使用的 LiveKit 实时音频房间服务。
-
----
-
-## 4. 端到端流程
-
-1. Flutter 应用进入录音页面。
-2. `RecordingNotifier` 调用 Dispatcher 的 `/connect`。
-3. Dispatcher 创建 LiveKit 房间并返回 URL/room/token。
-4. Flutter 连接 LiveKit 并发布麦克风音频流。
-5. Dispatcher 为该房间启动一个 `Worker`。
-6. Worker 加入房间,订阅参与者音频并运行 VAD。
-7. 语音片段通过 ASR 转写。
-8. 转写与回复更新通过 LiveKit 数据通道传递给客户端。
-9. Worker 还可能合成回复音频并发布到房间。
-10. 客户端显示实时文本,并可听到 AI 语音。
-
----
-
-## 5. 系统特性
-
-- 房间级 Worker 模型:每次连接创建一个 Worker。
-- 音频轨道 + 数据通道结合架构。
-- 本地/云混合能力:本地 Qwen ASR / vLLM,可选 Mimo 备用。
-- Flutter 前端使用 Riverpod 状态管理和 GoRouter 路由。
-- 后端通过环境变量配置,前端通过 SharedPreferences 配置。
-
----
-
-## 6. 配置点
-
-- 后端环境变量:
-  - `LIVEKIT_URL`、`PUBLIC_LIVEKIT_URL`
-  - `ASR_MODEL_PATH`
-  - `VLLM_URL`、`LLM_MODEL`
-  - `MIMO_KEY`、`MIMO_API_BASE`
-  - `LLM_PROVIDER`、`ASR_PROVIDER`
-- Flutter 设置:
-  - Dispatcher URL
-  - LiveKit URL
-  - WebSocket 后端 host/port
-
----
-
-## 7. 备注
-
-- Dispatcher 使用开发 JWT 密钥和房间创建逻辑,生产环境应替换。
-- Flutter 应用中录音状态包含固定测试/演示元数据。
-- 后端 Worker 目前将转写与 AI 回复生成放在同一个服务流中。