Documentation | Guava
DocumentQA
DocumentQA answers caller questions against documents using retrieval-augmented generation (RAG). It operates in one of two modes:
- Server mode (default): Documents are uploaded to the Guava server and questions are answered server-side. Intended for simple use cases with few documents.
- Local mode: Bring your own vector store and generation model for full control over the RAG pipeline. Guava provides ready-made backends for ChromaDB, LanceDB, pgvector, and Pinecone.
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()