§15.21

Use Gemini API File Search (managed RAG)

Create a managed File Search store with the google-genai SDK, import a file, query it with the file_search tool, and read citations.

by published 21 Oct 2026 checked against docs 21 Oct 2026 3 min in Building with the API Markdown

On this page6 sections
  1. 1. Install google-genai and set GEMINI_API_KEY
  2. 2. Create a File Search store
  3. 3. Upload a file into the store and wait for indexing
  4. 4. Query with the file_search tool
  5. 5. Read the answer and its citations
  6. Verify it worked

File Search is Gemini’s managed RAG: you create a store, Google chunks and embeds your files, and a query retrieves the relevant passages automatically. It runs on the current google-genai SDK over the v1beta API. The OpenAI analog is file search; for a from-scratch version see minimal RAG in Python.

1. Install google-genai and set GEMINI_API_KEY

pip install -U google-genai

Installs the current SDK (the legacy google-generativeai package is different).

export GEMINI_API_KEY="AIza..."

The client reads this variable on its own.

2. Create a File Search store

from google import genai

client = genai.Client()  # reads GEMINI_API_KEY

store = client.file_search_stores.create(
    config={"display_name": "handbook", "embedding_model": "models/gemini-embedding-2"},
)

Creates an empty store; its store.name identifies it for uploads and queries.

3. Upload a file into the store and wait for indexing

import time

op = client.file_search_stores.upload_to_file_search_store(
    file="handbook.pdf",
    file_search_store_name=store.name,
    config={"display_name": "handbook.pdf"},
)
while not op.done:
    time.sleep(5)
    op = client.operations.get(op)

Uploads and indexes the file as a long-running operation you poll until done.

4. Query with the file_search tool

interaction = client.interactions.create(
    model="gemini-3.8-flash",
    input="What is the refund window?",
    tools=[{"type": "file_search", "file_search_store_names": [store.name]}],
)
print(interaction.output_text)

The file_search tool retrieves matching chunks and grounds the answer in them.

5. Read the answer and its citations

for step in interaction.steps:
    if step.type != "model_output":
        continue
    for block in step.content:
        for ann in getattr(block, "annotations", None) or []:
            if ann.type == "file_citation":
                print(ann.file_name, getattr(ann, "page_number", ""))

Citations arrive as file_citation annotations on the model_output text blocks, each naming the source file and page.

Stores persist until you delete them with client.file_search_stores.delete(name=store.name, config={'force': True}); raw uploaded files expire after 48 hours, but indexed data stays. Each document can be up to 100 MB, and you pay for embeddings at indexing time while storage and query-time embeddings are free. Confirm the current method names and model ids on the File Search docs.

Verify it worked

interaction.output_text should answer from the document, and at least one file_citation should name your file.

If it fails:

  • Empty or ungrounded answer — the operation had not finished; poll op.done before querying, indexing is not instant.
  • AttributeError on file_search_stores — your google-genai is too old; run pip install -U google-genai (image search needs 1.75.0+).
  • No citations in steps — you read output_text only; citations live in the model_output steps’ annotations, not the plain text.

Next: your first Gemini API request · glossary: RAG.

← All Building with the API plates · Search all guides

↑↓ move↵ openalt+↵ copy first command

Keyboard

⌘/ctrl+K or /
Search all guides
alt+↵
In search: copy the guide's first command
j / k
Move through a list of guides
c
On a guide: copy its first command
t
Toggle light / dark
?
This list