Building with the API

Use Gemini API File Search (managed RAG)

3 min read

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:


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

Open the full interactive version (with copy buttons) ↗

← All guides