End-to-End: Document Q&A Mini Project
Harry
· 13 Sep 2026
· 1 views
The RAG Pipeline
Retrieval-Augmented Generation (RAG) answers questions using your own documents: chunk, embed, store, retrieve, and let the model answer from the retrieved text.
Step 1 - Prepare Chunks
documents = [
"GroovyGrails teaches Java from zero to advanced.",
"Spring Boot makes Java web apps fast to build.",
"Groovy is a JVM language that pairs with Java.",
"Vector databases power retrieval in AI assistants.",
]
chunks = [documents[i:i] for i in range(len(documents))]Step 2 - Embed and Store
from sentence_transformers import SentenceTransformer
import chromadb
model = SentenceTransformer("all-MiniLM-L6-v2")
client = chromadb.PersistentClient(path="kb")
kb = client.get_or_create_collection("kb", metadata={"hnsw:space": "cosine"})
kb.add(
ids=[f"c{i}" for i in range(len(chunks))],
documents=chunks,
)Step 3 - Retrieve
query = "Which framework builds Java web apps quickly?"
hits = kb.query(query_texts=[query], n_results=2)
context = " | ".join(hits["documents"][0])
print(context)Step 4 - Generate the Answer
prompt = f"Answer using only the notes below.
{context}
Question: {query}"
# result = call_your_llm(prompt) # plug in your model or API key
# print(result)The model receives only the retrieved notes, so answers stay grounded in your content.
Improving the Project
- Use overlapping chunks of a few hundred characters.
- Add metadata such as source titles and dates.
- Return more chunks and rerank them before generation.
- Ask the model to cite the chunk it based each part on.
Key Points
- RAG = chunk, embed, retrieve, generate.
- Retrieved context keeps answers grounded.
- Persist the knowledge base so you build once and reuse.
- Reranking and chunk tuning raise answer quality.