Files
kangkang/docs/superpowers/specs/2026-05-25-kangji-features-design.md
link2026 771b28e7ef fix(ai): ModelKind rawValue 改为真实 HF mlx-community 仓库名
实际查 HuggingFace 后,mlx-community 下的仓库名:
- Qwen3-1.7B-4bit(不是 Qwen3-1.7B-MLX-4bit)
- Qwen2.5-VL-3B-Instruct-4bit(VL 模型带 Instruct 后缀)

改动:
- ModelKind.llm/vl rawValue 改名,这也是沙盒 Models/ 下的子目录名
- 加 huggingFaceRepo computed:"mlx-community/\(rawValue)"
- CLAUDE.md §2 表格补 HF 仓库 ID
- spec §2.2 模型来源行修正

W2 plan 中的下载脚本已陈旧(用了 huggingface-cli + 错名),
W2 retro 时会修正。

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-25 15:50:20 +08:00

642 lines
24 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 康记 / 体己 —— 功能设计 Spec(v1.0)
**日期**:2026-05-25
**状态**:Draft, 已与产品方对齐 §1-§6
**关联**:[CLAUDE.md](../../../CLAUDE.md) 工程前提
---
## 0. 概要
康记是一个 iOS 原生健康影像档案 App,**100% 端侧 AI 推理**,基于 SwiftUI + SwiftData + MLX Swift,目标 6 周交付决赛 demo。本 spec 把原始功能清单收敛为 **方案 B**:核心 5 模块 + Live Activity + 分享摘要,其余 P2/P3 全部 deferred。
**5 大核心模块**
1. 统一拍照(合并原 1.x 异常项快拍 + 2.x 关键报告归档)
2. 文字日记
3. 本地 RAG 问答(结构化检索)
4. 趋势分析(Swift Charts + AI 一句话解读)
5. 影像档案库 C1 列表 + C2 详情(看的一半)
**附加 P1**:Live Activity(demo 杀手锏)、分享文字摘要、首启动 Onboarding、Face ID + 永久删除
---
## 1. 整体架构
### 1.1 模块分层
```
UI 层 (SwiftUI)
├─ Tab: Home / Trend / Me
├─ Modal Sheet: RecordSheet → UnifiedCaptureFlow / DiaryComposer / AskSheet
└─ Navigation: ArchiveListView → ReportDetailView
*Service 层
├─ CaptureService // 拍照 → VL → draft → commit
├─ AskService // 两段式 RAG
├─ TrendService // 聚合 + AI 解读
└─ ReportCompareService // 同类型上一份报告 diff(纯模板,不调 LLM)
AIRuntime (actor 单例)
├─ LLMSession (Qwen3-1.7B, 流式)
└─ VLSession (Qwen2.5-VL-3B, 单次)
Persistence
├─ SwiftData (Indicator / Report / DiaryEntry / Asset / ChatTurn)
└─ FileVault (Application Support/Vault/, .completeFileProtection)
```
### 1.2 模块职责与边界
| 模块 | 干什么 | 不干什么 |
|---|---|---|
| **UI** | View + ViewModel,组织展示 | 不直接调 MLX,不读写文件 |
| **CaptureService** | 拍一张全流程:`UIImage → VL prompt → 结构化 JSON → 存盘 + Indicator/Report` | 不管 UI 状态机 |
| **AskService** | RAG:`query → SwiftData 关键词检索 → 拼 prompt → 流式输出 → 引用回链` | 不管对话历史展示样式 |
| **TrendService** | 按指标名/时间范围聚合数据,生成 Chart 数据点 + LLM 一句话解读 | 不画图表 |
| **ReportCompareService** | 找上一份同类型 Report,逐指标 diff,模板拼装 | 不调 LLM |
| **AIRuntime** | MLX 模型加载/卸载/推理,actor 单例,串行化推理 | 不懂业务 |
| **Persistence** | SwiftData 持久化 + FileVault 原图加密目录 + 永久删除 | 不懂 AI |
### 1.3 强制规则(违反即反 spec)
- **UI 永远不直接调 `AIRuntime`**——必须经过 Service 中转,这样 UI 可注入 mock、可预览
- **`AIRuntime` 必须 actor**——同一时刻只允许一个推理任务,MLX 共享显存,并发会 OOM
- **`*Service` 不直接读写 SwiftData 主上下文**——传入 `ModelContext` 或走 ServiceLocator
- **B3 写,C2 读,不要合并主框架**——B3 是 draft 编辑(写入路径),C2 是 detail 浏览(读取路径)
---
## 2. AI 链路
### 2.1 `AIRuntime` 接口
```
体己/AI/
├── AIRuntime.swift // actor 单例,推理串行化
├── ModelStore.swift // 模型路径管理 + 下载 + bundle 旁路
├── LLMSession.swift // Qwen3-1.7B 文本生成,流式
├── VLSession.swift // Qwen2.5-VL-3B 图像理解,单次
└── Prompts/
├── VLExtraction.swift // 拍照解析(含 few-shot)
├── KeywordExtraction.swift // RAG 第一步
├── ChatRAG.swift // RAG 第二步
└── TrendNarrative.swift // 趋势一句话解读
```
```swift
actor AIRuntime {
static let shared = AIRuntime()
enum Status { case notReady, downloading(Double), loading, ready, error(String) }
private(set) var status: Status = .notReady
func prepare() async throws
func generate(prompt: String, maxTokens: Int) -> AsyncThrowingStream<TokenChunk, Error>
func analyze(image: UIImage, instruction: String) async throws -> String
var lastDecodeRate: Double { get }
}
struct TokenChunk {
let text: String
let decodeRate: Double
}
```
### 2.2 模型分发
| 项 | 决策 |
|---|---|
| 模型来源 | HuggingFace `mlx-community/Qwen3-1.7B-4bit` + `mlx-community/Qwen2.5-VL-3B-Instruct-4bit` |
| 体积 | LLM ~1.0GB + VL ~2.0GB ≈ 3GB |
| 存储 | `Application Support/Models/`,`URLSession.downloadTask` + 断点续传 |
| 首启动 | 启动屏 → 隐私承诺 → "下载模型"页(进度 + WiFi 提示) → 主界面 |
| 旁路 | `ModelStore.seedModelsFromBundle()`,demo 现场预装机用 |
| 模型缺失 | App 可启动,AI 入口显示"模型未就绪,前往下载" |
### 2.3 VL Pipeline:拍一张统一流程
```
拍照 (UIImage)
▼ Step 1 预处理 (CaptureService)
- 缩放到 ≤ 1024 长边
- 写 Vault 作为 Asset(加密)
▼ Step 2 VL 解析 (AIRuntime.analyze)
- VLExtraction prompt 要求输出 JSON
- 期望 { kind: "single"|"report", items: [...], summary: "..." }
▼ Step 3 解析容错
- JSONDecoder + 宽松正则兜底
- 失败 → A2/B3 字段为空,提示"识别不完整,请手动补充"
▼ Step 4 确认页
- kind=single → A2ConfirmView(单项 + 一句话)
- kind=report → B3MetaView(指标列表 + 整体摘要,异常优先)
- 所有字段可编辑
▼ Step 5 保存
- draft → commit,事务写入 Indicator + Report + Asset
```
**VL prompt 要点**
- 明确"只输出 JSON,不要解释"
- 带 2 个 few-shot 示例(单项 + 多项)
- 异常状态由 VL 基于参考范围直接判断
- **不能让用户卡在错误屏**——失败回退到手动录入
### 2.4 RAG:结构化检索 + LLM 生成(不做 embedding)
```
用户问句
▼ Step 1 关键词抽取 (Qwen3-1.7B, ~50 token, <1s)
{ indicators: [...], time_range: {days: 90}, intent: "trend"|"value"|"diary" }
▼ Step 2 SwiftData 检索 (AskService)
- 按 indicators 模糊匹配 Indicator.name
- 按 time_range 过滤 capturedAt
- intent=diary 时检索 DiaryEntry.content
- 返回 ≤ 10 条 + 引用 ID
▼ Step 3 拼 ChatRAG prompt
- System: 不诊断、不建议就医、只描述数据
- Context: 检索结果, 每条编号 [1]-[n]
- User: 原始问句
▼ Step 4 流式生成 (LLMSession.generate)
- UI 打字机效果
- 顶部小字: "本机推理中 · 24.3 tok/s"
▼ Step 5 引用回链
- [1][2] 后处理为可点击 Pill
- 点击 → 跳 Indicator/Report C2 详情
- 整轮存 ChatTurn(referencedIDs + decodeRate)
```
**Step 1 失败回退**:近 30 天全表扫描,不卡死。
**Step 5 跨页跳转**:Report 引用走 ReportDetailView,Indicator 引用走 Trends 高亮该点。
### 2.5 Live Activity
| 项 | 决策 |
|---|---|
| 触发 | VL 推理 / RAG 生成开始 |
| 显示 | "Qwen2.5-VL · 24.3 tok/s" / "本机问答中 · 22.1 tok/s" |
| 实现 | ActivityKit + WidgetExtension target,`AIRuntime.lastDecodeRate` 每 0.5s `Activity.update` |
| 结束 | 完成后保留 2s "已完成 · 0.8s" 再 dismiss |
| 真机限定 | 模拟器不支持,W5 末预留 1d 真机调试 |
---
## 3. 数据流与数据模型
### 3.1 SwiftData @Model 全集
```swift
@Model final class Indicator {
var name: String
var value: String // , ">10" ""
var unit: String
var range: String
var statusRaw: String // "high" | "low" | "normal"
var note: String?
var capturedAt: Date
var report: Report? // ,nil
var asset: Asset?
var pinned: Bool = false // C2 "" true
}
@Model final class Report {
var title: String
var typeRaw: String
var reportDate: Date
var institution: String?
var note: String?
var summary: String? // VL 100
var pageCount: Int
var createdAt: Date
@Relationship(deleteRule: .cascade, inverse: \Indicator.report)
var indicators: [Indicator] = []
@Relationship(deleteRule: .cascade)
var assets: [Asset] = []
}
@Model final class DiaryEntry {
var content: String
var createdAt: Date
var tags: [String] = [] // VL/LLM
}
@Model final class Asset {
var relativePath: String
var mimeType: String
var bytes: Int
var createdAt: Date
}
@Model final class ChatTurn {
var question: String
var answer: String
var referencedIndicatorIDs: [String]
var referencedReportIDs: [String]
var createdAt: Date
var decodeRate: Double
}
```
### 3.2 SwiftData migration
- **W2-W4**:破坏性迁移,改 schema 就删模拟器沙盒。不要写 `VersionedSchema`
- **W5 起**:冻结 schema。需要改 → 写 `SchemaMigrationPlan`,只允许加字段
- **demo 翻车**:启动检测不兼容 → 弹"数据格式更新,需重建" → 删库重启。**绝不静默丢数据**
### 3.3 FileVault
```swift
final class FileVault {
static let shared = FileVault()
private let vaultURL: URL // Application Support/Vault/
func writeJPEG(_ image: UIImage, quality: CGFloat = 0.85) throws -> (relativePath: String, bytes: Int)
func loadImage(relativePath: String) throws -> UIImage
func remove(relativePath: String) throws
func wipe() throws
}
```
- 目录 `.completeFileProtection`,iOS 硬件级加密
- 不做版本管理、不做去重、不做缩略图缓存(YAGNI)
- 屏幕锁定时文件不可读 → AI 入口本来就由 Face ID 拦,业务上不冲突
### 3.4 拍照→保存时序
```
User → UI(B2Scan) → CaptureService → AIRuntime → Persistence
│ openCamera
│ ◄── images[]
│ analyze(images)
│ writeJPEG × N
│ ─────────────────────────► Assets stored
│ analyze(image1) ──► MLX VL
│ ◄── JSON
│ (repeat for img2…)
│ ◄── draft (Report + Indicators in-memory)
│ edit + save
│ commit ──────────────────► Report + Indicators
│ ◄── reportID
```
- N 页 VL 推理**串行**(AIRuntime 串行化),UI 显示 "第 k/N 页解析中" + 取消按钮
- draft 阶段 SwiftData 未提交,用户取消则 Asset 一并回滚
---
## 4. UI 改造与新建清单
### 4.1 现有视图改造
| 文件 | 改造 | 工作量 |
|---|---|---|
| `RootView` | RecordSheet 加"问问看";首页常驻"问问看"入口 | 0.5d |
| `HomeView` | `@Query` 接真数据,时间线 5 条,"今日摘要"接 `TrendService.dailyDigest()`,影像档案入口数量 | 1.5d |
| `Quick/A1Viewfinder` | 改用 `VNDocumentCameraView` 单张模式 | 0.5d |
| `Quick/A2Confirm` | 接 Indicator draft,字段可编辑,显示一句话解读 | 1d |
| `Quick/A3Batch` | **复用为整份报告指标列表**,异常优先 | 1d |
| `Quick/QuickCaptureFlow` | 改为 `UnifiedCaptureFlow`,kind 分叉 | 1d |
| `Archive/B1Guide` | **砍** | -0.5d |
| `Archive/B2Scan` | 改用 VNDocumentCameraView 多页 | 0.5d |
| `Archive/B3Meta` | 接 Report draft + AI 摘要 + 共用 A3 指标列表 | 1d |
| `Archive/B4Progress` | "第 k/N 页"+ 取消,绑 AIRuntime 队列 | 1d |
| `Trends/TrendsView` | 全新(见 4.2) | 3d |
| `Me/MeView` | 模型管理 + Face ID + 永久删除 + 关于 | 2d |
| `Record/RecordSheet` | 四入口 | 0.5d |
| `Models/Models.swift` | 加 Asset / ChatTurn + 字段 | 0.5d |
### 4.2 新建视图
#### `Features/Capture/UnifiedCaptureFlow.swift`(P0,1d)
状态机 View,根据 `CaptureService` 状态切换 Camera → Progress → A2 / B3。
#### `Features/Ask/AskSheet.swift`(P0,2d)
- Modal sheet, fraction(0.9)
- 顶部:3 个动态推荐问题 chip
- 中部:对话流(`ChatTurn` 气泡)
- AI 流式打字机 + 顶部小字 tok/s
- 引用 `[1][2]` → Pill → 跳源
- 底部输入框 + 发送
- **不做**:多轮上下文连续追问(每问独立 RAG)
#### `Features/Trends/TrendsView.swift`(P0,3d)
- 顶部横向 chip:指标(从 pinned + 高频 Indicator.name 去重)
- 时间范围 segmented:3M / 6M / 1Y / 全部
- Swift `Chart`:折线 + 参考范围 `RuleMark` 条带 + 异常点高亮
- 点 tap → C2 详情
- 下方 AI 解读卡片(`TrendNarrative`)
#### `Features/Archive/ArchiveListView.swift`(P0,2d)—— C1
- `@Query` 全部 Report,按 `reportDate` 年份分组
- 顶部分类 chip:全部 / 体检报告 / 化验单 / 影像报告 / 处方
- 卡片:左缩略图 + 右(标题 + 异常 chip + 日期 + 机构)
- 入口:HomeView "我的报告档案" 卡 → push
#### `Features/Archive/ReportDetailView.swift`(P0,2d)—— C2
- 三 Tab Picker:原图 / 解读 / 指标
- **原图 Tab**:`TabView(.page)` 翻页,点击放大,长按保存到相册(需相册权限)
- **解读 Tab**:数字摘要(`indicators.count` / 偏高 / 偏低 / 正常)+ `Report.summary` + **对比上次区块**
- **指标 Tab**:`Report.indicators`,异常优先
- 底部两按钮:
- **关联到趋势** → 本报告 `Indicator.pinned = true` 批量更新
- **重新解读** → `CaptureService.reanalyze(report:)` 重跑 VL
- 其他入口:ChatTurn 引用 / Trends 数据点 / Home 时间线
#### `Features/Me/MeView.swift`(P1,2d)
1. 模型状态:Qwen3-1.7B / Qwen2.5-VL-3B 状态、占用空间、上次速度
2. 隐私:Face ID Toggle(`@AppStorage`)、永久删除(二次确认)
3. 数据:导出文字摘要(`UIActivityViewController`)
4. 关于:版本 + 模型许可证
#### `Features/Onboarding/OnboardingFlow.swift`(P1,2d)
3 页:隐私承诺 → 模型下载(进度 + WiFi 提示) → 完成。`@AppStorage("onboarded")` 记录。
#### `LiveActivity/CaptureActivity.swift` + WidgetExtension target(P1,2d)
- `CaptureActivityAttributes`: modelName / status / decodeRate / elapsedMs
- 锁屏 + 灵动岛 compact/expanded
- AIRuntime 推理时 start/update/end
- 真机限定
### 4.3 服务层文件
```
体己/AI/ [7.5d]
├── AIRuntime.swift 2d
├── ModelStore.swift 1d
├── LLMSession.swift 1d
├── VLSession.swift 1d
└── Prompts/ 2.5d
├── VLExtraction.swift
├── ChatRAG.swift
├── KeywordExtraction.swift
└── TrendNarrative.swift
体己/Services/ [4.5d]
├── CaptureService.swift 1.5d
├── AskService.swift 1.5d
├── TrendService.swift 1d
└── ReportCompareService.swift 0.5d
体己/Persistence/ [1d]
├── FileVault.swift 0.5d
└── PermanentDelete.swift 0.5d
体己/Security/ [0.5d]
└── AppLock.swift 0.5d
```
### 4.4 工作量
| 类别 | 估算 |
|---|---|
| 现有改造 | ~13d |
| 新建视图(含 C1/C2 +4d) | ~16d |
| AI 层 | ~7.5d |
| Services 层(含 ReportCompare +0.5d) | ~4.5d |
| Persistence / Security | ~1.5d |
| **纯开发** | **~42.5d** |
| 联调 / Bug / polish | ~7.5d 缓冲 |
| **总计** | **~50d ≈ 6 周** |
任何一项延期 > 1d,按 §6.R7 砍 P1 不动 P0。
---
## 5. 6 周时间表
### W2(本周,5/25-5/31)—— AI 跑通 + Schema 重建
- MLX SPM 引入 + Xcode target
- `AIRuntime` actor + `prepare()` + `generate()`
- `LLMSession` 跑通 Qwen3-1.7B 加载 + 文本生成
- `ModelStore` 路径管理 + bundle 旁路(下载延后到 W6)
- `Models/Models.swift` 新增字段 + Asset / ChatTurn
- 删模拟器沙盒确认 Schema 重建
- `FileVault` 写/读/删测试图
**里程碑**:debug 按钮点击控制台打印 LLM 流式输出 + 速度
**验收**:decode ≥ 15 tok/s,无 OOM
**红线**:跑不通周五前换 llama.cpp
### W3(6/1-6/7)—— 日记 + 基础 RAG
- `DiaryComposer` 接 RecordSheet
- `AskSheet` 打字机 UI + 流式
- `AskService` 两段式 RAG:`KeywordExtraction` → SwiftData → `ChatRAG`
- 引用 `[1][2]` → Pill(目标视图可 stub)
- `ChatTurn` 持久化
**里程碑**:写 3 条日记 → 问"我最近写了什么" → 带引用回答
**验收**:首 token < 2s,引用 ID 匹配
**红线**:JSON 抽取失败率 > 30% → 加 few-shot 或换 prompt
### W4(6/8-6/14)—— VL + 统一拍照 + C1
- `VLSession` 跑通 Qwen2.5-VL 加载 + 单图推理
- `VLExtraction` prompt(few-shot + JSON)
- `CaptureService.analyze` → draft → commit
- `UnifiedCaptureFlow` 状态机
- A1/B2 改 `VNDocumentCameraView`
- A2/A3/B3/B4 接真数据
- **W4 末:`ArchiveListView` C1**(分类 + 年份分组)
**里程碑**:三张真化验单 → 70% 字段自动填好;档案列表可见所有报告
**验收**:VL 单页 < 8s,JSON 失败有可见兜底
**红线**:VL > 15s 或失败率 > 40% → 降级 Vision OCR + Qwen3 文本后处理
### W5(6/15-6/21)—— C2 + Trends + 隐私 + Live Activity
- **`ReportDetailView` C2** 三 Tab + 关联到趋势 + 重新解读
- **`ReportCompareService`** + C2 解读 Tab "对比上次"
- `TrendService` + `TrendsView`(Swift Charts + AI 解读)
- `HomeView``@Query` 真数据 + 时间线 5 条
- `TrendService.dailyDigest()` 接首页摘要卡
- `AppLock` Face ID 启动锁
- `PermanentDelete` 接 Me 页
- WidgetExtension target + `CaptureActivity`
- **真机调试 Live Activity**
**里程碑**:C1 → C2 三 Tab → 对比上次 → 关联到趋势 → Trends 上看到新指标;拍照灵动岛滚 tok/s
**验收**:Charts ≥ 3 个指标各 ≥ 6 点;Live Activity 锁屏可见
**红线**:Live Activity 周三前调不通 → 降级 App 内顶部条
### W6(6/22-6/28)—— 首启动 + Me + Polish + Demo
- `OnboardingFlow`(隐私承诺 + 模型下载 + 完成)
- `ModelStore` 真实 URLSession 下载 + 续传 + 进度
- `MeView`(模型状态 + 隐私 + 关于)
- 9.4 分享文字摘要
- 所有空状态插画 / 文案
- `#if DEBUG` 种子数据(12 份报告)
- 真机录 3 分钟 demo 视频(含 Live Activity)
- PPT 5 页核心(按卖点排序)
**里程碑**:零安装到首问答 < 5 分钟;demo 视频成片
**验收**:评委 iPhone 跑得动(提前预拷模型)
**红线**:W6 不再加新功能
### 每周日 retro 决策树
```
本周 P0 全完成?
├─ 是 → 进下周
└─ 否,延期 > 2d
→ 砍下周 1 项 P1
砍顺序:Live Activity → Onboarding 简化 → 分享摘要 → Me polish
绝不动:C1 / C2 / 对比上次 / 统一拍照 / AskSheet / Trends / Face ID
```
---
## 6. 风险与回退预案
### R1 · MLX 跑不通 / 速度太慢 🔴 致命
**信号**:W2 周五,decode < 10 tok/s 或首 token > 5s,OOM
**回退**:① 更小量化 → ② llama.cpp + GGUF(失 SME2 卖点)→ ③ Qwen2.5-0.5B
**预防**:W2 第一天就跑通;iPhone 15 Pro+ 基线
### R2 · VL 准确率不够 🔴 致命
**信号**:W4 中,5 张真化验单 < 60% 字段正确;频繁残缺 JSON
**回退**:① 加强 few-shot 到 4-5 个 → ② 降级 Vision OCR + Qwen3 文本后处理(失"VL"故事但保识别)→ ③ Demo 只用已知能解析的图
**预防**:W3 末准备 5-10 张真单做回归集;A2/B3 必备兜底文案
### R3 · Live Activity 真机调不通 🟠 高
**信号**:W5 末,Capability/证书问题,模拟器没法测
**回退**:① 只保锁屏不要 App 内顶部条 → ② 整个砍,改 App 内顶部 `safeAreaInset` 粘性条 → ③ Demo 视频后期加字幕
**预防**:W5 周一建好 target
### R4 · SwiftData migration 翻车 🟠 高
**信号**:Schema 编过但启动崩 / cascade 误删
**回退**:W5 前删沙盒;W5 后 `VersionedSchema` 只加字段;demo 翻车显式弹窗"重建",绝不静默丢数据
**预防**:每次改 @Model 重启验证;Schema 改动 W2-W4 集中,W5 冻结
### R5 · 3GB 下载体验灾难 🟠 高
**信号**:demo 现场装包后下载 30 分钟还没好,中断不能续
**回退**:① demo 用预拷模型设备 + `seedModelsFromBundle()` → ② 分两步下(先 LLM 后 VL)→ ③ 视频备份
**预防**:W6 在 2 台 demo 机断网测试
### R6 · 健康话术翻车 🟡 中
**信号**:LLM 输出"你应该……""建议就医"
**回退**:System prompt 末尾追加禁令;AskService 后处理过滤诊断关键词;启动屏永久免责小字
**预防**:W3 RAG 跑通后立刻做 20 条危险问题安全测试,写进单元测试
### R7 · 时间不够 🟡 中
**信号**:某周日 P0 还有 > 1d 没完成
**回退顺序**:Live Activity → Onboarding 简化 → 分享摘要 → Me polish
**绝不砍**:C1/C2、对比上次、统一拍照、AskSheet、Trends、Face ID
**预防**:每周日 retro
### R8 · 评委 iPhone 不支持 SME2 🟡 中
**信号**:iPhone 14 非 Pro 装包,速度比预期慢
**回退**:不依赖评委设备,自带 iPhone 15 Pro / 16 Pro 演示
**预防**:W6 准备 2 台 A17/A18 demo 机
### 风险红绿灯仪表盘
| 风险 | W2 | W3 | W4 | W5 | W6 |
|---|---|---|---|---|---|
| R1 MLX | 🔴 | 🟡 | 🟢 | 🟢 | 🟢 |
| R2 VL | — | — | 🔴 | 🟡 | 🟢 |
| R3 Live Activity | — | — | — | 🔴 | 🟡 |
| R4 Migration | 🟡 | 🟡 | 🟡 | 🟠 冻结 | 🟢 |
| R5 模型下载 | — | — | — | 🟡 | 🔴 |
| R6 医疗话术 | — | 🟡 | 🟡 | 🟡 | 🟢 |
| R7 P0 进度 | 🟡 | 🟡 | 🟠 | 🔴 | 🟡 |
| R8 demo 设备 | — | — | — | — | 🔴 |
每周日 retro 显式确认当周"关键"项:**通过 / 需补救 / 触发回退**。
---
## 7. 非目标(明确不做)
写代码时如果想加,先回这里看一眼:
- ❌ 医疗诊断、剂量推荐、急诊判断、医生预约
- ❌ 连拍模式(1.6)
- ❌ AES 自实现 / 截屏黑屏防护(走 iOS 系统级)
- ❌ 加密 ZIP 导出(9.1-9.3)——只留 9.4 文字摘要
- ❌ 多页 PDF 自写透视校正(VisionKit 白送)
- ❌ 用药提醒、复检提醒、体检周年提醒(11.x)
- ❌ 语音输入(12.x)
- ❌ 多指标相关性、聚类(13.x)
- ❌ 暗黑模式、主题色切换(14.x)
- ❌ 多 profile / 家庭成员(15.x)
- ❌ AI 模型升级 in-app(17.x)
- ❌ iCloud 同步(18.x,与"100% 本地"冲突)
- ❌ Widget / Home Screen 小组件(19.x;Live Activity 不算)
- ❌ 社交、广告、内购、账号系统
**例外加回**:报告对比 16.1(P0,已加回,见 §4.2 C2 + §5 W5)
---
## 8. 评委 PPT 卖点排序
写每个功能时记住为什么这么做:
1. **影像档案系统**(统一 VL 拍照 + C1/C2 归档库)— 核心创意
2. **100% 本地 + SME2 加速** — 技术亮点
3. **本地 RAG 长期记忆** — 端侧不可替代性
4. **隐私三件套**(系统级 file protection + Face ID + 永久删除)— 信任建立
5. **AI 趋势解读 + 对比上次** — 长期价值
6. **Live Activity 实时 tok/s** — 现场记忆点
每写一个功能,问自己:这条提升了上面哪一项?都没有就别做。
---
## 附录 · 与原始功能清单的映射
| 原编号 | 状态 | 落地位置 |
|---|---|---|
| 1.x 异常项快拍 | **合并** | UnifiedCaptureFlow(kind=single) |
| 1.2 智能取景框 | **砍** | VNDocumentCameraView 取代 |
| 1.6 连拍模式 | **砍** | YAGNI |
| 2.x 关键报告归档 | **合并** | UnifiedCaptureFlow(kind=report) |
| 2.1 多页扫描 | 改造 | VNDocumentCameraView 多页 |
| 2.6 原图加密 | 改造 | FileVault `.completeFileProtection` |
| 3.x 自然语言日记 | P0 | DiaryComposer + DiaryEntry |
| 4.x AI 问答 | P0 | AskSheet + AskService(结构化 RAG) |
| 4.4 流式输出 | P0 | LLMSession + AskSheet 打字机 |
| 5.x 趋势分析 | P0 | TrendsView + TrendService + Swift Charts |
| 6.1-6.2 本地 + 离线 | 自然结果 | MLX + 无网络依赖 |
| 6.3 数据加密 | 改造 | `.completeFileProtection`(系统级) |
| 6.4 Face ID | P0 | AppLock |
| 6.5 截屏防护 | **砍** | iOS 无官方 API |
| 6.6 永久删除 | P0 | PermanentDelete |
| 7.x 首页 | P0(已有骨架) | HomeView 接真数据 |
| 8.x 模型管理 | P1 | MeView |
| 9.4 分享文字摘要 | P1 | MeView "导出" |
| 9.1-9.3 加密 ZIP 导出 | **砍** | |
| 10.x 引导 | P1(简化) | OnboardingFlow 3 页 |
| 11.x 提醒 | **砍** | |
| 12.x 语音 | **砍** | |
| 13.x 进阶趋势 | **砍** | |
| 14.x 暗黑/主题 | **砍** | |
| 15.x 多 profile | **砍** | 数据模型成本太大 |
| **16.1 报告对比** | **加回 P0** | C2 解读 Tab + ReportCompareService |
| 17.x 模型升级 | **砍** | |
| 18.x iCloud 同步 | **砍** | 与本地卖点冲突 |
| 19.2 灵动岛 | P1 加分 | CaptureActivity LiveActivity |
| 19.1 Widget | **砍** | |
| **C1 档案列表** | **新增 P0** | ArchiveListView |
| **C2 报告详情三 Tab** | **新增 P0** | ReportDetailView |
| **C2 关联到趋势** | **新增 P0** | Indicator.pinned 批量更新 |
| **C2 重新解读** | **新增 P0** | CaptureService.reanalyze |
---
**END OF SPEC v1.0**