latentSource

I Put an AI in My World Cup Pool. Here's How It Actually Did.

A bot that reads live match status off the open web, turns a qualitative read of each game into a scoreline, and gets graded against real results every day. The group stage is over, all 72 matches are graded, and the bot is on top of the pool.

·7 min read
Share
I Put an AI in My World Cup Pool. Here's How It Actually Did.

Every World Cup my friends run a prediction pool. You call the scoreline of each match, you get points for being close, and someone talks trash in the group chat for a month. This year I added a twelfth player to our pool that isn't a person. It's an agent I built into a Discord app, it predicts every match on its own, and it gets scored against real results exactly like the rest of us. We call it Memo Ocho Bits.

I didn't want a toy. I wanted to know whether an LLM grounded in live web data could actually compete with people who watch a lot of football. So I gave it two real jobs (read the live status of every match off the open web, and turn a qualitative read of each game into a concrete prediction) and then I graded it against reality every day. Both jobs run on Google Gemini. Here's how each one works, and then the part that matters: the full 72-match group stage is now in the books, so the answer isn't a projection anymore.

Reading the live match status

The hardest problem isn't the model. It's that the model's training data has no idea what happened in a match that kicked off twenty minutes ago. Static weights can't tell you the current score. So the live tracker doesn't ask Gemini what it knows: it asks Gemini to go read the web right now, using Google Search grounding. That grounding feature is the only reason this works, and at the moment it's the one real differentiator Gemini has over the other providers for this kind of job.

Every few minutes, for each match in its live window, the bot fires a grounded query, gets back a pile of analysis text scraped from whatever the web is saying about the game, and then forces that mess into a strict shape:

{ "home_score": 2, "away_score": 1, "minute": 67, "status": "live", "confidence": 0.86 }

So the qualitative chatter of a live match (commentary, match reports, half-sentences of "and it's two-one after a scrappy hour") collapses into a few typed fields the rest of the system can act on. If the confidence clears the bar and the match looks final, the bot commits that score to the database and re-scores everyone's predictions. No human in the loop. That last part made me nervous at first, which is why the confidence gate exists. A grounded read of a live game is good but not infallible, and you do not want to settle a betting pool on a hallucinated 3-2.

Turning a read of the game into a number

Now the part that competes with my friends. Before a match, the AI makes its pick in two Gemini calls, not one, and the split is deliberate.

The first call is the qualitative one. Go read the web for this fixture (betting odds, expert previews, form, injuries) and write an honest assessment of how the game is likely to go. That gives you a paragraph of reasoning anchored in what bookmakers and analysts actually think today, not what a model half-remembers from training. The second call takes that paragraph and squeezes the judgment into a number:

{ "home_goals": 1, "away_goals": 0, "confidence": 0.62 }

I keep these as two steps on purpose. A qualitative read and a clean numeric extraction are different jobs, and asking one call to both reason freely and emit tidy JSON gives you a worse version of each. Separate them and the reasoning stays rich while the output stays parseable. The whole prompt set lives in editable files, so when the AI says something dumb I can tune the instructions without redeploying.

The pick then gets fanned out to every guild running a pool and dropped in as a normal prediction under user id 1. From the leaderboard's point of view, it's just another player.

Grading it every day

This is the part I care about most, because it's the part that keeps everyone honest. The AI gets scored by the same Kicktipp-style rules as the humans: nail the exact score and you get the most points, get the goal difference right a bit less, just call the winner less again, and miss the result entirely and you get a participation point. Knockout matches score the same as group matches; the double-points multiplier didn't survive the group chat. The AI's predictions run through the identical scoring function the second a match goes final. No special treatment, no grading on a curve.

The group stage is done. All 72 matches predicted, all 72 graded. Here's the honest scoreboard for Memo Ocho Bits.

It nailed the exact scoreline 10 times, more than any human in the pool. The first was the opener, Mexico 2-0 South Africa, and the list ended up with real range: Brazil 3-0 Haiti, France 3-0 Iraq, Scotland 0-1 Morocco, USA 2-0 Australia, Jordan 1-2 Algeria, and a Paraguay 0-0 Australia I'll come back to. It called the right result (winner or draw) in 47 of 72 matches. That's 65%, on a three-way outcome where blind guessing sits at 33%. Not magic, but clearly doing something.

Every prediction the AI made across the 72-match group stage, by match day. Green is an exact scoreline, blue got the winner or draw right, grey missed the result. Hover any segment for the count. June 24 is the all-blue day: five matches, five correct sides. The all-grey June 12 was its only shutout.

Where it shines and where it falls apart is the interesting part, and the data tells on it cleanly. Its best stretch came late: June 19 went three for three with two exact hits, and June 24 went five for five on the result. Its worst day was June 25, when it missed four of six, including picking Czechia 2-1 over Mexico on the day El Tri won 3-0. Early on it looked allergic to draws: the June 15 slate had three of them (Spain 0-0 Cape Verde, Iran 2-2 New Zealand, Saudi Arabia 1-1 Uruguay) and the model called none, because a predictor anchored on betting odds almost never lands on a draw as the single most likely outcome.

Then that pattern moved, which I did not expect. Over the full group stage it committed to a draw 7 times. One of them was Paraguay 0-0 Australia, called exactly. It took winner-level points on Netherlands 2-2 Japan with a 1-1 pick, and again on Colombia 0-0 Portugal and Algeria 3-3 Austria, both picked 1-1. The group stage produced 20 draws in 72 matches, so 7 picks still under-calls the real rate, but "under-calls" is a different animal from "never". The grounded previews started flagging evenly matched sides, and the model followed the evidence instead of the favorite. I'd flag this as the most genuinely interesting behavior it showed all month.

The other tell never went away: it lowballs blowouts. It had Germany over Curaçao, but said 3-0. The real score was 7-1. Canada 6-0 Qatar came in as a polite 2-1. Sweden 5-1 Tunisia was a tight 1-0 pick, Netherlands 5-1 Sweden a 2-1, Belgium's 5-1 over New Zealand a 0-3, Senegal 5-0 Iraq a 3-1. Grounded on the odds, it predicts cautious, plausible scorelines, which is exactly what the odds describe and exactly what makes it boring and correct more often than not. It gets the direction right and shaves the magnitude toward the mean, every single time. Twenty-five misses in 72 matches, and not one of them came from an outlandish pick.

And the standing that actually settles the trash talk: Memo Ocho Bits finished the group stage on top of the pool. 191 points from all 72 matches, ahead of the two best humans at 184 and 183. The friend who led it by 8 points a week and a half in (the one who watches a frankly unreasonable amount of football) got run down and passed. Part of that is the exact scores: 10 against his 8. Part of it is attendance. The bot never skipped a fixture, while half the pool has gaps in their card. Eleven people entered a prediction pool against a bot, and all eleven are currently losing to it.

Final group-stage standings. The AI (amber) tops the pool of 12 with 191 points and 10 exact scores. Hover any bar for matches played and exact hits. It predicted every one of the 72 fixtures. Several humans didn't, and it shows in the table.

What I actually learned

Neither job is doing anything exotic. Grounded search instead of trusting the weights. A qualitative read split from the numeric extraction so each call does one thing well. The same scoring function for the machine and the people. The lesson, the one I keep relearning, is that the interesting part was never the model call: it was the data discipline around it. The confidence gate that won't settle a pool on a bad read. The structured-output step that keeps every pick parseable. And the honesty of grading the thing against reality every single day, which is what surfaced the patterns worth knowing: it shaves every scoreline toward the favorite, and it learned to call a draw when the evidence pointed there.

Leading the pool after the group stage is, honestly, a better result than I expected. I would have taken second and bragged about it. The knockout rounds will be a different test. There are no draws to hide behind now; the bracket forces the bot to commit to an advancing side in every match, and one bad weekend puts the humans right back in it. You can watch it defend the lead through the knockouts at mundial.mexicodev.org.