Spots

My AI Running Coach Didn't Need a Better Prompt. It Needed My Training History.

After every run I used to open the Mi Fitness app, take a few screenshots, and upload them to ChatGPT for analysis. On paper, that was a personal coach: the watch collects the data, I show it to AI, AI tells me what to do next. In practice it fell apart quickly, and not because of the prompt.

A single workout doesn't fit on one screenshot

A single workout doesn't fit on one screenshot: summary, charts, heart rate zones and other metrics all live on separate screens. Charts were the worst: a human can stitch several screens into one picture, but for the chat I was rebuilding the context from fragments every time.

The bigger problem: one workout means almost nothing

The bigger problem: one workout means almost nothing without the previous ones. A heart rate of 168 is just a number. It is a different story if at roughly the same distance it was 158, then 164, 167, 168, 170 and 172. Useful advice needs a trend, and through screenshots I was bringing AI a small fragment of what the watch app already knew. So the problem wasn't finding a better prompt. I needed a real channel between the watch data and the model. This is a shortened fragment of a real coach prompt that the portal assembles after a run:

The real request contains more: the current run

The real request contains more: the current run, the history of recent workouts, and stored context about my state. I can edit the template itself from the portal's UI.

That is the whole difference from screenshots. Before

That is the whole difference from screenshots. Before, I showed AI a picture of the data. Now the code gathers the facts and builds the context, I set the rules and the response format, and the model interprets the context. The data layer: running-portal

running-portal syncs my running workouts from Mi Fitness

running-portal syncs my running workouts from Mi Fitness, stores the history, and loads detailed data for a specific run. For me it is an ordinary training log. For the model it is a persistent source of context.

I did not reverse-engineer the private Mi Fitness

I did not reverse-engineer the private Mi Fitness API. The sync module is based on Mi-Fitness-Sync by kevinkwee (MIT License), which already implemented Xiaomi authorization, fetching workouts, and parsing detailed Mi Fitness data. A coding agent wrote running-portal and integrated that code; credit for the protocol work goes to the author of Mi-Fitness-Sync.

The integration is not pleasant: a private API

The integration is not pleasant: a private API and internal data formats, including separate files with detailed value series. That is one reason I treat the portal as a personal tool, not the basis for a public service.

The workout card shows me the same things

The workout card shows me the same things that go to the model in structured form: heart rate, pace, cadence, stride length, load, recovery, heart rate zone distribution, and detailed time series. To me, charts. To the model, raw numbers. What the coach does with it The analysis shows up on the same workout card. Assessment → risks → one specific next session.

In this example the coach looks beyond average

In this example the coach looks beyond average heart rate: most of the run happened in a high heart rate zone, it compares that with previous runs, and it suggests not increasing the load. I set a rigid response structure on purpose. I don't need sports motivation; I need an assessment, the risks, and the next workout. This is where I stopped thinking of the prompt as magic text. The usefulness came from the context. Guardrails in code, explanation from the LLM The portal also answers a shorter daily question: run today, run easy, or rest? At the time of this screenshot, less than the estimated recovery time had passed since the last run.

News

My AI Running Coach Didn't Need a Better Prompt. It Needed My Training History.

After every run I used to open the Mi Fitness app, take a few screenshots, and upload them to ChatGPT for analysis.

@spots #dev
Source: Dev.to
See more like this