edit | blame | history | raw

Round 2 PRD:语言检测与语言版本设置

状态:v0.1 启动稿
所属子项目:02-P-NBL
Round:Round 2
日期:2026-06-03
关联文档:

1. 背景

Round 1 已经把现有 SenseVoice 纳入 ModelProfile 架构,并通过 QA 验证:

  • 老用户旧模型目录 models/sensevoice 可 fallback。
  • 新用户模型可安装到 models/sensevoice-zh
  • SelectedModelID=sensevoice-zh 已成为隐藏配置。
  • LanguageProfile 已有最小中文实现,但尚未真正参与语言选择和 UI 设置。

后续产品路线要求:

语言版本 默认轻量模型 高级模型
中文 SenseVoice Qwen3-ASR
English Moonshine English Parakeet

Round 2 的任务不是接入英文模型,而是先建立语言版本机制,让后续 Round 3 可以把 English 默认模型切到 Moonshine。

2. 本轮目标

Round 2 完成后,系统内部应从:

前端按 navigator.language 自行判断 zh/en
后端没有语言版本配置

演进为:

Config.LanguageMode / Config.LanguageID
  -> LanguageRegistry
  -> EffectiveLanguage
  -> UI locale
  -> 未来默认模型选择

用户可见目标:

  • 中文系统首次启动默认中文界面。
  • English 系统首次启动默认 English 界面。
  • 其他系统语言暂时默认 English。
  • 设置页可手动选择中文或 English。
  • 选择“自动”时跟随系统语言。
  • 语言选择持久化,重启后仍生效。

3. 本轮非目标

明确不做:

  • 不接入 Moonshine。
  • 不接入 Parakeet。
  • 不接入 Qwen3-ASR。
  • 不做模型选择页。
  • 不做模型删除、回滚、清理。
  • 不做 30+ 语言列表。
  • 不做粤语作为独立语言版本。
  • 不做法语、德语、西班牙语、意大利语、葡萄牙语、俄语、乌克兰语等欧洲语言 UI。
  • 不根据语言切换自动删除任何模型。
  • 不强制老用户重新下载 SenseVoice。
  • 不改变用户词库、历史记录格式。
  • 不做正式安装包签名和 notarization。

4. 用户故事

4.1 中文系统的新用户

作为中文 macOS 用户,我第一次安装 VoiceSnap 后,应用应默认使用中文界面,并继续使用 SenseVoice。

验收点:

  • LanguageMode=auto
  • 有效语言解析为 zh-CN
  • UI 显示中文。
  • 默认模型仍为 sensevoice-zh
  • 新用户模型下载路径不退化。

4.2 English 系统的新用户

作为 English macOS 用户,我第一次安装 VoiceSnap 后,应用应默认显示 English UI。

验收点:

  • LanguageMode=auto
  • 有效语言解析为 en
  • UI 显示 English。
  • 本轮模型仍为 sensevoice-zh
  • 不出现 Moonshine 或 Parakeet。

说明:

Round 2 的 English 只是语言版本和 UI 准备。真正的 English 默认 Moonshine 在 Round 3 交付。

4.3 其他系统语言的新用户

作为法语、德语、日语等系统语言用户,本轮应用应默认进入 English UI,避免误判为中文。

验收点:

  • 系统语言不是中文且不是 English 时,有效语言为 en
  • UI 显示 English。
  • 模型仍为 sensevoice-zh

4.4 老用户升级

作为已有 VoiceSnap 用户,我升级到 Round 2 后,不应因为新增语言配置而丢失设置、词库、历史或模型。

验收点:

  • config.json 缺少 LanguageMode / LanguageID 时可以正常加载。
  • 默认补齐为 LanguageMode=auto
  • 中文用户有效语言为 zh-CN
  • SelectedModelID 兼容。
  • userdict.jsonhistory.json、模型目录不被修改。

4.5 用户手动切换语言

作为用户,我可以在设置页选择“自动、中文、English”。

验收点:

  • 选择中文后 UI 切到中文。
  • 选择 English 后 UI 切到 English。
  • 选择自动后根据系统语言解析有效语言。
  • 重启后保持选择结果。
  • 切换语言不触发模型下载、删除或迁移。

5. 配置规则

新增配置字段:

{
  "LanguageMode": "auto",
  "LanguageID": "zh-CN"
}

5.1 LanguageMode

允许值:

含义
auto 跟随系统语言
manual 使用用户手动选择的语言

非法值处理:

  • 回退为 auto
  • 记录日志。
  • 不中断 App 启动。

5.2 LanguageID

当前允许值:

含义 UI locale
zh-CN 中文 zh
en English en

非法值处理:

  • manual 模式下回退为 zh-CNen,具体规则由默认有效语言决定。
  • auto 模式下忽略非法 LanguageID,按系统语言重新解析。
  • 不中断 App 启动。

5.3 有效语言

后端需要提供一个确定性的有效语言解析:

EffectiveLanguage = Resolve(LanguageMode, LanguageID, SystemLocale)

规则:

条件 有效语言
LanguageMode=manualLanguageID=zh-CN zh-CN
LanguageMode=manualLanguageID=en en
LanguageMode=auto 且系统语言为中文 zh-CN
LanguageMode=auto 且系统语言为 English en
LanguageMode=auto 且系统语言为其他语言 en

6. LanguageProfile

Round 2 需要把 Round 1 的最小 language registry 扩展为:

zh-CN
en

建议字段:

type LanguageProfile struct {
    ID             string
    DisplayName    string
    NativeName     string
    UILocale       string
    SystemMatchers []string
    DefaultModelID string
}

Round 2 profile:

ID DisplayName NativeName UILocale SystemMatchers DefaultModelID
zh-CN Chinese 中文 zh zh, zh-CN, zh-Hans, zh-Hant sensevoice-zh
en English English en en, en-US, en-GB, en-AU, en-CA sensevoice-zh

注意:

  • en 的默认模型本轮仍是 sensevoice-zh
  • Round 3 再把 English 默认模型切换为 moonshine-en

7. 系统语言检测

系统语言检测必须在后端有确定实现,不能只依赖前端 navigator.language

优先级建议:

  1. macOS 系统 locale,例如 AppleLocale / AppleLanguages
  2. 环境变量 LANG / LC_ALL / LC_MESSAGES
  3. 无法读取时默认 en

研发实现时应提供可 mock 的检测接口,便于单元测试覆盖:

type SystemLocaleDetector interface {
    Detect() string
}

8. 前端交互

设置页新增“语言版本”区域。

中文 UI:

语言版本
自动(跟随系统)
中文
English

English UI:

Language
Automatic
Chinese
English

交互规则:

  • 使用单选或分段控制,不使用自由输入。
  • 当前选择必须有清晰选中状态。
  • 切换后立即保存。
  • 保存成功后 UI 文案立即切换。
  • 保存失败时保留原选择并显示现有风格的错误提示或静默回退日志,本轮不新增复杂弹窗。

9. 后端 API

建议新增或扩展 ConfigService

GetLanguageSettings() LanguageSettings
SetLanguageAuto() LanguageSettings
SetLanguageManual(languageID string) LanguageSettings

建议返回结构:

type LanguageSettings struct {
    LanguageMode        string
    LanguageID          string
    EffectiveLanguageID string
    UILocale            string
    Options             []LanguageOption
}

其中 Options 只包含:

  • zh-CN
  • en

如果研发希望直接扩展 GetConfig(),必须保证旧前端调用不破坏。

10. 验收标准

Round 2 必须全部满足:

  • 老配置缺少语言字段时可正常加载。
  • 新配置保存后包含 LanguageModeLanguageID
  • 中文系统 auto 解析为 zh-CN
  • English 系统 auto 解析为 en
  • 其他系统语言 auto 解析为 en
  • 手动选择中文后 UI 立即切到中文。
  • 手动选择 English 后 UI 立即切到 English。
  • 手动选择重启后仍生效。
  • 切换语言不删除、不迁移、不重新下载模型。
  • SelectedModelID 保持 sensevoice-zh
  • 词库、历史、热键、音频设备、Dock 设置不丢失。
  • 不出现 Moonshine、Parakeet、Qwen3-ASR。

11. 已知风险

风险 说明 处理
系统语言检测不稳定 macOS locale 来源可能有多个 使用 detector 抽象和 mock 测试
前后端语言源冲突 当前前端自己用 navigator.language Round 2 以后以前端从后端 effective language 为准
English UI 文案缺失 现有 i18n 已有 en.json,但可能不完整 QA 检查关键设置页和 onboarding
用户误解为英文模型 Round 2 English UI 仍用 SenseVoice 文档和 UI 不展示模型升级承诺
语言切换引发模型切换 本轮不应发生 QA 明确验证模型目录和 SelectedModelID 不变