Commit fe84e3aced7cbb488fe824a73d6827927db2edaa

Authored by yibo
1 parent f6ea1028

docs(CLAUDE.md): 加 lifelog-recorder 章节 + 多子项目顶层映射

顶层「项目概述」从「lemonPCRM 单项目」改成「3 个互相关联但独立的
子项目(lemonPCRM / wechat_plain / lifelog-recorder)」总览表。

新增「lifelog-recorder」整章(位于「微信集成架构」与「注意事项」
之间),覆盖:

- 项目目标(Pixel 当永远开机的麦克风,0 元 0 网络,下接 lemonPCRM
  人脉图谱当个人记忆库)
- 架构骨架 ASCII 图 + 技术栈摘要(Kotlin 2.1 / Compose / Room /
  sherpa-onnx)
- 组件间数据流接口表 + 外部 HTTP/WS 接口
- 历史沿革 Round 1-3:全云 ASR(讯飞 80 元包根本不存在)/
  whisper.cpp on-device(0.6× 跑不动)/ sherpa-onnx paraformer
  (20-32× realtime 真机实测,选定),含完整 RTF/质量对比表
- 关键坑摘要 6 条(asset mmap SIGSEGV / silero LFS 拦截 /
  线程甜点 4 / AID_INET / keys.properties / 232MB 模型不进仓库)
- 未来计划摘要(详细见 lifelog-recorder/HANDOFF.md §五)
- 与 lemonPCRM 的关系(目前独立,v2 计划打通 GraphStore
  MENTIONED_IN 边)

细节避雷清单、命令速查、Pipeline 详图都不在此重复,全指向
lifelog-recorder/HANDOFF.md。CLAUDE.md 只勒住架构骨架 + 决策来源
便于每次 session 加载时快速建立心智模型。

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Showing 1 changed file with 106 additions and 0 deletions
CLAUDE.md
... ... @@ -4,10 +4,22 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
4 4  
5 5 ## 项目概述
6 6  
  7 +本仓库(`aipcrm/`)现在托管 **3 个互相关联但独立的子项目**:
  8 +
  9 +| 子项目 | 路径 | 形态 | 状态 |
  10 +|---|---|---|---|
  11 +| **lemonPCRM** | `server/` + `frontend/` + `packages/` | Node.js + Express 后端 + 静态前端 | 主线 |
  12 +| **wechat_plain** | `wechat_plain/` | Android Xposed/A11y 模块 + Pixel 部署脚本 | 主线 |
  13 +| **lifelog-recorder** | `lifelog-recorder/` | Pixel 原生 Android 应用(Kotlin + Compose) | v0.1 (2026-06) |
  14 +
7 15 **lemonPCRM** — lemonAI 出品的 Local-First AI 个人人脉管理系统(Personal CRM)。以人为中心、以对话为链接,通过知识图谱管理微信、LinkedIn、X 等多平台社交关系,将每个联系人与其社媒动态、会议纪要、文件、照片全面关联。
8 16  
9 17 AI 对话与编排层基于 ACP 协议驱动本地 Claude CLI 进程,提供单 Agent 执行和 Master → Sub-Agent 多轮编排能力。Node.js + Express,无数据库依赖(使用 Node 22.5+ 内置 `node:sqlite`),数据完全本地化。
10 18  
  19 +**wechat_plain** — Pixel 上微信 bot 的 Xposed/A11y 落地(A11y UI 自动化是当前唯一能真把消息推进 message 表的发送链路;详见下文 §微信集成架构)。
  20 +
  21 +**lifelog-recorder** — Pixel 8 Pro 上的 24/7 录音 + 本地中文 ASR + 时间轴 lifelog 应用(2026-06 新增,详见下文 §lifelog-recorder)。
  22 +
11 23 ## 常用命令
12 24  
13 25 ```bash
... ... @@ -151,6 +163,100 @@ Launcher (ProcessLauncher spawn / NoneLauncher 无操作)
151 163  
152 164 详见 `server/services/wechat/README.md`。
153 165  
  166 +## lifelog-recorder(Pixel 8 Pro 24/7 录音 + 本地中文 ASR,v0.1)
  167 +
  168 +> 完整接手地图、踩坑清单、命令速查见 `lifelog-recorder/HANDOFF.md`。本节只勒住整个项目的**架构骨架 + 关键决策来源**,不重复细节。
  169 +
  170 +### 项目目标
  171 +
  172 +把 Pixel 8 Pro 当成**永远开机的麦克风**:7×24 后台录音 → VAD 切段 → 中文 ASR 转文字 → 入库 → 按时间轴显示和搜索 → LLM 总结成纪要。最终目的是把所有「我说过 / 别人对我说过」的内容沉淀成可搜索、可回放的个人记忆库,下接 lemonPCRM 的人脉图谱(某段语音 → 某联系人 → 某项目)。
  173 +
  174 +约束:**完全本地 / 零云端依赖 / 月成本 0 元 / 隐私走 0 网络**。
  175 +
  176 +### 架构骨架
  177 +
  178 +```
  179 +Foreground Service (foregroundServiceType=microphone, WAKE_LOCK partial)
  180 + └ AudioRecord 16k mono PCM16 (VOICE_RECOGNITION source, no AGC/NS)
  181 + └ Silero VAD ONNX (sherpa-onnx 包装,500ms 静音切 / 30s 强切)
  182 + └ paraformer-zh int8 ONNX (sherpa-onnx JNI, 4 threads, 25× realtime)
  183 + └ Room SQLite (Segment / Transcript / Summary)
  184 + └ Compose LazyColumn 时间轴 UI (倒序,按 startTs)
  185 + ↓ (待办) hermes gateway 8642 → Kimi → 纪要 Worker
  186 +```
  187 +
  188 +技术栈:Kotlin 2.1 + Compose BOM 2024.12.01 + Room 2.6.1 + WorkManager 2.10 + OkHttp 4.12,AGP 8.7.3,minSdk 30 / targetSdk 35(Android 14 强制 `foregroundServiceType` 起步),arm64-v8a 单 ABI。
  189 +
  190 +### 接口
  191 +
  192 +**内部组件接口**(pipeline,详见 `lifelog-recorder/HANDOFF.md` §四):
  193 +
  194 +| 上游 | → | 下游 | 数据形式 |
  195 +|---|---|---|---|
  196 +| `AudioCapture` | SharedFlow | VAD | `FloatArray` 30ms 帧 (512 samples) |
  197 +| `Vad.acceptWaveform()` | poll | `Vad.front()` / `pop()` | `SpeechSegment(start, samples: FloatArray)` |
  198 +| `ParaformerEngine.transcribeFloat()` | sync | — | `OfflineRecognizerResult(text, tokens, timestamps, lang, emotion, event)` |
  199 +| `SegmentWriter` | sync | filesystem | `filesDir/segments/YYYY-MM-DD/HH-MM-SS-MS.wav` |
  200 +| `Repository.segments/transcripts` | suspend | Room | DAOs in `data/Daos.kt` |
  201 +
  202 +**外部接口**:
  203 +- `ModelDownloader` → `https://hf-mirror.com/csukuangfj/sherpa-onnx-paraformer-zh-2023-09-14/`(断点续传,fallback huggingface.co)
  204 +- `XfyunIatClient` → `wss://iat.xf-yun.com/v1`(讯飞大模型,**仅作云复核 fallback**)
  205 +- 未来 Summary Worker → `http://127.0.0.1:8642/v1/chat/completions`(hermes gateway 转发到 Kimi)
  206 +
  207 +**对外暴露的 IPC**:`RecorderService` 仅做自启/暂停(`startForegroundService` / `stopService`),状态走 `RecorderState` (StateFlow) 推给 UI;没有 binder/广播接口。
  208 +
  209 +### 历史沿革 / PoC 失败与成功记录
  210 +
  211 +> 这一节是**为什么选了 paraformer 而不是 whisper / 云 ASR** 的完整溯源。后面 session 想换技术栈前必读。
  212 +
  213 +**Round 1 — 全云 ASR 路线(弃)**:最初想用「VAD 段 → 上传讯飞 / 百度 / Groq Whisper」流式 ASR。讯飞「中文识别大模型」WebSocket 客户端已经写完(`asr/XfyunIatClient.kt`,鉴权 + 三段帧协议 + 增量结果解析),但发现按次计费下 24/7 用量会冲到月 5000+ 元。「讯飞流式听写区间包 80 元/月 unlimited」是**消费端「讯飞听见」App 的卡,不是开发者 API**——这是用户和我都踩过的坑。
  214 +
  215 +**Round 2 — whisper.cpp on-device(弃)**:在 Pixel 8 Pro Termux 编了 whisper.cpp + NEON 优化,跑 95s 中文 TTS sample:
  216 +
  217 +| 模型 | 线程 | RTF | 速度 | 中文质量 |
  218 +|---|---|---|---|---|
  219 +| ggml-tiny.bin | 4 | 0.26 | **3.8× realtime** | ❌ 输出乱码「战亡未来一年」,中文不可用 |
  220 +| ggml-small-q5_1.bin (181 MB) | **8 (最快)** | 1.66 | **0.60× realtime** | ✓ 转写正确 |
  221 +| ggml-small.bin (fp16, 465 MB) | 4 | 1.76 | 0.57× | 同 q5_1(量化省的全被 ARM dequant 吃回) |
  222 +
  223 +**结论**:whisper-small **任何配置都 < 1× realtime**,连续录会越积越多。tiny 够快但中文崩。**on-device whisper 路线直接砍掉**。
  224 +
  225 +**Round 3 — sherpa-onnx + 中文专门优化模型(采用)**:阿里 DAMO 的 paraformer-zh 跟 SenseVoice 都是 ONNX 部署、Android 友好。同样 95s sample:
  226 +
  227 +| 模型 | 测试环境 | RTF | 速度 | 备注 |
  228 +|---|---|---|---|---|
  229 +| paraformer-zh int8 (232 MB) t=4 | proot Ubuntu | 0.068 | **14.7× realtime** | 选定 |
  230 +| paraformer-zh int8 t=8 | proot | 0.099 | 10.1× | 8 线程反而慢,X3+A715 协调开销 |
  231 +| SenseVoice int8 (228 MB) t=4 | proot | 0.092 | 10.9× | 带情绪/事件 metadata,但慢 |
  232 +| **paraformer-zh int8 t=4** | **真机 Android app** | **0.048** | **20.94× realtime** | proot 摘掉后再快 43% |
  233 +| **paraformer-zh int8 t=4** | **真实活语音(用户对手机说)** | — | **20-32×** | 1-10s 段,~50-300ms 转写 |
  234 +
  235 +**结论**:on-device paraformer 完胜。月成本 0 元,延迟 <300ms,隐私零网络。讯飞客户端代码留作云复核 fallback。
  236 +
  237 +### 关键坑(接手必读)
  238 +
  239 +1. **不要把 .onnx 当 asset mmap**:sherpa-onnx v1.13.2 native code 对 asset 压缩兼容差,silero VAD 直接 SIGSEGV。已加 `androidResources.noCompress.add("onnx")` 但保险起见在 `RecorderService.runPipeline` 里把 VAD 模型从 assets 拷到 `filesDir` 后再用 file path 加载。
  240 +2. **silero_vad.onnx 别从 snakers4 的 GitHub raw 拉**:会被 LFS 重定向成 HTML。用 `https://github.com/k2-fsa/sherpa-onnx/releases/download/asr-models/silero_vad.onnx`。
  241 +3. **Tensor G3 paraformer 线程甜点 = 4,不是 8**。
  242 +4. **AID_INET (3003) gotcha**:跨 root + adb 调试 Termux 用户态时必须 `su -G 3003 10288 -c "..."`,否则 DNS 全断。详见 `~/.claude/projects/-Users-yibo-Documents-aipcrm/memory/magisk-su-android-inet-group.md`。
  243 +5. **`keys.properties` gitignored**:讯飞凭证从这里读到 `BuildConfig.XFYUN_*`。模板 `keys.properties.example`。
  244 +6. **232 MB paraformer 模型不进仓库**:首次启动从 hf-mirror.com 下到 `app.filesDir/models/paraformer-zh/`。dev 加速可以预先 `adb push` 进去(HANDOFF.md §三)。
  245 +
  246 +### 未来计划(按优先级)
  247 +
  248 +完整待办、估时、技术路线见 `lifelog-recorder/HANDOFF.md` §五。摘要:
  249 +
  250 +- 🔥 **Opus 编码**(WAV 24/7 跑 ~3 GB/天,必须)
  251 +- 🔥 **自启动 + 电池白名单**(BOOT_COMPLETED + REQUEST_IGNORE_BATTERY_OPTIMIZATIONS,让 v1 真能脱离 dev 环境跑)
  252 +- ⭐ **声纹识别 / speaker diarization**(用户语音里提了 3 次,sherpa-onnx `Speaker.kt` 现成可用)
  253 +- ⭐ **FTS5 中文搜索**(Room + ICU tokenizer)
  254 +- ⭐ **LLM 纪要 Worker**(cron + idle 触发 → hermes gateway → Kimi)
  255 +
  256 +### 与 lemonPCRM 的关系
  257 +
  258 +目前**完全独立**——lifelog-recorder 的 Room DB 跟 lemonPCRM 的 GraphStore 没打通。未来计划:把 Transcript / Summary 表里的实体(人名 / 地名 / 项目)抽到 GraphStore 当 `MENTIONED_IN` 边,让你的「某次会议说了什么」可以从图谱里反查。这是 v2 范畴。
  259 +
154 260 ## 注意事项
155 261  
156 262 - `server/src/standalone-entry.js` 的 `loadConfig()` 优先读 `backends.json` + `agents.json`,无需数据库。
... ...