# Round 3 研发任务拆解:Moonshine English 默认模型 状态:v0.1 研发拆解稿 所属子项目:`02-P-NBL` Round:Round 3 日期:2026-06-03 输入文档: - [`prd.md`](prd.md) - [`../engineering-plan.md`](../engineering-plan.md) - [`../plan.md`](../plan.md) ## 1. 研发目标 Round 3 的研发目标是: ```text English effective language 默认使用 moonshine-en,并通过 sherpa-onnx Moonshine v1 完成英文离线识别。 ``` 本轮必须保持中文 SenseVoice 路径不退化。 ## 2. 交付边界 ### 2.1 必须交付 - `moonshine-en` model profile。 - `BackendMoonshine` backend kind。 - English language profile 的 `DefaultModelID=moonshine-en`。 - 当前模型解析器:effective language + model selection mode。 - Moonshine required files 校验。 - Moonshine 下载、解压、安装、状态记录。 - Moonshine sherpa config builder。 - Engine factory 支持 SenseVoice 和 Moonshine 分发。 - Onboarding 改为下载 current model profile。 - 语言切换后同步 current model 状态。 - 单元测试覆盖 profile、resolver、下载校验、backend 分发。 - 开发自查、QA handoff。 ### 2.2 明确不交付 - Parakeet。 - Qwen3-ASR。 - Moonshine v2。 - 模型选择页。 - 模型删除 UI。 - 高级模型切换 UI。 - 30+ 语言列表。 - 正式签名和 notarization。 ## 3. 推荐任务顺序 ```text T0 代码现状确认 T1 Moonshine profile T2 默认模型解析器 T3 Engine factory/backend builder T4 Onboarding 下载 current model T5 语言切换后的模型同步 T6 前端文案与状态展示 T7 单元测试 T8 开发自查 T9 QA handoff ``` ## 4. 任务明细 ### T0:代码现状确认 负责人:后端 + 前端 类型:准备任务 重点文件: - `privatevoice.src/internal/model/profile.go` - `privatevoice.src/internal/model/registry.go` - `privatevoice.src/internal/model/downloader.go` - `privatevoice.src/internal/model/install_state.go` - `privatevoice.src/internal/config/config.go` - `privatevoice.src/internal/language/resolver.go` - `privatevoice.src/internal/engine/engine.go` - `privatevoice.src/internal/engine/engine_darwin.go` - `privatevoice.src/services/engine_service.go` - `privatevoice.src/services/config_service.go` - `privatevoice.src/frontend/src/components/onboarding/OnboardingView.svelte` - `privatevoice.src/frontend/src/App.svelte` 完成标准: - 明确哪些 API 仍写死 SenseVoice。 - 明确 config 默认值和旧配置兼容策略。 - 明确前端 onboarding 当前调用路径。 ### T1:Moonshine profile 负责人:后端 建议文件: - `privatevoice.src/internal/model/profile.go` - `privatevoice.src/internal/model/registry.go` - `privatevoice.src/internal/model/model_test.go` 工作内容: - 新增常量: - `MoonshineModelID = "moonshine-en"` - `BackendMoonshine = "moonshine"` - 新增 `moonshine-en` profile。 - English language profile 的 `DefaultModelID` 改为 `moonshine-en`。 - 配置 required files: - `preprocess.onnx` - `encode.int8.onnx` - `uncached_decode.int8.onnx` - `cached_decode.int8.onnx` - `tokens.txt` - `ProviderOrder` 使用 `cpu`。 - `DownloadURLs` 使用官方 base-en-int8 URL。 完成标准: - `GetModelProfile("moonshine-en")` 可返回完整 profile。 - `ListModelProfiles()` 顺序稳定。 - `NormalizeModelID("moonshine-en")` 返回自身。 - Moonshine 缺任意 required file 时校验失败。 ### T2:默认模型解析器 负责人:后端 建议文件: - `privatevoice.src/internal/config/config.go` - `privatevoice.src/internal/language/resolver.go` - `privatevoice.src/internal/model/registry.go` - `privatevoice.src/internal/model/selection.go` - `privatevoice.src/internal/model/selection_test.go` 工作内容: - 新增配置字段: - `ModelSelectionMode string` - 允许值: - `auto` - `manual` - 旧配置缺字段时默认 `auto`。 - 新增 current model resolver: ```text ResolveCurrentModel(cfg, detector) ``` - 规则: - auto 模式按 effective language 的 `DefaultModelID`。 - manual 模式按 `SelectedModelID`。 - manual 非法时 fallback 到 effective language 默认模型并记录日志。 完成标准: - English fresh config 解析为 `moonshine-en`。 - Chinese fresh config 解析为 `sensevoice-zh`。 - 旧 Round 2 config 没有 `ModelSelectionMode` 时不会锁死在 SenseVoice。 - 单元测试覆盖 auto/manual/非法值。 ### T3:Engine factory/backend builder 负责人:后端 建议文件: - `privatevoice.src/internal/engine/engine.go` - `privatevoice.src/internal/engine/engine_darwin.go` - `privatevoice.src/internal/engine/engine_test.go` 工作内容: - `NewWithResolvedModel` 不再只允许 `BackendSenseVoice`。 - 根据 `resolved.BackendKind` 分发到: - `buildSenseVoiceConfig` - `buildMoonshineConfig` - SenseVoice builder 保持现有逻辑。 - Moonshine builder 设置: ```go config.ModelConfig.Moonshine.Preprocessor = resolved.Files["preprocessor"] config.ModelConfig.Moonshine.Encoder = resolved.Files["encoder"] config.ModelConfig.Moonshine.UncachedDecoder = resolved.Files["uncached_decoder"] config.ModelConfig.Moonshine.CachedDecoder = resolved.Files["cached_decoder"] config.ModelConfig.Tokens = resolved.Files["tokens"] config.ModelConfig.Provider = "cpu" ``` - `HardwareInfo()` 对 Moonshine 显示可区分信息,例如 `Moonshine English · CPU`。 完成标准: - SenseVoice 初始化路径不变。 - Moonshine 初始化可执行。 - 未知 backend 返回明确错误。 - 初始化失败日志包含 model id、backend、provider。 ### T4:Onboarding 下载 current model 负责人:后端 + 前端 建议文件: - `privatevoice.src/services/engine_service.go` - `privatevoice.src/frontend/src/components/onboarding/OnboardingView.svelte` - `privatevoice.src/frontend/src/App.svelte` 工作内容: - 新增 `EngineService.GetCurrentModelStatus()` 或等价 API。 - 新增 `EngineService.DownloadCurrentModel()`。 - `ModelExists()` 检查 current model。 - 前端 onboarding 调用 `DownloadCurrentModel()`,不再传 config URL。 - 下载进度事件沿用 `model:download-progress`。 - 下载完成后调用 init callback 重新初始化。 完成标准: - English fresh user 下载 Moonshine。 - Chinese fresh user 下载 SenseVoice。 - 不再由前端决定模型 URL。 - 下载失败可重试。 ### T5:语言切换后的模型同步 负责人:后端 + 前端 建议文件: - `privatevoice.src/services/config_service.go` - `privatevoice.src/services/engine_service.go` - `privatevoice.src/frontend/src/components/settings/GeneralPage.svelte` - `privatevoice.src/frontend/src/App.svelte` 工作内容: - `SetLanguageAuto()` / `SetLanguageManual()` 后,前端刷新 current model 状态。 - 如果当前模型未安装,进入 need_model/onboarding。 - 如果当前模型已安装,重新初始化引擎。 - 切换失败时显示错误,不删除旧模型。 完成标准: - 中文切 English:如 Moonshine 未安装,提示下载。 - English 切中文:如 SenseVoice 已安装,恢复 SenseVoice。 - 重启后按同样规则解析 current model。 ### T6:前端文案与状态展示 负责人:前端 建议文件: - `privatevoice.src/frontend/src/lib/i18n/zh.json` - `privatevoice.src/frontend/src/lib/i18n/en.json` - `privatevoice.src/frontend/src/components/onboarding/OnboardingView.svelte` 工作内容: - Onboarding 文案避免写死“同步中文模型”。 - English UI 下文案应明确正在准备 offline speech model。 - 中文 UI 下文案仍自然。 - 状态展示不需要新增模型管理页。 完成标准: - English onboarding 没有中文文案。 - 中文 onboarding 没有英文突兀文案。 - 下载 MB 进度显示正常。 ### T7:单元测试 负责人:后端 + 前端 后端至少覆盖: - Moonshine profile 查询。 - Moonshine required files 校验。 - English default model 为 `moonshine-en`。 - Chinese default model 为 `sensevoice-zh`。 - old config 缺 `ModelSelectionMode` fallback。 - current model resolver。 - unknown backend error。 - SenseVoice builder 不退化。 前端至少覆盖: - build 通过。 - onboarding 不再调用旧 URL 参数 API。 - 语言切换后会刷新 engine/model 状态。 建议命令: ```bash cd privatevoice.src go test ./... cd privatevoice.src/frontend npm run build ``` ### T8:开发自查 负责人:研发 必须执行: ```bash cd privatevoice.src/frontend npm run build cd privatevoice.src go test ./... -count=1 git diff --check ``` 自查结论必须记录: - 变更范围。 - 测试命令和结果。 - 未覆盖风险。 - 是否进入 QA。 ### T9:QA handoff 负责人:研发 + QA QA 移交必须包含: - commit。 - 变更范围。 - 测试命令。 - 当前模型下载 URL。 - 英文新用户测试方式。 - 中文老用户回归方式。 - 已知风险。