Route B · MVP Plan

路线 B 计划:iPhone 实时转写 + Watch best-effort 触发(Focus/Shortcuts/Siri)

2026-02-01 · 个人使用 · iPhone-only realtime · Watch best-effort

保留“实时转写”,把 Watch 触发收敛为 best-effort(不承诺锁屏口袋 100% 唤起录音)

目标是尽快把“稳定可用”的 iPhone 实时转写做成每天能用的工具:中文识别(on-device 优先,失败再网络兜底),音频备份 10 天后自动删除,文本永久保留;入口以 iPhone 快捷键/锁屏触发为主,Apple Watch 只负责触发一个可见的状态切换(Focus),再由 iPhone 自动化尽力唤起 App。

MVPzh-CNOn-device → Network fallbackAudio retention: 10 daysTranscript: foreverBest-effort Watch trigger

What you get

实时转写
iPhone OK
手表一键
Best-effort
音频留存
10 天后删
文本留存
永久

交付物(MVP)

  • iPhone 端:开始/停止录音落盘实时转写(partial + final)。
  • 触发入口:App 内按钮 + voicetranscribe://start|stop|toggle(Shortcuts/Siri 可调用)。
  • Watch 触发:只做“可达时更方便”的 best-effort(Focus/Shortcuts/Siri),不写 100% 口袋唤起承诺。
  • 留存策略:音频 10 天清理(尽力定期跑 + 每次 stop/启动时必跑一次);文本永久。
  • 可验证的测试:Core 留存清理单测 + 设备手动测试清单(含失败路径)。

Best-minds 结论(把不确定性写进产品合同)

  • Shortcuts/Focus 专家视角:把 Watch 当“遥控开关”,Focus 是最稳的跨设备信号;但“后台无感开麦”不可依赖。
  • iOS 音频/语音工程视角:实时转写要先把音频会话、后台 Audio、权限弹窗做对;触发入口越少越稳。
  • 平台安全视角:麦克风属于高敏感权限,系统会主动阻止从后台/自动化悄悄录音;承诺 100% 很容易变成“产品债”。

Hard boundaries

明确不做(至少在 MVP)

  • 不做 watchOS App / Complication(只用 Watch 端 Shortcuts/Focus/Siri)。
  • 不承诺“锁屏 + 口袋 + 一键必开录”(只承诺 best-effort + 明确失败提示/替代路径)。
  • 不做云端同步/上传(后续再考虑 GitHub / Cloudflare R2 / Vercel)。
  • 不做说话人分离、长音频二次转写、复杂降噪。

必须面对的系统限制

  • Shortcuts/自动化对“打开 App/录音”这类敏感动作存在提示/限制,且不同 iOS 版本差异很大。
  • Watch 触发 iPhone 的即时性不稳定:取决于可达性、系统状态、是否需要解锁。
  • Speech on-device 能力与机型/系统/语言包有关;必须准备网络兜底路径。

体验路径(把“失败”也设计出来)

主路径:iPhone 一键(推荐)

  1. 用户通过 Action Button / 锁屏小组件 / Back Tap 触发快捷指令。
  2. 快捷指令:打开 URLvoicetranscribe://toggle
  3. App 前台/可唤起时:立即开始录音 + 实时转写;屏幕可锁,录音继续。
  4. 录制结束:写入 meta.json / transcript.json,并触发一次“清理旧音频”。

辅助路径:Watch 一键(Best-effort)

  1. Watch Complication 运行快捷指令:切换 Focus Recording
  2. iPhone 自动化(Focus 开启/关闭)尽力执行:
    • 理想:打开 URL(start/stop)。
    • 保底:显示通知/震动提示“点开开始/结束”。
  3. 如果 iPhone 需要解锁/无法后台开麦:用户看到明确提示,不会误以为“已经在录”。
产品合同(非常关键):“Watch 触发 ≠ 录音必定开始”。我们把它定义成 best-effort,并在失败时给出清晰反馈与下一步(打开 App 即可开始)。

系统结构(单端实时 + 双端触发)

Apple Watch Shortcuts / Siri Focus: Recording toggle as signal iPhone Automation best-effort actions Deep Link voicetranscribe:// iPhone App start/stop + UI Audio Capture AVAudioEngine Speech on-device → network Store files Cleaner 10d audio 不保证可唤起;失败则走通知/打开 App
结构图:iPhone 端负责“确定性能力”(录音+转写+存储+清理);Watch 端只负责“尽力触发”。

实施路线(按可验证里程碑)

Milestone 做什么 怎么验收(你能亲手验证)
M0 · 触发链路跑通
  • iPhone 建 Focus:Recording
  • iPhone 自动化:当 Recording 开启/关闭时执行“无争议动作”(通知/计时器)
  • Watch Complication:一键切换 Focus
你在 Watch 点一下,iPhone 锁屏也能稳定出现“通知/计时器变化/Focus 状态变化”。
M1 · iPhone 实时转写 MVP
  • 实现录音 + 实时转写(zh-CN,on-device 优先,失败改网络兜底)
  • 文件存储:meta.json / transcript.json / audio.caf
  • 停止时写入录制时长并触发一次“旧音频清理”
App 前台点击开始/停止:能看到实时文字滚动;录音结束后能在本地目录看到 3 个文件。
M2 · Shortcuts/Siri 接入
  • 支持 deep link:voicetranscribe://start|stop|toggle
  • 提供 3 个快捷指令模板:REC Start/REC Stop/REC Toggle
  • 把 iPhone 入口落在:Action Button / 锁屏小组件 / Back Tap / Siri
锁屏点一下快捷指令:App 被唤起并开始录音(或明确提示需要解锁/打开 App)。
M3 · 留存清理与“失败可见”
  • 音频 10 天清理:启动/停止时必跑 + 尽力后台任务
  • 失败提示:任何“触发未能开始录音”的情况都有明确反馈(通知/状态)
  • 导出:把转录文本导出到一个长期文件(Markdown/纯文本)
制造一个 11 天前的音频文件,触发清理后音频被删但 transcript 仍在;Watch 触发失败时能看到提示。

Best-effort 触发:可靠性矩阵(写进预期)

Trigger Unlocked Locked Pocket Overall App 内按钮(前台) 3/3 2/3 2/3 3/3 iPhone 快捷指令打开 URL 3/3 2/3 1/3 2/3 Focus 自动化 → 打开 URL 2/3 1/3 1/3 1/3 Watch 切 Focus(best-effort) 2/3 1/3 1/3 1/3 Siri 口令(视系统而定) 2/3 1/3 1/3 1/3
数据图:绿色越深越可靠。“Pocket”列(锁屏口袋)不写承诺,统一按 best-effort 处理,并设计失败可见。

测试策略(先把可测的做成可测)

自动化测试(现在就能跑)

  • Core:留存清理单测(删音频不删文本/元数据)。
  • Core:文件结构与 JSON 编解码(可加更多边界测试)。
当前已跑通的命令
CLANG_MODULE_CACHE_PATH=/tmp/clang-module-cache   swift test --disable-sandbox --package-path apps/voiceTranscribeMVP/VoiceTranscribeCore

设备手动测试(必须做)

  • 权限:首次授权麦克风/语音识别后的行为。
  • 识别:on-device 可用/不可用 → 网络兜底是否正常。
  • 触发:
    • iPhone(Action Button/锁屏小组件/Back Tap)
    • Watch(切 Focus → iPhone 自动化)
  • 失败路径:无法开录时必须给出“你现在没在录”的信号。

风险与对策(提前写掉未来的坑)

风险:触发不稳定 → 用户误判

  • 对策:任何 start/toggle 都要落一个“可见状态”(通知/状态条/音效/震动)。
  • 对策:失败时明确提示“需要解锁/打开 App 才能开始”。

风险:功耗/发热/存储

  • 对策:默认 PCM .caf 先跑通;后续切 AAC .m4a 降体积。
  • 对策:音频 10 天清理必跑;给一个手动“立即清理”入口。

风险:on-device 不可用

  • 对策:先尝试 on-device;失败自动切网络兜底,并把原因写入 meta(便于你排查)。

风险:分发与安装

  • 对策:MVP 先按“你自己能装到手机上”的方式推进(后续再决定是否上架/付费账号)。

Closing summary

一句话总结

路线 B 的核心是:把价值压在 iPhone 端“确定性实时转写” 上;把 Watch 触发定义为 best-effort,并把失败设计成“可见、可纠正”。

One next action

先按 docs/shortcuts_runbook.md 跑通 “Watch 切 Focus → iPhone 自动化无提示执行” 的链路(用通知/计时器验证),跑通后再把自动化动作替换成“打开 URL”。

先把“能稳定工作”的部分做到极致,再把“不稳定的触发”标成 best-effort。
Route B · Product Contract