Curious analysts and supporters
People who know the football question they want answered but do not want to write the query themselves.
03 · Agents · SQL analytics
An agentic football data analyst that turns plain-English questions into read-only SQL, executes the query, and grounds its answer and charts in the returned rows.
Problem
Static dashboards answer predefined questions. Football analysis often starts differently: “Which teams improved most after 2010?” or “How has this head-to-head changed?” Touchline lets a user ask a new question while keeping the calculation inspectable as SQL and returned rows.
People who know the football question they want answered but do not want to write the query themselves.
The connection, database pragma and query validator all prevent the agent from modifying data.
A convincing sentence is not enough; every stated number is checked against a tool result.
Data
The source snapshot contains 49,363 international match records. Seventy-two are future or unplayed 2026 fixtures with missing scores, so the build excludes them. The SQLite database used by the agent and browser demo therefore contains 49,291 completed matches from 1872 to 2026.
A long-form team_match view creates one row per team per match with goals for, goals against, venue and result. That makes team-centric questions easier to express and reduces repeated home-versus-away logic.
Approach
A model-agnostic tool loop receives the schema and question, proposes a tool call, receives the execution result, and either repairs its query or answers. The loop is capped at six iterations. The same harness runs local Ollama models and a frontier API model so their differences are attributable to the “brain,” not a different agent.
When a local model prints SQL as prose rather than emitting a native tool call, a text-extraction fallback recovers the query and executes it. This forces the model to see real rows before answering instead of accepting an unsupported guess.
System architecture
The text guard improves feedback and blocks stacked or obviously unsafe statements. The stronger control is below it: the database itself is opened read-only with query_only, so a prompt cannot grant the model write permission.
Evaluation method
Thirty natural-language questions span seven categories: lookup, aggregation, head-to-head, conditional, trend, superlative and multi-step. Each question has reference SQL; the gold answer is computed from the database rather than hand-entered.
The final prose is checked with numeric tolerance, and accuracy carries bootstrap 95% confidence intervals.
This catches a partially correct answer that adds an invented statistic around the correct value.
Valid-SQL rate, self-correction, tool calls, end-to-end latency and API token cost are recorded per run.
Results
| Model | Answer accuracy | Valid SQL | Grounded | Mean latency | Cost / question |
|---|---|---|---|---|---|
| Claude Opus 4.8 | 1.000 | 1.000 | 0.867 | 4.86 s | US$0.00798 |
| qwen2.5-coder:7b | 0.767 | 0.683 | 0.967 | 8.12 s | US$0 |
| llama3.1:8b | 0.733 | 0.857 | 0.833 | 5.36 s | US$0 |
The result is a trade-off, not a universal model ranking. The frontier run answered all 30 questions correctly and wrote valid SQL every time, but only 86.7% of responses passed the stricter numeric-grounding check. Qwen grounded numbers most consistently at 96.7% while producing executable SQL less often. Both local models cost nothing per call and kept processing on-device.
Failure cases & trade-offs
Qwen initially printed a query in prose and then hallucinated an answer without executing it. The extraction fallback made the query observable and forced a grounded second turn.
Qwen was stronger on several single-table conditions; Llama produced more valid SQL and handled head-to-head joins better. Their overall confidence intervals overlap.
One Qwen question entered a 37-second sequence of failed repairs. A hard loop and query timeout bound latency even when reasoning does not converge.
An early fine-tune over-specialised: original-set single-shot accuracy fell from 60% to 40%. A broader bank and held-out gate were needed before a later round improved both tracked sets.
Its SQL execution and charts are live, but model plans come from recorded runs. Live planning would require a server and credentials that this static site deliberately does not expose.
What I would improve next
Live demo & source
The database and evaluation runs load only when the panel opens. The demo executes read-only SQL with sql.js and redraws the result locally; no user query or data is sent to a model API.
Faithful but lightweight: SQL and charts run now against the shipped database. The agent reasoning is replayed from recorded evaluation runs because live language-model planning needs a server.
Open this panel to load the in-browser database.