Skip to content

OpenKikCoc/Soma

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

3 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Soma

面向家庭的本地化健康数据管理平台。把散落的 PDF、影像、化验单组织成可索引、可检索、可提醒的个人档案——全部在你自己的机器上,不上传任何原始数据。

不是电子病历、诊断工具或云服务;把家庭健康文件目录变成可查询数据库的一组工具链,首页直观展示「未来 6 个月要做什么复查」。


工作原理

PDF / 图片 / Markdown
      │  (soma ingest)     OCR 派发
      ▼
all-in-one.data.json      目录级 OCR 汇总
      │  (soma llm-extract) LLM 结构化
      ▼
summary.data.json         labs / medications / findings / events / guidance
      │  (soma reindex)     索引入 SQLite
      ▼
SQLite ──► FastAPI ──► Next.js UI / iCal 导出 / CLI 查询

两条硬约束贯穿始终

  1. 源文件只读:annotate / ingest / llm-extract 永远只新增 .meta.yaml / .data.json / _ai/summary.md,绝不修改或删除原文件。
  2. 索引库是派生数据:schema 要变就 soma reindex --wipe 重建,不写迁移。

组件

组件 技术 默认端口
后端 API Python + FastAPI + uvicorn 8001
前端 UI Next.js (React) 3000
CLI Python(cli/soma

仓库结构

Soma/
├── backend/          FastAPI + indexer + LLM extractor + pipeline
├── frontend/         Next.js App Router UI
├── cli/soma          统一 CLI 入口
├── scripts/          soma 子命令的实现
├── docs/             扩展文档(见下方链接)
└── .health/prompts/  AI 摘要 prompt 模板

数据目录(完全独立于代码仓):

$HEALTH_DATA_ROOT/
├── _alice/
│   └── 甲状腺/_alice_2026_04/
│       ├── report.pdf                ← 源文件(只读)
│       ├── .meta.yaml                ← soma annotate 新增
│       ├── all-in-one.data.json      ← soma ingest 新增
│       ├── summary.data.json         ← soma llm-extract 新增
│       └── _ai/summary.md            ← 可选:soma summarize 新增
└── 2024体检/
    └── ...

上述是 inline 布局(默认)。也支持 external 布局把所有 sidecar 挪到 data_root/_soma/ 镜像树,让源目录保持干净——挂到云端时更友好,详见 docs/STORAGE_LAYOUTS.md

目录命名规范详见 docs/DIRECTORY_CONVENTION.md


安装

前置python3 >= 3.11npmclaude / gemini / codex CLI 任一可选(见 docs/LLM_BACKENDS.md)。

git clone https://github.com/OpenKikCoc/Soma ~/code/Soma
cd ~/code/Soma
./cli/soma init --data-root "/path/to/your/HealthData"

soma init 幂等,失败重跑即可。它会:建 .venv/pip install -e backend/npm install 前端依赖 → 写 ~/.config/soma/config.yaml(存 data_root / db_path / code_root)→ 给未标注目录 soma annotate --apply 新增 .meta.yamlsoma reindex 建 SQLite。

soma 加到 PATH(后续示例都假设你做了这步):

ln -s ~/code/Soma/cli/soma ~/.local/bin/soma   # 确保 PATH 有 ~/.local/bin
#
export PATH="$HOME/code/Soma/cli:$PATH"        # 写到 ~/.zshrc

5 分钟上手

首次 soma init 之后只有 .meta.yaml——ingest / LLM 尚未触发。第一次 soma run 打开 http://localhost:3000 大概率是人员名字有了、化验/用药/发现全空,首页明显提示:

⚠️ OCR 有缺口         ⚠️ LLM 结构化待更新(0/36)
missing=36 failed=0   fresh=0 · stale=0 · missing=36

跑完整流水线:

soma llm-extract --estimate          # 先看看 LLM 会烧多少钱
soma reindex --wipe --force-llm --concurrency 3 --cost-limit 2.0

第一条输出形如:

=== 成本预估(model=claude-haiku-4-5)===
  扫描目录: 70     需调 LLM: 36  跳过(hash hit): 0
  待处理文本量: 801,091 chars
  估算 input ~490,545 tokens, output ~122,636 tokens
  估算成本: $1.104  (当前 --cost-limit $5.00)

第二条实际执行 ingestllm-extractreindex。跑完刷新首页,两张覆盖率卡片应变绿。


日常工作流

加了新文件:丢到数据目录任一位置,soma reindex 增量处理,或 soma watch 前台跑(1.5s 防抖后自动 ingest + reindex)。reindex 会按需跑 ingest(新文件)→ llm-extract(source_hash 变)→ SQLite 重建。

手工校对 OCR 原文:通过 /browse 页的 OcrActions 改完,点 RebuildButton(调 /api/ingest/fast-reindex),或命令行 soma reindex——会检测到 source_hash 变化并重跑 LLM。

重命名/移动目录所有派生文件都不可重命名,但可以随便加新子目录。确需重组旧目录请先备份再手动处理,Soma 只保证 additive。

全量重建

soma reindex --wipe --force-llm --concurrency 3 --cost-limit 2.0
flag 作用
--wipe 清空 SQLite 从零重建(不删数据目录任何文件)
--force-llm 无视 source_hash 缓存,重跑所有 LLM,重写 summary.data.json
--skip-llm 跳过 LLM 阶段,只重建 SQLite
--concurrency N -j N 同义,N 个 LLM 子进程并发
--cost-limit N 累计 >N USD 就中止派发(默认 5.0)

换台机器 / 迁移 data_rootconfig.yamlindex.db、代码仓都是派生物,可丢。把数据目录带走 → 新机器 git clone + soma init --data-root <新路径>soma reindex --force-llm 重建。把 data_root 搬到 Google Drive 的分步流程见 docs/STORAGE_LAYOUTS.md

暂时不想跑 LLMsoma reindex --skip-llm——只用目录结构 + .meta.yaml 建 SQLite,前端能看文件树和提醒,但 labs/findings/medications 全空。


Web UI 一览

启动:soma run(后端 :8001 + 前端 :3000 同时前台运行,Ctrl-C 双杀)。

路由 用途
/ 家庭总览:OCR / LLM 覆盖率卡 · 临近 5 条提醒 · 成员卡片
/people/[slug] 成员详情:病情档案、生活指导、化验趋势、近期资料
/conditions/[id] 病情详情:提醒时间线、临床发现、用药记录、指导、关联资料
/reminders 所有复查/预约/手术时间轴(按人/窗口过滤;另有 /api/reminders.ics
/browse 文件树 + OcrActions 原地改 OCR + RebuildButton 触发增量重建
/summaries 所有目录的 summary.data.json 列表
/coverage OCR 覆盖率详情:missing / unknown-kind / failed 文件清单
/file?path=... 单个源文件查看(PDF 嵌入 / 图片 / markdown 渲染)

右上角 RebuildButton 任意页触发 POST /api/ingest/fast-reindex


更多文档

  • CLI 参考 — 所有 soma 子命令的完整 flag 列表
  • 配置config.yaml、本地 overlay、环境变量
  • 目录布局与云端备份inline vs external、挂到 Google Drive/iCloud/Dropbox、从本地迁到 Drive 的分步流程
  • LLM backend — claude / gemini / codex / api 四种 backend 选择
  • 目录规范 — 数据目录命名与结构规范

排错

现象 处理
HEALTH_DATA_ROOT 未配置 没跑 soma init~/.config/soma/config.yaml 不存在。重跑 init,或 export HEALTH_DATA_ROOT=...
soma: command not found 没加到 PATH。用 ./cli/soma ...,或见 安装
首页 ⚠️ LLM 结构化待更新(0/N) 正常——提醒跑 LLM。先 soma llm-extract --estimate 看成本,再 soma reindex --force-llm
首页 ⚠️ OCR 有缺口 有文件未被 OCR。点卡片进 /coverage 看 missing/failed 清单
claude CLI 不可用 没装或不在 PATH。装 Claude Code,或 HEALTH_LLM_BACKEND=gemini_cli/codex_cli,或设 ANTHROPIC_API_KEY 走 SDK
gemini / codex CLI 不可用 对应命令没装或不在 PATH。装完后 gemini --version / codex --version 验证
gemini / codex 输出非 JSON 模型没听 prompt。重跑,或切回 HEALTH_LLM_BACKEND=cli
累计成本 >$X,停止派发 命中 --cost-limit。提高上限或调低 --concurrency
前端 404 / 空 后端没起来。curl http://localhost:8001/api/people 确认
DB 里东西不全 soma llm-extract 让 summary.data.json 齐全,再 soma reindex --wipe
soma watch 不跑 LLM 预期行为——避免偶发 save 烧钱。LLM 刷新手动 soma reindex

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors