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.
Running Gemini Chat History on Redis — Field Notes on Not Losing Conversation State in Production
Keep a Gemini ChatSession in process memory and it evaporates on every redeploy or scale event. Here is how I back it with Redis in production, covering token budgets, concurrent sends, SDK coupling, and graceful degradation, with the code I actually run.
Catching Deprecated Gemini Models in CI ― A Guard for Back-to-Back Shutdown Deadlines
When shutdowns and deprecations pile up, build a CI check that mechanically finds stale Gemini model strings across your repo. Includes a deprecation registry, a scanner, and a days-remaining warn/fail tier you can copy and run.
Before You Let a Managed Agent Ship: Designing Your Own Acceptance Gate
Let the public-preview Managed Agents generate files and broken artifacts will flow straight into production. Here is how to build a verification gate that artifacts must pass before you accept them, with runnable Python and a rejection-feedback loop.
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.
When Your Firestore × Gemini Embeddings RAG Quietly Degrades — Designing for Re-Embedding
A RAG built on Firestore native vector search and Gemini Embeddings drifts when the embedding model changes generations, and retrieval quality drops with no errors. Here is how to detect the drift, re-embed without downtime, and keep retrieval cost in check.
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.
Defending Against Prompt Injection When You Pass External Text to the Gemini API
User reviews, scraped articles, and other untrusted text are the entry point for indirect prompt injection when you feed them to the Gemini API. Here is a prioritized, code-backed defense you can drop into a production pipeline: trust-boundary isolation, schema constraints, a two-stage screening pass, and output sanitization.
Permission-Aware RAG — Designing Gemini Search That Only Cites What the User Is Allowed to See
The day you add RAG to internal search, drafts and finance memos nobody should see start leaking into answers. This is a production design — metadata filtering, defense in depth, and audit logging — for letting Gemini search while respecting permissions, with working code.
How a Deep Think Verification Step Tripled My API Bill, and How thinking_level Got It Back
After wiring API-accessible Gemini 3 Deep Think into my output-verification step, my projected monthly cost jumped roughly 3x. Here is the implementation record of capping it with thinking_level and a cost guardrail, then settling on a two-stage design with Flash.
Controlling Image Tokens with the Gemini API media_resolution Setting — Tuning Batch Image Classification by Measurement
media_resolution, introduced in the Gemini 3 line, switches how many tokens an image input consumes across three levels. Through real batch-classification measurements, this guide shows how to balance cost and accuracy by assigning the right tier per task.
When Gemini API Cuts Your Response Off Mid-Sentence — Detecting finish_reason: MAX_TOKENS and Stitching the Continuation
Long-form generation that ends mid-sentence is usually finish_reason: MAX_TOKENS. This failure arrives as a quiet HTTP 200, no exception. Here is how to detect it, stitch a continuation to recover the full text, and avoid the thinking-token trap that makes it worse on 3.x models.