RAG Basics
10 examples to get you started with AI Agents & RAG - 7 basic and 3 intermediate.
Search across all documentation pages
10 examples to get you started with AI Agents & RAG - 7 basic and 3 intermediate.
uv venv && source .venv/bin/activate
uv pip install "openai>=1.60" "chromadb>=0.5" "tiktoken>=0.8"
export OPENAI_API_KEY="sk-..."Split long text into retrieval-sized pieces.
def chunk_text(text: str, size: int = 500, overlap: int = 50) -> list[str]:
chunks = []
start = 0
while start < len(text):
chunks.append(text[start:start + size])
start += size - overlap
return chunksRelated: Chunking & Ingestion
Create vectors and save to a collection.
import chromadb
from openai import OpenAI
client = OpenAI()
chroma = chromadb.Client()
collection = chroma.create_collection("docs")
texts = ["FastAPI is a Python web framework.", "pytest runs Python tests."]
emb = client.embeddings.create(model="text-embedding-3-small", input=texts)
collection.add(ids=["1","2"], documents=texts, embeddings=[e.embedding for e in emb.data])Query by semantic similarity.
query = "How do I test Python?"
q_emb = client.embeddings.create(model="text-embedding-3-small", input=[query])
results = collection.query(query_embeddings=[q_emb.data[0].embedding], n_results=2)
print(results["documents"])Inject retrieved context into the LLM prompt.
context = "\n".join(results["documents"][0])
prompt = f"Answer using ONLY this context:\n{context}\n\nQuestion: {query}"Send grounded prompt to the LLM.
response = client.chat.completions.create(
model="gpt-4o-mini",
messages=[{"role": "user", "content": prompt}],
temperature=0,
)
print(response.choices[0].message.content)Combine retrieve + generate.
def rag_answer(query: str, collection, k: int = 3) -> str:
q_emb = client.embeddings.create(model="text-embedding-3-small", input=[query])
hits = collection.query(query_embeddings=[q_emb.data[0].embedding], n_results=k)
context = "\n---\n".join(hits["documents"][0])
resp = client.chat.completions.create(
model="gpt-4o-mini",
messages=[
{"role": "system", "content": "Answer from context only. Say 'I don't know' if not found."},
{"role": "user", "content": f"Context:\n{context}\n\nQuestion: {query}"},
],
temperature=0,
)
return resp.choices[0].message.content or ""Include chunk IDs in the response.
for i, (doc, meta) in enumerate(zip(hits["documents"][0], hits["metadatas"][0])):
print(f"[{i+1}] {doc[:80]}...")Filter retrieval by document type or date.
collection.query(
query_embeddings=[q_emb.data[0].embedding],
n_results=3,
where={"source": "docs"},
)Combine keyword and semantic scores.
Check if the right chunk appears in top-k.
def recall_at_k(query: str, expected_text: str, k: int = 5) -> bool:
hits = collection.query(query_embeddings=[embed(query)], n_results=k)
return any(expected_text in doc for doc in hits["documents"][0])Stack versions: This page was written for Python 3.14.0 (stable 3.14, maintenance 3.13), FastAPI 0.115+, Django 5.2, Flask 3.1, Pydantic 2, PyTorch 2.6+, pandas 2.2+, Polars 1.x, ruff 0.9+, and uv 0.6+.
Reviewed by Chris St. John·Last updated Jul 16, 2026