Overview
This guide walks you through building a complete Retrieval-Augmented Generation (RAG) system step by step. By the end, your agent will answer questions using your own documents.
Prerequisites
Install the required dependencies:
uv pip install "upsonic[chroma,pdf-loader,embeddings]"
Complete Example
from upsonic import Agent, Task, KnowledgeBase
from upsonic.embeddings import OpenAIEmbedding, OpenAIEmbeddingConfig
from upsonic.vectordb import ChromaProvider, ChromaConfig, ConnectionConfig, Mode
from upsonic.loaders.pdf import PdfLoader
from upsonic.loaders.config import PdfLoaderConfig
# Step 1: Setup embedding provider
embedding = OpenAIEmbedding(OpenAIEmbeddingConfig(
model_name="text-embedding-3-small"
))
# Step 2: Setup vector database
vectordb = ChromaProvider(ChromaConfig(
collection_name="my_rag_kb",
vector_size=1536,
connection=ConnectionConfig(
mode=Mode.EMBEDDED,
db_path="./rag_database"
)
))
# Step 3: Setup PDF loader
loader = PdfLoader(PdfLoaderConfig())
# Step 4: Create knowledge base with documents
kb = KnowledgeBase(
sources=["document.pdf"],
embedding_provider=embedding,
vectordb=vectordb,
loaders=[loader]
)
# Step 5: Create agent and task
agent = Agent("anthropic/claude-sonnet-4-5")
task = Task(
description="What is the daily working hours policy described in the text?",
context=[kb]
)
# Step 6: Execute and get results
result = agent.do(task)
print(result)
Step-by-Step Breakdown
1. Embedding Provider
The embedding provider converts text into vector representations for semantic search. The vector_size in your vector database config must match the embedding model’s output dimension (1536 for text-embedding-3-small).
from upsonic.embeddings import OpenAIEmbedding, OpenAIEmbeddingConfig
embedding = OpenAIEmbedding(OpenAIEmbeddingConfig(
model_name="text-embedding-3-small"
))
2. Vector Database
The vector database stores embedded document chunks for fast similarity search. Choose any supported provider — this example uses Chroma in embedded mode.
from upsonic.vectordb import ChromaProvider, ChromaConfig, ConnectionConfig, Mode
vectordb = ChromaProvider(ChromaConfig(
collection_name="my_rag_kb",
vector_size=1536, # Must match embedding model dimension
connection=ConnectionConfig(
mode=Mode.EMBEDDED,
db_path="./rag_database"
)
))
3. Knowledge Base
KnowledgeBase orchestrates the entire pipeline: it loads documents, chunks text, generates embeddings, and stores them.
from upsonic import KnowledgeBase
from upsonic.loaders.pdf import PdfLoader
from upsonic.loaders.config import PdfLoaderConfig
loader = PdfLoader(PdfLoaderConfig())
kb = KnowledgeBase(
sources=["document.pdf"],
embedding_provider=embedding,
vectordb=vectordb,
loaders=[loader]
)
If you don’t specify loaders, KnowledgeBase auto-detects the appropriate loader based on file extension. Explicit loaders give you more control over parsing behavior.
4. Agent + Task
Pass the knowledge base as context to the Task. The agent automatically queries it for relevant chunks before generating a response.
from upsonic import Agent, Task
agent = Agent("anthropic/claude-sonnet-4-5")
task = Task(
description="What is the main topic?",
context=[kb]
)
result = agent.do(task)
What Happens Behind the Scenes
- Document Loading — KnowledgeBase detects the file type and loads the document
- Text Chunking — The document is split into smaller chunks optimized for retrieval
- Embedding Generation — Each chunk is converted to a vector embedding
- Vector Storage — Embeddings are stored in the vector database
- Query Processing — When the task runs, the description is embedded and matched against stored chunks
- Context Injection — The most relevant chunks are injected into the agent’s context
- Response Generation — The agent uses the retrieved context to generate an answer
Next Steps
- Examples — More patterns: async, streaming, multiple KBs, custom splitters
- Using as Tool — Let agents actively search the KB (instead of auto-injection)
- Vector Stores — Compare and choose the right vector database
- Query Control — Fine-tune when RAG context is injected