edit | blame | history | raw

Round 1 研发任务拆解:模型 Profile 基础设施

状态:v0.1 研发拆解稿
所属子项目:02-P-NBL
Round:Round 1
日期:2026-06-02
输入文档:

1. 研发目标

Round 1 的研发目标是:

在不改变用户体验的前提下,把现有 SenseVoice 单模型实现改造成可扩展的 ModelProfile 架构。

本轮不接入 Moonshine、Parakeet、Qwen3-ASR,不做语言 UI,不做模型选择 UI。

2. 交付边界

2.1 必须交付

  • ModelProfile / ModelRegistry
  • LanguageProfile / LanguageRegistry 最小实现
  • RequiredFileRule,支持 allOf / anyOf
  • ModelInstallState,读写 models/state.json
  • ModelResolver,支持 state、新目录、旧目录 fallback
  • ResolvedModel
  • sensevoice-zh profile
  • SelectedModelID 隐藏配置,默认 sensevoice-zh
  • EngineFactory 初步实现
  • SenseVoice 新旧路径兼容
  • 下载器 staging + required files 校验 + 安全落盘
  • Wails public API 兼容
  • 自动化测试覆盖核心解析、校验、状态文件、下载失败保护

2.2 明确不交付

  • Moonshine 真实模型接入
  • Parakeet 真实模型接入
  • Qwen3-ASR 真实模型接入
  • 语言设置 UI
  • 模型选择 UI
  • 模型删除 UI
  • 旧模型目录自动迁移
  • 每个模型目录下的 manifest.json
  • checksum / 签名校验
  • 远程模型 catalog

3. 推荐任务顺序

T0 代码现状确认
T1 Profile / Registry 基础类型
T2 Required files 校验器
T3 Install state 读写
T4 ModelResolver
T5 Config 兼容与 SelectedModelID
T6 EngineFactory 改造
T7 下载器安全安装
T8 EngineService / Wails 兼容
T9 自动化测试
T10 开发自查与交付说明

建议按顺序推进。T1-T5 是地基,T6-T8 是业务接入,T9-T10 是进入 QA 前的门禁。

4. 任务明细

T0:代码现状确认

负责人:后端
类型:准备任务
建议文件:

  • privatevoice.src/internal/engine/engine.go
  • privatevoice.src/internal/engine/engine_darwin.go
  • privatevoice.src/internal/model/downloader.go
  • privatevoice.src/internal/paths/paths.go
  • privatevoice.src/internal/config/config.go
  • privatevoice.src/services/engine_service.go
  • privatevoice.src/frontend/src/App.svelte
  • privatevoice.src/frontend/src/components/onboarding/OnboardingView.svelte

工作内容:

  • 标出当前写死 SenseVoice 的路径。
  • 标出前端 Wails 调用链。
  • 标出下载器中会删除旧目录的风险点。
  • 确认当前测试命令和前端构建命令。

完成标准:

  • 形成代码改动前 checklist。
  • 明确哪些 public API 不允许改签名。

T1:Profile / Registry 基础类型

负责人:后端
建议文件:

  • privatevoice.src/internal/model/profile.go
  • privatevoice.src/internal/model/registry.go

工作内容:

  • 新增 ModelProfile
  • 新增 LanguageProfile
  • 新增 RequiredFileRule 类型。
  • 新增 sensevoice-zh profile。
  • 新增 zh-CN language profile。
  • 提供 GetModelProfile(id)DefaultModelProfile()ListModelProfiles() 等最小 registry 方法。

关键要求:

  • ModelProfile 使用 SupportedLanguageIDsRecommendedFor 两个字段,不混用。
  • sensevoice-zhInstallDirNamesensevoice-zh
  • BackendKindsensevoice

完成标准:

  • 未知 model id 返回明确错误。
  • 默认 profile 为 sensevoice-zh
  • 单元测试覆盖 registry 查询。

T2:Required files 校验器

负责人:后端
建议文件:

  • privatevoice.src/internal/model/validator.go

工作内容:

  • 实现 RequiredFileRuleAllOf / AnyOf 校验。
  • 文件不存在视为失败。
  • 文件为 0 字节视为失败。
  • 对 SenseVoice 输出角色化文件路径:modeltokens
  • 同时存在 model.int8.onnxmodel.onnx 时优先选择 model.int8.onnx

完成标准:

  • 只有 model.onnx 时可通过。
  • 只有 model.int8.onnx 时可通过。
  • 两个模型文件都存在时选择 int8。
  • 缺少 tokens.txt 时失败。
  • 0 字节 required file 失败。

T3:Install state 读写

负责人:后端
建议文件:

  • privatevoice.src/internal/model/install_state.go
  • privatevoice.src/internal/paths/paths.go

工作内容:

  • 新增 paths.ModelInstallDir(name string)
  • 新增 paths.ModelStatePath()
  • 实现 models/state.json 最小 schema。
  • path 字段存相对 models 根目录路径。
  • 非法 JSON、空文件、未知 model id 都不能 panic。

完成标准:

  • state 不存在时返回空状态。
  • state 非法 JSON 时返回可恢复错误,由 Resolver fallback。
  • state 写入失败不阻塞旧模型加载。

T4:ModelResolver

负责人:后端
建议文件:

  • privatevoice.src/internal/model/resolver.go

工作内容:

  • 实现 ResolvedModel
  • 实现安装状态枚举。
  • 路径候选顺序:
  1. state 中 sensevoice-zh 记录路径
  2. models/sensevoice-zh
  3. models/sensevoice
  • 每个候选目录都执行 required files 校验。
  • state 指向坏目录时继续 fallback。
  • 新旧目录都完整且无 state 时使用新目录。

完成标准:

  • 旧目录完整时可解析。
  • 新目录完整时可解析。
  • state 损坏时可 fallback。
  • 不完整目录不会被解析为可用。
  • 返回 ResolvedModel.Files["model"]ResolvedModel.Files["tokens"]

T5:Config 兼容与 SelectedModelID

负责人:后端
建议文件:

  • privatevoice.src/internal/config/config.go

工作内容:

  • 新增隐藏字段 SelectedModelID string
  • 老配置缺失该字段时默认 sensevoice-zh
  • 空值或未知 model id 回退 sensevoice-zh
  • 保存配置时不得丢失旧字段。
  • 保留 ModelDownloadUrlFallbackModelDownloadUrl

完成标准:

  • config.json 可正常加载。
  • ConfigService.GetConfig() 返回兼容旧前端的数据。
  • 新字段不会要求 UI 改动。

T6:EngineFactory 改造

负责人:后端
建议文件:

  • privatevoice.src/internal/engine/engine.go
  • privatevoice.src/internal/engine/factory.go
  • privatevoice.src/internal/engine/engine_darwin.go
  • privatevoice.src/internal/engine/engine_linux.go
  • privatevoice.src/internal/engine/engine_windows.go

工作内容:

  • 保留 engine.New()
  • 新增内部入口 NewWithModelID(modelID string)
  • 新增内部入口 NewWithResolvedModel(resolved model.ResolvedModel)
  • 平台 newPlatformEngine 改为接收 ResolvedModel
  • SenseVoice config 使用 resolved.Files["model"]resolved.Files["tokens"]
  • 用户可见 HardwareInfo() 保持 SenseVoice · CoreML/CPU 风格。

完成标准:

  • 调用方不用再直接拼 SenseVoice 路径。
  • 不完整模型不会进入 sherpa 初始化。
  • sherpa 初始化失败不导致 App 崩溃。

T7:下载器安全安装

负责人:后端
建议文件:

  • privatevoice.src/internal/model/downloader.go

工作内容:

  • 保留旧外部调用能力。
  • 内部按默认 profile sensevoice-zh 安装。
  • 下载到 models/.downloads/sensevoice-zh/<run-id>
  • 解压到临时 extract 目录。
  • 校验 staging 目录 required files。
  • 校验通过后安装到 models/sensevoice-zh
  • 写入或更新 models/state.json
  • 下载失败、解压失败、校验失败不得破坏旧 models/sensevoice

完成标准:

  • 不再直接 RemoveAll(models/sensevoice)
  • 半成品不会被 Resolver 误判为可用。
  • 下载失败后可再次重试。

T8:EngineService / Wails 兼容

负责人:后端 + 前端确认
建议文件:

  • privatevoice.src/services/engine_service.go
  • privatevoice.src/frontend/src/App.svelte
  • privatevoice.src/frontend/src/components/onboarding/OnboardingView.svelte

工作内容:

  • 保持 EngineService.ModelExists() bool 签名。
  • 保持 EngineService.DownloadModel(primaryURL, fallbackURL) error 签名。
  • ModelExists() 返回当前 default/selected model 是否完整可用。
  • 目录不完整时返回 false。
  • 保持 model:download-progress payload。
  • 保持 engine:status 事件语义。

完成标准:

  • 前端无需改调用即可运行。
  • ModelExists -> need_model -> OnboardingView -> DownloadModel -> ready 链路正常。
  • 不出现新模型 UI。

T9:自动化测试

负责人:后端 + QA 协作
建议文件:

  • privatevoice.src/internal/model/*_test.go
  • 必要时补充 engine 相关测试

最低测试集:

  • registry 默认模型。
  • required files allOf / anyOf
  • int8 优先。
  • state 缺失 fallback。
  • state 非法 JSON fallback。
  • state 指坏目录 fallback。
  • 新旧目录优先级。
  • 不完整目录不可用。
  • SelectedModelID 默认和无效值回退。
  • 下载失败不破坏已有目录。

完成标准:

  • Go 单元测试通过。
  • 测试能在无真实大模型的 fixture 目录下运行。

T10:开发自查与交付说明

负责人:研发负责人
建议文件:

  • 02-P-NBL/round-1/dev-checklist.md

工作内容:

  • 记录开发自查结果。
  • 记录执行过的命令和结果。
  • 记录手工 smoke 结果。
  • 记录仍需 QA 覆盖的风险。

完成标准:

  • 开发自查完成后才能移交 QA。
  • 交付说明包含变更范围、测试范围、已知风险。

5. 依赖关系

任务 依赖
T1 T0
T2 T1
T3 T1
T4 T1, T2, T3
T5 T1
T6 T4, T5
T7 T2, T3, T4
T8 T4, T6, T7
T9 T1-T8
T10 T9

6. 研发完成定义

Round 1 研发完成必须同时满足:

  • 所有必须交付项已实现。
  • 旧 Wails public API 未破坏。
  • 老用户旧目录场景可用。
  • 新用户下载路径可用。
  • 不完整模型不会进入 engine。
  • 下载失败不会破坏已有完整模型。
  • Go 单元测试通过。
  • 前端构建或现有前端检查通过。
  • 研发自查记录完成。

7. 进入 QA 的交付包

研发移交 QA 时应提供:

  • 分支名 / commit id。
  • 变更文件列表。
  • 开发自查记录。
  • 执行命令和结果。
  • 测试 fixture 说明。
  • 已知风险。
  • 需要 QA 特别关注的路径:
  • 旧目录兼容。
  • state 损坏 fallback。
  • 下载失败保护。
  • Wails API 兼容。
  • 断网已有模型识别。