Pendant dix semaines, j'ai reçu chaque matin à 10h un mail de mon coach. Personne ne l'écrivait. Un script l'envoyait, après avoir lu ma montre.
Pour préparer une course, je me suis construit un coach qui n'existe pas. Pas une appli, pas un abonnement. Un dossier sur mon ordinateur, quelques scripts Python, un plan dans un fichier texte, et ma Garmin branchée dessus. Je n'ai pas écrit une ligne de code moi-même : c'est un agent IA qui a tout construit.
La course est passée depuis quelques mois. J'ai laissé retomber avant d'écrire : comment c'était fait, ce que ça valait vraiment, et ce que je ne referais pas.
Le point de départ : une allure cible et deux points faibles
L'objectif : tenir 5:41 au kilomètre le jour de la course, pendant 21 km. Dix semaines de préparation pour y arriver.
Le problème, ce n'est pas le chrono. C'est le corps. Une tendinite d'Achille qui revient quand je change brutalement de charge, et un genou fragile côté fascia lata. Un plan trouvé sur Internet ne connaît ni l'un ni l'autre. Une appli de course non plus, ou alors elle me demande comment je me sens et n'en fait pas grand-chose.
Ce que je voulais : un plan qui s'adapte à ce que mon corps dit vraiment, chaque jour, sans que j'aie à y penser. Un coach qui me connaît, qui ne dort pas, et qui ne me pousse pas à me casser.
Comment c'est construit
Un dossier dédié dans OpenClaw, l'agent IA que j'utilise, jouait le rôle de coach. Il contenait le plan, cinq scripts Python, un journal des séances envoyées et un log quotidien. C'est l'agent qui a écrit les scripts ; mon rôle a été de dire ce que je voulais, de vérifier, de corriger.
Le plan alimente la montre, la montre alimente Garmin Connect, et le script du matin referme la boucle en réécrivant la semaine à venir.
Mon plan semi-marathon est un fichier texte
Tout le programme tenait dans un fichier YAML : 10 semaines, 70 séances, chacune avec sa date, sa durée, son détail, sa fréquence cardiaque cible et ses notes. Un fichier lisible, modifiable, versionnable. Comme du code.
Ce n'est pas un template générique. Il est calé sur mes données :
- Zones cardiaques recalibrées : FC max fixée à 193 (189 observés sur mes sorties, plus une marge), cinq zones de la récupération au VO2max.
- Allures chiffrées par type d'effort : endurance fondamentale 6:10 à 6:25/km, tempo 5:35 à 5:45, seuil 5:20 à 5:30, allure course 5:41.
- Une semaine construite autour des blessures : la sortie longue le samedi, la qualité le jeudi, le renforcement le mercredi pour le genou.
- Des interdits écrits noir sur blanc : pas de 30-30, pas de sprint en descente, 15 minutes d'échauffement minimum.
Ce dernier point change tout. Mes contraintes ne sont plus dans ma tête, où je les oublie un jour de forme. Elles sont dans le plan, et le plan les applique.
Garmin Connect devient un backend
La partie qui m'a le plus surpris. Un script parle directement à Garmin Connect, via une bibliothèque Python communautaire (garminconnect). Il ne se contente pas de lire mes données : il écrit sur ma montre.
Concrètement, pour chaque séance du plan, il :
- construit l'entraînement au format natif Garmin, avec échauffement, intervalles, récupération et retour au calme, et des cibles cardiaques en bpm ;
- le planifie à la date prévue dans le calendrier Garmin ;
- le synchronise sur la montre.
Le jour J, je lançais la séance et la montre me guidait étape par étape : 15 minutes d'échauffement, 4 fois 5 minutes au seuil avec 1:30 de récupération, 10 minutes de retour au calme. Je ne regardais plus mon téléphone en courant. Chaque envoi était tracé dans un journal.
Le vrai coach, ce sont les règles d'adaptation
Pousser un plan sur une montre, c'est pratique. Mais un plan figé reste un plan figé. Ce qui fait un coach, c'est qu'il change le programme quand le corps ne suit pas.
Chaque matin à 10h, une tâche planifiée lance le script quotidien. Il récupère mes 7 derniers jours sur Garmin (courses, fréquence cardiaque, charge d'entraînement, VFC, sommeil), les compare à ce que le plan prévoyait, recalcule les 7 jours suivants et m'envoie le tout par mail.
Les adaptations sont des règles simples, écrites à l'avance :
| Si… | Alors… |
|---|---|
| VFC déséquilibrée 2 jours de suite | la séance de qualité devient de l'endurance fondamentale |
| Douleur à l'Achille au-dessus de 3/10 | le fractionné saute |
| Moins de 6h de sommeil sur 3 nuits | la qualité redevient de la récupération |
| Charge cumulée au-delà de 130 % du plan | alerte, et proposition d'endurance fondamentale |
Il n'y a pas d'intelligence magique là-dedans. Ce sont des « Si… Alors… » qu'un bon entraîneur appliquerait de tête. La différence, c'est qu'ils sont appliqués tous les matins, sans exception, même quand j'ai envie de forcer. Pour quelqu'un qui a un tendon qui réagit aux changements brusques de charge, c'est exactement ce qui manquait.
C'est là que je vois la différence entre une appli gadget et un coach : pas dans la quantité de données, dans la qualité des décisions qu'on en tire.
Les chiffres bruts
| Indicateur | Valeur |
|---|---|
| Semaines de préparation | 10 |
| Séances dans le plan | 70 |
| Sorties réelles par semaine | 2 à 3 |
| Mail du coach | tous les matins, sans interruption |
| Lignes de code écrites par moi | 0 |
| Allure cible | 5:41/km |
| Résultat | 20 km courus sans trop de problème |
Ce qui coince
Le système a marché. Il a aussi ses angles morts, et je préfère les poser ici.
- Le plan était plus ambitieux que ma vraie vie. 70 séances prévues, 2 à 3 sorties par semaine en pratique. Le coach constatait l'écart tous les matins, mais il ne courait pas à ma place.
- L'accès Garmin n'est pas officiel. La bibliothèque utilisée est maintenue par la communauté, pas par Garmin. Une mise à jour côté Garmin peut tout casser du jour au lendemain, et il faut stocker ses identifiants pour que ça tourne.
- Mes données de santé circulent. Sommeil, VFC, fréquence cardiaque : ce sont des données sensibles. Savoir exactement où elles passent fait partie du travail, pas d'un détail technique.
- Une règle n'est pas un kiné. Le seuil de douleur à 3/10 protège d'une erreur grossière. Il ne remplace pas un avis médical si le tendon se réveille vraiment.
- Le ressenti reste une saisie. La montre ne mesure pas ma douleur à l'Achille. Une partie de l'intelligence du coach dépend de ce que je lui déclare.
Au final : 20 km, sans casse
J'ai couru les 20 km sans trop de problème. Le mail est arrivé tous les matins jusqu'au bout, et la montre a toujours su quoi faire.
Avec quelques mois de recul, ce test m'a surtout appris une chose : l'IA ne m'a pas donné un coach. Elle m'a permis de construire le mien, avec mes données, mes contraintes et mes règles, en quelques échanges plutôt qu'en quelques semaines de code. Le vrai travail a été de dire clairement ce que je voulais protéger.
Ce que j'en garde : un plan, tout le monde peut en trouver un. Ce qui m'a amené au bout sans casse, ce sont les règles écrites à l'avance et appliquées sans exception.
Sous le capot : comment c'est fait, pour qui veut savoir
Cette section s'adresse à ceux qui veulent comprendre l'implémentation. Les autres peuvent sauter directement à la newsletter.
Architecture
Tout tient dans un workspace OpenClaw local, exécuté en ligne de commande. Pas de serveur, pas de base de données : des fichiers texte et cinq scripts Python.
~/.openclaw/workspace-coach-run/
├── plans/semi-2026-11-08.yaml # 10 semaines, 70 séances
├── scripts/
│ ├── coach_daily.py # cerveau quotidien, lancé à 10h
│ ├── push_workouts.py # pousse les séances sur la montre
│ ├── analyze_today.py # analyse la dernière course
│ ├── baseline.py # calibrage sur 30 jours d'historique
│ └── send_plan.py # récap initial du plan par e-mail
├── data/pushed_workouts.jsonl # traçabilité des séances poussées
└── memory/coach_daily.log # journal quotidien
| Script | Rôle | Déclenchement |
|---|---|---|
baseline.py | Calcule FC max observée et zones sur 30 jours | Une fois, au démarrage |
send_plan.py | Envoie le plan complet par e-mail | Une fois, au démarrage |
push_workouts.py | Convertit YAML → format Garmin, planifie, trace | À la demande ou par lot |
coach_daily.py | Lit 7 jours, compare au plan, applique les règles, mail | Cron, 10h |
analyze_today.py | Analyse détaillée de la dernière sortie | À la demande |
Stack
| Composant | Rôle | Statut |
|---|---|---|
| OpenClaw | Agent IA local, cron intégré | Open source, auto-hébergé |
| Python 3 | Langage des cinq scripts | — |
garminconnect | Client Garmin : lecture santé/activités + écriture de séances | MIT, non officiel |
| PyYAML | Lecture du plan | MIT |
| cron | Déclenchement quotidien à 10h | Système |
| SMTP | Envoi du récap quotidien | — |
Accès Garmin Connect
Le projet parle à Garmin Connect via garminconnect, un client non officiel : il s'authentifie comme l'app mobile et appelle les mêmes services web. C'est ce qui permet d'écrire sur le compte — donc de pousser des séances — ce que l'API personnelle officielle, en lecture seule, ne permet pas.
Trois voies possibles en octobre 2026 :
| Voie | Lecture | Écriture | Conditions |
|---|---|---|---|
garminconnect (non officiel) | Oui | Oui | Aucune validation ; peut casser à tout changement côté Garmin |
| API personnelle Garmin (officielle) | Oui | Non | Clé générée depuis les réglages Connect |
| Programme développeurs (Starter / Enterprise) | Oui | Oui (Training API) | Validation business, site public, politique de confidentialité |
Point d'attention, octobre 2026 : Garmin a durci ses conditions pour les tiers et fermé plusieurs apps intermédiaires (Intervals Pro, 12 octobre). Ce projet lit Garmin directement, sans plateforme intermédiaire : il n'est pas visé par cette restriction. Il reste exposé à un durcissement de l'accès non officiel. Évolution naturelle : lire par l'API personnelle, et ne garder garminconnect que pour l'écriture.
Séances structurées : du YAML à la montre
Une séance Garmin est un objet workout découpé en segments et étapes typées — échauffement, intervalle, récupération, retour au calme — chacune avec une condition de fin (durée ou distance) et une cible facultative (allure, FC, puissance, cadence).
push_workouts.py enchaîne trois opérations :
| Étape | Méthode | Effet |
|---|---|---|
| 1. Créer | upload_running_workout(workout) | Ajoute la séance à la bibliothèque Garmin, renvoie un workoutId |
| 2. Planifier | schedule_workout(workout_id, "AAAA-MM-JJ") | Place la séance à la date du plan dans le calendrier Connect |
| 3. Envoyer | synchronisation de la montre | La séance apparaît sur la montre |
Le plan en YAML
Le programme est une donnée, pas un document. Il se versionne avec Git, se relit à l'œil, se modifie sans outil.
athlete:
fc_max: 193
allures:
ef: ["6:25", "6:10"]
tempo: ["5:45", "5:35"]
seuil: ["5:30", "5:20"]
course: "5:41"
contraintes:
- pas de 30-30
- pas de sprint en descente
- echauffement_min: 15
semaines:
- numero: 7
seances:
- date: 2026-10-15
type: seuil
duree_min: 45
detail: "15' échauffement, 4 x 5' seuil r=1'30, 10' retour au calme"
fc_cible: z4
notes: "stop si Achille > 3/10"
Fondement scientifique des règles
Trois des quatre règles s'appuient sur une littérature solide ; aucune n'est une prescription médicale.
| Règle | Fondement | Écart avec la littérature |
|---|---|---|
| VFC déséquilibrée 2 jours de suite | Entraînement guidé par la VFC | Cohérent ; bénéfice modeste mais réel |
| Douleur Achille > 3/10 | Modèle de surveillance de la douleur (Silbernagel 2007) | Plus prudent que le seuil étudié (< 5/10) |
| Sommeil < 6h sur 3 nuits | Association manque de sommeil / blessure | Preuves surtout chez l'adolescent ; prudence raisonnable chez l'adulte |
| Charge cumulée > 130 % du plan | Ratio aigu/chronique (Gabbett 2016) | Le projet compare au plan, pas à la charge chronique réelle |
Deux méta-analyses de 2021 montrent que l'entraînement guidé par la VFC améliore surtout les marqueurs physiologiques sous-maximaux, avec un gain de performance faible mais moins de « non-répondeurs ». L'essai de Silbernagel et al. (AJSM 2007) montre que continuer à courir avec un modèle de surveillance de la douleur n'a pas d'effet négatif par rapport au repos, tant que la douleur reste sous 5/10. Gabbett a précisé en 2019 que son ratio charge aiguë/chronique montre une association, pas une prédiction : il ne doit jamais être lu isolément.
Sécurité
VFC, FC, sommeil et douleur déclarée sont des données de santé au sens du RGPD. Pour un usage strictement personnel, le RGPD ne s'applique pas. Il s'applique dès que le montage est proposé à d'autres.
| Point | Mesure |
|---|---|
Jetons Garmin (garmin_tokens.json) | Droits 0600, jamais dans Git, révocation côté compte en cas de doute |
| Mot de passe Garmin | Saisie interactive au premier login ; MFA activé |
| Envoi aux modèles d'IA | Savoir quel modèle OpenClaw appelle, limiter aux agrégats |
| Mail de récap | Contenu minimal, boîte personnelle |
Journal et .jsonl | Chiffrement du disque, rétention limitée |
Un livre blanc technique complet (architecture, bibliothèques, extraits de code, références scientifiques et sources) est disponible sur demande.
---
Vous voulez recevoir mes prochains tests de ce genre ? Inscrivez-vous à la newsletter Because Friday. Chaque semaine, un test vécu, ce qui a marché et ce qui a coincé.
Transparence : les scripts ont été écrits par un agent IA (OpenClaw), cet article a été rédigé avec l'aide de Claude à partir de mes notes. Le plan, les choix et les kilomètres sont à moi.
