【免费下载链接】mirobody
Turn scattered health data into answers you can trace. Self-hosted AI health data engine for lab reports, wearables and genetics, with a built-in MCP server. Run it with Docker and one LLM key, or keep every model local on llama.cpp.
Mirobody 是一个可自托管的 AI 健康数据引擎,能把化验单、可穿戴设备和基因文件变成可追溯的回答。它内部有一条完整的健康数据管线:一个数字从手表或化验单进来,要经过11 个阶段才能被提问。这篇文章带你走完这条 Mirobody 管线的每一步,理解"从入站到 AI 回答"背后每个环节解决的真实问题。
为什么数据要经过 11 步才能回答一个问题?
因为"一个数字"和"它意味着什么"是两回事。同一项化验,不同医院会印Total Cholesterol-TC、Cholesterol, Total、总胆固醇三种名字;两块设备测同一天,可能各自"都对"。Mirobody 管线(官方完整文档见 docs/pipeline.md)用 11 个阶段把混乱的原始数据变成一份有编码、有单位、有权威来源的记录。
| # | 阶段 | 干什么 | 对应代码位置 |
|---|---|---|---|
| 1 | Connect 连接 | 凭据状态机,失败后退避、超阈值停止重试 | mirobody/kernel/connect.py |
| 2 | Pull 拉取 | 向厂商要一个时间窗,保留原始报文 | mirobody/collect/providers/ |
| 3 | Decode 解码 | 厂商 JSON → 目录单位下的Fact | mirobody/kernel/decoders/ |
| 4 | Resolve 归一 | 这个指标到底是哪个——名字、编码、形状 | mirobody/kernel/metrics.py |
| 5 | Gate 门禁 | 拒绝不可能的值,转换可转换的单位 | mirobody/kernel/quality.py |
| 6 | Store 存储 | 单一写入者、一天一列、指纹去重 | mirobody/collect/observations.py |
| 7 | Aggregate 聚合 | 一天的数据点 → 一个数 | mirobody/kernel/series.py |
| 8 | Elect 选举 | 这一天对外发布哪个来源的数 | mirobody/translate/aggregate/election.py |
| 8b | Derive 派生 | 没被直接测量的量:睡眠效率、HR 区间 | mirobody/translate/derive/rules.py |
| 9 | Correct 更正 | 人的修改作为"覆盖层",不改原始行 | mirobody/kernel/overlay.py |
| 10 | Read 读取 | 一个权威查询,明确窗口语义 | mirobody/kernel/query.py |
| 11 | Answer 回答 | 一个工具、一个信封、一个叙述的模型 | mirobody/agent/tools/ |
下面分四段讲透这 11 步。
前 3 步:数据如何"安全地进来"
1. Connect:连接失败不会变成攻击
凭据被建模成一个小型状态机(linked → refreshing → expired → revoked)。授权失败会按次数退避,超过阈值彻底停止——防止你改了厂商密码后,同步循环以全速率一直撞门,有些厂商会把这种频率当作攻击并锁号。
2. Pull:一次补一年,不是一口吞四年
PullWindow和backfill_windows把长历史切成有界窗口分批拉取,每个厂商的原始报文都留在自己的表里——原始值永远可追溯。
3. Decode:只转换,不猜测
解码表把厂商字段映射到目录指标,并转换成目录的单位(单位本身从不写在表里,解码器不可能和聚合器对ms的含义产生分歧)。目录不认识的指标键直接隔离,绝不映射到相邻名字——宁可空,不猜错。
中间 4 步:标准化与质量门禁
4. Resolve:92 万别名的离线词表
metrics.mapping_for给出指标的名字、规范编码(公开无争议的 LOINC,否则用本项目自己的mirobody-device命名空间)、状态类和日窗口。自由文本走engine.resolve的离线别名索引。一个自信的错编码比诚实的命名空间更危险:两个都缺编码的写入者仍会达成一致。
5. Gate:只拒绝"物理上不可能"
时间门禁(没有起点、终点早于起点、跨度超 36 小时、测量时间是未来的某一天)和数值门禁(百分比越出 0–100、非有限数)在唯一写入者内、落库前逐行运行。被拒的行按原因码计数并丢弃。注意管线不维护参考区间:"心率 190 偏高"是开放式临床资产,这里只拒绝对不可能。
6. Store:写入时定型,表只追加
th_observation旁边保存逐字原文,旁边是派生出的类型化层。local_date、value_num、unit_ucum、series_id、fingerprint等列在写入时一次性算好——"这是哪一天"从此不再随读者时区漂移;指纹保证重复同步不产生重复行。更正不是UPDATE而是指向旧行的新行(amends),唯一会 DELETE 的是隐私路径。
7. Aggregate:按状态类选择聚合策略
| 状态类 | 策略 | 原因 |
|---|---|---|
| instant 瞬时值 | mean/min/max 或 last | 心率是采样 |
| cumulative 累计值 | sum_delta | 步数是差值,运行总和求平均无意义 |
| interval/session 区间 | duration_union | 重叠时段不能数两次 |
| provider_daily 厂商日报 | provider_value | 厂商算好的日子数只投影,不二次平均 |
第 8–9 步:一天只有一个权威数字
8. Elect:选举只发生一次
两块设备测同一天,series.elect按"测量者优先于档案回声 → 覆盖率 → 测量时刻 → 部署自定优先级"排序,胜者写入独立表th_day_authority。之前选举发生在读侧两处,同一个周二,聊天和仪表盘会给出两个不同的数——现在不会了。候选数字物理上不可能(总睡眠时长超过那一夜)时直接拒绝,不参与排序。
9. Correct:改正是覆盖层,不是改写
overlay.Override记录"谁把哪个字段改成了什么、何时"。存储行永不重写,删除也是一种覆盖——所以源端重推数据不会悄悄抹掉你的更正。
最后 2 步:一个权威,一个信封
10. Read:所有界面走同一个查询
聊天、MCP、网页的指标页全部读同一个query.HealthQuery。窗口在主体时区里用显式now解析,日粒度读取得到的是选举出的权威值,窗口语义被报告(tz_exact/date_padded_naive)而不是假设。
11. Answer:工具报告,模型叙述
模型只拿到少数几个封闭模式工具(query_health_indicators、query_medications等,详见 docs/answers.md),返回的是带状态、溯源、截断标记的tools.Envelope。管线中没有任何环节判断"这个数是不是好消息"——判断权留给你和医生。
10 条不变量:这条管线的底线
- 读数属于哪一天,由目录窗口在写入时决定一次。
- 指标单位来自目录;解码器只转换进去,从不声明单位。
- 未映射的指标被隔离,从不猜测。
- 选举只发生一次、发布之前;一天只有一个权威。
- 重叠区间做并集,从不相加。
- 厂商自算的日报值只投影,不二次平均。
- 时间从不伪造:没有时间戳的记录解码为空。
- 更正是覆盖层;存储行不被重写。
- 每个回答都声明自己用了哪种窗口语义。
- 日志只带 id、计数、时长、状态码——从不带数值本身。
每一条都对应维护者本地测试套件中的一个模块(见 mirobody/tests/)。
想亲手验证?
- 用 Docker 一条命令启动整套栈(含 2,019 条演示读数):
./deploy.sh,流程见 README.md。 - 不带数据库、不联网体验词表:
mirobody resolve "LDL cholesterol" 血红蛋白。 - 深入文档:管线 · 四分钟走查 · 标准化 · 答案层
【免费下载链接】mirobody
Turn scattered health data into answers you can trace. Self-hosted AI health data engine for lab reports, wearables and genetics, with a built-in MCP server. Run it with Docker and one LLM key, or keep every model local on llama.cpp.
相关推荐
Olmo-3-7B-Instruct:如何在3步内快速部署这个推理能力领先的开源AI模型
Olmo 3 7B Instruct:如何在3步内快速部署这个推理能力领先的开源AI模型 Olmo 3 7B Instruct 是Allen Institute
大模型深度学习免费性能加速:lmdb-js 弱引用 LRU/LFU 缓存机制原理与配置指南
免费性能加速:lmdb js 弱引用 LRU/LFU 缓存机制原理与配置指南 lmdb js 是一个简单、高效、超高速的可扩展数据存储器封装库(Simple,
Llama3数据冒险之旅:从文字输入到AI答案的完整揭秘
Llama3数据冒险之旅:从文字输入到AI答案的完整揭秘 你是否好奇AI大模型Llama3如何将"生命、宇宙与一切的答案是"这样的问题,一步步转化为"42"这个
示例工程大模型人工智能
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考