Terms and Conditions for a Mobile App: What to Include and Why It Matters

What Are Terms and Conditions?

Terms and conditions (also called terms of service or terms of use) are a legal agreement between you and your users. By downloading or using your app, users agree to your terms.

They define:

  • What your app does and doesn’t do
  • What users are and aren’t allowed to do with it
  • What happens when things go wrong
  • Who owns what
  • How disputes get resolved

Without them, any of these questions are answered by default law — which may not favour you.

Why Mobile Apps Specifically Need Them

Both Apple and Google require apps in their stores to have terms and conditions if the app:

  • Requires user accounts or sign-up
  • Processes payments or subscriptions
  • Collects personal data
  • Offers in-app purchases
  • Provides any kind of service or content

Apple’s App Store Review Guidelines explicitly state that apps collecting user data must have a privacy policy. Google Play has the same requirement. Both platforms can reject or remove apps that don’t comply.

Beyond the stores — users expect them. An app without terms and conditions looks unfinished. Enterprise users and business customers will specifically look for them before allowing your app into their organisation.

What Your Mobile App Terms and Conditions Must Cover

1. What the app does
A clear description of your service. What does the app do? What are users getting?

2. User eligibility
Who can use the app. Age restrictions (especially important if your app could be used by minors). Geographic restrictions if applicable.

3. Account rules
If users create accounts: password responsibilities, prohibited activities, what happens if an account is terminated.

4. What users can and cannot do
Acceptable use policy. This protects you if a user does something harmful with your app. Common prohibitions: reverse engineering, scraping, reselling, using the app for illegal purposes.

5. Intellectual property
Who owns the app, the content, and any content users create within it. If your app lets users upload content, you need to clarify what licence you have to display or process it.

6. Payment terms
If your app has paid features, subscriptions, or in-app purchases: pricing, billing cycles, refund policy, what happens on cancellation.

7. Disclaimer and limitation of liability
This is the most protective clause in your terms. It limits your liability if the app goes down, loses data, or causes indirect harm. Without this, a user could theoretically claim unlimited damages.

8. Changes to the app and terms
Your right to update the app and the terms without prior notice (within reason).

9. Governing law
Which country’s laws apply to disputes. For UK-based apps: England and Wales.

10. Contact details
How users can reach you with questions, complaints, or legal notices.

The One Clause Every App Builder Gets Wrong

The limitation of liability clause. Most founders either skip it or copy something vague from another app.

A proper limitation of liability clause should:

  • Cap your total liability to the amount the user paid (or a fixed small sum if the app is free)
  • Exclude liability for indirect, consequential, or incidental damages
  • State clearly that the app is provided “as is” without warranties

This clause is what protects you if a user claims your app caused them to lose business, data, or money. Without it, your exposure is theoretically unlimited.

Subscription Apps: Additional Clauses You Need

If your app charges a recurring subscription, you also need to cover:

  • Free trial terms (if applicable) and when billing starts
  • How and when prices can change
  • Cancellation process — how users cancel and what happens to their data
  • Refund policy — whether you offer pro-rata refunds, no refunds, or something in between
  • What happens at the end of a subscription — does access end immediately or at the period end?

App Store subscriptions have their own rules (Apple and Google handle billing) but your terms still need to cover the basics.

Getting It Done Without a Legal Bill

A solicitor will charge £300–£800 to draft app terms and conditions from scratch. For a bootstrapped solo founder, that’s a significant cost before you’ve made a single sale.

InkTerms generates a complete, personalised set of terms and conditions for your mobile app based on answers to 14 questions about your product. The document is written in plain English, structured for readability, and covers all the clauses above. You answer the questions, we generate the document, you edit and publish.

From £9. Ready in minutes.

Generate your app terms and conditions →

InkTerms provides AI-assisted document generation and is not a substitute for professional legal advice. We recommend reviewing any generated document with a qualified legal professional before relying on it for your business.

Originally published on InkTerms Blog

🏏 Captain Cool: Building a Multi-Agent IPL Strategist with Google Gemini & ADK

In the high-pressure cooker of T20 cricket, a captain has mere seconds to make decisions that dictate the outcome of a match. Who bowls the death overs? How do you set a field for a rampaging Suryakumar Yadav on a gripping pitch?

For the Agentic Premier League, I set out to solve the captain-strategist problem. Standard AI chatbots are too generic & agreeable to make tough, high-stakes sports decisions. To fix this, I built Captain Cool, a virtual IPL captain powered by the Google Gemini stack.

Instead of a single prompt, Captain Cool uses a Multi-Agent Debate Framework orchestrated via the Google Agent Development Kit (ADK). It actively fetches live weather data, proposes a strategy, aggressively critiques its own plan, and outputs a fan-friendly tactical breakdown.

Here is a deep dive into the architecture, the agentic design, and how to run it yourself.

🏗️ High-Level Design (HLD) & Architecture

To achieve a true “agentic” workflow, the system cannot rely on a single LLM call wearing multiple hats. It requires distinct personas executing a sequential loop.

The application is built on a Python backend wrapping the google-genai SDK and the google-adk. The frontend is a sleek, responsive dashboard built with Streamlit.

The 5-Turn Agentic Loop

Here is the logical flow of our system.

🔬 Low-Level Design (LLD): The Agentic Team & Prompts

To optimize for both speed and deep reasoning, I utilized model routing. The deep-thinking agents (Strategist/Advocate) run on gemini-2.5-pro, while the fast data-gatherers and summarizers (Analyst/Commentator) run on gemini-2.5-flash.

Here are the system prompts engineered for the team:

1. The Stats Analyst (The Tool Caller)

Model: gemini-2.5-flash
Role: To ground the LLM in reality rather than hallucinating conditions.
Prompt:

“You are a precise cricket data analyst. You will receive a JSON of the current match state. Before doing anything else, you MUST execute your provided Python tool call get_venue_weather(venue) to fetch the live temperature and dew risk for the provided stadium. Append this real-world data to the match context and pass it forward.”

2. The Strategist (The Captain)

Model: gemini-2.5-pro
Role: The primary decision-maker.
Prompt:

“You are an elite, proactive IPL Captain (think MS Dhoni or Rohit Sharma). Review the match state and the Analyst’s weather report. Propose the exact next tactical decision: who bowls the next over, the field setup, and how to utilize remaining bowlers for the death. Be decisive and explain your cricketing reasoning based on matchups and pitch conditions.”

3. The Devil’s Advocate (The Skeptic)

Model: gemini-2.5-pro
Role: To force the AI to self-correct and avoid obvious traps.
Prompt:

“You are a ruthless cricket tactician and skeptic. Review the Strategist’s proposal. Your ONLY job is to attack this plan. Point out vulnerabilities, batter vs. bowler mismatches, or instances where they ignored the dew factor or pitch conditions. Do not be polite. Highlight the risk of their strategy.”

4. The Match Commentator (The Explainer)

Model: gemini-2.5-flash
Role: Fan-facing communication and stretch-goal execution.
Prompt:

“You are a charismatic cricket commentator like Harsha Bhogle. Take the Strategist’s final defended decision and explain the internal debate to the fans in exciting, natural cricket language. YOU MUST INCLUDE TWO THINGS AT THE END: 1) A Confidence Score (0-100%) for the decision. 2) A ‘Counterfactual’ explaining exactly how the win probability would drop if they had taken the safe route instead.”

⚙️ Real Tool Calling in Action

Instead of hardcoding a JSON payload to fake “live context,” the Stats Analyst agent uses Google Gemini’s native function calling to execute a real Python script.

When the user inputs “Wankhede Stadium”, the Analyst executes a function that pings the free Open-Meteo API, parses the coordinates, and returns the exact live temperature and humidity to determine the dew risk. This proves the system can break out of its training data and interact with the live internet to make decisions.

📸 End-to-End Walkthrough: The Wankhede Scenario

Let’s look at the system in action during a high-stakes scenario.

The Situation: 2nd Innings. 15.6 overs gone. 67 runs needed off 24 balls. Suryakumar Yadav (75 off 34) is on strike. Pitch is slowing down and gripping.

[Insert Screenshot of your Streamlit Sidebar Input here]

Once we click “Generate Strategy”, the ADK routes the inputs through our 5-turn debate.

[Insert Screenshot of the Chat UI showing the Strategist and Devil's Advocate debate here]

The Debate:

  • The Strategist proposes bowling Rashid Khan in the 17th over, arguing that we need a wicket-taking option immediately on a gripping pitch, saving Bumrah for the absolute death (18 and 20).
  • The Devil’s Advocate violently objects, calling it a “glaring vulnerability” and a “perilous gamble” because SKY is a master at dissecting wrist-spinners and is fully set.
  • The Defense: The Strategist absorbs the critique but defends the move, stating that bowling a medium pacer like Mohit Sharma is just as risky but without the wicket-taking upside. It’s a calculated necessity.

Finally, the Commentator agent wraps it up, translating the intense AI reasoning into an engaging broadcast format, complete with a 75% confidence score and a detailed counterfactual.

[Insert Screenshot of the final Counterfactual output box here]

🎯 Hitting the Stretch Goals

This architecture was specifically designed to hit the hackathon’s advanced requirements:

  • Explainability: The Commentator removes ML jargon and outputs pure cricket logic.
  • Confidence & Counterfactuals: Hardcoded into the final output agent for deep fan insight.
  • Memory Across Overs: The Streamlit session_state appends the final strategy to a match_history list. If the user advances the over from 15.6 to 16.0, the context is fed back into the Strategist, ensuring the AI remembers its previous overs!

💻 Tech Stack

  • Google Gemini API: gemini-2.5-pro & gemini-2.5-flash
  • Google Agent Development Kit (ADK): Orchestrating the multi-agent pipeline.
  • Google Antigravity: Google’s agentic IDE used for 100% of the vibe-coding and environment setup.
  • Streamlit: For the rapid, chat-based dashboard UI.

🏆 Try it Yourself!

Want to see the agents debate your favorite IPL scenarios? The complete codebase is open-source and ready to run locally.

GitHub Repository: https://github.com/mayureshkate/captain-cool-ipl/tree/main

Quick Start Guide:

# 1. Clone the repository
git clone [https://github.com/mayureshkate/captain-cool-ipl.git](https://github.com/mayureshkate/captain-cool-ipl.git)
cd captain-cool-ipl

# 2. Set up the virtual environment
python3 -m venv venv
source venv/bin/activate  # On Windows use: venvScriptsactivate

# 3. Install dependencies
pip install -r requirements.txt

# 4. Add your Gemini API Key
echo "GEMINI_API_KEY=your_api_key_here" > .env

# 5. Launch the Streamlit App
streamlit run app.py --server.port 3000

Cricket is a captain’s game. But with Gemini and ADK, it’s an agent’s game too.

Built for the Agentic Premier League Hackathon.


Two Sum — LeetCode #1 (Easy)

TL;DR

Single-pass hash map lookup: store each number’s index as you go, check for the complement before storing. O(n) time, O(n) space.

The Problem

Given an array of integers nums and an integer target, return the indices of the two numbers that add up to target.

Input: nums = [2,7,11,15], target = 9
Output: [0,1]

The answer is indices 0 and 1 because nums[0] + nums[1] == 9. Note: return indices, not values.

Constraints

  • 2 <= nums.length <= 10^4
  • -10^9 <= nums[i] <= 10^9
  • -10^9 <= target <= 10^9
  • Exactly one valid answer exists.

Naive Approach

Fix one number, scan every number after it for the complement. Repeat for each starting index.

class Solution:
    def twoSum(self, nums: list[int], target: int) -> list[int]:
        for i in range(len(nums)):
            for j in range(i + 1, len(nums)):
                if nums[i] + nums[j] == target:
                    return [i, j]

O(n²) time, O(1) space — ~50 million pair checks on a 10,000-element array.

Key Insight

At every index i, you already know the complement you need: target - nums[i]. The only question is whether that value appeared earlier. Instead of scanning backwards, keep a hash map that answers “have I seen value v?” in O(1).

Two things to get right: use the value as the key and the index as the value (you look up by value, you want to retrieve the index); and check the map before inserting the current number, so a value can’t match itself.

Optimal Solution

One pass. For each element, compute need = target - x. If need is already in seen, you’re done. Otherwise, record x → i and continue.

class Solution:
    def twoSum(self, nums: list[int], target: int) -> list[int]:
        seen = {}
        for i, x in enumerate(nums):
            need = target - x
            if need in seen:
                return [seen[need], i]
            seen[x] = i

Step-by-step on [2, 7, 11, 15], target 9:

  1. i=0, x=2 — need=7. seen={}, not found. Store seen[2]=0.
  2. i=1, x=7 — need=2. seen={2:0}, found. Return [seen[2], 1] → [0, 1].

The loop never reaches indices 2 or 3.

Complexity

Approach Time Space
Naive (nested loops) O(n²) O(1)
Hash map (one pass) O(n) O(n)

Pattern Recognition

This is the complement lookup pattern: when a problem asks for a pair satisfying some condition, storing what you’ve seen in a hash map turns a second scan into a O(1) lookup. You’ll find the same structure in 3Sum (reduce to Two Sum), subarray sum equals k, and any problem where “what do I need to complete this?” has a clear formula.

In Interviews

The brute force buys you nothing here — interviewers expect the hash map solution immediately. What they’re actually watching for: correct key/value orientation in the map, and the check-before-insert rule (if seen[x] = i runs before the lookup, x + x == target would return [i, i] — wrong).

Common follow-ups:

  • What if multiple valid pairs exist — return all of them? Collect results instead of returning early; decide whether to deduplicate.
  • What if the array is sorted? Two-pointer from both ends achieves O(n) time with O(1) space — no hash map needed.

📺 Watch the full walkthrough on YouTube: https://youtu.be/4JUNrRN16gM

Captain Cool — How I built a multi-agent IPL strategist with Gemini & ADK in one sitting

description: “Five Gemini agents argue with each other about who should bowl the next over. Then they tell you who won the argument.”
tags: gemini, agents, ai, cricket

🏏 Cricket is a captain’s game. AI is an orchestration game. This is both.

The problem

You’re MS Dhoni. Innings 2, over 17.2, MI need 38 off 16 with Suryakumar set on 48 and Tilak Varma at the other end. Dew is heavy. Jadeja has 1 over left. Mustafizur has 1. Pathirana has 2.

What do you do?

There is no clean “right answer” — it’s matchup math + pitch read + gut feel + risk appetite, all weighted against the next ball. Real captains decide this in 90 seconds. They confer with the bowling coach, the analyst flashes a sheet, the assistant coach pushes back. Then the captain calls it.

That’s the system I wanted to build. Not a chatbot that recites stats. A dressing room — multiple specialised agents that genuinely debate, with the disagreement rendered transparently, before a final call is committed.

This was my submission for the Agentic Premier League by GDG Cloud Pune. Mandatory stack: Google Gemini, ADK, Antigravity, AI Studio. So I leaned in.

Architecture

Five Gemini-powered agents, orchestrated by ADK’s SequentialAgent, each writing to shared session state that the next agent reads via prompt template substitution.

        ┌───────────────────────────────────────────────────────┐
        │                Captain Cool (SequentialAgent)         │
        └───────────────────────────────────────────────────────┘
   1. Stats Analyst  (Flash) ──── FunctionTools: lookup_batter,
                                                  lookup_bowler,
                                                  lookup_venue,
                                                  matchup_score
   2. Pitch Reader   (Flash) ──── FunctionTool:  lookup_venue
   3. Strategist     (Pro)   ──── FunctionTool:  win_probability   ← proposes
   4. Devil's Adv.   (Pro)   ──── FunctionTool:  win_probability   ← challenges
   5. Strategist     (Pro)   ──── FunctionTool:  win_probability   ← revises / defends
   6. Commentator    (Flash)                                       ← packages for fans

Why SequentialAgent over a LoopAgent? Because the roles are sequential and named. A captain’s debate isn’t an unbounded loop — it’s a structured exchange: stats → conditions → call → challenge → defend → publish. ADK lets me model that exactly.

Two Strategist invocations sit in the pipeline (StrategistPropose and StrategistRevise) because the same role is asked to do two distinct things — write to different output_keys, with the second reading the dissent before deciding to defend or revise.

The agents (with their actual prompts)

1. Stats Analyst — gemini-2.5-flash

You are the Stats Analyst on a virtual IPL captain's bench.
Your job: take the raw match state and produce a factual brief.

Required tool usage:
- For each batter at the crease, call `lookup_batter` once.
- For each bowler with overs remaining, call `lookup_bowler` once.
- Call `lookup_venue` for the ground.
- For the bowler types still available, call `matchup_score` against the striker.

Output format (strict, in this order):
**MATCH SITUATION** — one sentence
**BATTERS** — name, handed, role, SRs vs pace / spin / leg-spin
**BOWLING OPTIONS** — type, overs left, phase economy, who they favour
**VENUE & CONDITIONS** — par score, ground size, dew expectation, pitch behavior
**KEY MATCHUPS** — 2-4 bullets of the most decisive matchups

Be terse. This is a brief, not a column.

The strict output format matters — downstream agents read it via {stats_brief} template substitution, so consistent structure beats verbose prose.

2. Pitch Reader — gemini-2.5-flash

Translates pitch / dew / boundary size into actionable “do X, avoid Y” guidance. I want this in voice-of-a-coach, not voice-of-a-model:

“two-paced wicket — stroke-makers will find it hard to time the cut”
“dew is coming in by the 12th over — bowling first will get the harder ball gripping for half the innings”
“60-metre straight boundary — leg-spin into the breeze is asking for trouble”

3. Strategist (Propose) — gemini-2.5-pro

The captain. Reads both briefs, calls win_probability, commits a call:

**THE CALL** — one specific sentence (who bowls / who comes in / field setup)
**WHY (cricket talk)** — 3–5 sentences in commentator language
**WIN PROBABILITY** — number from tool call + meaning
**ALTERNATIVE CONSIDERED** — the second-best option ruled out

4. Devil’s Advocate — gemini-2.5-pro

This is the agent that makes the system agentic — not just a pipeline. Its prompt explicitly says:

“You are NOT here to disagree for the sake of disagreement. You are here to surface the best alternative the Strategist may have under-weighted. If the proposal is genuinely correct, say so plainly and stand it up.”

And critically: it calls win_probability on its counterfactual, so its dissent comes with a number, not vibes:

“If we bowl Mustafiz at SKY here, WP drops to 0.62. Save him for the 19th when Hardik’s at strike; that climbs back to 0.71.”

5. Strategist (Revise) — gemini-2.5-pro

Reads the proposal and the dissent. Decides: DEFEND or REVISE. Has explicit guidance against caving and against pride:

“Don’t cave to the dissent just because it sounds smart. Don’t cling to your call out of pride. This is the difference between an average captain and a great one.”

Outputs a CONFIDENCE number 0-100 and a WHY-NOT-THE-ALTERNATIVE line that directly addresses the dissent.

6. Match Commentator — gemini-2.5-flash

The explainability layer required by the rubric. Channels Harsha Bhogle’s clarity, Ravi Shastri’s punch:

“This is captaincy 101. He’s saving Bumrah for the 19th. With the lefty at the crease and dew settling in, it’s a no-brainer to bring Jadeja in now.”

The tools (real function calls, not hardcoded JSON)

Five Python functions wrapped as ADK FunctionTools:

Tool Used by Purpose
lookup_batter Stats Analyst Returns handedness, SR vs pace/spin/leg-spin, role
lookup_bowler Stats Analyst Returns type, phase economies, vs-left/right averages
lookup_venue Stats Analyst, Pitch Reader Returns par score, boundary size, dew factor
matchup_score Stats Analyst Computes batter-vs-bowler-type advantage with handedness adjustment
win_probability Strategist, Devil’s Advocate Heuristic WP model: RRR vs CRR, wickets in hand, dew, pitch

The win_probability calculator is the real unlock for the debate. It’s a sigmoid-on-rate-gap model — not perfect calibration, but defensible and consistent. Both Strategist and Devil’s Advocate call it on different decisions and compare the deltas. The captain’s call now includes a counterfactual: “bowling Pathirana here is WP 0.71; if I’d given Mustafiz the ball instead, it’d drop to 0.62.”

Bonus tool: fetch_live_match (BeautifulSoup over Cricbuzz/ESPN HTML) lets the user paste a live URL and pre-fill the form.

The streaming dressing room

One thing I really wanted: the user should see the disagreement, not just the conclusion.

So the FastAPI endpoint /api/decide/stream is a Server-Sent-Events stream. Each ADK event yields one of:

  • tool_call — small badge appears showing the agent called a function
  • agent_turn — the agent’s final markdown lands as a card
  • final — structured decision payload renders into the verdict box

The frontend reads the stream with fetch().body.getReader() and appends agent cards as they arrive, with a …thinking ellipsis between turns. It feels like watching a dressing room work in real time.

A walkthrough — the Wankhede scenario

The default scenario in the UI:

Wankhede Stadium · 2nd innings · Over 17.2 · MI 148/4 · target 186 · two-paced pitch · heavy dew
Suryakumar 48(29) on strike · Tilak Varma 22(18) at the non-striker · Jadeja, Mustafizur, Pathirana, Ashwin all have overs left.

What the agents actually say in this run:

Stats Analyst flagged the SKY-vs-leg-spin SR of 145 (high), Tilak’s left-hand SR vs off-spin (132 — okay), and Pathirana’s death economy of 9.1.

Pitch Reader noted Wankhede is dew-heavy and 64-metre straight — yorker plans favoured, leg-spin into the wind avoided.

Strategist (Propose) called: “Bowl Mustafiz right now. Angle the ball across SKY, who scores 70% of his off-side runs through cover — a left-armer cramps him. Save Pathirana for the 19th.” WP: 0.68.

Devil’s Advocate pushed back: “With dew this heavy, Mustafiz’s grip is gone. Even if he beats SKY twice, the four overs he and Pathirana will bowl combined give up 40+. Bowl Jadeja now while the ball still grips, force a strike change, then attack the new batter.” Counterfactual WP for Jadeja-now: 0.71.

Strategist (Revise) verdict: REVISE. “The dissent’s right on dew. Jadeja in — left-arm spin into the lefty Tilak is the mismatch we want.” Confidence: 78.

Commentator: “Captaincy 101 from the dressing room. They’re going Jadeja before the dew makes him useless — Tilak’s the soft target, force a strike turn, then Mustafiz for the 18th when SKY’s facing again. Smart cricket, this.”

That’s the system working.

What I’d add next

  • Memory across overs — Gemini context caching so a full innings of debates costs almost nothing.
  • Real form pull — Cricbuzz player page scraper feeding into lookup_batter to replace the seed JSON.
  • Vertex AI Agent Engine hosting — currently runs locally via python run.py.
  • Multimodal pitch image input — upload a photo of the pitch; Gemini Vision reads cracks/wear.

Try it / clone it

GitHub: <your-repo-here>
AI Studio prompt for the Strategist (Propose): <your-AI-Studio-link>

Built on Google Gemini · ADK · Antigravity · AI Studio · vibed in one sitting.

🏏 Cricket is a captain’s game. Built on Gemini.

Building an AI-Powered Multi-Agent IPL Match Strategist with Streamlit and Gemini

@gdgcloudpune

Cricket, especially the fast-paced T20 format of the IPL, is a game of quick decisions, intense pressure, and strategic gambles. What if you could bring the analytical power of a professional dugout right to your screen?

In this post, we’ll dive into The Multi-Agent IPL Match Strategist, an MVP built using Python, Streamlit, and Google Gemini, to simulate real-time cricket tactics through multi-agent debate.

🏗️ Architecture Overview

The application utilizes a lightweight, serverless architecture centered around Streamlit and Google’s Gemini LLM. Instead of spinning up multiple different LLM calls for each “Agent,” we use a single, highly structured prompt to generate a simulated debate in one pass, drastically reducing latency.

flowchart TD
    User([🏏 User Input: Match Context]) --> Streamlit[Streamlit Frontend]
    Streamlit --> Backend[Python Backend logic]

    Backend -->|Compiles Context & Prompt| Gemini[Google Gemini API <br> gemini-2.5-flash]

    Gemini -->|Generates JSON Response| Parser[JSON Parser]

    Parser -->|Agent 1| Strategist[🧠 Core Strategist]
    Parser -->|Agent 2| Advocate[😈 Devil's Advocate]
    Parser -->|Agent 3| Captain[👨‍✈️ Captain Final Call]
    Parser -->|Metric| WinProb[📈 Win Probability]

    Strategist --> StreamlitUI[Streamlit Interactive Dashboard]
    Advocate --> StreamlitUI
    Captain --> StreamlitUI
    WinProb --> StreamlitUI

📝 The Multi-Agent Prompt

To make the AI simulate a “virtual dugout,” we instruct the model to adopt multiple personas simultaneously and output the debate as a structured JSON object.

Here is the exact master prompt that orchestrates our agents:

You are simulating an IPL tactical dugout consisting of multiple AI agents analyzing the following match situation:
- Batting Team: {batting_team}
- Bowling Team: {bowling_team}
- Score: {score} in {overs} overs
- Target/Runs Needed: {runs_needed} from {balls_left} balls (Wickets left: {wickets_left})
- Batters at Crease: {striker} (Striker) & {non_striker} (Non-Striker)
- Pitch: {pitch_type}
- Dew Factor: {dew_factor}
- Captain Personality for Final Decision: {captain_personality}

Generate a short, tactical, and realistic response in JSON format. The JSON must contain exactly these keys:
"win_probability": (A percentage string representing the bowling team's chance, e.g. "62%")
"win_prob_float": (A float between 0.0 and 1.0 representing the bowling team's chance)
"strategist": (1-2 sentences of tactical advice from the Core Strategist, focusing on bowling/fielding changes)
"advocate": (1-2 sentences from the Devil's Advocate countering the strategist's idea)
"decision": (1-2 sentences from the Captain, reflecting the selected {captain_personality} personality, making the final call)

Respond ONLY with valid JSON. Do not include markdown formatting like ```

json.


Try it out in Google AI Studio!

You can easily adapt and test this exact prompt directly in Google AI Studio to experiment with different agent personalities and match contexts before writing any code.

🏏 Walkthrough: A Live Match Scenario

Let’s put the app to the test with a classic IPL nail-biter.

The Situation:

  • Batting: MI
  • Bowling: CSK
  • Score: 154/4 in 16.2 overs
  • Equation: MI needs 36 runs from 22 balls.
  • Required Run Rate (RRR): 9.82
  • Crease: Suryakumar Yadav (Striker) and Tim David (Non-Striker)
  • Conditions: Turning pitch, but Dew is present.
  • Captain Personality selected: Dhoni

The App’s Output:

  1. 📈 Win Probability: 45% (Advantage tilts slightly to MI because SKY is on strike and dew makes gripping the ball harder)
  2. 🧠 Core Strategist: “Bring in your best spinner to exploit the turning pitch against Tim David if he gets on strike, but keep the pacers bowling wide yorkers to Suryakumar Yadav to deny him his sweep shots.”
  3. 😈 Devil’s Advocate: “With heavy dew on the field, gripping the ball for spin is incredibly risky. A wet ball might result in full tosses which SKY will easily lap over fine leg. Stick to pace off the ball.”
  4. 👨‍✈️ Final Decision (Dhoni Mode): “We will trust the spinner for one over but pack the leg-side boundary deep. If the ball slips, we immediately shift to defensive wide pace. Keep it simple, don’t panic.”

🚀 The Tech Stack & Features

To build this quickly and beautifully, we used:

  • Streamlit: For the frontend. It allowed us to build a responsive, interactive UI entirely in Python. We utilized Streamlit’s layout columns and custom CSS to create a sleek, dark-themed “cricket scoreboard” aesthetic.
  • Google Gemini API (gemini-2.5-flash): The brain of the operation. We chose Gemini 2.5 Flash for its blazing-fast response times.
  • Dynamic UI:

    • Smart dropdowns ensure you can’t select the same player as both Striker and Non-Striker.
    • Required Run Rate (RRR) calculates instantly as you type in runs and balls left.

Whether you’re an AI enthusiast looking to explore prompt engineering or a cricket fan wanting to second-guess your favorite captain, this project demonstrates the incredible potential of LLMs in building interactive, simulation-based applications.

🏏 CaptainCool AI — Building a Multi-Agent IPL War Room with Gemini 2.5

Modern T20 cricket is a tactical war room.

Captains constantly calculate:

  • bowling matchups
  • dew impact
  • field placements
  • momentum shifts
  • death-over strategy
  • batter weaknesses

So we asked ourselves:

“What if IPL captains had an AI tactical command center?”

That became CaptainCool AI — a Gemini-powered multi-agent IPL strategist that thinks like a real captain under pressure.

🚀 What is CaptainCool AI?

CaptainCool AI is a multi-agent AI system that simulates an IPL captain’s decision-making process in real time.

The user enters:

  • score
  • wickets
  • overs
  • venue
  • pitch conditions
  • dew factor
  • current batters
  • bowlers remaining

Then multiple AI agents debate the best tactical move before generating the final captain’s decision.

Instead of acting like a generic chatbot, the system behaves like a real IPL war room.

🧠 The Core Idea

Most sports AI projects simply generate commentary.

We wanted something deeper:

  • tactical reasoning
  • disagreement between agents
  • live cricket analytics
  • explainable decisions
  • real-time debate

So we designed a multi-agent architecture powered by Google Gemini 2.5 Flash.

⚡ The Multi-Agent System

CaptainCool AI uses 5 specialized agents.

1️⃣ Strategist Agent

Acts like the tactical captain.

Inspired by:

  • MS Dhoni
  • Rohit Sharma
  • Hardik Pandya

Responsibilities:

  • choose next bowler
  • field placements
  • bowling rotation
  • timeout timing
  • impact player decisions

2️⃣ Stats Analyst Agent

The data-driven cricket analyst.

Uses tools to analyze:

  • batter vs bowler matchups
  • win probability
  • pitch behavior
  • dew impact
  • venue patterns

This agent actively performs Gemini tool calling.

3️⃣ Devil’s Advocate Agent

The most important agent.

This agent intentionally challenges the proposed strategy.

Example:

“Bowling leg-spin in heavy dew could backfire because grip reduction is significant.”

This prevents shallow AI reasoning and creates real tactical debate.

4️⃣ Strategist Revision Agent

After criticism, the strategist revises or defends the plan.

This creates genuine multi-turn reasoning instead of fake “multi-agent roleplay.”

5️⃣ Commentator Agent

Transforms tactical reasoning into cinematic IPL-style commentary.

This made the experience feel like:

  • live sports broadcasting
  • tactical television analysis
  • IPL commentary panels

🏗️ Architecture

Our architecture was built using:

  • FastAPI
  • Vanilla HTML/CSS/JS
  • Google Gemini 2.5 Flash
  • SSE Streaming
  • Multi-agent orchestration
  • Gemini tool calling

Flow

User Input
   ↓
FastAPI Backend
   ↓
Orchestrator
   ↓
Strategist Agent
   ↓
Stats Agent + Tools
   ↓
Devil's Advocate
   ↓
Strategist Revision
   ↓
Commentator
   ↓
Oracle Decision Engine
   ↓
Live Streaming Frontend

🔧 Gemini Tool Calling

One of the biggest goals was making the system genuinely “agentic.”

So we implemented real Gemini tool usage.

Tools Used

  • get_matchup_stats()
  • calculate_win_probability()
  • get_pitch_conditions()
  • get_weather_and_dew()
  • fetch_player_recent_form()

These tools allow the AI agents to reason using structured cricket intelligence instead of hallucinating tactics.

Example:

{
  "bowler": "Jadeja",
  "batter": "Rohit Sharma",
  "strike_rate": 162,
  "dismissals": 2
}

🎨 Frontend Experience

We didn’t want a normal dashboard.

We wanted:

“F1 race strategy room meets IPL broadcast studio.”

So we built:

  • futuristic glassmorphism UI
  • tactical war-room aesthetic
  • live AI debate feed
  • streaming agent messages
  • animated tactical cards
  • dynamic field visualization
  • momentum engine
  • confidence meters
  • Gemini health monitor

The frontend was built entirely using:

  • HTML
  • TailwindCSS
  • Vanilla JavaScript

No React.

⚔️ The Debate System

This was the most exciting part.

Instead of a single AI response, agents actually challenge each other.

Example flow:

Strategist

“Bring Bumrah now for wide yorkers.”

Stats Analyst

“Yorkers reduced boundary percentage by 41% tonight.”

Devil’s Advocate

“But the left-hander has a strong scoop-shot range against wide yorkers.”

Strategist Revision

“Adjusting field: deep third goes finer.”

This made the system feel alive.

📡 Real-Time Streaming

We implemented:

  • SSE (Server Sent Events)
  • async FastAPI streaming
  • live agent feed
  • cinematic loading states
  • reconnect handling
  • retry management

The UI streams each tactical message in real time like a live war-room broadcast.

🛡️ Solving Gemini Free-Tier Challenges

One of the hardest parts was handling Gemini rate limits.

Initially:

  • too many agents
  • too many requests
  • quota crashes

We optimized heavily by:

  • reducing prompt size
  • compressing debate context
  • caching responses
  • adding retry queues
  • exponential backoff
  • fallback tactical logic
  • lightweight local synthesis

This made the demo stable enough for hackathon environments.

🎙️ Fun Features

We also added:

  • voice commentary
  • captain personality modes
  • tactical alerts
  • cinematic intro audio
  • animated reconnect states
  • backend diagnostics
  • fallback tactical engine

💡 What We Learned

This project taught us something important:

Multi-agent systems become powerful when agents genuinely disagree.

The Devil’s Advocate agent dramatically improved tactical quality because it forced deeper reasoning.

We also learned:

  • streaming UX matters a lot
  • tool calling makes AI feel trustworthy
  • sports strategy is a perfect use case for agentic AI

🚀 Final Thoughts

CaptainCool AI started as:

“What if Dhoni had AI assistants in his earpiece?”

It evolved into:

  • a tactical cricket simulator
  • a real-time AI debate system
  • a multi-agent sports intelligence platform

And honestly?

Watching AI agents argue about IPL death-over tactics is ridiculously fun.

🏏 Tech Stack

  • Google Gemini 2.5 Flash
  • FastAPI
  • Python
  • Vanilla JavaScript
  • TailwindCSS
  • SSE Streaming
  • Gemini Tool Calling

🔥 Future Improvements

We’d love to add:

  • live Cricbuzz integration
  • real scorecard ingestion
  • multimodal pitch analysis
  • AI-generated field maps
  • voice conversations with captains
  • real-time match simulations

👋 Thanks for Reading

If you love:

  • cricket
  • AI agents
  • sports analytics
  • Gemini-powered systems

then CaptainCool AI was built for you.

🏏⚡
🏏 Built CaptainCool AI — a Gemini-powered multi-agent IPL war room that thinks like a real captain under pressure.

⚡ Strategist Agent
📊 Stats Analyst
😈 Devil’s Advocate
🎙️ Commentator AI

Real tactical debate. Real tool calling. Real-time streaming. Built with Google Gemini 2.5 + FastAPI + Vanilla JS.

“What if Dhoni had AI analysts in his earpiece?” 👀

Huge shoutout to the amazing community and energy around building agentic AI systems 🚀

GoogleGemini #GeminiAI #GDG #GDGPune #GoogleDeveloperGroups #AI #AgenticAI #IPL #Hackathon #FastAPI #Python #WebDevelopment #GenerativeAI #GoogleAI #MultiAgentSystems #BuildWithAI #CloudCommunity #SportsAI

@GDG Pune @GDG Cloud Pune

The Evolution of AI Coding Styles: From Syntax Warriors to Intent Architects

The way we write code is undergoing a seismic shift. For decades, developers were defined by their mastery of syntax, their ability to debug obscure errors at 2 AM, and their encyclopedic knowledge of standard libraries. Today, AI has fundamentally rewritten the rules of the game.

We’re transitioning from a syntax-first era — where writing code line-by-line was the job — to an intent-first era, where expressing what you want to build matters more than remembering how to build it.

This isn’t about AI replacing developers. It’s about the evolution of coding styles — from autocomplete assistants to autonomous agent swarms — and what that means for how we think, architect, and ship software.

Let’s break down the five distinct paradigms of modern AI-assisted development, how they work, and what they demand from developers.

1. Inline Copiloting: The Navigator in Your Editor

What It Is

Inline copiloting is the most familiar AI coding style. Tools like GitHub Copilot, Tabnine, and Amazon CodeWhisperer sit inside your IDE and provide real-time, context-aware code suggestions as you type.

Think of it as pair programming with an AI. You’re still the pilot — you write the function signature, name the variables, define the logic — but the AI acts as a highly competent navigator that fills in the repetitive, predictable parts.

How It Works

  • You type a comment: // fetch user data from API
  • Copilot suggests the entire function body: API call, error handling, JSON parsing
  • You accept, reject, or modify the suggestion
  • You stay in control of architecture, flow, and edge cases

Developer Role: The Pilot

You’re driving. The AI is suggesting the next turn, but you decide the route, the destination, and when to override.

Strengths

  • Speed: Eliminates boilerplate, common patterns, and repetitive loops
  • Context-aware: Reads your existing code and adapts suggestions
  • Low friction: Feels like enhanced autocomplete, not a context switch

Weaknesses

  • No architectural thinking: Copilot won’t design your system
  • Passive assistance: You still write most of the code manually
  • Quality variance: Suggestions range from brilliant to buggy

Best For

  • Writing tests, boilerplate, utility functions
  • Exploring unfamiliar libraries or languages
  • Developers who want AI help without changing their workflow

2. Prompt Engineering: Code as Context, Prompts as Instructions

What It Is

Prompt engineering treats the AI like a highly skilled contractor. Instead of typing code line-by-line, you write a structured, precise prompt that acts like a specification document. The AI generates the implementation, and you review, refine, and integrate.

This isn’t casual ChatGPT usage. It’s context-rich, constraint-heavy, version-controlled prompting where the quality of your output is directly proportional to the quality of your prompt.

How It Works

You are a senior backend engineer specializing in FastAPI and async SQLAlchemy.

Task: Build a REST API endpoint for user authentication with the following requirements:
- POST /auth/login
- Accept email and password
- Validate input using Pydantic v2
- Query Users table using async SQLAlchemy
- Hash passwords with bcrypt
- Return JWT token on success
- Return 401 on invalid credentials
- Include error handling for database timeouts

Style: Clean, production-ready, type-hinted Python 3.11+
Return: Only the FastAPI route function and dependencies

The AI generates the code. You review, test, and integrate.

Developer Role: The Analytical Architect

You’re not writing code — you’re writing instructions for code. Your job is to define constraints, edge cases, design patterns, and quality criteria with surgical precision.

Strengths

  • High-quality output: Well-structured prompts produce production-grade code
  • Reusability: Save prompts as templates for similar tasks
  • Iterative refinement: Debug the prompt, not just the code

Weaknesses

  • Prompt fragility: Small wording changes can drastically alter output
  • No execution: The AI doesn’t run, test, or debug the code
  • Context limits: Large codebases require careful chunking

Best For

  • Generating components, schemas, services, or modules from scratch
  • Refactoring existing code with specific constraints
  • Developers comfortable with specification-driven development

3. Vibe Coding: Intent-Driven Development

What It Is

Vibe coding is the most radical departure from traditional development. Instead of writing code or prompts, you describe what you want in natural language or voice, and the AI autonomously builds, debugs, runs, and iterates until it works.

Tools like Cursor, Replit Agent, v0 by Vercel, and bolt.new are purpose-built for this style. You act as a director or product manager, and the AI is the development team.

How It Works

You say (or type):

“Build a React dashboard with a sidebar, a table showing user data from /api/users, and a search filter. Use Tailwind for styling. Make it responsive.”

The AI:

  • Scaffolds the React components
  • Fetches data from the API
  • Applies Tailwind classes
  • Runs the dev server
  • Debugs errors autonomously
  • Shows you a working preview

You review, request changes, and the AI iterates.

Developer Role: The Director

You’re not coding. You’re managing outcomes. You define the goal, provide feedback, and steer the direction. The AI handles implementation, package installation, and debugging.

Strengths

  • Fastest prototype-to-product loop: Go from idea to working app in minutes
  • No syntax barriers: Accessible to non-developers or those learning new stacks
  • Autonomous debugging: AI fixes its own errors and retries

Weaknesses

  • Loss of control: You don’t see every line being written
  • Black-box risk: Hard to debug when the AI gets stuck
  • Quality ceiling: Works brilliantly for prototypes, struggles with complex architecture

Best For

  • Rapid prototyping, MVPs, side projects
  • Learning new frameworks by observing AI’s approach
  • Developers who want to ship fast and iterate faster

4. Agentic Orchestration: Multi-Agent Swarms

What It Is

Agentic orchestration is the next frontier. Instead of a single AI assistant, you deploy multiple specialized AI agents that collaborate autonomously. Each agent has a distinct role — PM Agent, Dev Agent, QA Agent, DevOps Agent — and they communicate, divide tasks, and execute in parallel.

Tools like AutoGPT, MetaGPT, CrewAI, and LangGraph enable this workflow.

How It Works

You define a high-level goal:

“Build a SaaS app for invoice generation with user authentication, PDF export, and Stripe integration.”

The orchestration layer deploys:

  • PM Agent: Breaks down requirements, defines user stories
  • Dev Agent: Writes backend (FastAPI), frontend (React), database schema
  • QA Agent: Writes tests, runs them, reports failures
  • DevOps Agent: Dockerizes the app, sets up CI/CD

The agents execute autonomously, passing context between each other. You monitor progress and intervene only when needed.

Developer Role: The System Overseer

You’re not a coder. You’re a systems orchestrator. Your job is to define the goal, configure the agent swarm, review outputs, and handle exceptions.

Strengths

  • Massive parallelization: Agents work simultaneously on different parts of the system
  • Separation of concerns: Each agent is optimized for its domain
  • End-to-end automation: From requirements to deployment

Weaknesses

  • Complexity: Orchestrating agents requires deep architectural knowledge
  • Coordination failures: Agents can conflict or duplicate work
  • Cost: Running multiple agents simultaneously is expensive

Best For

  • Large, complex projects with well-defined requirements
  • Teams exploring fully autonomous development pipelines
  • Developers who want to scale their impact exponentially

5. Forensic / Remedial Coding: Refactoring the Past

What It Is

Forensic coding is the AI-assisted art of analyzing, refactoring, and modernizing legacy, broken, or inefficient codebases. This is the opposite of greenfield development — it’s archaeology, surgery, and translation all at once.

AI excels at reading decades-old COBOL, mapping dependencies in spaghetti code, identifying vulnerabilities, and translating legacy systems into modern languages.

How It Works

You feed the AI a legacy codebase:

“This is a 10,000-line COBOL program for payroll processing. Map all dependencies, identify security vulnerabilities, and generate a Python equivalent using modern best practices.”

The AI:

  • Parses the COBOL syntax
  • Maps data flows and business logic
  • Flags SQL injection risks, buffer overflows, hardcoded credentials
  • Generates a Python/FastAPI equivalent with type hints, async support, and tests

Developer Role: The Code Archaeologist

You’re not building new features — you’re rescuing, refactoring, and modernizing. Your job is to understand the original intent, validate the AI’s translation, and ensure nothing breaks.

Strengths

  • Speed: Refactors in hours what would take weeks manually
  • Pattern recognition: AI spots anti-patterns humans miss
  • Cross-language translation: Converts COBOL → Python, PHP → Node.js, etc.

Weaknesses

  • Context gaps: AI may misinterpret obscure legacy logic
  • Risk: Automated refactoring can introduce subtle bugs
  • Validation burden: You must rigorously test the output

Best For

  • Migrating legacy systems to modern stacks
  • Security audits of old codebases
  • Developers maintaining or sunsetting legacy apps

The Great Shift: Syntax-First → Intent-First

Here’s how the developer skillset is fundamentally changing:

Old Coding Era (Syntax-First) Modern AI Coding Era (Intent-First)
Memorizing syntax and standard libraries Knowing which AI tool fits the task
Writing boilerplate from scratch Reviewing and refining AI-generated code
Debugging line-by-line manually Prompting AI to debug and explain errors
Googling Stack Overflow for solutions Prompting AI with context and constraints
Deep expertise in 1-2 languages Broad fluency across stacks via AI assistance
Lone-wolf coding sessions Collaborating with AI agents and tools
Code quality = your skill ceiling Code quality = your review + verification rigor
Speed = typing speed + recall Speed = prompt quality + orchestration skill
Architecture in your head Architecture in prompts, docs, and diagrams
Career defined by what you can build alone Career defined by what you can build with AI

The Takeaway: Adapt Without Losing Your Edge

The intent-first era doesn’t mean traditional coding skills are obsolete. It means they’re being abstracted up the stack.

Here’s how to thrive:

  1. Master the fundamentals — AI accelerates execution, but it won’t architect your system. You still need to understand data structures, algorithms, API design, and software patterns.

  2. Learn to review, not just write — Your new superpower is critical code review. Can you spot the subtle bug in AI-generated code? Do you know when a suggestion is brilliant vs. dangerous?

  3. Become a prompt engineer — Writing precise, constraint-rich prompts is a skill. Treat it like writing tests: specific, deterministic, and version-controlled.

  4. Experiment with all paradigms — Inline copiloting for boilerplate, prompt engineering for components, vibe coding for prototypes, agentic orchestration for complex projects. Use the right tool for the job.

  5. Build verification systems — AI moves fast. You need automated tests, type checkers, linters, and security scanners to catch what AI misses.

  6. Stay curious, not defensive — The developers who resist AI will be left behind. The ones who integrate it strategically will 10x their impact.

The future of coding isn’t about writing less code. It’s about building better systems, faster, with higher-quality outputs, by orchestrating AI as a force multiplier.

The question isn’t whether AI will change how you code.

The question is: How fast can you adapt your coding style to harness it?

What’s your current AI coding style? Are you still in the syntax-first era, or have you made the leap to intent-first development? Drop a comment below — I’d love to hear how you’re adapting!

“Captain Cool” — The Multi-Agent IPL Match Strategist

GitHub logo

A submission for the Google Gemini Agentic Hackathon.

🏏 Captain Cool — The Multi-Agent IPL Match Strategist

A pure vanilla, zero-dependency AI orchestrator built on the Google Gemini tech stack for the Agentic Hackathon.

Captain Cool AI

Overview

Cricket is a captain’s game. To win an IPL match, you need to read the pitch, analyze the stats, anticipate the opponent, and make a gut call. “Captain Cool” is an AI-powered IPL Match Strategist that orchestrates four distinct AI agents in a real-time debate loop to make the ultimate tactical decision.

🤖 Agent Architecture

Our system uses a sequential reasoning loop built on ADK principles:

  1. 📊 Stats Analyst (Tool User): Uses Gemini Function Calling to query the getVenueContext tool, retrieving real-time data on dew factor, pitch behavior, and average scores for the selected stadium.
  2. ♟️ Strategist: Takes the match context and Analyst’s data to propose a highly tactical, data-driven move (e.g., “Bowl the left-arm spinner now because the RHB strike rate against…

Overview

Cricket is a captain’s game. To win an IPL match, you need to read the pitch, analyze the stats, anticipate the opponent, and make a gut call. “Captain Cool” is an AI-powered IPL Match Strategist built entirely on the Google Gemini tech stack.

Instead of a single prompt, Captain Cool orchestrates four distinct AI agents using principles from the Agent Development Kit (ADK) in a real-time debate loop.

Architecture & Agent Roles

Our multi-agent system uses a sequential reasoning loop:

  1. Stats Analyst (Tool User): Uses Gemini Function Calling to query the getVenueContext tool, retrieving real-time-ish data on dew factor, pitch behavior, and average scores for the selected venue.

  2. Strategist: Takes the match context and Analyst’s data to propose a highly tactical, data-driven move (e.g., “Bowl the left-arm spinner now because the RHB strike rate against SLA is low”).

  3. Devil’s Advocate: Critiques the Strategist and points out the risks and flaws in the proposed plan.

  4. The Captain (Final Call): Reads the debate and makes the final gut decision. The output is delivered in authentic cricket dressing-room terminology.

Tech Stack & Hackathon Requirements Met

  • AI / LLM: Google Gemini (gemini-2.5-pro & gemini-2.5-flash)
  • SDK: @google/genai (Official JS/TS SDK loaded natively via ESM)
  • Framework & Orchestration: Built with ADK principles for multi-agent architecture
  • Multimodal Flair: UI cover art generated using Google’s Imagen 3 / Lyria ecosystem
  • IDE: Vibe-coded entirely using Google Antigravity in a 3-hour session
  • Frontend: Pure Vanilla HTML/CSS/JS with zero dependencies

How It Meets the Hard Requirements

  1. Three or more distinct agents: Yes — Analyst, Strategist, Advocate, Captain.
  2. Real Tool Call: The Analyst uses Gemini Function Calling (getVenueContext) to pull pitch stats.
  3. Multi-Turn Reasoning Loop: Strategist proposes → Advocate critiques → Captain resolves.
  4. Explainability in Cricket Jargon: The Captain’s prompt forces authentic cricket terminology like “leggie”, “death overs”, and “turning track” instead of ML jargon.

Prompts Used (Snippet)

Devil’s Advocate:
“You are the Devil’s Advocate. Your job is to critique the Strategist’s proposal. Point out the risks and why it might backfire. Keep your response concise and direct. Do not write huge paragraphs.”

Captain:
“You are MS Dhoni / Rohit Sharma (Captain Cool). Make the final decision based on the debate. Explain your reasoning using authentic dressing-room cricket terminology like ‘leggie’ and ‘death overs’. Keep your final decision short, authoritative, and to the point.”

Running it locally

Since this project was built without Next.js or heavy frameworks, running it is simple:

  1. Double-click index.html to open it in your browser.
  2. Enter your Gemini API key in the UI.
  3. Input the match state and click “Execute Agent Strategy”.

No npm install or servers required. It works end-to-end directly in the browser using the @google/genai library via ESM.

Vibe-coded in 3 hours using Google Antigravity.

Show HN: Needle distilled Gemini tool calling en 26M parámetros — lectura técnica sin hype

Show HN: Needle distilled Gemini tool calling en 26M parámetros — lectura técnica sin hype

Estaba revisando mi pipeline de Ollama cuando apareció el post en HN: Needle, un modelo de 26M de parámetros destilado desde Gemini específicamente para tool calling. Mi primera reacción fue escéptica. 26M suena a juguete. Después leí con más calma y entendí que el punto interesante no es el tamaño: es el problema que están atacando.

Acá va mi lectura técnica, sin euforia y sin descarte fácil.

El problema real detrás de Needle y la destilación de Gemini para tool calling

Mi tesis es esta: el cuello de botella en sistemas con herramientas externas no es el razonamiento general del LLM, sino la parsabilidad del output. Si el modelo produce JSON mal formado, llama funciones con argumentos incorrectos o alucina nombres de tools que no existen, el sistema entero se rompe — no importa qué tan “inteligente” sea el modelo en otras tareas.

Esto lo experimenté directamente mientras armaba loops de agentes con Claude Code. La parte más frágil nunca fue el razonamiento; fue la confiabilidad del contrato de datos. Me acordé de cuando me resistí a TypeScript durante años pensando que los tipos eran burocracia. Después entendí que muchas fallas evitables empiezan como contratos de datos mal expresados. Con tool calling pasa exactamente lo mismo: un modelo puede ser brillante en prosa y pésimo para respetar un esquema JSON estricto bajo presión de latencia.

Needle ataca ese punto específico: toma el comportamiento de tool calling de Gemini — que es consistente y bien estructurado — y lo destila en un modelo pequeño y especializado. La hipótesis es que para esta tarea concreta, 26M entrenados con el comportamiento correcto pueden superar a modelos gigantes generalistas que no fueron ajustados para respetar esquemas de función con precisión.

¿Es verdad? En benchmarks propios, según el repositorio del proyecto, sí. En producción real propia, no lo sé todavía — y esa diferencia importa.

Qué es la destilación de conocimiento y por qué importa aquí

La destilación de conocimiento (knowledge distillation) es una técnica donde un modelo grande — el teacher — genera outputs que después se usan para entrenar un modelo pequeño — el student. El student no aprende de datos crudos: aprende a imitar el comportamiento del teacher en las distribuciones que más importan.

# Concepto simplificado del pipeline de destilación para tool calling:
# 1. Teacher (Gemini) genera miles de ejemplos de tool calling correcto
# 2. Student (Needle, 26M) entrena sobre esos ejemplos
# 3. El student aprende la distribución de outputs del teacher, no reglas escritas a mano

Para tool calling, esto tiene sentido particular. No necesitás que el modelo sepa historia universal. Necesitás que cuando le pasés este schema:

// Definición de herramienta — el modelo tiene que respetar esto al 100%
const tools = [
  {
    name: "buscar_producto",
    description: "Busca un producto por ID en el catálogo",
    parameters: {
      type: "object",
      properties: {
        producto_id: { type: "string" },
        incluir_stock: { type: "boolean" }
      },
      required: ["producto_id"]
    }
  }
]

El output sea exactamente:

{
  "name": "buscar_producto",
  "arguments": {
    "producto_id": "SKU-4821",
    "incluir_stock": true
  }
}

Y no alguna variación creativa con claves renombradas, tipos erróneos o campos inventados. En eso los modelos pequeños generalistas fallan bastante. Si Needle lo resuelve de forma confiable, el caso de uso existe.

Cómo probarlo en Ollama: checklist reproducible

Si querés validar si un modelo como Needle tiene lugar en tu stack, el criterio no debería ser un benchmark ajeno. Debería ser tu propio conjunto de herramientas bajo las condiciones reales de tu sistema.

# Paso 1: Instalar Ollama si no lo tenés
curl -fsSL https://ollama.com/install.sh | sh

# Paso 2: Cuando el modelo esté disponible en Ollama registry, pull directo
# (verificar disponibilidad en https://ollama.com/search)
ollama pull needle  # nombre tentativo — verificar el registry oficial

# Paso 3: Preparar un set de pruebas de tool calling propio
# No uses los ejemplos del README del modelo; usá TUS herramientas reales
// prueba-tool-calling.ts
// Criterios de validación que yo usaría para evaluar cualquier modelo pequeño

interface ResultadoPrueba {
  caso: string;
  esperado: object;
  obtenido: string;
  jsonValido: boolean;
  schemaRespetado: boolean;
  latenciaMs: number;
}

async function evaluarModeloToolCalling(
  modelo: string,
  casos: Array<{ prompt: string; schemaEsperado: object }>
): Promise<ResultadoPrueba[]> {
  const resultados: ResultadoPrueba[] = [];

  for (const caso of casos) {
    const inicio = Date.now();

    // Llamada al modelo vía API de Ollama
    const respuesta = await fetch("http://localhost:11434/api/chat", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        model: modelo,
        messages: [{ role: "user", content: caso.prompt }],
        // Pasar las herramientas como parte del request
        tools: [caso.schemaEsperado],
        stream: false,
      }),
    });

    const data = await respuesta.json();
    const latencia = Date.now() - inicio;

    // Validar si el JSON es parseable y si respeta el schema
    let jsonValido = false;
    let schemaRespetado = false;
    let obtenido = "";

    try {
      // El tool_call debería estar en message.tool_calls[0]
      const toolCall = data.message?.tool_calls?.[0];
      obtenido = JSON.stringify(toolCall ?? data.message?.content ?? "");
      jsonValido = !!toolCall;
      // Validación básica de schema: las claves required tienen que estar presentes
      if (toolCall?.function?.arguments) {
        const args = toolCall.function.arguments;
        const requiredKeys = Object.keys(caso.schemaEsperado);
        schemaRespetado = requiredKeys.every((k) => k in args);
      }
    } catch {
      obtenido = "parse error";
    }

    resultados.push({
      caso: caso.prompt.slice(0, 50),
      esperado: caso.schemaEsperado,
      obtenido,
      jsonValido,
      schemaRespetado,
      latenciaMs: latencia,
    });
  }

  return resultados;
}

Mi criterio mínimo de aceptación para cualquier modelo de tool calling en un sistema real:

Métrica Mínimo aceptable Por qué
JSON válido 99%+ Un parse error en producción rompe el flujo entero
Schema respetado 95%+ Argumentos incorrectos son silenciosamente peligrosos
Latencia p95 < 500ms local Si tarda más que una API externa, perdiste el punto
Hallucination de tool names 0% Un nombre inventado es un error no recuperable

Los límites que el hype no menciona

Hay tres limitaciones que no aparecen en los titulares y que me parecen centrales antes de apostar por un modelo destilado en un sistema real.

Primero, la distribución del teacher define el techo. Si Gemini tiene sesgos en cómo genera tool calls — ciertos patrones de argumentos, ciertas convenciones de nombrado — el student los hereda sin filtro. Esto importa si tu API tiene convenciones que se alejan del estilo de Gemini.

Segundo, la generalización a schemas no vistos es una pregunta abierta. Un modelo destilado puede ser excelente en los patrones que aprendió y frágil frente a schemas complejos con anyOf, $ref anidados o validaciones condicionales. Hay que probarlo explícitamente con los schemas propios, no asumir que el benchmark general aplica.

Tercero, el tamaño de 26M parámetros implica capacidad de contexto limitada. En sistemas donde el prompt incluye muchas herramientas al mismo tiempo — algo común en backends con docenas de endpoints expuestos como tools — la degradación puede ser significativa. Es una hipótesis que hay que validar, no asumir.

Esto no invalida el proyecto. Lo ubica. La misma disciplina que apliqué al revisar problemas de caché en CI con pnpm workspaces aplica acá: primero entender el límite, después decidir si encaja.

Dónde Needle sí tiene sentido y dónde no

Escenarios donde tiene sentido probar Needle:

  • Pipelines de agentes locales donde la latencia de red hacia APIs externas es el cuello de botella
  • Edge devices o entornos con recursos limitados donde un modelo de 26M entra en memoria cómodamente
  • Sistemas con un conjunto acotado y estable de herramientas — no docenas de schemas cambiantes
  • Como fallback local cuando las APIs externas no están disponibles

Escenarios donde probablemente no alcanza:

  • Sistemas donde el razonamiento entre pasos de tool calling es complejo — decidir cuándo llamar qué tool, no solo cómo llamarla
  • APIs con schemas profundamente anidados o polimórficos
  • Flujos donde el contexto conversacional largo importa — el límite de contexto de 26M va a doler
  • Entornos que necesitan garantías de seguridad auditables — un modelo destilado privado es una caja más opaca

La tensión que señaló el post de Spring Boot Actuator en producción aplica de otra manera acá: la comodidad de “funciona en el demo” puede esconder riesgos de superficie que solo aparecen bajo carga o con inputs inesperados.

Lo que esto anticipa para el ecosistema de modelos pequeños

Lo incómodo de Needle no es el modelo en sí. Es lo que confirma: la especialización funcional va a presionar la hegemonía de los modelos grandes generales en tareas estructuradas.

Tool calling, clasificación de intents, extracción de entidades con schema fijo — son tareas donde un modelo destilado bien entrenado puede ganarle a GPT-4 o Claude en costo y latencia sin sacrificar confiabilidad. Eso cambia el cálculo de arquitectura.

En mi stack actual con Claude Code para razonamiento complejo y Ollama para tareas locales, hay un hueco exactamente donde Needle apuntaría: el router de herramientas que decide qué función llamar y con qué argumentos, sin necesitar el overhead de un modelo de 70B para eso. No digo que lo vaya a adoptar mañana. Digo que la categoría tiene sentido y que el experimento merece seguimiento.

Al igual que cuando evalué tradeoffs de Jakarta EE vs Spring Boot o comparé gestores de paquetes en monorepos reales, la respuesta honesta no es “adoptalo ya” ni “ignoralo”: es “probalo con tus propios criterios antes de comprometerte”.

FAQ: Needle, destilación y tool calling en modelos pequeños

¿Qué es exactamente la destilación de modelos en el contexto de LLMs?
Es un proceso donde un modelo grande (teacher) genera un dataset de comportamiento correcto — en este caso, ejemplos de tool calling bien formados — que se usa para entrenar un modelo pequeño (student). El student aprende a imitar la distribución de outputs del teacher en las tareas específicas para las que fue destilado, sin necesitar la arquitectura completa del teacher.

¿26M parámetros es suficiente para tool calling confiable?
Depende del scope. Para un conjunto acotado de herramientas con schemas simples, probablemente sí. Para sistemas con docenas de herramientas complejas, contextos largos o razonamiento multi-paso, es una hipótesis abierta. El benchmark del proyecto es optimista; la validación con schemas propios es obligatoria antes de apostar.

¿Cómo lo pruebo localmente sin comprometer un sistema en producción?
Con Ollama, si el modelo está disponible en el registry, es tan simple como ollama pull [nombre] y después evaluar con un script propio contra los schemas que ya usás. El checklist de validación de este post es un punto de partida. Siempre contra tus herramientas reales, nunca contra los ejemplos del README.

¿Cuál es la diferencia práctica entre Needle y usar function calling de OpenAI o Anthropic?
Latencia, costo y privacidad. Un modelo local no tiene RTT de red, no tiene costo por token y no manda los schemas de tus herramientas a una API externa. La contrapartida es que la confiabilidad depende enteramente de la calidad del entrenamiento del modelo local, sin el respaldo de un proveedor con SLA.

¿Vale la pena para un stack individual o solo para empresas con infraestructura?
Un modelo de 26M entra en una MacBook con 8GB de RAM sin drama. No es infraestructura de empresa. Si ya usás Ollama para otras tareas — como yo — agregar un modelo especializado es operativamente trivial. El costo real es el tiempo de evaluación, no el hardware.

¿Qué pasa si el modelo alucina un nombre de herramienta que no existe en mi sistema?
Es el peor caso y hay que diseñarlo como falla esperada. La capa de routing que consume el output del modelo tiene que validar que el name de la tool call corresponda a una herramienta registrada antes de ejecutar. Si no existe, el error tiene que ser explícito y no silencioso. Esto es diseño defensivo básico, independiente del modelo que uses.

Conclusión: probalo con los ojos abiertos

No voy a decir que Needle es el futuro ni que es ruido. Mi postura es más específica: la destilación funcional de comportamiento de modelos grandes en modelos pequeños especializados es una dirección legítima, y tool calling es un caso de uso donde tiene sentido técnico genuino.

Lo que no compro es el entusiasmo sin fricción. Un modelo de 26M tiene límites reales de contexto, de generalización y de confiabilidad bajo schemas no vistos. Esos límites no aparecen en el post de HN y aparecerán en producción.

Mi recomendación concreta: si tenés un pipeline de agentes con un conjunto estable de herramientas y latencia es un problema, armá un harness de prueba con los schemas propios, correlo contra los criterios de aceptación del post y medí. Si pasa el umbral de 99% de JSON válido y 95% de schema respetado en tus propios casos, tenés algo útil. Si no, sabés exactamente por qué.

Eso es más útil que cualquier benchmark ajeno.

¿Estás usando modelos locales para tool calling? Contame en juanchi.dev qué stack armaste y dónde encontraste los límites.

Este artículo fue publicado originalmente en juanchi.dev

Show HN: Needle distilled Gemini tool calling into 26M parameters — technical read, zero hype

Show HN: Needle distilled Gemini tool calling into 26M parameters — technical read, zero hype

I was in the middle of reviewing my Ollama pipeline when the HN post appeared: Needle, a 26M parameter model distilled from Gemini specifically for tool calling. My first reaction was skeptical. 26M sounds like a toy. Then I read more carefully and understood that the interesting point isn’t the size — it’s the problem they’re actually attacking.

Here’s my technical read. No euphoria, no easy dismissal.

The real problem behind Needle and Gemini tool calling distillation

My thesis is this: the bottleneck in systems with external tools isn’t the LLM’s general reasoning — it’s the parsability of the output. If the model produces malformed JSON, calls functions with wrong arguments, or hallucinates tool names that don’t exist, the whole system breaks — doesn’t matter how “intelligent” the model is at other tasks.

I ran into this directly while building agent loops with Claude Code. The most fragile part was never the reasoning; it was the reliability of the data contract. It reminded me of when I resisted TypeScript for years thinking types were bureaucracy. Then I understood that most avoidable failures start as poorly expressed data contracts. Tool calling is exactly the same: a model can be brilliant in prose and terrible at respecting a strict JSON schema under latency pressure.

Needle attacks that specific point: it takes Gemini’s tool calling behavior — which is consistent and well-structured — and distills it into a small, specialized model. The hypothesis is that for this specific task, 26M parameters trained on the right behavior can outperform giant generalist models that were never fine-tuned to respect function schemas with precision.

Is it true? In their own benchmarks, according to the project repo, yes. In my own real production, I don’t know yet — and that difference matters.

What knowledge distillation is and why it matters here

Knowledge distillation is a technique where a large model — the teacher — generates outputs that are then used to train a smaller model — the student. The student doesn’t learn from raw data: it learns to imitate the teacher’s behavior on the distributions that matter most.

# Simplified concept of the distillation pipeline for tool calling:
# 1. Teacher (Gemini) generates thousands of correct tool calling examples
# 2. Student (Needle, 26M) trains on those examples
# 3. The student learns the teacher's output distribution, not hand-written rules

For tool calling, this makes particular sense. You don’t need the model to know universal history. You need it to, when you hand it this schema:

// Tool definition — the model has to respect this 100%
const tools = [
  {
    name: "search_product",
    description: "Searches for a product by ID in the catalog",
    parameters: {
      type: "object",
      properties: {
        product_id: { type: "string" },
        include_stock: { type: "boolean" }
      },
      required: ["product_id"]
    }
  }
]

Produce exactly:

{
  "name": "search_product",
  "arguments": {
    "product_id": "SKU-4821",
    "include_stock": true
  }
}

Not some creative variation with renamed keys, wrong types, or invented fields. Small generalist models fail at this constantly. If Needle solves it reliably, the use case exists.

How to test it in Ollama: a reproducible checklist

If you want to validate whether a model like Needle has a place in your stack, the criterion shouldn’t be someone else’s benchmark. It should be your own set of tools under your system’s real conditions.

# Step 1: Install Ollama if you haven't
curl -fsSL https://ollama.com/install.sh | sh

# Step 2: When the model is available in the Ollama registry, pull directly
# (check availability at https://ollama.com/search)
ollama pull needle  # tentative name — verify the official registry

# Step 3: Prepare your own tool calling test suite
# Don't use the model README's examples; use YOUR real tools
// tool-calling-test.ts
// Validation criteria I'd use to evaluate any small model

interface TestResult {
  case: string;
  expected: object;
  received: string;
  validJson: boolean;
  schemaRespected: boolean;
  latencyMs: number;
}

async function evaluateToolCallingModel(
  model: string,
  cases: Array<{ prompt: string; expectedSchema: object }>
): Promise<TestResult[]> {
  const results: TestResult[] = [];

  for (const testCase of cases) {
    const start = Date.now();

    // Call the model via Ollama API
    const response = await fetch("http://localhost:11434/api/chat", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        model: model,
        messages: [{ role: "user", content: testCase.prompt }],
        // Pass tools as part of the request
        tools: [testCase.expectedSchema],
        stream: false,
      }),
    });

    const data = await response.json();
    const latency = Date.now() - start;

    // Validate if the JSON is parseable and if it respects the schema
    let validJson = false;
    let schemaRespected = false;
    let received = "";

    try {
      // The tool_call should be in message.tool_calls[0]
      const toolCall = data.message?.tool_calls?.[0];
      received = JSON.stringify(toolCall ?? data.message?.content ?? "");
      validJson = !!toolCall;
      // Basic schema validation: required keys must be present
      if (toolCall?.function?.arguments) {
        const args = toolCall.function.arguments;
        const requiredKeys = Object.keys(testCase.expectedSchema);
        schemaRespected = requiredKeys.every((k) => k in args);
      }
    } catch {
      received = "parse error";
    }

    results.push({
      case: testCase.prompt.slice(0, 50),
      expected: testCase.expectedSchema,
      received,
      validJson,
      schemaRespected,
      latencyMs: latency,
    });
  }

  return results;
}

My minimum acceptance criteria for any tool calling model in a real system:

Metric Minimum acceptable Why
Valid JSON 99%+ A parse error in production breaks the entire flow
Schema respected 95%+ Wrong arguments are silently dangerous
p95 latency < 500ms local If it’s slower than an external API, you’ve lost the point
Tool name hallucination 0% An invented name is a non-recoverable error

The limits that the hype doesn’t mention

There are three limitations that don’t show up in the headlines and that I consider essential before betting on a distilled model in a real system.

First, the teacher’s distribution defines the ceiling. If Gemini has biases in how it generates tool calls — certain argument patterns, certain naming conventions — the student inherits them unfiltered. This matters if your API has conventions that drift from Gemini’s style.

Second, generalization to unseen schemas is an open question. A distilled model can be excellent on the patterns it learned and brittle against complex schemas with anyOf, nested $refs, or conditional validations. You have to test it explicitly against your own schemas — don’t assume the general benchmark applies.

Third, 26M parameters implies limited context capacity. In systems where the prompt includes many tools simultaneously — common in backends with dozens of endpoints exposed as tools — degradation can be significant. That’s a hypothesis to validate, not assume.

None of this invalidates the project. It locates it. The same discipline I applied when reviewing pnpm workspaces cache issues in CI applies here: understand the limit first, then decide if it fits.

Where Needle makes sense and where it doesn’t

Scenarios where it makes sense to try Needle:

  • Local agent pipelines where network latency to external APIs is the bottleneck
  • Edge devices or resource-constrained environments where a 26M model fits in memory comfortably
  • Systems with a bounded and stable set of tools — not dozens of shifting schemas
  • As a local fallback when external APIs are unavailable

Scenarios where it probably doesn’t cut it:

  • Systems where reasoning between tool calling steps is complex — deciding when to call which tool, not just how to call it
  • APIs with deeply nested or polymorphic schemas
  • Flows where long conversational context matters — the 26M context limit is going to hurt
  • Environments that need auditable safety guarantees — a privately distilled model is a considerably more opaque box

The tension that surfaced in the Spring Boot Actuator in production post applies differently here: the comfort of “it works in the demo” can hide surface risks that only show up under load or with unexpected inputs.

What this signals for the small model ecosystem

The uncomfortable thing about Needle isn’t the model itself. It’s what it confirms: functional specialization is going to pressure the hegemony of large general models on structured tasks.

Tool calling, intent classification, entity extraction with fixed schemas — these are tasks where a well-trained distilled model can beat GPT-4 or Claude on cost and latency without sacrificing reliability. That changes the architecture calculation.

In my current stack with Claude Code for complex reasoning and Ollama for local tasks, there’s a gap exactly where Needle would aim: the tool router that decides which function to call and with what arguments, without needing the overhead of a 70B model for that. I’m not saying I’ll adopt it tomorrow. I’m saying the category makes sense and the experiment deserves follow-through.

Same as when I evaluated Jakarta EE vs Spring Boot tradeoffs or compared package managers in real monorepos, the honest answer isn’t “adopt it now” or “ignore it” — it’s “test it against your own criteria before committing.”

FAQ: Needle, distillation, and tool calling in small models

What exactly is model distillation in the LLM context?
It’s a process where a large model (teacher) generates a dataset of correct behavior — in this case, well-formed tool calling examples — which is used to train a small model (student). The student learns to imitate the teacher’s output distribution on the specific tasks it was distilled for, without needing the teacher’s full architecture.

Is 26M parameters enough for reliable tool calling?
Depends on the scope. For a bounded set of tools with simple schemas, probably yes. For systems with dozens of complex tools, long contexts, or multi-step reasoning, it’s an open hypothesis. The project’s own benchmark is optimistic; validation against your own schemas is mandatory before betting on it.

How do I test it locally without risking a production system?
With Ollama, if the model is available in the registry, it’s as simple as ollama pull [name] and then evaluating with your own script against the schemas you already use. The validation checklist in this post is a starting point. Always against your real tools — never against the README examples.

What’s the practical difference between Needle and using function calling from OpenAI or Anthropic?
Latency, cost, and privacy. A local model has no network RTT, no per-token cost, and doesn’t send your tool schemas to an external API. The tradeoff is that reliability depends entirely on the local model’s training quality, without the backing of a provider with an SLA.

Is it worth it for an individual stack or only for companies with infrastructure?
A 26M model runs on a MacBook with 8GB of RAM without drama. This isn’t enterprise infrastructure. If you’re already using Ollama for other tasks — like I am — adding a specialized model is operationally trivial. The real cost is evaluation time, not hardware.

What happens if the model hallucinates a tool name that doesn’t exist in my system?
That’s the worst case and you have to design for it as an expected failure. The routing layer that consumes the model’s output has to validate that the tool call name corresponds to a registered tool before executing anything. If it doesn’t exist, the error has to be explicit and not silent. This is basic defensive design, independent of which model you use.

Conclusion: test it with your eyes open

I’m not going to say Needle is the future or that it’s noise. My position is more specific: functional distillation of large model behavior into small specialized models is a legitimate direction, and tool calling is a use case where it makes genuine technical sense.

What I don’t buy is enthusiasm without friction. A 26M model has real limits around context, generalization, and reliability on unseen schemas. Those limits don’t appear in the HN post and they will appear in production.

My concrete recommendation: if you have an agent pipeline with a stable set of tools and latency is a problem, build a test harness with your own schemas, run it against the acceptance criteria in this post, and measure. If it clears 99% valid JSON and 95% schema respected on your own cases, you have something useful. If not, you know exactly why.

That’s more useful than any benchmark someone else wrote.

Are you using local models for tool calling? Tell me at juanchi.dev what stack you built and where you hit the limits.

This article was originally published on juanchi.dev