GEMINI LABJP
SPARK — Gemini Spark, Google's agentic assistant, arrives in the Gemini app for macOS and works on tasks on your behalfBRIEF — Daily Brief, powered by Personal Intelligence, distills priorities from Gmail and Calendar with suggested next stepsMODEL — Gemini 3.5 Flash reaches GA, offering faster, lower-cost AI with a 1M-token context windowGROWTH — The Gemini app has passed 900 million monthly active users, up from 400 million a year earlierAPPS — Spark now connects to Google Tasks and Google Keep and stays up to date on topics in real timeENTERPRISE — Gemini 3.5 Flash is generally available across the Global, US, and EU regions on Gemini EnterpriseSPARK — Gemini Spark, Google's agentic assistant, arrives in the Gemini app for macOS and works on tasks on your behalfBRIEF — Daily Brief, powered by Personal Intelligence, distills priorities from Gmail and Calendar with suggested next stepsMODEL — Gemini 3.5 Flash reaches GA, offering faster, lower-cost AI with a 1M-token context windowGROWTH — The Gemini app has passed 900 million monthly active users, up from 400 million a year earlierAPPS — Spark now connects to Google Tasks and Google Keep and stays up to date on topics in real timeENTERPRISE — Gemini 3.5 Flash is generally available across the Global, US, and EU regions on Gemini Enterprise
Articles/Advanced
Advanced/2026-07-08Advanced

When Your Knowledge Base Shifts Mid-Run: Pinning File Search to an Execution Epoch for Consistent Agent Grounding

When a File Search store is updated while a Managed Agent is running, a single execution can mix old and new grounding. Borrowing MVCC ideas, pinning an execution epoch keeps one agent run's evidence consistent. Here is the design and implementation.

Gemini API174Managed Agents5File Search6RAG13Architecture8

Premium Article

I was tracing an agent run that a nightly batch had produced, and I stopped cold.

The generated artifact justified its conclusion using a passage from an internal document. But that document had already been retired by a separate update process running at the same moment. The first half of the run cited the old revision; the second half cited the new one. Within a single execution, the grounding had swapped underneath it.

Managed Agents now run autonomously inside Google-hosted, isolated sandboxes, and File Search has reached GA with multimodal support. Behind the comfort of handing off the runtime, there is an easy trap to miss: a single agent run stretches from tens of seconds to several minutes, and the knowledge base keeps moving the entire time.

This article lays out a design for treating an agent execution as a single consistent snapshot, together with the implementation. It is an attempt to bring MVCC — multiversion concurrency control, familiar from databases — into File Search. As an indie developer running apps solo at Dolice, I welcome handing off the runtime; grounding consistency, though, is the one piece I still want to hold in my own hands.

Why an Agent Run Needs a Consistency Boundary

For a one-shot question, this problem never surfaces. Search, answer, done. It takes milliseconds, and the odds of a store mutating in that window are low.

An agent execution is different. It plans, searches several times, runs code partway through, then searches again. This whole sequence behaves like a single transaction, yet each intermediate search independently reaches for the latest store.

The result is inconsistency like this:

TimeAgent sideStore sideRead result
T0Run starts, searches doc-Adoc-A v1 (old)
T1doc-A updated to v2, v1 retired
T2Searches doc-A againdoc-A v2 (new)
T3Blends v1 and v2 into a conclusionContradictory artifact

In distributed-systems terms, this is a torn read. Without read consistency, the agent cannot notice that the premise of its own reasoning changed midway.

The key is not to solve this with full concurrency control. Freezing writes to the store while the agent runs is impractical — it would mean stopping the production app that is your revenue's front door. What you actually need is a mechanism that lets writes continue freely while the reader — the agent — keeps seeing "the world as it was the instant the run began."

Give Metadata a Version History

File Search lets you attach metadata to chunks and filter on it at query time. We repurpose that mechanism for versioning.

Each chunk carries two fields describing its validity window:

  • active_from: the logical time the chunk became active (a monotonically increasing integer epoch)
  • retired_at: the logical time it was invalidated. A large sentinel value (e.g., 9999999999) while still live.

An update is no longer an overwrite; it becomes "retire the old revision, add the new one." A delete is not a physical removal but a soft delete that sets retired_at to the current epoch. With this, the state at any past point can be reconstructed from a filter expression alone.

Use a logical counter that increments per write, not wall-clock time — clocks can go backward under skew. Stand up a single counter (a transactional Firestore increment, or an atomic KV add) as your one "version issuer."

# Version issuer: hands out a monotonically increasing epoch on each write.
# Assumes an atomic KV increment (Firestore / Redis / Durable Object all work).
 
def next_epoch(kv) -> int:
    # Atomic add. Returns a monotonic value with no duplicates under concurrency.
    return kv.incr("filesearch:epoch")
 
def now_epoch(kv) -> int:
    v = kv.get("filesearch:epoch")
    return int(v) if v is not None else 0

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 concrete implementation that pins an execution epoch so a single agent run always sees one consistent snapshot of search results
The write-side design that turns updates and deletes into soft deletes, with a cost estimate for when to prune
How to build drift detection and a fail-safe for when grounding shifts mid-run
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

Advanced2026-07-08
One File Search Store for Many Apps: Splitting Retrieval With customMetadata and Chunk Config
Put several apps' FAQs in a single Gemini File Search store and metadataFilter can silently return empty grounding, or answers get split across chunk boundaries. Here is the customMetadata design, the AIP-160 filter-syntax trap, and measured chunkingConfig tuning.
Advanced2026-05-31
The Day You Switch Gemini Embedding Models: Designing a Zero-Downtime Reindex
Upgrade your embedding model and every vector you ever stored becomes incompatible. Here is a dual-index design for re-embedding hundreds of thousands of vectors without downtime, complete with a resumable reindex job and a query-side abstraction layer.
Advanced2026-07-01
Getting Artifacts Out of a Managed Agents Sandbox Safely — Scoped Credentials and Egress Design
Gemini API Managed Agents run in a Google-hosted isolated sandbox. Here is the short-lived, least-privilege credential and egress-boundary design I use to return generated artifacts to my own repository safely.
📚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 →