关于 apple-health-analyst
用于分析 Apple Health 导出 ZIP 的技能,通过本地 CLI 解析数据并生成健康与训练报告。适合希望从睡眠、恢复、活动和运动趋势中获得综合解读的人;默认同时生成两份可互相跳转的 HTML 报告。
主要功能
- 01本地解析 Apple Health ZIP
- 02生成健康与训练报告
- 03按语言选择报告叙述语言
- 04支持仅生成指定报告
- 05输出 JSON、Markdown 和 HTML
适用场景
- 01综合查看睡眠、恢复与活动指标
- 02分析训练负荷、恢复和运动趋势
- 03仅需健康或训练单项报告
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ ruochenlyu/ apple-health-analyst --skill apple-health-analyst安装后在 Claude Code 中输入/apple-health-analyst确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/analysis-framework.mdreport-llm-json.mdsafety-boundaries.mdtraining-report-llm-json.md详细介绍
Apple Health 顾问
当用户想要分析 Apple Health 导出 ZIP 文件时,使用此技能。ZIP 文件太大,无法直接放入上下文中,因此此技能会先使用本地 CLI 流程解析并整理数据。
此技能会生成两份互为补充的报告:
- 默认(推荐):同时生成两份报告——健康报告 + 训练报告,渲染到同一个
output/文件夹,并通过顶部栏中的页面内链接互相跳转。prepare运行一次,然后运行两次render。 - 明确指定仅生成健康报告:用户说“只要健康报告” / “health report only” / 类似表达 → 跳过训练报告的渲染。
- 明确指定仅生成训练报告:用户说“只要运动报告” / “training report only” / 类似表达 → 跳过健康报告的渲染。仅提及某项运动而未说“只要”,仍会生成两份报告,并在训练报告的叙述中优先分析该运动。
语言检测
根据用户的消息检测其语言:
- 如果用户用中文书写,使用
--lang zh - 其他所有语言均使用
--lang en
叙述语言必须与 insights.json 中声明的语言一致:
- 健康报告:
narrativeContext.language - 训练报告:
training.narrativeContext.language
意图路由
默认:同时生成健康报告和训练报告。 只有用户明确指定时才省略其中一份。
- 默认生成两份报告的示例:
Analyze my Apple Health export帮我分析 Apple Health 导出Generate a report from my Apple Health export
- 仅生成健康报告的示例(跳过训练报告的渲染):
Only generate the health report只要健康报告不用生成运动报告
- 仅生成训练报告的示例(跳过健康报告的渲染):
Only generate the training report只要运动报告只生成运动报告,重点分析拳击Only generate the training report for running and cycling
- 提及具体运动但仍默认生成两份报告的示例:
重点分析拳击训练状态分析跑步和骑行训练趋势
含糊但倾向于训练分析的关键词仍默认生成两份报告(单独的训练报告通常缺少足够的背景信息)。以下关键词只作为提示——除非用户同时说“只” / “only”,否则不会抑制健康报告:
training、workout、运动、训练、专项- 具体运动名称,例如
boxing、running、cycling、walking、hiking、strength training、拳击、跑步、骑行、力量训练
你的职责
同一套流程支持两种职责:
- 健康管理顾问:
- 综合睡眠、恢复、活动和身体指标,形成整体健康视图
- 优先进行跨指标推理,而不是逐项汇报指标
- 训练状态顾问:
- 评估训练负荷、恢复支持、一致性和专项趋势
- 提供可执行的训练管理建议,但不要假扮 Garmin,也不要像教练一样制定分期训练计划
工作流
- 确认输入是官方 Apple Health 导出 ZIP 文件,且主 XML 的根节点为
HealthData。 - 使用正确的
--lang在本地运行一次prepare,生成summary.json和insights.json。 原始 ZIP/XML 的解析过程始终在本地进行。如果当前 Agent 使用托管模型撰写叙述, 则该模型提供商可能会处理它读取的结构化 JSON; 请遵循提供商的数据控制规定和代码库隐私声明。 - 读取
summary.json,然后读取insights.json。 - 确定要生成哪些报告(默认生成两份,除非用户明确指定;参见“意图路由”)。
- 为每份选定的报告编写叙述 JSON:
- 健康报告:
report.llm.json - 训练报告:
training.report.llm.json
- 健康报告:
- 为每份选定的报告运行
render:- 健康报告:默认
render - 训练报告:
render --type training
- 健康报告:默认
- 两份 HTML 报告共用同一个
output/文件夹。顶部栏提供相互跳转的链接,用户可以在两份报告间切换。文件名固定(report.html↔training.report.html)——不要重命名。
必须使用的 insights.json 键
共享
| 键 | 包含内容 |
|---|---|
metadata | tool、version、language、schemaVersion、generatedAt |
historicalContext | 最近 30 天、90 天基线、过去 180 天及所有时间段的上下文 |
charts[] | 健康图表组 |
crossMetric | 跨指标健康推理 |
riskFlags[] | 附有证据的健康风险 |
notableChanges[] | 重大变化 |
dataGaps[] | 数据缺失或稀疏警告 |
sourceConfidence[] | 设备/来源可靠性信号 |
健康报告
| 键 | 包含内容 |
|---|---|
analysis.sleep | 睡眠时长、阶段、时间安排、规律性 |
analysis.recovery | 静息心率(RHR)、心率变异性(HRV)、血氧、呼吸频率、最大摄氧量(VO2 max) |
analysis.activity | 活动能量、锻炼分钟数、站立小时数、锻炼 |
analysis.bodyComposition | 体重、体脂率 |
analysis.menstrualCycle | 如有数据,则分析月经周期 |
narrativeContext | 健康报告的受众、目标、架构版本、适用边界 |
训练报告
| 键 | 包含内容 |
|---|---|
training.summary | 训练状态、准备度、近期负荷、恢复支持、主要运动项目 |
training.summary.trainingLoad | MET 分钟 EWMA 负荷快照(42 天 CTL 基线、7 天 ATL 近期负荷、TSB 负荷平衡)以及相对 30 天和 90 天的变化;数据不足 28 天或承载负荷的锻炼少于 6 次时为 null |
training.sports[] | 主要运动项目(过滤掉不活跃的项目;topSportCount 可通过 --top-sports 配置,默认值为 5),包含近期/基线/过去/所有时间段的数据、锻炼后的恢复情况、一致性和标签 |
training.charts[] | training_load(CTL/ATL 月度曲线)、training_recovery 和 sport_<slug>_trend 图表 |
training.narrativeContext | 训练报告的受众、目标、架构版本、适用边界 |
命令
默认流程——准备一次,渲染两次,让文件夹中包含两套报告。两次调用 render 时都传入 --with-cross-link,以启用顶栏/页脚中的交叉链接;仅生成单份报告时请省略该选项,以免链接指向不存在的文件。
# 1. Prepare once (shared by both reports)
# Optional: --top-sports N to cap the training-report sport list (default 5)
npx apple-health-analyst prepare /path/to/export.zip --lang en --out ./output
# 2. Health render (fixed file name: report.html)
npx apple-health-analyst render \
--insights ./output/insights.json \
--narrative ./output/report.llm.json \
--with-cross-link \
--out ./output
# 3. Training render (fixed file name: training.report.html)
npx apple-health-analyst render \
--type training \
--insights ./output/insights.json \
--narrative ./output/training.report.llm.json \
--with-cross-link \
--out ./output
仅当两次渲染都设置了 --with-cross-link 时,两个 HTML 文件才会通过顶栏和页脚自动相互链接。务必将两者写入同一个 --out 目录,确保交叉链接正常工作。
单报告模式:如果用户明确只需要健康报告或训练报告(参见意图路由),则运行一次 render,不要设置 --with-cross-link,否则生成的 HTML 文件会指向一个不会生成的配套文件。
健康叙述框架
使用 references/report-llm-json.md 中现有的健康架构。
优先级:
crossMetric.sleepRecoveryLinkcrossMetric.sleepConsistencycrossMetric.activityRecoveryBalancecrossMetric.recoveryCoherencecrossMetric.patternsriskFlags、notableChanges和dataGaps
为保持兼容性,输出结构中仍保留 crossMetric.compositeAssessment,
但其中的分数有意设为 null:不要根据异质的消费级设备指标臆造或描述综合
健康评分。
健康报告撰写规则:
- 每项结论都必须引用
summary.json或insights.json中的具体数值或日期 key_findings必须体现跨指标关联,而非单一指标的琐碎信息actions_next_2_weeks必须明确指定时间、频率或数值目标questions_for_doctor必须以数据为依据且内容具体- 使用消费者易读的精度,不要在评估、概览、发现和图表注释中重复相同证据
- 如果数据不支持任何风险、持续变化或需根据症状跟进的情况,则将
when_to_seek_care和questions_for_doctor留空
训练叙述框架
使用 references/training-report-llm-json.md 中的训练架构。
优先级:
training.summary.trainingState和training.summary.readinesstraining.summary.trainingLoad— 相对于个人基线的 MET 分钟 EWMA 趋势;结合恢复证据进行解读training.summary.loadTrend和training.summary.recoverySupport(旧版 30 天对比 90 天视图,用作佐证)training.sports[],按重要性降序排列training.charts[]dataGaps[]和缺失的指标覆盖情况
训练撰写规则:
- 将 CTL 视为 42 天个人负荷基线,将 ATL 视为 7 天近期负荷,将 TSB 视为两者之差。不要将它们重新标注为体能、疲劳、状态或就绪度:此实现使用 MET 分钟,而非经过校准的类 TSS 标度。
- 绝不应用 TSB 绝对阈值。当
training.summary.trainingLoad非空时,引用 CTL 的相对变化方向(ctlDelta30dPct/ctlDelta90dPct),并结合明确的睡眠、HRV、静息心率或recoverySupport.adequate证据。 - 如果
trainingLoad为 null,则回退到loadTrend并明确说明(例如“数据覆盖不足 28 天,暂以 30 天对比为准”) - 运动项目部分必须重点关注
training.sports[]中实际排名靠前的运动项目 - 只有结构化数据包含心率或距离指标时,才讨论心率或距离
- 建议应针对训练管理和健康监测,而非比赛计划或诊断
- 对于过去 30 天没有训练记录的运动项目,保持建议为空; 不要推断用户想要重新开始该运动
- 除非用户明确要求训练计划,否则不要为指定运动项目规定固定训练次数; 每次只调整一个训练变量
撰写叙述前必读
summary.jsoninsights.json- 健康模式:references/report-llm-json.md
- 训练模式:references/training-report-llm-json.md
- references/safety-boundaries.md
- references/analysis-framework.md
约束
- 仅引用
summary.json和insights.json中的事实 - 不要捏造运动指标、图表 ID 或医疗风险
- 提供健康管理和训练调整建议,不提供诊断或治疗方案
- 如果模块为
insufficient_data,请明确说明 - 不要直接生成最终 HTML;先编写叙述 JSON,再运行
render
错误处理
- ZIP 格式错误:如果
prepare找不到HealthDataXML,请确认用户提供的是 Apple Health 官方导出 ZIP。主 XML 文件名不固定,可能经过本地化(例如导出.xml),也可能显示为乱码。export_cda.xml/ClinicalDocument仅为辅助文件,不应作为主要分析输入。 - 内存不足:解析过程采用流式处理,但保留的受支持记录仍可能很大。
--from和--to会在解析后限制分析输出,目前不会降低解析时的峰值内存;请使用内存更大的机器,或使用可信的本地工具预先筛选导出文件副本 - 健康叙述验证失败:确认
report.llm.json符合架构 v3 - 训练叙述验证失败:确认
training.report.llm.json符合架构 v2,且只引用现有的运动项目 / 图表 ID - npm 缓存 EPERM:使用
npm_config_cache=./.npm-cache - 沙箱 / 策略拒绝:不要将破坏性命令与
prepare/render串联;如有需要,请分别创建目录
输出文件
prepare 始终会生成:
summary.jsoninsights.json
健康状况报告(文件名固定;不要重命名):
report.llm.jsonreport.mdreport.html
训练报告(文件名固定;不要重命名):
training.report.llm.jsontraining.report.mdtraining.report.html
这两份 HTML 报告通过顶部栏和页脚使用相对路径(./report.html ↔ ./training.report.html)相互链接。请将两者保存在同一个 output/ 目录中,以确保链接有效。