feat(history): 详情页展示 ASR/LLM 模型与分步耗时,可观测的模型表现对比 - #826
Conversation
- DictationSession 新增 asr_provider/asr_model/llm_provider/llm_model/asr_ms/polish_ms 六个可选字段(旧 JSON 兼容);听写收尾实测写入,Raw 直通不记 LLM 字段 - asr_ms 量松键后等待转写结果的时间(流式=收尾延迟,批式=完整转写); polish_ms 量 LLM 润色/翻译调用耗时 - 失败/空转写历史也记 ASR provider/model,方便模型对比排查; 手动重转用当前 ASR 覆盖并清掉旧润色信息 - 详情页底部改为 识别/润色/插入 三行流水线明细;录音时长加「录音」前缀 并给识别行加悬停说明,避免与分步耗时混淆 - 润色卡片复制按钮移入卡片头部,与原文卡片对称 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
PR Reviewer Guide 🔍(Review updated until commit c4d5318)Here are some key observations to aid the review process:
|
|
@appergb 给决策 |
appergb
left a comment
There was a problem hiding this comment.
Senior review — exact head a2ab3537b251ef6a7700f7e8543fdc322676c06a
Strengths
- Rust
Option<T>+#[serde(default)]与 camelCase TS 镜像使旧history.json的读取兼容路径合理;旧版本 serde 默认也会忽略新增未知字段,不需要一次性迁移。 - 重转录成功后覆盖 ASR 字段并清空旧
llm_*/polish_ms,避免新转写挂着旧润色元数据,这个契约方向正确。 - 新增持久化字段只有 provider/model 标识与耗时,没有把 API key、token、endpoint 或 extra headers 写入历史;未发现新的凭据泄露。
- exact-head CI 已核对:macOS、Windows、Linux、Android cargo check 及 PR-Agent 均成功,所有 check run 的
head_sha都是该 SHA。 - PR 没有 GitHub 正式关联的 closing issue;我同时阅读了最贴近动机的 #373(处理速度异常慢)。该 issue 也暴露了 Volcengine 资源标识的可观测性缺口,见下方。
Critical
- 无。
Important
-
模型归因不是调用快照,可能把结果记到错误 provider/model。
coordinator/dictation.rs:2882在 ASR 完成后调用asr_history_label(&inner.prefs.get()),润色也是请求返回后重新读 vault;会话中切换 provider/model 时,历史记录与实际已构建客户端不一致。Foundry/Sherpa 的构建路径还会把未知 alias 回退到默认模型,而 label helper 直接记录未归一化 pref。请在构建实际 ASR/LLM provider 时捕获规范化 label,并随 session/result 传到持久化点,而不是事后重读全局设置。 -
“LLM 真正被调用才记录”的契约目前由模式推断,失败路径会产生伪数据。
coordinator/dictation.rs:3136的llm_used只看 translate/mode/style pack;例如 Gemini 缺 key 时在read_gemini_credentials就返回,HTTP/模型没有被调用,但仍写入llmProvider、llmModel和很短的polishMs。应让 polish dispatch 返回真实调用元数据(或至少明确 attempted vs completed),再决定是否持久化。 -
亚秒延迟的展示精度不足,直接削弱模型比较目标。
History.tsx:443/:454复用了录音时长 formatter,只保留 0.1 秒;截图中已经出现0.0 秒。快速流式收尾常在几十毫秒量级,这会把多个有差异的结果显示成同一个值。建议 step latency 小于 1 秒时显示整数毫秒,较大值再显示秒。 -
Volcengine 的可比较标识被丢弃。 #373 的 ASR 配置明确是
volc.seedasr.sauc.duration,代码里对应VolcengineResourceId;coordinator.rs:2444当前固定返回model=None,因此不同 Volc resource/engine 的历史全都只显示volcengine,无法支持这个最接近动机的排障场景。请评估把非密钥的规范化 resource/engine 标识写入 model 字段(若某类 resource id 可能包含租户敏感信息,则先定义脱敏/allowlist)。 -
没有新增行为/契约测试。 这 13 个文件只更新了 mock 数据,没有测试旧 JSON 缺字段反序列化、camelCase 序列化、各 provider 默认/alias 映射、Raw 直通不落 LLM 字段、LLM preflight failure、重转清理旧字段,以及精细耗时格式。现有 CI 全绿只能证明编译与原测试不回归,不能保护这次新增的数据语义。
Minor
stepAsrHint使用不可聚焦的span title=...:桌面鼠标可 hover,但键盘和 Android 触屏无法可靠发现/读取。应使用可聚焦 tooltip/popover trigger,并补 aria 语义。- 现有视觉证据只有桌面深色模式。三列 grid 在窄屏、长 provider/model、长本地化状态文本下的换行/溢出,以及浅色/高对比度状态尚无验证证据。
Ready to merge verdict
- 逻辑质量:Not ready。 上述归因、调用语义、显示精度与测试问题会让“模型表现对比”的数据不可靠。
- UI / 发布门禁:Not ready,禁止合并。 这是明确的用户可见 History UI 改动;即使逻辑修完,也需完成移动端/桌面、触屏/键盘、窄宽度、浅/深色的 UI 验收再进入发布。按本次门禁要求,本 review 不会批准或合并。
按 Open-Less#826 review 逐条修复: 1. ASR/LLM 归因改为构建时快照。store_asr_for_session 新增 AsrCallLabel 参数 (编译期强制 11 个构建分支交出快照),记录实际构建的具体协议 id(含统一百炼 重定向后的 effective id)与归一化后的模型/alias;LLM 侧 polish 链路新增 llm_call 出参,在成功构建 provider、即将发起真实调用时才填充。会话中途改 设置不再污染归因。 2. preflight 失败不再产生伪数据。凭据缺失等构建失败时 llm_call 保持 None, 不落 llm_*/polish_ms;polish_ms 也只在真实调用发生时记录。 3. 步骤耗时 <1s 显示整数毫秒(durationMillis,5 语言包),流式收尾几十毫秒 不再被 0.1s 精度拍平。 4. Volcengine 经 allowlist(volc. 命名空间、ASCII 安全字符集、≤64)脱敏后 把 resource id 落入 asr_model,支持 issue Open-Less#373 的引擎对比排障;异常值不落盘。 5. 识别行提示改用可聚焦 Tooltip 组件(hover/键盘 focus/触摸三通道 + 虚线下划线)。 6. 重转录命令改用 retranscribe_pcm 返回的构建时快照;抽出 apply_retranscription 纯函数。新增测试:旧 JSON 缺字段反序列化、camelCase 序列化、volc allowlist、 重转覆盖归因并清 LLM 字段、Raw 直通不产生调用快照。 UI 验收:深/浅色 × 桌面/移动 × 超长 provider/model 换行 × 键盘聚焦均通过 (mock 数据已扩成对应压力画像)。 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
@appergb 感谢这轮 review——五条 Important 全部成立,尤其 1/2 指出的归因时机问题正中要害。已在 0fcb8fc 逐条修复: 1. 归因改为构建时快照 ✅
2. preflight 失败不再产生伪数据 ✅ 3. 亚秒毫秒精度 ✅ 4. Volcengine resource id ✅ 5. 测试 ✅
Minor A(a11y)✅ 识别行提示改用仓库统一的 Minor B(UI 验收)✅ mock 数据扩成四种压力画像(亚秒流式收尾、volc resource id、超长 provider/model、Raw 无润色行/旧条目缺字段),实测通过:深色/浅色 × 桌面 1280 / 移动 375 宽; 另外重转录命令现在使用 CI 绿后请再过目。 🤖 Generated with Claude Code |
|
Persistent review updated to latest commit 0fcb8fc |
|
Persistent review updated to latest commit c4d5318 |
User description
初衷
现在换 ASR 供应商、换润色模型都很方便,但换完之后「到底哪个模型更快、哪个更准」没有任何可以回看的地方——历史页只记了润色模式、时间和录音时长。想做模型能力对比时,只能靠当场的体感。
这个 PR 把每次听写实际用了什么模型、各步花了多久记进历史,让历史页成为一个可以监测转写模型与 LLM 表现的地方:连续用两个供应商各说几段话,翻历史就能直观对比收尾延迟、润色耗时和输出质量。
改动
历史详情页底部改为「识别 / 润色 / 插入」三行流水线明细:
bailian · fun-asr-realtime)codex_oauth · gpt-5.5)后端:
DictationSession新增 6 个可选字段asr_provider / asr_model / llm_provider / llm_model / asr_ms / polish_ms,全部#[serde(default)],旧 history.json 完全兼容(旧条目前端自动隐藏对应行,信息量与改版前一致)。耗时语义(也是几个字段设计上想清楚的点):
asr_ms量的是松键后等待转写结果的时间:流式 ASR 边录边转,这里是用户感知的收尾延迟;批式 ASR 则是完整转写耗时。含自动静默重试的时间(那也是用户在等的时间)。polish_ms只在 LLM 真正被调用时记录(翻译 / 非 Raw / Raw 但风格包带 LLM),Raw 直通为 None,前端隐藏润色行。顺手的两个 UI 修正:
五个语言包(en / zh-CN / zh-TW / ja / ko)同步新增文案;移除已无引用的
insertedTo。测试
cargo check+cargo check --tests通过(含新增 DashScope 多模态 / ElevenLabs 供应商分支的模型标签)tsc --noEmit+vite build通过效果
PR Type
Enhancement, Bug fix
Description
详情页流水线展示 ASR/LLM 模型与分步耗时
构建时快照确保归因准确,旧数据 Serde 缺省兼容
自动静默重试和失败条目也记录模型信息
前端 UI 组件重排并添加多语言 i18n 支持
Diagram Walkthrough
File Walkthrough
11 files
重转录逻辑更新,添加 apply_retranscription 与测试添加 AsrCallLabel、volc_resource_history_label,集成快照build_qa_asr_start 返回标签,各分支提供构建时快照端到端会话捕获 ASR/LLM 快照和耗时,更新失败处理添加 LLM 调用标签和耗时记录,增加 Raw 直通测试更新 QA 会话 DictationSession 构造填充新字段新增 take_asr_label_for_session 函数添加 LlmCallLabel 定义和 call_label 方法DictationSession 新增 6 个可选字段,添加上序列化测试TypeScript 类型添加 asrProvider 等 6 个字段详情底部改为流水线网格,添加悬停提示5 files
添加录音前缀和分步标签的英文 i18n同步新增日语 i18n 键同步新增韩语 i18n 键同步新增简体中文 i18n 键同步新增繁体中文 i18n 键1 files
更新 mock 数据包含新字段(轮换画像)