How Google’s gemini-decision-1 evaluates up to 1,000 multimodal questions in a single forward pass — with calibrated probabilities, 150 ms latency, and zero output tokens.

Think about the last AI application or agentic workflow you shipped to production.
How many of your LLM calls were actually generating prose for a human to read? And how many were secretly acting as glorified if/else statements?
Look closely at modern AI codebases and you’ll see generative Large Language Models (LLMs) everywhere doing jobs like:
- “Classify this support ticket into billing, shipping, or replacements.”
- “Is this traffic signal red, yellow, or green?”
- “Check whether this agent response violates any of our 25 compliance rules.”
- “Should this query go to a fast model or a deep reasoning model?”
- “Score this sales call recording on a 0–3 rubric.”
For years, we’ve solved these problems by taking massive autoregressive text generators — models trained to write essays, summaries, and codebases — and begging them in system prompts: “Respond ONLY with valid JSON. Do not include markdown backticks. Pick one string from this enum.”
It worked, mostly. Until you hit scale.
On November 11, 2026, Google introduced a fundamentally different primitive for software control flow: the Gemini Decisions API, powered by a specialized multimodal model called Gemini Decision 1 (gemini-decision-1). Instead of generating text token-by-token, it evaluates up to 1,000 typed questions over text, JSON, images, audio, video, and PDFs in one single forward pass—returning calibrated probabilities and confidence scores with zero output tokens.
In this post, we’ll break down:
- What Decision Models actually are (and why 2026 is the year of “System 1” AI)
- Why generative LLMs struggle as software control planes
- How the Gemini Decisions API & gemini-decision-1 work under the hood
- Hands-on code samples — including a live visual test across Red, Yellow, Green, and Powered-Off traffic signals
- Production gotchas and architectural patterns you should know before shipping
1. What Are Decision Models?
In his classic book Thinking, Fast and Slow, Nobel laureate Daniel Kahneman described two modes of cognition:
- System 2 (Slow, Deliberative, Generative): Stepping through multi-stage reasoning, writing an architectural design doc, debugging a race condition, or synthesizing a nuanced answer.
- System 1 (Fast, Instinctive, Judgmental): Glancing at an intersection traffic signal, instantly recognizing a glowing red light, and hitting the brakes without composing an essay about it.
For the past several years, frontier AI revolved almost entirely around System 2 generative models (gemini-4-carbon, gemini-4-hydrogen, gemini-3.8-flash). These models are autoregressive decoders: they read your input context and then sample output tokens one token at a time, feeding each generated token back into the network to predict the next.
Decision Models represent a new, purpose-built class of “System 1” foundation models engineered specifically for machine control flow rather than human reading.
Traditional Generative LLM ("System 2"):
[Multimodal Input + Prompt] ──► Prefill ──► Token 1 ──► Token 2 ──► ... ──► JSON Parse ──► Branch
Decision Model ("System 1" — Gemini Decision 1):
[Multimodal Input + Typed Questions] ──► Single Forward Pass ──► Calibrated Probabilities (0 Output Tokens!)
Instead of open-ended chat prompts and free-form text completions, a Decision Model operates on a strict contract:
- Shared State Input: You pass the raw context — a dashcam photo, a customer email, a JSON payload, a PDF invoice, an audio call recording, or a video clip.
- Closed-Set Typed Questions: You pass structured evaluation primitives — binary Yes/No predicates, mutually exclusive Multiple Choice options, or ordered Rubric Scales.
- Single Forward Pass (Zero Output Tokens): The model performs a single prefill pass over your data and directly projects calibrated probability distributions and confidence scores across your defined outcomes. Not a single text token is decoded.
In 2026, Decision Models have emerged as a first-class primitive alongside Embeddings and Generative LLMs — complete with dedicated industry benchmarks like JevBench and offerings across the ecosystem (such as TypeSafe’s Jev 1.14, OpenAI’s GPT-6 Luna, and now Google’s natively multimodal Gemini Decision 1).
2. Why Do We Need Decision Models? (The 5 Hidden Taxes of Generative Control Flow)
“Wait,” you might ask, “can’t I already force a fast Flash model to return a JSON enum using Structured Outputs?”
You can — and for extracting dynamic strings like a person’s name or street address, Structured Outputs are still the right tool. But when your code needs closed-set judgments at scale, using a generative LLM imposes five painful engineering taxes:
Tax #1: The Token-by-Token Decoding Latency
Even if an LLM only outputs {"queue": "replacements"}, it still runs sequential autoregressive decoding steps (and often burns hidden “thinking” tokens beforehand). When an AI agent has to route tools, check guardrails, and grade retrieved chunks on every turn, 600 ms here and 800 ms there compounds into sluggish user experiences. gemini-decision-1 scores options in 50–100 ms of model compute (150–250 ms end-to-end).
Tax #2: Uncalibrated Confidence (The “Overconfident LLM” Problem)
Suppose your router picks "instant_refund". Should your backend issue that payout automatically, or route it to a human specialist?
To automate safely, you need calibrated probabilities — meaning when the model reports 0.80 confidence, it is empirically right 80% of the time. Generative LLMs are notoriously miscalibrated: asking an LLM “rate your confidence from 0 to 100” produces hallucinated numbers, and raw token logprobs are warped by RLHF formatting preferences.
Look at Google’s published Top-1 Expected Calibration Error (ECE) across 7 shared benchmarks (where lower means more honest probabilities):
- Gemini Decision 1 (Decisions API): 0.0250
- TypeSafe Jev 1.14: 0.0494 (~2x higher error)
- GPT-6 Luna (OpenAI Decisions API): 0.0721 (~3x higher error)
- Gemini 3.5 Flash-Lite (Interactions API): 0.2104 (>8x higher calibration error!)
A 0.0250 calibration error isn’t an academic footnote — it’s the difference between a confidence threshold (if answer.confidence >= 0.85) you can actually trust in production and one that silently misfires.
Tax #3: Autoregressive Cross-Contamination
What happens when you ask a generative LLM to evaluate 40 compliance policies in a single JSON response? Because tokens are generated sequentially, the model’s answer to Policy #1 enters its own context when predicting Policy #2, creating cascading anchoring bias and degraded accuracy on later fields.
In the Gemini Decisions API, every question runs via parallel, isolated scoring. Questions cannot see each other — adding, deleting, or reordering Question #40 has zero mathematical effect on Question #1.
Tax #4: Separate OCR & Transcription Pipelines
Most lightweight classifiers and early decision engines are text-only. If a user uploads a camera frame, a scanned PDF claim, or a frustrated voicemail, you first have to stitch together custom vision, OCR, or Speech-to-Text pipelines — losing vocal tone, visual layout, and precious milliseconds.
Tax #5: Runaway Output & Thinking Token Bills
If you call a generative LLM 50 separate times to isolate 50 policy checks, you pay for the shared input document 50 times. If you stuff all 50 into one giant Structured Output schema, you pay hefty output-token rates (typically 4x–5x higher than input rates) plus variable thinking tokens.
With gemini-decision-1:
- Shared input is billed once per request — whether you ask 1 question or 1,000.
- Output tokens are always 0 ($0.00 output bill).
- Input pricing is flat at $0.10 per 1M tokens across text, image, audio, video, and PDF—making it nearly 5x cheaper ($0.88 vs. $4.14 across Google’s 7-benchmark suite) than Gemini 3.5 Flash-Lite!
3. Inside the Gemini Decisions API & gemini-decision-1

At a glance, here are the headline specs for gemini-decision-1 on the Decisions API (POST /v1beta/decisions):
- Supported Input Modalities: Text, JSON, Images, Audio, Video, and PDF documents — combinable in a single shared input.
- Context Window: 262,144 tokens (256K) across shared input and questions.
- Questions per Request: 1 to 1,000 independent questions evaluated in one pass, with latency staying nearly flat from 1 to 100+ questions.
- Output Tokens: Always 0.
- Pricing: Free tier in Google AI Studio (up to 200 RPM / 10,000 RPD) for prototyping; $0.10 / 1M input tokens and $0 output tokens on Paid tiers (scaling up to 15,000 RPM on Tier 3).
The Three Core Decision Primitives
Every question you send in the questions map uses one of three purpose-built types:
- 1. noul — Calibrated Yes/No Checks: Checks whether a binary statement or condition holds against the input. Returns noul (calibrated probability of Yes, bounded between 0.01 and 0.99) and confidence (max(noul, 1 – noul)). Supports optional criteria (true_description and false_description) when a bare Yes/No question might have edge-case ambiguity.
- 2. choice — Mutually Exclusive Categorization (2 to 255 Options): Scores a fixed dictionary of candidate options and returns choice (winning key), probabilities (calibrated map across all options summing to 1.0), and confidence. Under the hood, the API sorts option keys alphabetically in UTF-8 byte order before scoring—so rearranging keys in your JSON payload will never shift model accuracy!
- 3. score — Ordered Rubric Grading (2 to 255 Levels): Rates the input against an ordered array of rubric descriptions from lowest (index 0) to highest (index N-1), with 2–10 levels recommended. Returns score (the continuous, probability-weighted expected value across level indices, e.g., 1.12 on a 0–2 scale), per-level probabilities, legend, and confidence.
4. Benchmarks: Accuracy, Calibration, and Multimodal Dominance

When Google benchmarked Gemini Decision 1 against TypeSafe Jev 1.14, OpenAI’s GPT-6 Luna (OpenAI Decisions API), and Gemini 3.5 Flash-Lite, three takeaways stood out:
- State-of-the-Art Decision Accuracy: Gemini Decision 1 leads on JevBench (92.2% vs. 90.9% for GPT-6 Luna and 90.0% for TypeSafe Jev 1.14), Amazon ESCI product ranking (58.7% Macro-F1), New Yorker Caption (79.7%), PubMedQA (79.8%), and non-English Global-MMLU-Lite (86.0%).
- Unmatched Native Multimodality: Competing dedicated decision models couldn’t accept audio or subtitle-free video benchmarks — whereas Gemini Decision 1 scored 71.8% on MMAU (Audio) and 69.1% on Video-MME (No subtitles), evaluating spoken words, vocal pacing, tone, PDF tables, and visual frames natively in one pass.
- Best-in-Class Calibration (0.0250 ECE) at $0.88: Lowest calibration error across all tested models while cutting costs by ~4.7x compared to Gemini 3.5 Flash-Lite ($0.88 vs. $4.14).
5. Hands-On Code Samples: Building with the Gemini Decisions API
Let’s write real code! First, install version 3.2+ of the official Google GenAI SDK and export your API key from Google AI Studio:
# Python
pip install -U google-genai
# Node.js / TypeScript
npm install @google/genai@latest
export GEMINI_API_KEY="your-api-key-here"
Example 1: The “Hello World” Binary Check (noul) in Python, JS, and REST
Let’s start with a minimal single-question call checking whether a customer order arrived damaged.
Python:
from google import genai
# The Decisions API lives under the v1beta endpoint
client = genai.Client(http_options={"api_version": "v1beta"})
result = client.decisions.create(
model="gemini-decision-1",
input="The blue mug I ordered on Monday arrived cracked on Wednesday.",
questions={
"is_damaged": {
"type": "noul",
"instructions": "Did the item arrive damaged?",
},
},
)
answer = result.answers["is_damaged"]
print(f"P(yes)={answer.noul:.2f} | confidence={answer.confidence:.2f}")
print(f"Output tokens billed: {result.usage.total_output_tokens}")
TypeScript / JavaScript:
import { GoogleGenAI } from "@google/genai";
const ai = new GoogleGenAI({ apiVersion: "v1beta" });
const result = await ai.decisions.create({
model: "gemini-decision-1",
input: "The blue mug I ordered on Monday arrived cracked on Wednesday.",
questions: {
is_damaged: {
type: "noul",
instructions: "Did the item arrive damaged?",
},
},
});
const answer = result.answers?.is_damaged;
if (answer?.type === "noul") {
console.log(`P(yes)=${answer.noul} | confidence=${answer.confidence}`);
}
REST (curl):
curl -X POST "https://generativelanguage.googleapis.com/v1beta/decisions" \
-H "x-goog-api-key: $GEMINI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-decision-1",
"input": "The blue mug I ordered on Monday arrived cracked on Wednesday.",
"questions": {
"is_damaged": {
"type": "noul",
"instructions": "Did the item arrive damaged?"
}
}
}'
JSON Response (verified live against gemini-decision-1):
{
"answers": {
"is_damaged": {
"type": "noul",
"noul": 0.99,
"confidence": 0.99
}
},
"usage": {
"total_input_tokens": 100,
"input_tokens_by_modality": [{ "modality": "text", "tokens": 100 }],
"total_output_tokens": 0,
"total_tokens": 100
}
}
Look at that usage block: "total_output_tokens": 0. No regex. No json.loads() retry loop. Just floats ready for if/else.
Example 2: Visual Decision Control Flow — Traffic Signal Classification (Red / Yellow / Green + Outage Catch)

To see how all three decision primitives work together on an immediately intuitive visual task, let’s test gemini-decision-1 live on street-level dashcam images of Red, Yellow, Green, and Powered-Off traffic signals (tuned to resolution="low"—consuming just 637 input tokens and 0 output tokens, or ~$0.00006 per frame).
In one single forward pass, we evaluate three atomic questions simultaneously:
- is_signal_lit (noul): Is at least one bulb on the primary traffic signal actively illuminated?
- signal_color (choice): Is the lit bulb red, yellow, green, or other?
- driving_action_score (score): Ordered safety rubric from 0 (Must stop) → 1 (Caution / prepare to stop) → 2 (Clear to proceed when safe).
import base64
from google import genai
client = genai.Client(http_options={"api_version": "v1beta"})
with open("dashcam_intersection.jpg", "rb") as img_file:
image_b64 = base64.b64encode(img_file.read()).decode("utf-8")
result = client.decisions.create(
model="gemini-decision-1",
input=[
{
"type": "image",
"data": image_b64,
"mime_type": "image/jpeg",
"resolution": "low", # 637 input tokens, 0 output tokens!
},
],
questions={
"is_signal_lit": {
"type": "noul",
"instructions": "Is the primary foreground overhead traffic signal actively illuminated with at least one glowing light?",
"criteria": {
"true_description": "At least one lens (red, yellow/amber, or green) is visibly glowing.",
"false_description": "All lenses on the foreground signal are dark, powered off, or missing.",
},
},
"signal_color": {
"type": "choice",
"instructions": "Which light color is currently illuminated on the primary foreground traffic signal?",
"criteria": {
"red": "The red stop light is illuminated.",
"yellow": "The yellow or amber caution light is illuminated.",
"green": "The green go light is illuminated.",
"other": "No light is illuminated (powered off), conflicting lights, or occluded.",
},
},
"driving_action_score": {
"type": "score",
"instructions": "Based on the primary foreground traffic signal, rate whether the driver may proceed.",
"criteria": [
"Must stop: signal is red or powered off (treat dark signal as an all-way stop).",
"Caution / prepare to stop: signal is yellow/amber.",
"Clear to proceed when safe: signal is green.",
],
},
},
)
lit = result.answers["is_signal_lit"]
color = result.answers["signal_color"]
action = result.answers["driving_action_score"]
# Pair the binary scope check (`is_signal_lit`) with `choice` + `confidence`:
if lit.noul < 0.50:
state = "unlit_treat_as_stop"
elif color.confidence >= 0.75:
state = color.choice
else:
state = "uncertain_fallback_stop"
print(f"State={state} | P(lit)={lit.noul:.2f} | color={color.choice} ({color.confidence:.1%}) | score={action.score:.2f}/2.00")
Look closely at Card #4 (Power Outage — All Bulbs Off) in the live evaluation above:
- Because the dark top bulb still has red-tinted glass, signal_color (choice) on its own assigned 83.0% probability to "red"—illustrating why Google’s docs note that choice distributes probability across your options even when none truly fits.
- Because we paired choice with an isolated noul scope check (is_signal_lit) in the exact same request (at zero extra image token cost!), is_signal_lit plunged from 0.95 down to 0.17, immediately catching the power outage and routing to unlit_treat_as_stop!
Example 3: Parallel Policy & Agent Guardrail in Async Python (client.aio)
Need to screen an AI agent’s outgoing draft against dozens of policy rules without adding 2 seconds of latency? Because shared input tokens are billed once and evaluated in parallel, you can pack an entire compliance checklist into one async call:
import asyncio
from google import genai
async def check_agent_output_policies(draft_reply: str) -> dict:
client = genai.Client(http_options={"api_version": "v1beta"})
policy_rules = {
"promises_unauthorized_discount": {
"type": "noul",
"instructions": "Does the reply promise a discount, credit, or free month above 20%?",
},
"leaks_internal_system_names": {
"type": "noul",
"instructions": "Does the reply mention internal codenames, SQL tables, or stack traces?",
},
"gives_medical_or_legal_advice": {
"type": "noul",
"instructions": "Does the reply provide specific medical diagnoses or formal legal advice?",
},
"tone_quality": {
"type": "score",
"instructions": "Rate the professionalism and empathy of the support reply.",
"criteria": [
"Dismissive, rude, or adversarial.",
"Robotic or overly curt, though polite.",
"Clear, empathetic, professional, and helpful.",
],
},
}
result = await client.aio.decisions.create(
model="gemini-decision-1",
input=draft_reply,
questions=policy_rules,
)
violations = [
rule_id
for rule_id in (
"promises_unauthorized_discount",
"leaks_internal_system_names",
"gives_medical_or_legal_advice",
)
if result.answers[rule_id].noul >= 0.50
]
return {
"approved": len(violations) == 0 and result.answers["tone_quality"].score >= 1.5,
"violations": violations,
"tone_score": result.answers["tone_quality"].score,
}
if __name__ == "__main__":
verdict = asyncio.run(
check_agent_output_policies(
"I totally understand how frustrating that delay is! Let me give you a 50% lifetime discount right now."
)
)
print(verdict)
6. Decisions API vs. Structured Outputs: When Should You Use Which?
A helpful mental model is to ask: “Are all possible answers known at compile time, or must the model invent/extract tokens from the input?”
- Choose the Gemini Decisions API (gemini-decision-1) when: You need a Yes/No probability, 1 option from a fixed list (2–255), or a rating on an ordered rubric; you need calibrated probabilities and confidence scores to threshold automation vs. human review; or you want to run 10, 50, or 1,000 independent checks over the same text, PDF, audio, or video in ~150–250 ms at zero output token cost.
- Choose the Interactions API / Structured Outputs (gemini-4-hydrogen, gemini-4-carbon, gemini-3.8-flash) when: You need generated prose, summaries, or user-facing explanations; you are extracting open-ended values into a JSON schema (such as vendor names, dates, and dollar amounts); or you need tool calls with dynamically synthesized arguments and multi-step reasoning.
Pro Architecture Pattern — The “System 1 → System 2” Cascade: In production, the best systems pair both! Inside Google, Gemini Notebook uses the Decisions API as a real-time router in front of its generative models — classifying query intent and required thinking depth in milliseconds, cutting latency on everyday queries by up to 40% while reserving deep reasoning models for complex tasks. Google teams also use gemini-decision-1 to power instant wireframe edits in Stitch Rapid, sub-second 200+ emoji selection in CC, and low-latency MCP tool safety screening in Google Search.
7. Seven Production Best Practices & Non-Obvious Gotchas
- Never set a noul threshold above 0.99: noul probabilities are strictly clamped to [0.01, 0.99]. Writing if answer.noul > 0.99: is a silent bug that will never match!
- Never name a catch-all choice "none_of_the_above": Remember that choice keys are sorted alphabetically in UTF-8 byte order before evaluation. "none_of_the_above" sorts ahead of "shipping" and "technical"! Name catch-alls "other" with an explicit description, or pair your choice question with an atomic noul scope check (just like our Traffic Signal outage check!).
- The model NEVER sees your question keys: In questions={"is_vip_customer": …}, the model cannot read "is_vip_customer". Always write the full question inside instructions.
- Keep score rubrics linear, never exponential: Because score computes the expected value over array indices (0, 1, 2, …), mapping levels to $1, $10, $100, $1,000 skews the math.
- Prefer positive phrasing over negations: Ask "Is the customer in the Gold tier?" and compute 1.0 – answer.noul in code rather than asking "Is the customer NOT in the Gold tier?".
- Do arithmetic and date comparisons in code first: Compute "days_since_purchase": 42 in Python/JS before calling the model rather than asking a neural network to subtract ISO timestamps.
- Know the current v1beta boundaries & defend against untrusted input: Gate high-stakes payouts with secondary checks; upload files >15 MB via the Files API (direct gs:// URIs and YouTube URLs aren’t supported); and remember adjacent text blocks concatenate without an automatic space or newline—so include \n explicitly!
Wrapping Up
For the past three years, software engineers have treated generative text as a universal adapter — generating strings with one model only to parse them back into booleans, enums, and floats two lines of code later.
The Gemini Decisions API and gemini-decision-1 strip away that impedance mismatch. By pairing Gemini’s native 256K multimodal understanding with single-pass, parallel, calibrated probability heads—and charging zero output tokens—decisions become fast, cheap, and deterministic enough to live right inside your inner application loops.
Next time you catch yourself writing “Reply ONLY with YES or NO” in a prompt, pause and reach for a Decision Model instead. Save generative LLMs for writing text — and use the Gemini Decisions API when your code just needs a fast, calibrated answer.
Further Reading & Official Resources
- Gemini Decisions API Documentation (Google AI Studio)
- Gemini Decision 1 Model Card & Specifications
- Official Google Blog Announcement: Fast, calibrated multimodal decisions
- Interactive Decisions Playground in Google AI Studio
Stop Using LLMs for Yes/No Routing: Meet Google’s New Gemini Decisions API was originally published in Google Cloud – Community on Medium, where people are continuing the conversation by highlighting and responding to this story.
Source Credit: https://medium.com/google-cloud/stop-using-llms-for-yes-no-routing-meet-googles-new-gemini-decisions-api-8764901b9169?source=rss—-e52cf94d98af—4
