This exact generation's usage wasn't recorded separately — cost and time above reuse the comparison run at the same model and effort. Effort output isn't deterministic, so treat them as representative, not exact.
Spain played a 4-2-3-1 from kick-off to 90' while England played a 4-2-3-1 from kick-off to 70'. Spain's average position in possession was 6.4 yards higher than England's (Spain kick-off to 46', England kick-off to 61') and England's average out-of-possession position was 9.1 yards deeper than Spain's. Spain's passing was more concentrated than England's: the top three players had 44.8% of involvement against 37.0% (kick-off to 46') and Aymeric Laporte and Robin Le Normand combined 31 times (kick-off to 46'). Daniel Carvajal took 56 of 60 touches on the right wing (kick-off to 46') while Lamine Yamal took 29 of 40 touches on the right wing (kick-off to 46'). England's passing had no single hub; the most involved player, John Stones, had 12.8% (kick-off to 61') while England's average position in possession was in their own half (kick-off to 61'). The score was level at 0-0 from kick-off to 47' and Martín Zubimendi replaced Rodri for Spain (46'). Nico Williams scored for Spain (47') and Spain led 1-0 from 47' to 73'. Spain's passing had no single hub; the most involved player, Fabián Ruiz, had 14.3% (46' to 68') while Nico Williams took 8 of 12 touches on the left wing (46' to 68'). Ollie Watkins replaced Harry Kane for England (61') then Mikel Oyarzabal replaced Álvaro Morata for Spain (68'). Cole Palmer replaced Kobbie Mainoo for England (70') then Jude Bellingham moved from Left Wing to Right Defensive Midfield (70') and Phil Foden moved from Center Attacking Midfield to Left Wing (70'). Cole Palmer scored for England (73') and the score was level at 1-1 from 73' to 86'. Nacho replaced Robin Le Normand for Spain (83') then Mikel Oyarzabal scored for Spain (86'). Spain led 2-1 from 86' to full time and Mikel Merino replaced Lamine Yamal for Spain (89'). Ivan Toney replaced Phil Foden for England (90') then England changed from a 4-2-3-1 to a 4-1-2-1-2 (90'). Bukayo Saka moved from Right Wing to Right Center Midfield (90') and Jude Bellingham moved from Right Defensive Midfield to Left Center Midfield (90') and Declan Rice moved from Left Defensive Midfield to Center Defensive Midfield (90'). Ollie Watkins moved from Center Forward to Right Center Forward (90') while Daniel Olmo moved from Center Attacking Midfield to Right Wing (90'). Spain beat England 2–1.
No issues flagged in the hand check for this run.
Five runs of the same match, built on StatsBomb open data, each one an outcome call plus a tactics call. Cost and tokens come from the API's own usage numbers, not estimates. Errors are called out by hand rather than scored: there's no automated evaluation yet, so a wrong claim is recorded, not disqualifying. One run per combination, and output varies between runs, so small gaps are noise. Read any run's full text in the tabs above.
| Model | Effort | Cost | Time | Tokens in / out | Outcome errors | Tactics errors | MOTM (Nico Williams) |
|---|---|---|---|---|---|---|---|
Haiku 4.5 | none | $0.17 outcome $0.13 · tactics $0.05 | 31s outcome 15s · tactics 16s | 164,148 / 1,719 | 2 errors | 7 errors | hit |
Sonnet 5 | medium | $0.38 outcome $0.28 · tactics $0.10 | 32s outcome 16s · tactics 16s | 181,961 / 1,765 | 1 error, 2 minor | 3 errors, 2 minor | miss |
Opus 5 Chosen · Tactics | medium | $0.99 outcome $0.70 · tactics $0.29 | 55s outcome 16s · tactics 39s | 181,961 / 3,351 | 0 errors, 2 minor | 1 error, 1 minor | hit |
Sonnet 5 Chosen · Outcome | low | $0.38 outcome $0.28 · tactics $0.10 | 31s outcome 14s · tactics 17s | 181,961 / 1,847 | 0 errors, 1 minor | 2 errors, 2 soft | miss |
Sonnet 5 | high | $0.41 outcome $0.31 · tactics $0.10 | 84s outcome 54s · tactics 30s | 181,961 / 4,964 | 1 error, 2 soft | 2 errors, 3 minor | hit |
MOTM (Nico Williams): Named by Tyler as the match's man of the match. None of the six source files carries a man-of-the-match field, so the model cannot know it: a miss is not a grounding error, and the prompt must not be tuned, or outside data added, to make it hit, because that would use information the model would not have in production. Hits (cells 1, 3, 5) are picks the data it did have supports (8 progressive actions, tied for the most on Spain), though cell 1's supporting figure is wrong. Recorded as an observation only, not a selection criterion.
Cost is each call's token usage at list prices as of 2026-09-21; time is wall-clock for both calls; the "chosen" tags mark the runs whose config the shipped default uses — a default, to revisit once there's an automated evaluation. Full record: ai/match_summary/output/3943043/comparison-3943043.json.
Takes the full StatsBomb event data for a match and generates a structured outcome (headline, key stats, standout performers) plus free-form tactics prose. It lives inside the Match Analysis Dashboard's Match Summary modal, which shows the "Shipped" tab above — the same generated content, without the dialog. The other tabs are alternate models and effort levels tested alongside it, not live on the dashboard.
A Python script, generate_match_summary.py, loads a match's extracted data — stats, formations, team shape, pass networks — and calls a Claude model twice: once in structured-output mode for the outcome section, once for free-form tactics prose. The result is written once per match ID to a static JSON file; the site only ever reads that file, no model call happens at request time.
The two calls use different settings: Sonnet 5 at low effort for the outcome section, Opus 5 at medium effort for tactics — the "Shipped" tab above. Flip through the other tabs to see what four alternative configurations produced, or see the full comparison table below. The routing was picked from measured cost, speed, and what each run got wrong, not guessed — a default, to revisit once there's an automated evaluation.
Splitting the two calls was deliberate. A field like "standout performer" reads as objective, but which stats count as key and who counts as standout is an editorial call the model is making, not a fact it's reporting. Keeping that judgment call in one narrow, structured call — separate from the open-ended tactics prose — made it easier to see where the model's interpretation was entering the output, instead of it being spread across the whole thing.
Each tab above lists what a hand check found wrong in that run, left in on purpose. The check was a targeted pass over numbers, comparisons, players, formations, and substitutions, not every sentence.
More broadly: this was checked once, by hand, on one match. There's no automated evaluation yet — that's planned, not built — so a new match, or a re-run of this one, could reintroduce issues this pass happened to catch. And nothing here regenerates live: this page and the dashboard both read the same static file(s), generated once, not on demand.
A second AI-engineering feature here, and an automated check to replace the one-time manual trace.