DEV Community

Ritesh Deshmukh
Ritesh Deshmukh

Posted on

UndercoverCaptain


 # OverMind: I Built a Multi-Agent IPL Captain Using Google Gemini — Here's How the Agents Argue

"What if Dhoni's instinct, a data scientist's spreadsheet, and an argumentative assistant coach all lived inside one AI system?"

That's the question I set out to answer at this hackathon. The result is OverMind — a multi-agent AI system that acts as a virtual IPL captain, makes tactical decisions ball by ball, and shows you the internal debate before committing to the call.


The Problem: Cricket Strategy is a Multi-Brain Problem

Real captaincy isn't one person thinking alone. Watch any IPL dugout — there's the captain reading the pitch, the coach watching the data, the assistant flagging the tired bowler, and the commentator framing it for the crowd.

Most AI cricket tools give you one answer from one model. OverMind gives you four agents genuinely arguing — and you see the argument.


Architecture Overview

User Input (Match State)
        │
        ▼
  ┌─────────────┐
  │ Orchestrator │  ← multi-turn debate loop manager
  └──────┬──────┘
         │
    ┌────┴──────────────────────────────────┐
    │           │              │            │
    ▼           ▼              ▼            ▼
Stats       Strategist    Devil's       Commentator
Analyst     (proposes)    Advocate      (final voice)
(tool calls) │            (challenges)       │
    │         │              │               │
    │    ◄────┘  ← IF HIGH severity:         │
    │         revision round                 │
    │                                        │
    └────────────────────────────────────────┘
                        │
                        ▼
              Final Captain's Call
        (Decision + Debate + Win Probability)
Enter fullscreen mode Exit fullscreen mode

Tech stack:

  • Gemini 2.5 Flash via @google/genai (JS/Node.js)
  • Google Antigravity for agentic vibe-coding
  • Google AI Studio for prompt prototyping
  • Google ADK pattern for multi-agent orchestration
  • Gemini function calling for live tool use
  • Express.js backend + vanilla HTML frontend

The Four Agents

Agent 1 — Stats Analyst 📊

Role: Pure data. No opinions. Just numbers and matchup records.

System prompt:

You are a data-driven IPL cricket analyst. Given match state and available 
tools, you analyze bowler vs batsman matchups, venue history, and recent form. 
You speak in numbers and percentages. You MUST call the calculateWinProbability 
tool and at least one cricket stats tool before forming your analysis. 
Output structured JSON: { winProbability, keyMatchup, recommendation, confidence }
Enter fullscreen mode Exit fullscreen mode

Tools it calls:

  • calculateWinProbability(innings, over, score, wickets, target, pitchFactor) — logistic regression based on required run rate, wickets in hand, overs remaining
  • getBowlerVsBatsmanRecord(bowlerName, batsmanName) — dismissals, economy, dot ball %, average from Cricbuzz API
  • getVenueStats(venue, playerName) — historical strike rate and average at venue

This is where the real Gemini function calling happens. The agent doesn't hardcode win probability — it calls the tool and gets a live computed result.


Agent 2 — Strategist 🧠

Role: Captain's tactical brain. Reads the Analyst's findings and makes ONE specific call.

System prompt:

You are the IPL captain's tactical brain — like MS Dhoni's instinct combined 
with data. You receive the Stats Analyst's findings and propose ONE specific 
tactical decision: who bowls the next over, field placement, batting order 
change, timeout call, or Impact Player activation.

Justify your call in cricket commentary language — mention pitch, dew, 
matchups, pressure. Never use ML jargon. Output JSON: 
{ decision, primaryReason, alternativeConsidered, confidenceLevel }
Enter fullscreen mode Exit fullscreen mode

What makes it agentic: It's a separate Gemini API call that receives the Analyst's output as context. Not one call wearing two hats — genuinely two calls, two system prompts, one conversation.


Agent 3 — Devil's Advocate 😈

Role: Finds the flaw in every plan. Proposes a counter-decision. Rates severity.

System prompt:

You are the assistant coach who always challenges the captain's first instinct. 
Your job is to find flaws in the Strategist's proposed decision. Consider:
- What if dew makes spin ineffective?
- Is the bowler being brought on actually tired or out of rhythm?
- Is the batter due for a big shot?
Challenge hard. Propose a counter-decision if the original is wrong.
Output JSON: { challenge, counterDecision, severity (low/medium/high) }
Enter fullscreen mode Exit fullscreen mode

The key mechanic: If severity === "high", the orchestrator routes back to the Strategist for a revision round. The Strategist must either defend or update its decision. This is the loop that makes OverMind genuinely multi-turn.


Agent 4 — Commentator 🎙️

Role: Takes the full debate transcript and turns it into cricket language any fan can understand.

System prompt:

You are Harsha Bhogle meets Nasser Hussain — you turn tactical cricket 
decisions into vivid, exciting commentary. You receive the full agent debate 
and the final decision. Write:
1. FINAL DECISION — one crisp sentence
2. CAPTAIN'S CALL — 3-4 lines of rich cricket commentary explaining why
3. THE DEBATE — summarize what the Devil's Advocate said and how the 
   Strategist responded
4. WHY NOT THE OTHER OPTION — one line explaining the rejected alternative

Write like you're on air. No jargon. Output plain text.
Enter fullscreen mode Exit fullscreen mode

The Orchestrator: Where the Magic Happens

async function runOverMind(matchState) {
  // Step 1: Stats Analyst with real tool calls
  const analysis = await statsAnalystAgent(matchState);

  // Step 2: Strategist proposes a decision
  const proposal = await strategistAgent(matchState, analysis);

  // Step 3: Devil's Advocate challenges it
  const challenge = await devilsAdvocateAgent(matchState, proposal);

  // Step 4: Revision loop if severity is HIGH
  let finalDecision = proposal;
  if (challenge.severity === 'high') {
    finalDecision = await strategistAgent(matchState, analysis, challenge);
  }

  // Step 5: Commentator writes the final call
  const commentary = await commentatorAgent({
    analysis, proposal, challenge, finalDecision
  });

  return {
    finalDecision,
    commentary,
    debateTranscript: [analysis, proposal, challenge, finalDecision],
    winProbability: analysis.winProbability
  };
}
Enter fullscreen mode Exit fullscreen mode

The Strategist potentially runs twice — that's the revision round, and that's what makes the debate real.


A Full Match Scenario: CSK vs MI, Over 15

Input: Innings 2 | Over 15 complete | Score 120/3 | Target 185 | Striker: Jadeja (22 off 18) | Dew setting in | Wankhede

Stats Analyst says:

Win probability: 41%. Jadeja scores at 178 SR against mystery spinners. Hardik's pace is down 2 kmph from over 10. Dew factor increasing — spin grip deteriorates by over 17.

Strategist (Round 1) says:

"Bowl Hardik Pandya in over 16. His yorkers in overs 15-17 are a proven weapon — 8 wickets this season. Dew won't affect pace."
Confidence: HIGH

Devil's Advocate fires back:

"Hardik's last over went for 14. A tired fast bowler at Wankhede against a set Jadeja on a small ground is a full-toss machine, not a yorker bowler. CSK will get 18+."
Counter: Bowl Pollard. Severity: HIGH

Strategist (Revision Round) says:

"Conceded on the fatigue point. Revised: Pollard in over 16, with a 7-2 field. Third man back for Jadeja's ramp shot — he's played it twice tonight. Pollard's slower ball is a wicket-taking delivery with this setup."

Commentator's Final Call:

Kieron Pollard, over 16.

"Rohit's gone to his big man, and you know what — this is smart captaincy. The temptation was Hardik, but look at him — he's been running hard all night and that last over told you everything. Pollard is fresh, he's got the slower ball, and crucially — he's got Jadeja's number this season. The field is set beautifully: seven men on the leg side, third man back for that ramp Jadeja's been teasing all match. If CSK get less than 14 off this over, MI win this game."


Tool Calls in Detail

calculateWinProbability

// Gemini function definition
const winProbTool = {
  name: "calculateWinProbability",
  description: "Calculate batting team win probability based on match state",
  parameters: {
    type: "object",
    properties: {
      innings: { type: "number" },
      over: { type: "number" },
      score: { type: "number" },
      wickets: { type: "number" },
      target: { type: "number" },
      pitchFactor: { type: "number", description: "1.0 = flat, <1 = difficult" }
    },
    required: ["innings", "over", "score", "wickets", "target"]
  }
};

// The actual computation
function calculateWinProbability({ innings, over, score, wickets, target, pitchFactor = 1.0 }) {
  const ballsLeft = (20 - over) * 6;
  const needed = target - score;
  const rrrRatio = (needed / ballsLeft * 6) / (target / 120); // vs par RRR
  const wicketsInHand = 10 - wickets;

  // Logistic regression weights (tuned on IPL 2022-2024 data)
  const z = 2.1 - (1.8 * rrrRatio) + (0.15 * wicketsInHand) + (0.3 * pitchFactor);
  const prob = 1 / (1 + Math.exp(-z));

  return { winProbability: Math.round(prob * 100), ballsLeft, needed };
}
Enter fullscreen mode Exit fullscreen mode

The Stats Analyst calls this via Gemini function calling — the model decides when to invoke it and what arguments to pass. That's genuine agentic tool use, not hardcoded JSON.


What I Built with Google Antigravity

OverMind was vibe-coded over 3 hours in Antigravity. The .antigravity/ folder in the repo contains:

  • Agent trace logs from each run (showing which agent called which tool)
  • Prompt iteration history (I went through 4 versions of the Devil's Advocate system prompt before it started challenging hard enough)
  • The commit history shows the moment I added the revision loop — that was the turning point where the system felt genuinely alive

Key things Antigravity helped with:

  1. Scaffolding all 4 agent files in one shot
  2. Writing the Gemini function calling boilerplate correctly the first time
  3. Debugging the orchestrator revision loop (the severity === 'high' routing logic had an off-by-one bug on the conversation history)

Stretch Goals Implemented

  • Win probability gauge in the UI — shows the shift from pre-decision to post-decision projected probability
  • Debate timeline UI — each agent's output shown as a chat-style timeline so you can follow the argument step by step
  • Confidence scores — Strategist outputs confidenceLevel which the Commentator references
  • Counterfactual line — Commentator always ends with "why not the other option"

What I'd Do With More Time

  1. Real-time Cricbuzz URL scraping — paste a live match URL, Gemini's URL context tool reads the scorecard automatically
  2. Voice I/O — Web Speech API in + Gemini Live API out, so the captain literally talks back
  3. Memory across overs — Gemini context caching to track the full match arc cheaply across 20 overs
  4. Multimodal input — feed Gemini a pitch image or scorecard screenshot

Lessons Learned

The revision loop is everything. A system where the Strategist can change its mind because of the Devil's Advocate is categorically different from a system that just presents multiple options. The revision loop is what turns OverMind from a chatbot with cricket lipstick into something that actually feels like a dugout debate.

Separate system prompts matter. Early versions used one Gemini call with a long prompt asking for multiple roles. The quality improved dramatically when each agent got its own API call and its own system prompt. The Commentator in particular — when it only had to think about how to say things, not what to decide — started producing genuinely vivid cricket language.

Let the agents surprise you. I didn't expect the Devil's Advocate to start flagging fatigue signals I hadn't put in the match state. It inferred from the economy rate data that the bowler had been bowling in short bursts — and challenged the plan on that basis. That's the system working better than I designed it.


Links

- 🎯 Live demo: https://agentic-premier-league-lemon.vercel.app/

Built with Google Gemini 2.5 Flash, Google Antigravity, and way too much love for IPL cricket.

Top comments (0)