Skip to main content
Source Code: src/gaia/rag/sdk.py
Detailed Spec: spec/rag-sdk
What You’ll Learn: What RAG is and why you need it, how documents become searchable through chunking and embeddings, how to configure RAG for different use cases, how to tune parameters for quality vs. speed, what Agentic RAG is and how it differs from traditional RAG, how to implement multi-step retrieval patterns, and common pitfalls and how to avoid them.

The Problem RAG Solves

LLMs have a knowledge cutoff—they don’t know about your company’s documents, your project’s codebase, or yesterday’s meeting notes.
The LLM can only say it doesn’t know.
RAG stands for Retrieval-Augmented Generation:
  • Retrieval → Find relevant information from your documents
  • Augmented → Add that information to the LLM’s context
  • Generation → LLM generates an answer using your documents
Supported document formats: PDF, Word (.docx), PowerPoint (.pptx), Excel (.xlsx), EPUB e-books (.epub, DRM-free), plus plain text, Markdown, CSV, JSON, HTML, and common source code files. Legacy binary Office formats (.doc, .ppt, .xls) and OpenDocument files (.odt, .ods, .odp) are not supported — re-save them as .docx / .pptx / .xlsx or PDF. Any other binary file is refused with an error rather than indexed as text.

How RAG Works: A Mental Model

Think of RAG as a smart research assistant:

Phase 1: Preparation (Indexing)

This happens once when you index documents:

Phase 2: Query (Retrieval)

This happens each time you ask a question:
Key Insight: The magic is in the vectors. Text that has similar meaning ends up with similar vectors—even if the words are different. “System requirements” and “hardware needed” would have similar vectors because they mean similar things.

Getting Started with RAG

Quick RAG: One-Line Document Q&A

For simple use cases, quick_rag handles everything in one call:
What happens behind the scenes:
  1. Extracts text from the PDF
  2. Splits into chunks (default: 500 tokens each)
  3. Generates embeddings for all chunks. A short, empty, or dimensionally inconsistent batch is retried under the existing two-retry policy, then fails indexing if still invalid with an actionable error; partial vectors are never paired with different chunks.
  4. Creates temporary FAISS index
  5. Searches for relevant chunks
  6. Sends chunks + question to LLM
  7. Returns the generated answer as a string
Best for: Quick exploration, one-off questions, prototyping

RAG SDK: Persistent Index

For applications where you’ll ask multiple questions, create a persistent RAG instance:
Key advantage: Documents are indexed once, then you can query as many times as you want without re-processing. Check the success field returned by index_document(). A failed cache write leaves the searchable index unchanged, so retrying does not duplicate chunks. Use reindex_document(path) after changing a document; if replacement fails, the previously indexed version remains available for queries. Embedding dominates indexing time, so a thousand-page PDF on a CPU embedder takes minutes. Pass progress_callback=lambda done, total: ... to index_document() to follow it; the callback fires as embedding starts and every 250 chunks. Queries over other documents keep working while it runs.

Understanding Chunks

Chunking is the most important concept in RAG. Let’s understand it deeply.

Why Do We Need Chunks?

LLMs have limited context windows. You can’t send a 500-page PDF directly. Instead:

What is chunk_size?

chunk_size controls how many tokens (roughly 3/4 of a word) go into each chunk:
500 is the ceiling. The embedder reads at most 2,048 tokens per chunk, and a number-heavy table can take one token per character, so no chunk is cut longer than 2,000 characters (EMBED_MAX_CHARS in gaia.rag.sdk). That way every word of every chunk is searchable. A larger chunk_size logs a warning at startup and its chunks are capped at 2,000 characters. To give the model more context per answer, raise max_chunks instead.
Trade-offs:

Small Chunks (256)

Pros: Precise matching, less noise in results, faster embedding.Cons: May miss surrounding context, more chunks to search, fragmented information.

Large Chunks (500)

Pros: More context preserved, fewer chunks overall, complete ideas captured.Cons: Less precise matching, more irrelevant text included, slower embedding.

What is chunk_overlap?

Overlap ensures information isn’t lost at chunk boundaries:
Rule of thumb: Set chunk_overlap to 10-20% of chunk_size:
  • chunk_size=256 → chunk_overlap=25-50
  • chunk_size=500 → chunk_overlap=50-100

Configuration Deep Dive

Here’s the full RAGConfig with explanations:
The default embedder is user.embeddinggemma-300m-GGUF (EmbeddingGemma 300M, 768-dim). The on-disk cache under cache_dir stores only extracted document text and chunks, never vectors: vectors are regenerated via Lemonade on every index, so changing embedding_model needs no cache clearing. A cache entry is keyed on the file’s path and content plus chunk_size, chunk_overlap, use_llm_chunking and the embedder’s input limit, so changing any of those re-indexes the document instead of reusing chunks cut to the old settings.

Tuning max_chunks

max_chunks controls how many chunks are sent to the LLM: Visualization:

RAG Response Object

When you query, you get back a rich response object:

Interpreting Relevance Scores


Beyond Basic RAG: Agentic RAG

Traditional RAG follows a simple pattern: one question → one search → one answer. But real-world information needs are rarely that simple. Agentic RAG adds intelligent reasoning to the retrieval process, allowing the agent to:
  • Make multiple retrieval calls when needed
  • Refine queries based on initial results
  • Combine information from multiple documents
  • Know when it has enough information to answer
  • Recognize when documents don’t contain the answer

Traditional RAG vs. Agentic RAG

How it works: User asks a question, system searches once for relevant chunks, top chunks are sent to LLM, LLM generates answer from those chunks.Limitations: If initial search misses relevant info it’s gone, can’t handle multi-part questions, no ability to refine or dig deeper, doesn’t know when it lacks information.

When Agentic RAG Shines

The Agentic RAG Mental Model

Think of the difference like this: Traditional RAG = A librarian who:
  • Takes your question
  • Goes to one shelf
  • Grabs the first 5 books that seem related
  • Hands them to you
Agentic RAG = A research assistant who:
  • Discusses your question to understand what you really need
  • Searches multiple sections of the library
  • Evaluates if the books actually answer your question
  • Goes back for more if needed
  • Tells you honestly if the library doesn’t have what you need
  • Synthesizes findings into a coherent answer

How GAIA Implements Agentic RAG

GAIA’s agents use RAG as a tool, not just a pipeline. This is the key architectural difference:
What happens under the hood:

The RAG Tool Interface

When RAG is used as an agent tool, the LLM can make intelligent decisions:

Multi-Step Retrieval Example

Here’s how an agent handles a complex question: Question: “What were our top 3 product launches this year and how did each perform?” Traditional RAG would:
  1. Search “top product launches performance”
  2. Return 5 random chunks about products
  3. Generate a potentially incomplete answer
Agentic RAG does:

Implementing Agentic RAG Patterns

When initial results are insufficient, refine and search again:
For questions with multiple parts, search each aspect:
Usage by agent:
Always check confidence before making claims:
Verify information appears in multiple sources:

When to Use Each Approach

Key Takeaways: Agentic RAG

RAG as a Tool, Not Pipeline

In Agentic RAG, retrieval is a tool the agent chooses to use—not a fixed pipeline.

Multiple Searches Are Normal

Complex questions often need 3-5 searches to gather complete information.

Confidence Matters

Agents should check relevance scores and admit when documents don’t have the answer.

Synthesis Over Retrieval

The agent’s job is to synthesize information, not just return search results.

Tuning RAG for Your Use Case

FAQs are short, focused questions with direct answers:
Why these settings:
  • Small chunks match FAQ Q&A pairs precisely
  • Low max_chunks prevents mixing unrelated FAQs
  • Focused answers are better for support
Academic papers need more context to understand concepts:
Why these settings:
  • The largest chunks keep a methodology paragraph together
  • High overlap preserves logical flow
  • More chunks bring in the surrounding argument
Code docs mix short references with detailed explanations:
Why these settings:
  • Medium chunks handle both code and prose
  • More chunks show multiple code examples
  • Balanced for API reference + tutorials

Security: Restricting Document Access

RAG can be restricted to specific directories for security:
An agent that already has a PathValidator passes it in, RAGSDK(config, path_validator=validator), so a path the user grants mid-session is readable to indexing too. Without it the SDK builds its own validator from allowed_paths.
Security Consideration: Without allowed_paths, RAG can index any file the process can read. In production, always set explicit allowed paths — and set them to the files you mean, not the directories they sit in, since a directory grant covers everything else in it.allowed_paths is a scope, not a safety guarantee: it says which paths are in bounds, not which are safe. The agent’s file tools apply separate denylists on top (secrets on read, login-execution files on write), and the agent’s index_document / index_directory tools apply them too. Calling RAGSDK.index_document directly checks the scope only.

Common Pitfalls and Solutions

Symptom: Asking about weather, but RAG returns technical documentation.Cause: RAG always retrieves the “most similar” chunks, even if similarity is low.Solutions:
Symptom: Answer is technically correct but missing important details.Cause: Chunks are too small, cutting off important context.Solutions:
Symptom: Indexing 100 documents takes 30+ minutes.Cause: Embedding generation is CPU/GPU intensive.Solutions:
Symptom: Python crashes or hangs when indexing large PDFs.Cause: Large documents create many chunks that consume memory.Solutions:

Practice Challenge

Build a Document Q&A System

Create a RAG system that: (1) Indexes multiple PDF documents, (2) Answers questions with source citations, (3) Indicates confidence based on relevance scores, (4) Handles missing information gracefully.Requirements: Configure appropriate chunk size for your documents, include relevance score checking, show which documents the answer came from.
Use response.source_files for citations. Check response.chunk_scores[0] for confidence. Use a threshold (e.g., 0.6) to detect unreliable answers.
Why this solution works:
  1. Confidence scoring: Users know when to trust the answer
  2. Citations: Users can verify information
  3. Graceful handling: Low confidence triggers a warning instead of wrong answer
  4. Configurable: Chunk settings can be adjusted for document types
  5. Statistics: Helps monitor and debug the system

Deep Dive: How Vector Similarity Works

What are embeddings?Embeddings convert text into vectors (lists of numbers) where similar meanings are close together:
How similarity is calculated:FAISS uses cosine similarity—measuring the angle between vectors:
Why this works for search:When you ask “What are the hardware specs?”, it becomes a vector that’s mathematically close to chunks about “system requirements”, “hardware needed”, “computer specifications”, etc.—even if none of those exact words appear in your question!

Key Takeaways

RAG = Search + Generate

Find relevant chunks from your documents, then use LLM to synthesize an answer.

Chunks are Everything

How you split documents determines what RAG can find. Tune chunk_size for your use case.

Check Confidence

Use chunk_scores to know when answers are reliable vs. when documents don’t have the info.

Index Once, Query Many

Use RAGSDK for applications—documents are indexed once, then queried unlimited times.

Next Steps

Agent SDK

Combine RAG with conversational memory

Security

Path validation and security best practices

Examples

Complete document Q&A examples