Documentation | Guava

DocumentQA

DocumentQA answers caller questions against documents using retrieval-augmented generation (RAG). It operates in one of two modes:

Constructor

from guava.helpers.rag import DocumentQA

DocumentQA(
    store=None,             # VectorStore for local mode; omit for server mode
    documents=None,         # str or list[str] — documents to index
    ids=None,               # list[str] — stable IDs for upsert/delete
    chunk_size=5000,        # max chars per chunk (local mode only)
    chunk_overlap=200,      # overlap between chunks (local mode only)
    instructions=None,      # system instruction override
    *,
    generation_model=None,  # GenerationModel (required for local mode)
    namespace=None,         # server-mode namespace for concurrent instances
)
Parameter Type Required Default Description
store `VectorStore None` No None
documents `list[str] str None` No
ids `list[str] None` No None
chunk_size int No 5000 Maximum characters per chunk (local mode only).
chunk_overlap int No 200 Overlap between consecutive chunks in characters (local mode only).
instructions `str None` No None
generation_model `GenerationModel None` Local mode None
namespace `str None` Server mode None

Methods

ask(question: str, k: int = 5) -> str — Retrieve relevant chunks and generate an answer. In server mode, k is ignored (the server uses full document context).

upsert_document(key: str, text: str) -> None — Add or replace a document by key. Stale chunks from a previously longer document are deleted automatically.

add_document(text: str) -> None — Add a document without specifying a key. In server mode, uses a content-derived key (SHA-256 hash).

delete_document(key: str) -> None — Delete a previously upserted document by key.

clear() -> None — Remove all documents from the store.

Available VectorStore Backends (Local Mode)

Class Import Install Default Embedding
ChromaVectorStore guava.helpers.chromadb pip install 'guava-sdk[chromadb]' Built-in all-MiniLM-L6-v2 (no API needed)
LanceDBStore guava.helpers.lancedb pip install 'guava-sdk[lancedb]' Required — pass an EmbeddingModel (GenAIEmbedding, OpenAIEmbedding, PineconeInferenceEmbedding, or a custom subclass)
PgVectorStore guava.helpers.pgvector pip install 'guava-sdk[pgvector]' Required — pass an EmbeddingModel (GenAIEmbedding, OpenAIEmbedding, PineconeInferenceEmbedding, or a custom subclass)
PineconeVectorStore guava.helpers.pinecone pip install 'guava-sdk[pinecone]' multilingual-e5-large via Pinecone Inference

Examples

from guava.helpers.rag import DocumentQA

# Server mode (default) — documents stored and queried on Guava's server
qa = DocumentQA(documents=[policy_text, faq_text], namespace="policy_faq")
answer = qa.ask("What is the deductible?")

# Server mode — multiple concurrent instances (use namespace to isolate)
dental = DocumentQA(documents=dental_docs, namespace="dental")
restaurant = DocumentQA(documents=restaurant_docs, namespace="restaurant")
dental.ask("What is the copay?")       # only searches dental docs
restaurant.ask("Do you have vegan options?")  # only searches restaurant docs

# Local mode — Gemini (guava-sdk[genai])
from google import genai
from guava.helpers.lancedb import LanceDBStore
from guava.helpers.genai import GenAIEmbedding, GenAIGeneration

client = genai.Client(vertexai=True, project="my-project", location="us-central1")
store = LanceDBStore("gs://my-bucket/lancedb", embedding_model=GenAIEmbedding(client=client))
qa = DocumentQA(store=store, generation_model=GenAIGeneration(client=client))
qa.upsert_document("policy", my_text)
answer = qa.ask("What is the deductible?")

# Local mode — OpenAI (guava-sdk[openai])
import openai
from guava.helpers.lancedb import LanceDBStore
from guava.helpers.openai import OpenAIEmbedding, OpenAIGeneration

openai_client = openai.OpenAI()  # or AzureOpenAI / custom base_url
store = LanceDBStore("./lancedb_data", embedding_model=OpenAIEmbedding(client=openai_client))
qa = DocumentQA(store=store, generation_model=OpenAIGeneration(client=openai_client))
qa.upsert_document("policy", my_text)
answer = qa.ask("What is the deductible?")

# Wiring into an Agent
import guava
from guava import Agent

agent = Agent(name="Support", organization="Acme Corp", purpose="Answer customer questions.")
document_qa = DocumentQA(documents=some_text)

@agent.on_question
def on_question(call: guava.Call, question: str) -> str:
    return document_qa.ask(question)

Incremental Document Management

Use ids to assign stable keys to documents at construction time, then use upsert_document, delete_document, and clear to manage documents without re-creating the DocumentQA instance.

from guava.helpers.rag import DocumentQA

# Load initial documents with stable IDs
qa = DocumentQA(
    documents=[policy_v1, faq_v1, terms_v1],
    ids=["policy", "faq", "terms"],
    namespace="insurance",
)

# Later: policy was updated — replace it in-place
qa.upsert_document("policy", policy_v2)

# Add a new document without a pre-assigned ID
qa.add_document(new_bulletin_text)

# Remove a document that's no longer relevant
qa.delete_document("terms")

# Wipe everything and start fresh
qa.clear()