历史基线:下文保留 2026-10-23 的调查与排期,不能作为当前待办清单。学习持久化、任务、反馈重练、复习、录音核对及 F/H/G 最小可信状态/I 资源控制已由后续提交交付。当前功能见 README,本次收尾及即时纠正校验见 2026-10-26 收尾验收。评分校准、真人学习效果和生产容量仍需单独验证。
初始梳理基于 a90b85c(2026-10-23),以实际入口、调用链和离线复现为依据。聊天优化已保存为 2f4fc30;第一轮 A–E 已合入独立分支 integrate/optimization-round-1,集成修复为 575164f。首次验收的 36 项失败已修复,重新联合验收通过:后端 1273 项全部通过,全包覆盖率 81.59% 达到原有 80% 门槛;前端 59 项、真实 API 浏览器、Gradio 会话及新源码 ARM64 Docker 检查通过。本轮修复、回归测试与验收文档统一保存为后续优化基线,结果和边界见 integration_recovery.md,首次失败记录保留在 integration_round_1.md。下文保留聊天优化前后的测量,后续按剩余批次推进。
React 页面通过相对 /api 请求访问 FastAPI。开发环境由 Vite 代理到 8010,容器环境由 Nginx 代理到后端;React 入口是 frontend/src/App.tsx,API 入口是 scripts/run_api.py 和 src/chatterpal/web/api_server.py。
Gradio 通过 python -m chatterpal.web.app 独立启动。两个 Web 入口共用配置和提供商工厂,进程内的会话、缓存及用户历史各自保存,没有数据库或跨进程状态同步。
| 层次 | 实际职责 | 主要代码 |
|---|---|---|
| Web 接口 | 请求和响应模型、音频上传/下载、场景与音色查询 | web/api_server.py、web/app.py |
| 对话 | 会话、历史、ASR → LLM → TTS、主题上下文 | services/chat.py、services/topic_generator.py |
| 提供商 | 本地 Whisper / Aliyun NLS、Edge / CosyVoice、百炼 / OpenAI | core/asr/、core/tts/、core/llm/ |
| 评估 | 基础评分、文本对照、声学和韵律特征、AI 文字建议 | core/assessment/、services/correction.py、services/evaluation.py、services/ai_correction.py |
| 资源与配置 | Settings、工厂、音频处理、缓存、偏好 JSON | config/、utils/ |
API 当前公开十条路由:根路径、健康检查、文本聊天、音频聊天、基础发音分析、AI 发音分析、场景列表、场景详情、音色列表及音频下载。前端主要提供对话和发音纠正两个页面。
- ASR、LLM 和 TTS 有实际提供商实现。ASR 的质量分与置信度包含应用自己的启发式规则,不能直接当作识别引擎的原始置信度。
PronunciationCorrector.assess()仍保留固定的演示评分:总分 75,其他维度也是固定值。本轮已加入实际整段声学摘要并标明尚未校准,尚未形成经过校准的声学评分模型。PhonemeAnalyzer能提取整段音频的声学统计特征,目前没有按参考文本进行音素切分、强制对齐或准确率验证。ProsodyAnalyzer部分指标来自 myprosody,部分为默认或估计值;本轮已增加测量来源、partial/不可用状态及真实 F0,兼容默认值明确标为非实测。- A 已修复 AI 纠错报告字段、提示词格式化和错误回退;没有配置 AI 或 AI 响应无效时明确返回基础分析。基础评分仍需后续校准。
- Gradio 实际聊天页面已由 D 接入浏览器独立的
gr.State;旧组件评分/纠错已修通真实服务并通过 HTTP 检查,但app.py中独立的演示回调和语音聊天入口仍属于后续接线工作。 - E 已修复旧测试的收集错误并加入外部网络、模型与设备的显式 opt-in。集成后的全量结果和覆盖率以联合验收实测为准。
/api/chat/audio 先同步识别音频用于返回转写,再调用 ChatService.chat_with_audio() 对同一文件重新识别。Gradio 的 process_chat() 也会为了显示文本而重复识别。不同次转写可能不一致,使页面文本和实际 LLM 上下文不同。
/api/chat 直接在异步路由里执行同步 LLM 调用;音频路由的第一次 ASR 调用也在事件循环中执行。慢识别或慢网络请求会阻塞健康检查及其他请求。
离线基线使用真实 API 路由、ChatService、ASR 基类质量检查和 EdgeTTS,仅替换外部识别、模型及合成边界。每次 ASR 和 LLM 固定等待 150 ms,运行结果为:
| 路径 | 请求耗时 | 最大事件循环停顿 | 成功音频请求的 ASR 次数 |
|---|---|---|---|
| 音频聊天 | 464.8 ms | 161.6 ms | 2,其中 1 次在 API 线程 |
| 文本聊天 | 154.3 ms | 156.4 ms | 不适用 |
这些数字仅用于比较同一离线负载下的调用结构,不代表真实模型、云端服务或生产部署的延迟。
- 在服务层保留一次识别的转写和回复结果,供 API 及 Gradio 复用;保留原
chat_with_audio()的三元组返回接口。 - 将同步 ASR、LLM 和 TTS 调用从 API 事件循环移至工作线程。
- 同一会话的文本对话轮次按顺序更新历史,不同会话可并发调用模型。
- 模型失败时不留下未配对的用户消息;保留音频上传独立命名和异常清理。
- 使用可控事件和调用计数测试上述行为,再以真实 HTTP socket 验证健康检查、聊天、下载与清理。
本批增加不可变的 AudioChatResult 和 chat_with_audio_result(),把同一次识别的转写、回复、音频及会话 ID 一并返回。API 与 process_chat() 使用该结果;原 chat_with_audio() 仍返回三元组,HTTP 响应字段保持一致。同步 ASR/LLM/TTS 在工作线程执行;文本对话的上下文生成和成对写入由会话锁保护,LLM 失败不会留下未配对的用户消息。
同一离线脚本和同一固定负载的优化后结果:
| 路径 | 请求耗时:优化前 → 优化后 | 最大事件循环停顿:优化前 → 优化后 | 识别次数 |
|---|---|---|---|
| 音频聊天 | 464.8 → 310.3 ms | 161.6 → 6.0 ms | 2 → 1,API 线程内调用从 1 → 0 |
| 文本聊天 | 154.3 → 154.8 ms | 156.4 → 5.7 ms | 不适用 |
音频请求减少约三分之一耗时来自省去一次模拟的 ASR 调用;文本请求的单次总等待时间基本不变,改进体现在慢调用期间其他请求仍可运行。上述为单轮离线机制验证,不是生产延迟承诺。
联合离线回归为 88 项通过,包含原有 80 项和新增单次识别、健康检查响应性、旧接口兼容、Gradio 复用、同会话有序、不同会话并发及 LLM 失败恢复测试。真实 Uvicorn HTTP socket 验证通过文本聊天、multipart WAV 聊天、音频下载、慢提供商期间的健康检查、历史一致性和上传清理;外部识别、模型和合成仍使用受控离线边界。服务器及测试音频均在验证后清理。
独立复核未发现本批改动引入的可确认回归:另行运行的 44 项相关回归全部通过;使用真实 ASR 基类的离线探针验证了识别重试、空识别、旧接口和 TTS 失败仍返回文本,ASGI 探针验证了同会话失败恢复和不同会话并发。这 44 项属于相关回归的复跑,不计为新增测试数量。
本批保留现有语音请求进入 ASR 的顺序、TTS 音色选择和返回文件格式。验证范围限于聊天调用链;其他接口的阻塞调用、Gradio 浏览器和默认麦克风元组输入、线程池饱和、请求取消,以及会话创建、删除和过期清理的并发行为尚待后续验证。
| 任务 | 已合入的行为 | 验收重点 |
|---|---|---|
| A 分析后端 | 报告保存真实转写、AI 字段映射与结构验证、明确基础回退、独占上传、只清理自有文件、取消后保留分析输入 | 基础与 AI 路由、失败回退、并发、取消和文件所有权 |
| B 前端 | 共用录音/播放与请求生命周期,真实重采样为单声道 16 kHz PCM16 WAV,Worker 编码,对象 URL 回收,页面状态保留 | 真实浏览器录音上传、晚响应隔离、结果字段、生产 Worker |
| C ASR | Whisper 实例内有界缓存与推理串行、完整读取录音、路径/字节/元组归一化、英语默认及显式语言/设备配置 | 加载次数、输入完整性、配置传递与外部边界验证 |
| D Gradio | 每个浏览器独立保存会话 ID,清空同步重置服务会话 | 实际事件、多轮上下文、两浏览器隔离、清空与失败恢复 |
| E 测试 | 修复旧收集错误、隔离测试文件和设置、网络/模型/设备显式 opt-in、离线 CI | 全量收集、完整离线运行、80% 覆盖率门槛 |
逐项结果和验证边界见联合验收记录。Whisper 缓存的机制测试不能替代真实模型冷启动、热请求与峰值内存测量。
| 顺序 | 方向 | 剩余代码证据 | 最小验收标准 |
|---|---|---|---|
| F | TTS 请求参数与音频格式 | 请求修改共享音色、缓存键与提供商参数需统一核对,实际编码与文件扩展名/Content-Type 仍需一致 | 并发请求音色隔离、缓存命中正确、音频真实解码与 HTTP 类型一致 |
| H | 打包和部署体积 | 公开 CLI 指向未进入 wheel 的 scripts 包;所有部署必装本地推理与设备录音依赖 |
干净目录安装后公开命令可运行;云端模式不需本地推理依赖;明确 CPU 安装方案并实测镜像大小 |
| G | 评估可信度和提供商接线 | 固定分数、缺失维度被当零分、部分真实特征未进入报告 | 标识每项结果来源与可用状态;没有证据的维度显示不可评估;使用有标注样本验证评分 |
| I | 运行资源和观测 | 生成音频、过期会话和缓存缺少统一上限/TTL,阶段延迟和线程池饱和需要测量 | 有界资源、取消与下载安全、可复跑负载与阶段指标,再逐步拆分职责 |
F、H 先后进行,G 在接口稳定后推进,I 在行为回归稳定后实施。Gradio 的评分和纠错演示页仍需在相应批次接入真实能力。
可维护性方面,services/chat.py 与 core/tts/base.py 均已超过千行,混合了提供商调用、缓存、播放、界面适配和会话操作;TTS 基类还存在同名方法后定义覆盖前定义的情况。应在上述行为测试稳定后,再逐步拆分职责和清理重复实现。
本轮优先在离线边界验证调用次数、线程位置、状态一致性及异常清理,未使用真实云端密钥。首轮集成测试因旧 fixture 和模型保护入口与 C 的直接 loader 不一致,意外下载 Whisper base.pt 后中止;已补齐直接模型与代理目标保护,详情见联合验收记录。后续正式验证使用受控模型边界,不把固定时延模拟当作真实推理速度提升。模型复用性能和评分改进仍需要各自的数据集与测量方案。
在仓库根目录可复跑本批验收:
uv run python -m pytest -o addopts='' -q \
tests/test_chat_pipeline.py \
tests/test_aliyun_asr_concurrency.py \
tests/test_config.py \
tests/test_configuration_contract.py \
tests/test_edge_tts_async.py \
tests/test_api_tts.py \
tests/test_docker_deployment.py \
-W error::RuntimeWarning这里显式覆盖全仓覆盖率选项,仅用于复跑聊天基线。第一轮集成验收使用默认全仓配置和 80% 覆盖率门槛;完整命令与结果见联合验收记录。