GEMINI LABJP
FLASH35 — Gemini 3.5 Flash is now GA and powers gemini-flash-latest, making everyday generation faster and more affordableAGENTS — Managed Agents launch in public preview in the Gemini API, running in secure, isolated Google-hosted Linux sandboxesMEDIA — Nano Banana 2 Lite and Gemini Omni Flash bring faster image and high-quality video generation across AI Studio and the APITTS — Streaming speech generation is now supported for gemini-3.1-flash-tts-preview via streamGenerateContentTRANSLATE — A new audio model detects 70+ languages for live speech-to-speech translation while preserving natural intonationSPENDCAP — Project-level spend caps for billing have been added in Google AI Studio to keep costs under controlFLASH35 — Gemini 3.5 Flash is now GA and powers gemini-flash-latest, making everyday generation faster and more affordableAGENTS — Managed Agents launch in public preview in the Gemini API, running in secure, isolated Google-hosted Linux sandboxesMEDIA — Nano Banana 2 Lite and Gemini Omni Flash bring faster image and high-quality video generation across AI Studio and the APITTS — Streaming speech generation is now supported for gemini-3.1-flash-tts-preview via streamGenerateContentTRANSLATE — A new audio model detects 70+ languages for live speech-to-speech translation while preserving natural intonationSPENDCAP — Project-level spend caps for billing have been added in Google AI Studio to keep costs under control
Articles/API / SDK
API / SDK/2026-06-15Advanced

When the Default Model Silently Upgrades: Catching Prompt Regressions in Numbers

Gemini 3.5 Flash is now the default and you can no longer turn it off. Assuming your responses can shift without you touching the prompt, here is how to bundle prompt, model, and sampling into one variant and catch regressions with canaries and an LLM judge — in working code.

gemini102gemini-api274prompt-engineering15canary2llm-as-judge5production137

Premium Article

The other day Gemini 3.5 Flash reached general availability, became the default in Enterprise apps, and the toggle to disable it simply disappeared. Reading that, I thought back to an unsettling half-day from about six months earlier. As an indie developer running my own chat app, I had not touched the prompt by a single character, yet one morning the tone of the responses turned oddly stiff for one slice of users. The change log was empty, and it ate my entire morning before I gave up looking for a cause I could prove.

My best guess is that a model checkpoint had been swapped behind the scenes. I could never confirm it. That inability to confirm was the real problem. I had only ever recorded when, who, and why a prompt changed — so when the model moved, I had no ruler in hand to separate cause from coincidence.

Instrument for "it changed without me touching it"

When the default rises to 3.5 Flash and cannot be disabled, any automation that calls the API without an explicit model is now subject, by policy rather than by accident, to "behavior changes one day." Since this comes from the platform side, the only place to absorb it is your own design.

There is really only one way to absorb it: snapshot the conditions that produced each response and measure quality continuously, per condition. For open-ended workloads like chat, unit tests tell you nothing beyond "no error thrown." A decay where error stays at zero while quality quietly sinks slips right past them. That is exactly why you need to treat a prompt as an explicit version and run several versions side by side on production traffic, comparing them in numbers.

The point I want to press hardest: do not make the unit of versioning the prompt string. If you version only the prompt while the model and sampling parameters move independently underneath, you can never pin down which factor a measured difference belongs to. Make the unit a variant that bundles prompt plus model ID plus sampling config. That is the spine of this whole piece.

The shape of it — four parts, and why shadow matters

There are four parts to build.

The Prompt Registry holds variants as Firestore documents, with a status field controlling whether each is serving, waiting in the wings, or retired. The Traffic Splitter picks a variant deterministically from a user ID and a task key, so the same person always gets the same version and the comparison never breaks mid-stream. The Metrics Collector is a thin wrapper around the API call that always writes one record: which variant, how much latency and how many tokens, and whether it succeeded or failed. The Evaluation Loop samples the accumulated logs, scores them with a judge model, and looks at the gap in mean score between variants.

The single most useful design choice is splitting status into active and shadow. An active variant goes out to real traffic; a shadow one does not. It stays in the wings and only gets offline scoring on a small sample. Having a gate where you can discard "this version is clearly weaker" before it ever touches a user noticeably reduces production incidents. After I added that gate, I became far bolder about trying new variants — useful when you are a one-person team and every regression lands on you alone.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
A Firestore registry that bundles prompt, model, and sampling into a single variant, with deterministic hashing for stable assignment
A three-stage path — shadow, canary, promotion — that freezes win/lose calls until a minimum sample size is reached
An evaluation batch that uses a stronger gemini-3-pro as judge and flags regressions with mean-score deltas and a quick z value
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $10 for lifetime access
View Membership →

Related Articles

API / SDK2026-03-25
Building a Prompt Evaluation & Optimization Pipeline with Gemini API — Automated Quality Scoring with LLM-as-Judge
Learn how to build a prompt evaluation pipeline using Gemini API. Covers the LLM-as-Judge pattern, A/B testing prompts, automated quality scoring, and cost-quality optimization for production systems.
API / SDK2026-06-17
Keep Your Flash-to-Pro Routing Threshold Honest with Shadow Re-evaluation
A Flash-generates, Pro-on-low-confidence router starts drifting the moment you hand-pick its threshold. This is a working build of a loop that samples your kept-Flash outputs, scores them against Pro, and recalibrates the threshold from a quality budget.
API / SDK2026-06-16
Don't Break When the Default Model Moves: A Startup Capability-Probing Layer for Gemini
Pinning a model name breaks on deprecation; trusting the default breaks when the weights swap silently. This is the design I settled on: probe what the served model can actually do at startup, then build every request from that answer. Includes runnable Python.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links
See all →