MVP 前后端设计方案 · 大模型识别 · 流式实时上屏 · 全平台
| 版本 | 日期 | 变更 |
|---|---|---|
| v0.2 | 2026-06-11 | 引入 design/ 官方设计系统后修订:① 计费模型由"订阅制 + 每日免费 10 分钟"改为时长包(不过期)+ 每日免费试用 3 分钟;② 第八章 mockup 已被设计系统高保真稿取代,正式以 design/ui_kits/ 为准;③ 数据表 plans/subscriptions 废弃,改时长账本。详细设计见配套文档:前端实现设计 v1.0 · 后端与数据架构 v1.0 |
| v0.3 | 2026-06-11 | 新增两项能力并更新配套文档至 v1.1:① 客户端打点(响应时间等指标采集与批量上报,监控首字延迟等体验目标);② 反馈问题(设置内提交文字 + 图片 + 诊断信息)。详见 前端实现设计 v1.1 第八/九章 · 后端与数据架构 v1.1 3.5/3.6 |
| v0.1 | 2026-06-11 | 初版 MVP 前后端设计方案 |
一款付费语音输入法,核心卖点:大模型识别准确度 + 流式实时上屏 + 极简交互。
| MVP 需求 | 说明 |
|---|---|
| 全平台覆盖 | Mac / Windows / iPhone / iPad / Android |
| 大模型识别 | 使用云厂商大模型 ASR,识别准确率显著优于传统方案 |
| 极简交互 | 桌面端:焦点在输入框时按住全局快捷键说话;移动端:键盘上按住按键说话 |
| 流式识别 | 说话过程中识别结果实时显示,不等说完 |
| 商业化 | 付费软件:微信登录 + 微信支付购买时长包 |
| 性能 | 识别快、无可感知卡顿(首字延迟 P95 < 500ms) |
| 决策点 | 选择 | 理由 |
|---|---|---|
| ASR 引擎 | 国内云厂商大模型流式 ASR 首选:阿里云百炼 gummy-realtime-v1备选:火山引擎豆包流式 ASR |
原生 WebSocket 流式、国内延迟低、自带标点/ITN/中英混说、按量计费免运维。通过 Provider 抽象接口接入,可随时切换 |
| 后端语言 | Go | 本质是 WS 流式中继 + 业务 CRUD,瓶颈在云端 ASR 而非自身代码,Rust 性能优势体现不出来;微信支付有官方 Go SDK(wechatpay-go);goroutine 天然适合"每连接一个转发循环";开发速度快 |
| 桌面端 | Tauri 2 + Rust | 体积小(~10MB)、常驻内存低;Rust 侧做全局快捷键/音频采集/文字注入等系统层;一套代码出 Mac + Windows |
| 移动端形态 | 系统第三方输入法(键盘扩展) | iOS Keyboard Extension / Android InputMethodService,按住说话直接上屏到任意 App,体验最佳。iOS 麦克风限制为最高风险项(见风险章节) |
| 移动端技术 | Swift / Kotlin 各自原生 | 协议简单(WS + JSON + PCM),不值得引入跨端框架的复杂度;输入法扩展本身必须原生 |
┌─────────────┐ ┌─────────────┐ ┌──────────────────┐
│ 桌面端 Tauri │ │ iOS/Android │ │ │
│ Mac/Windows │ │ 键盘扩展 │ │ 微信开放平台 │
└──────┬──────┘ └──────┬──────┘ │ (OAuth/支付回调) │
│ WSS 音频流 │ └────────┬─────────┘
▼ ▼ │
┌──────────────────────────────────────────────────────┐
│ Go 后端(单体起步) │
│ ┌─────────┐ ┌───────────┐ ┌─────────┐ ┌──────────┐ │
│ │ auth │ │asr-gateway│ │ billing │ │ quota │ │
│ │ 微信登录 │ │ WS 流式中继│ │ 微信支付 │ │ 用量/配额 │ │
│ └─────────┘ └─────┬─────┘ └─────────┘ └──────────┘ │
└────────────────────┼─────────────────────────────────┘
│ WSS(同区域部署,内网级延迟)
▼
┌─────────────────────┐ ┌──────────────┐
│ 阿里云百炼 Gummy │ │ PostgreSQL │
│ (流式大模型 ASR) │ │ + Redis │
└─────────────────────┘ └──────────────┘
wechatpay-go 官方 SDKserver/
cmd/server/main.go
internal/
auth/ 微信 OAuth(扫码 + App 登录)、JWT 签发与中间件
asr/ Provider 接口 + gummy / volcano 两个实现
gateway/ WS /v1/asr/stream 处理器(核心)
billing/ 微信支付下单、回调验签、订单状态机
quota/ 用量计量(Redis INCR + 异步落库)、试用/余额校验
user/ 用户、设备 CRUD、时长包查询
store/ gorm models + migrations
pkg/protocol/ 客户端协议常量与消息结构(5 端对齐的唯一真相源)
type Provider interface {
// 建立一次流式识别会话
StartSession(ctx context.Context, cfg SessionConfig) (Session, error)
}
type Session interface {
SendAudio(pcm []byte) error // 推 100ms 音频帧
Results() <-chan Result // {Text, IsFinal, BeginTime, EndTime}
Close() error
}
MVP 实现 gummy provider(DashScope WebSocket API,原生流式、自带标点和 ITN、中英混说)。
/v1/asr/stream)| 方向 / 类型 | 内容 |
|---|---|
| 上行 · 二进制帧 | 16kHz / 16bit / mono PCM,每 100ms 一帧(3200 字节) |
| 上行 · 文本帧 | {"type":"start","sample_rate":16000} / {"type":"stop"} |
| 下行 · partial | {"type":"partial","text":"今天天气"} — 增量结果,客户端实时刷新浮层 |
| 下行 · final | {"type":"final","text":"今天天气不错。"} — 句子定稿,客户端执行注入 |
| 下行 · error | {"type":"error","code":"QUOTA_EXCEEDED","message":"..."} |
鉴权:连接时带 Authorization: Bearer <JWT>。连接为长连接 + ping/pong 心跳,客户端启动时即预连接,按下快捷键时零握手开销。
| 端 | 方式 | 微信平台应用类型 |
|---|---|---|
| 桌面端 | 扫码登录:后端生成带 state 的二维码页 → 手机微信扫码授权 → 回调 → 客户端轮询 GET /v1/auth/qr/:state 拿 JWT | 网站应用 |
| 移动端 | 主 App 集成微信 OpenSDK 拉起授权 → code 换 token | 移动应用 |
用 unionid 关联同一用户的多端身份(桌面扫码与手机 App 登录是两个不同 openid)。
POST /v1/pay/notify:验签 → 订单状态机(pending → paid)→ 时长入账QUOTA_EXCEEDED。详见后端与数据架构 v1.0 第五章users、wechat_identities、duration_packs、orders、balance_ledger(时长账本)、trial_usage(每日试用)、asr_sessions、devices
一句话总结:PostgreSQL 管"钱和账"(强一致、持久),Redis 管"快和临时"(计数器、带过期时间的状态)。
| 表 | 用途 |
|---|---|
| users / wechat_identities | 用户账号,微信 openid/unionid 与用户的关联 |
| duration_packs / orders | 时长包定义(服务端可配)、微信支付订单——支付回调验签后改状态,钱相关数据必须强一致、可审计 |
| balance_ledger / trial_usage | 时长账本(只追加,余额 = 合计)与每日免费试用用量(180 秒/天,自然日重置) |
| asr_sessions | 每次识别会话的用量明细(时长、试用/余额扣减拆分),用于对账与数据分析 |
特点:写入频率低、绝对不能丢,且需要事务("回调到账 → 订单置为已支付 → 时长入账"必须原子完成)。
INCR 实时计数,后台异步批量落库到 balance_ledger / asr_sessions;按下快捷键 → 浮层弹出(光标附近)→ 采集音频流式上传 → partial 结果实时显示在浮层 → 松开快捷键 → final 注入焦点输入框 → 浮层消失
| 模块 | 方案 |
|---|---|
| 全局快捷键 | tauri-plugin-global-shortcut;默认按住 Cmd/Ctrl + Shift + Space 说话(press 开始 / release 结束)。macOS 监听 Fn 键需 CGEventTap,二期再做 |
| 音频采集 | cpal 采集 + 重采样到 16kHz mono PCM,100ms 分帧 |
| WebSocket | tokio-tungstenite,启动即预连接、断线指数退避重连 |
| 文字注入 macOS | 写剪贴板 → CGEvent 模拟 Cmd+V → 恢复剪贴板(兼容性最好);需引导用户授予辅助功能权限,首次启动做权限引导页 |
| 文字注入 Windows | SendInput + KEYEVENTF_UNICODE 直接注入 Unicode,无需剪贴板 |
| 浮层窗口 | Tauri 无边框 / 置顶 / 透明 / 不抢焦点(关键:focusable: false,否则焦点离开目标输入框)小窗,显示实时文本 + 音量波形 |
textDocumentProxy.insertText 上屏;InputMethodService):自绘键盘 + 按住说话,RECORD_AUDIO 权限即可在 IME 内录音(无 iOS 式限制),currentInputConnection.commitText 上屏,成熟可控。实施顺序:先 Android 后 iOS(风险低、验证快)。两端不引入跨端框架,Swift / Kotlin 各自原生实现协议(对齐 server/pkg/protocol)。
design/ 官方设计系统的高保真稿取代(计费已改时长包、视觉禁用渐变/emoji)。正式界面以 design/ui_kits/ 演示与前端实现设计 v1.0 为准,本章仅作历史记录保留。界面清单:① 识别浮层② 系统托盘菜单③ 设置窗口④ 登录/购买窗口
按下快捷键瞬间弹出在光标附近,不抢焦点;松开快捷键注入文字后淡出。
/v1/auth/qr),手机扫码授权后自动登录并关闭;界面清单:① 键盘面板(核心)② 候选/partial 文本条③ 未登录/超额提示态
MVP 键盘策略:以语音为主键盘——大麦克风按键 + 一行常用功能(切回系统键盘、退格、回车、标点),不做完整 26 键(降低开发量,用户在语音和系统键盘间一键切换)。
insertText 上屏,partial 显示在键盘自带的文本条里(不直接写入宿主输入框,避免修正抖动);界面清单:① 启用引导页② 登录页③ 套餐购买页④ 我的(用量/订阅管理)
| 页面 | 内容与交互 |
|---|---|
| ① 启用引导页 | 三步卡片式引导:添加键盘 →(iOS)开启完全访问 → 试一试(内置输入框练习)。每步带系统设置深链与动图示意 |
| ② 登录页 | 单按钮"微信一键登录"(拉起微信 OpenSDK),登录后 token 写入 App Group 供键盘扩展使用 |
| ③ 套餐购买页 | 免费版 vs 会员对比表 + 月/年价格卡片,点击拉起微信 APP 支付,支付回调后即时解锁 |
| ④ 我的 | 本月用量进度条、订阅到期时间、麦克风/键盘权限自检(异常时红点提示并跳设置) |
dudu/ server/ Go 后端 desktop/ Tauri 2(Mac + Windows) android/ Kotlin:主 App + IME Service ios/ Swift:主 App + Keyboard Extension docs/ 协议文档、架构决策记录
| 阶段 | 内容 | 周期 |
|---|---|---|
| M0 风险验证 | ① iOS 键盘扩展录音 spike;② Gummy 流式接入 demo;③ macOS 注入 + 不抢焦点浮层 demo;④ 立即启动微信开放平台(网站应用 + 移动应用)和商户号申请(周期数周,是关键路径;输入法上架需软著) | 1 周 |
| M1 核心链路 | 后端 auth / gateway / quota + 桌面端完整链路(快捷键 → 采集 → 流式 → 浮层 → 注入) | 2–3 周 |
| M2 商业化 | 微信登录(扫码 + App)、微信支付、时长包与配额 | 2 周 |
| M3 移动端 | 先 Android IME,后 iOS 键盘扩展 | 3–4 周 |
| M4 打磨 | 断网重连、错误兜底、延迟调优、内测分发 | 持续 |
| 风险 | 等级 | 缓解措施 |
|---|---|---|
| iOS 键盘扩展麦克风限制 | 高 | M0 第一周 spike 验证;降级方案:deep link 跳主 App 录音回传 |
| 微信开放平台 / 商户号申请周期长 | 中 | 第一天就启动申请(需企业资质、软著),与开发并行 |
| macOS 文字注入在部分应用不兼容 | 中 | 剪贴板 + 粘贴方案兼容面最广;M0 在微信/浏览器/IDE 实测 |
| ASR 厂商限流 / 故障 | 低 | Provider 抽象保证可热切到火山引擎备选 |
go test ./...;测试脚本推送 wav 文件模拟音频流,断言收到 partial/final 序列;微信支付用沙箱/模拟回调测试订单状态机;QUOTA_EXCEEDED 下发与客户端提示。