用 OpenClaw 搭建个人运动助手
把“小龙虾”变成真正懂我的跑步搭档
前言
最近玩了一下 OpenClaw,越用越觉得它很适合做一个长期运行的个人助手。
我平时喜欢跑步和徒步,于是就冒出了一个很具体的想法:能不能把它改造成一个真正懂我的运动搭档?不只是被动回答问题,而是能主动分析我的跑步数据、帮我生成训练计划并推送到 Garmin,甚至在我跑完步之后,给我一份像教练一样的分析报告。
折腾下来,我发现这件事不仅可行,而且一旦跑通,体验会非常顺手。真正的关键,不在于“让 AI 什么都自己想”,而在于把高频操作固化,把深度分析留给 AI。这样才能既省 Token,又保证实用性。
硬件和工具选择
我的配置很简单:
- 设备:树莓派 5
- 聊天入口:Telegram Bot
树莓派 5 的优势非常适合这种场景:可以 24 小时在线运行,功耗低、噪音小,放在家里几乎没有存在感。 而 Telegram Bot 的好处,则是可以自定义菜单按钮,交互非常直接。日常使用时,我只需要打开 Telegram,点一下菜单命令,就能立刻看到今天的健康数据、昨晚的睡眠情况,或者最近一次跑步的分析。
从“可用性”来说,这一点很重要。因为运动助手不是做出来展示的,而是要真的进入日常使用。
第一个坑:Token 消耗比想象中高得多
OpenClaw 默认会在 workspace 目录下生成大量上下文文件,包括人格设定、用户档案、工作规则、巡检配置、会话记忆和技能模块等。问题在于,这些内容在运行时会不断被带入上下文,Token 消耗很容易迅速放大。
OpenClaw 工作目录大致像这样(这些 .md 文件都会被作为上下文记忆带入查询中):
~/.openclaw/workspace/
├── SOUL.md # AI 人格定义
├── USER.md # 用户档案
├── AGENTS.md # 工作规则和命令处理
├── HEARTBEAT.md # 主动巡检配置
├── memory/ # 每次会话的记忆文件
│ ├── 2026-04-20-long-run-analysis.md
│ └── 2026-04-20-weekly-training-plan.md
└── skills/ # 技能模块
我一开始接的是 DeepSeek 的 API,以为成本会比较低,结果实际跑起来,几天就烧了不少钱。问题不在单次调用,而在于它面对这种“模糊任务”时,很容易进入一种高频试探状态:不断测试、不断生成临时代码、不断确认上下文。每一轮都在消耗 Token,但真正的有效产出并不高。
后来我开始用 Claude 来完善我的运动助手需求,明显感觉它在这类任务上更收敛,不太会在同一个问题上来回打转,需求到代码的转换高效且清晰。当然对于 OpenClaw 日常的 API 调用还是用 DeepSeek,主要由于 DeepSeek API 价格实惠,中文好。
这也让我意识到一个关键点:不要把高频、确定性的任务交给 AI 现想现做,而应该先把这些任务工程化。

上图可以看到在前几天需求模糊情况下,使用量激增(当日最高 Token 消耗 8 千万)。在需求明确之后进入稳定的工程化任务之后,整体的使用量不到先前的 1%。
核心思路:三步把 OpenClaw 变成真正可用的运动助手
整个方案最后可以归纳成三步:
- 把常用命令写成清晰脚本
- 把脚本包装成 OpenClaw Skill
- 把查询和分析拆开,分别处理
这三步看起来简单,但基本决定了这套系统到底是“好玩”,还是“好用”。
第一步:把常用命令固化成脚本
与其每次都让 AI 临时思考“怎么获取 Garmin 数据”“怎么生成训练计划”,不如直接把这些高频操作封装成脚本。
比如,我写了一个统一入口 garmin_commands.py,把最常用的健康数据和跑步查询都整理成明确命令:
# 今日健康数据
python3 scripts/garmin_commands.py health_data
# 昨夜睡眠分析
python3 scripts/garmin_commands.py sleep_analysis
# 最近一次跑步
python3 scripts/garmin_commands.py last_run
训练生成和推送,则走另一个统一入口 integrated_openclaw_skill.py:
# 生成并推送轻松跑到 Garmin Connect
python3 ~/.openclaw/workspace/skills/garmin-workout/scripts/integrated_openclaw_skill.py \
--command generate_and_push --args '{"command": "/easy_run 8公里 明天"}'
这样做的意义非常直接: AI 不再需要“想办法”,只需要“调用工具”。
我目前支持 6 种训练类型,每种都预设了相应的结构和配速区间:
| 命令 | 类型 | 结构 |
|---|---|---|
/easy_run | 轻松跑 | 热身 → 主跑 @6:30–7:00/km → 放松 |
/tempo_run | 节奏跑 | 热身 → 主跑 @5:20–5:40/km → 放松 |
/long_run | 长距离跑 | 热身 → 主跑 @5:50–6:10/km → 放松 |
/interval_run | 间歇跑 | 热身 → repeat 结构 → 放松 |
/recovery_run | 恢复跑 | 热身 → 主跑 @7:15–7:45/km → 放松 |
/fartlek_run | 法特莱克 | 热身 → repeat 结构 → 放松 |
这一步完成之后,很多日常命令的响应速度可以控制在几秒内,而且几乎不再额外消耗推理成本。
第二步:把脚本包装成 OpenClaw Skill
只有脚本还不够。真正让这套系统稳定运行的关键,是把它们包装成 OpenClaw 的 Skill。
Skill 的核心是一个 SKILL.md 文件,放在 skills/garmin-workout/ 目录下。它本质上是在告诉 AI:
- 这个技能是做什么的
- 遇到什么需求时应该调用它
- 调用的命令应该长什么样
- 参数怎么传
例如:
---
name: garmin-workout
description: Garmin Connect 训练集成。用户询问训练计划、推送训练到 Garmin、
查询健康数据(睡眠/VO2 Max/心率/身体电量)时使用。
覆盖全部 6 种训练类型。需要 python3 和 garminconnect。
---
这一层非常重要,因为它解决了一个现实问题: AI 重启之后,不能靠“记得”来工作,只能靠“结构化入口”来工作。
脚本放在那里,只是工具存在; Skill 写清楚之后,AI 才真正知道什么时候该用、怎么用。
同时,我还在 AGENTS.md 里把 Telegram 命令和具体执行脚本做了映射,例如:
| Telegram 命令 | 执行脚本 |
|---|---|
/last_run | python3 .../garmin_commands.py last_run |
/sleep_analysis | python3 .../garmin_commands.py sleep_analysis |
/easy_run 8km 明天 | integrated_openclaw_skill.py --command generate_and_push ... |
规则也尽量写得很直接:
收到这些命令后,立即运行对应脚本并原样返回输出;不要再追问用户想要什么数据,也不要临时生成探索性代码。
这样做之后,整个系统的行为会稳定很多:不绕路、不试探、不反复确认,直接执行。
第三步:保留 AI 的深度分析能力
把高频任务都脚本化,并不意味着放弃 AI 的价值。恰恰相反,真正值得让 AI 出场的,是“分析”,而不是“查数据”。
例如,我跑完步之后,先发一个 /last_run,先拿到结构化数据摘要:
🏃 2026-04-21 跑步数据
📋 Xuhui - 节奏跑 5.0km_2026-04-21
📏 距离: 5.09 km
⏱️ 用时: 33分钟
⚡ 均速: 6:30/km
🚀 最快1km: 5:38
🚀 最快5km: 32:19
💓 均心率: 139 bpm
🔴 最大心率: 162 bpm
📊 心率区间:
Z1 热身: 0分钟 (1%)
Z2 有氧: 6分钟 (20%)
Z3 阈值: 23分钟 (70%)
Z4 无氧: 2分钟 (9%)
👟 步频: 174 spm
⛰️ 爬升: 16 m
🔥 消耗: 302 kcal
🔋 体能消耗: 9 点
📈 有氧效果: 3.0
🐸 好好分析,跑得更快!
这一阶段只是脚本执行,几乎不消耗什么 Token。 如果我接着追问:“这次跑得怎么样?下次该怎么调整?”这时才让 AI 进入分析模式。
它就可以基于心率区间、配速控制、步频、有氧效果等指标,给出更像真人教练的建议,比如:
相比4月17日节奏跑(7:03/km,HR132):配速提升33秒/km; 心率从132→139 bpm:强度适当增加; 训练效果从2.8→3.0:进步明显
我后来越来越觉得,这种“两步走”设计特别关键:
- 查询走脚本:快、稳、省 Token
- 分析走 AI:慢一点没关系,但要有质量
也正因为做了这层拆分,这套系统才真正兼顾了日常可用性和 AI 的价值。
实际使用体验:它开始像一个真正的日常助手
现在我的 Telegram 菜单里大致有这些命令。
训练相关
/training_plan—— 查看接下来一周的训练计划/easy_run 5km 今天—— 生成轻松跑并推送到 Garmin/tempo_run 8km 明天—— 生成节奏跑/long_run 10km 周末—— 生成长距离训练/interval_run 今天—— 生成间歇跑/garmin_workouts—— 查看本周已排期训练
健康数据相关
/health_data—— 今日健康总览/sleep_analysis—— 昨夜睡眠分析/last_run—— 最近一次跑步分析/running_stats—— 过去 7 天跑步统计/body_battery—— 今日身体电量
比如我发一条:
/easy_run 8公里 明天
几秒钟之后,Garmin Connect 的日历里就会多出一条明天的训练安排,包含热身、主跑和放松三段结构,对应的配速目标也都已经设好。
这种感觉很不一样。因为它不再只是“你问我答”的聊天工具,而开始变成一个真的能执行动作的个人运动助手。
当前目录结构
整个项目目前大致是这样的:
~/.openclaw/workspace/
├── AGENTS.md # Telegram 命令处理规则(核心)
├── SOUL.md # AI 人格定义
├── USER.md # 用户信息
├── HEARTBEAT.md # 主动巡检任务
├── scripts/
│ └── garmin_commands.py # 健康数据统一入口
├── memory/
│ ├── 2026-04-20-long-run-analysis.md
│ └── 2026-04-20-weekly-training-plan.md
└── skills/
└── garmin-workout/
├── SKILL.md # 技能描述(AI 的入口)
├── scripts/
│ ├── integrated_openclaw_skill.py # 训练生成 + 推送
│ ├── garmin_auth.py # 认证管理
│ ├── generate_workout.py # 生成训练 JSON
│ ├── fitcoach_simple.py # FitCoach AI 规划
│ └── ...
└── workouts_template/
├── easy_run_5km.json
├── tempo_run_5km.json
├── long_run_10km.json
└── ...
从工程角度看,这种结构的优点也很明显:职责清晰、便于维护,也方便以后继续扩展更多训练类型或健康指标。
备份也要提前想好
OpenClaw 的配置、记忆和技能,基本都集中在 ~/.openclaw 目录下。所以最简单直接的做法,就是定期备份整个目录,或者至少备份 workspace。
# 备份整个 openclaw 配置
tar -czf openclaw_backup_$(date +%Y%m%d).tar.gz ~/.openclaw
# 或者只备份 workspace(技能、脚本、记忆)
tar -czf workspace_backup_$(date +%Y%m%d).tar.gz ~/.openclaw/workspace
再加一个 cron 定时任务,每天自动同步到外部存储或云端,就能把风险降到比较低。这样即使以后 SD 卡损坏,训练记忆、Skill 配置、Telegram 菜单设置这些关键内容也都能比较快地恢复。
对于这种长期运行的个人助手来说,备份不是“以后再说”的事,而应该从一开始就纳入方案设计。
总结
这次折腾 OpenClaw,我最大的感受是: 想把它做成一个真正好用的个人运动助手,关键不在于让 AI 更“聪明”,而在于让系统分工更清楚。
核心思路其实很简单:
- 把高频操作固化成脚本:Garmin 查询、训练生成这类确定性任务,直接调用,不交给 AI 即兴发挥
- 用 Skill 持久化入口:让 AI 每次启动后都知道工具在哪里、什么时候该调用
- 把查询和分析拆开:日常查数据走脚本,深度建议才交给 AI
当树莓派 24 小时在线,Telegram 成为交互入口,Garmin 负责训练落地之后,这整套系统就不再只是一个“能聊天的 AI”,而更像一个真正融入日常生活的运动搭档。
