# 康康 —— 功能设计 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 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**