GEMINI LABJP
ROBOTICS — The ER 1.6 preview that shut down on August 31 does have a successor. Gemini Robotics ER 2 is in public preview, in both standard and streaming variantsVIDEO — ER 2 judges success and failure from live video rather than still snapshots, which is what lets it catch spills, slips, and misalignments while a task is still runningDEADLINE — Next up is September 30, when gemini-omni-flash-preview is retired. The target is gemini-omni-1.1-flash, GA since August 27, and there are now under four weeks leftAPIKEY — Every remaining standard API key, restricted ones included, stops working during September. The replacement is an auth key bound to a Google Cloud service accountPRICE — Gemini 3.7 Flash keeps its introductory $0.75/$3.75 per 1M through December 31, then moves to $1.50/$7.50 on January 1, 2027. Any estimate crossing the year needs both figuresAUDIO — Gemini 3.5 Transcribe handles language detection across 85+ languages, speaker diarization, word-level timestamps, and custom vocabulary biasing of up to 1,000 termsROBOTICS — The ER 1.6 preview that shut down on August 31 does have a successor. Gemini Robotics ER 2 is in public preview, in both standard and streaming variantsVIDEO — ER 2 judges success and failure from live video rather than still snapshots, which is what lets it catch spills, slips, and misalignments while a task is still runningDEADLINE — Next up is September 30, when gemini-omni-flash-preview is retired. The target is gemini-omni-1.1-flash, GA since August 27, and there are now under four weeks leftAPIKEY — Every remaining standard API key, restricted ones included, stops working during September. The replacement is an auth key bound to a Google Cloud service accountPRICE — Gemini 3.7 Flash keeps its introductory $0.75/$3.75 per 1M through December 31, then moves to $1.50/$7.50 on January 1, 2027. Any estimate crossing the year needs both figuresAUDIO — Gemini 3.5 Transcribe handles language detection across 85+ languages, speaker diarization, word-level timestamps, and custom vocabulary biasing of up to 1,000 terms
Articles/Dev Tools
Dev Tools/2026-09-02Intermediate

An agreement-rate gate approves the model swap, then your category shares move

Swapping the model behind an image classification batch can pass a golden-set agreement gate while category shares quietly shift. I measured the sample sizes each check really needs and rebuilt the gate as a paired comparison.

Gemini API230Image Classification4Batch Processing6Model Migration7Quality Monitoring3

Premium Article

The week after I promoted a new classification model in my wallpaper app, the categories sitting near the top of the browse list had shifted a little.

No individual label was wrong. Looking at images one by one, every assignment was defensible. Yet the landscape shelf had thickened, and the small categories at the bottom had thinned out.

The promotion decision had been made with an agreement rate against a golden set — the share of images where the new model produced the same label as the old one. That check passed. It passed, and the shares moved anyway.

What follows is how I pinned down the reason with numbers, and how I rebuilt the gate so the shift shows up before promotion rather than after. The statistical figures come from a simulation I ran locally over a skewed 30-category distribution built to resemble the real one. The operational problem is from the classification batch I run for a wallpaper app I develop on my own. It ships on both the App Store and Google Play, and the browse ordering on each is assembled from the same classification output, so checking only one side proves nothing — an assumption that shapes everything below.

What a 92% agreement rate was hiding

I started by confirming that agreement and composition are genuinely different quantities.

Thirty categories, with a Zipf-like skew (19.8% for the top one, 11.1% second, 7.8% third, 32.7% for the bottom twenty combined). On top of that I imposed a specific confusion pattern: the new model returns the same label 92% of the time, and of the 8% that disagree, roughly 70% land in one of the top three categories. Errors are not scattered uniformly — they get absorbed by the dominant categories. Running 200,000 items gave this:

CategoryOld modelNew modelRelative change
1st19.78%21.18%+7.1%
2nd11.06%11.87%+7.3%
3rd7.80%8.40%+7.7%
4th6.13%5.71%-6.9%
Bottom 20 combined32.73%31.72%-3.1%

Effective agreement came out at 91.9%, with a total variation distance of 2.81%.

A gate that only reads agreement will wave this through if the threshold sits at 90%. Meanwhile the top categories have gained 7% and the bottom twenty have lost 3% between them. A few percent is exactly the range where browse ordering and the "new arrivals" shelf start to look different.

Agreement counts how many labels changed. Composition depends on where the changed ones went. Obvious once stated, but folding both into a single gate is how the distinction got lost.

Watching production output finds it far too late

The natural follow-up is to monitor the output distribution after promotion. This is where my expectation was furthest off.

Assume a chi-square goodness-of-fit test over the 30 shares (29 degrees of freedom, 5% significance, critical value 42.557). Against the sub-2% TVD drift above, the power came out like this:

Items used for the decisionPower
5009.5%
1,20019.2%
2,00039.8%
4,00079.2%

For a batch handling a few hundred images a day, accumulating 4,000 takes one to two weeks. Throughout that window power sits near 20%, which means most of the "nothing to report" readouts were reporting a shortage of data rather than an absence of drift.

I assumed narrowing to a single category would fix it, so I measured that too:

ItemsTop category (19.78%→21.18%)Third category (7.80%→8.40%)
1,80031.4%16.7%
3,00047.6%24.0%
6,00076.8%41.8%
15,00076.3%

Better than the omnibus test, but the order of magnitude does not change. Watching a 7.8% category takes 15,000 items.

The reason lies in where the variance comes from. When you observe the production distribution, most of the wobble comes from which images arrived that day. The model's contribution is a thin layer on top of that, buried under input variation, and the only lever you have is piling up more items.

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
You will be able to confirm that category shares have not moved before you promote a new classification model, even when the agreement gate is green
You will be able to choose between watching production output and running a paired new-versus-old comparison, based on the sample size each one actually requires
You will understand why a 30-category goodness-of-fit test still reaches only 79% power at 4,000 items, and redesign your monitoring around test granularity
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 $15 for lifetime access
View Membership →

Related Articles

API / SDK2026-05-03
Auto-Categorizing 3,000 Wallpaper Images With Gemini Vision API — A Real Production Account
Manually categorizing thousands of wallpaper images doesn't scale. This is a hands-on account of building an auto-classification pipeline with Gemini Vision API — covering design, implementation, actual cost, and the failure patterns I hit running 3,000 images through it.
Dev Tools2026-08-30
Why Shipped Clients Deserve a Refusal, Not a Silent Model Substitution
A model can retire, but the apps already on people's phones cannot. This is how I built a sunset ledger keyed on output contracts, and how I now back-date my own deadline from the version residue curve.
Dev Tools2026-08-28
A twice-daily batch that only ran once — reconstructing run counts from artifacts
One half of a scheduled job silently never fired, and throughput sat at half of plan for over a week without a single error in the logs. Here is how I reconstructed actual run counts from artifacts and backlog, with working code.
📚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 →