Module 8: Capstone RAG Project with ChromaDB
Capsule 08: Project - Production-Ready RAG
Capsule description
You've reached the guide's closure: deliver a complete RAG system, evaluated and deployable. This capsule consolidates everything built in the previous capsules and guides you step by step to integrate each piece into a portfolio-quality project.
Upon completing this capsule you'll have:
- A RAG system with 1,000+ documents indexed in ChromaDB
- A FastAPI API with
/ingest,/search,/ask,/health,/metricsendpoints - A Docker deployment with
docker-compose(rag-api + chromadb-server) - A test suite (unit, integration, performance, accuracy)
- Observability (Prometheus, structured logging)
- A README with architecture, API reference, and deployment guide
And most importantly: a solid base for Guide #8 (Advanced RAG Techniques), where you'll migrate to Pinecone, add re-ranking, and evaluate your RAG systematically.
Mandatory Deliverables
| # | Deliverable | Verification |
|---|---|---|
| 1 | System code (ingestion, retrieval, generation, API) | docker-compose up works |
| 2 | Docker configuration (Dockerfile, docker-compose.yml) | One command brings everything up |
| 3 | Test set and evaluation results | Accuracy report in metrics-report.md |
| 4 | Technical decisions document | DECISIONS.md or a section in the README |
| 5 | Production readiness checklist | Table in the README or a separate file |
Final Project Structure
rag-project/
├── app/
│ ├── __init__.py
│ ├── main.py # FastAPI app, routers
│ ├── config.py # Settings, env vars
│ ├── api/
│ │ ├── routes/
│ │ │ ├── ingest.py
│ │ │ ├── search.py
│ │ │ ├── ask.py
│ │ │ └── health.py
│ │ └── deps.py # Dependencies (ChromaDB client, etc.)
│ ├── ingestion/
│ │ ├── chunking.py
│ │ ├── pipeline.py
│ │ └── loaders.py
│ ├── retrieval/
│ │ ├── retriever.py
│ │ └── filters.py
│ ├── generation/
│ │ └── generator.py
│ ├── cache/
│ │ ├── embedding_cache.py
│ │ └── result_cache.py
│ ├── metrics.py # Prometheus
│ └── logging_config.py
├── tests/
│ ├── conftest.py
│ ├── unit/
│ ├── integration/
│ ├── performance/
│ └── evaluation/
│ └── golden_set.json
├── scripts/
│ ├── ingest_sample_docs.py # Generate 1000+ test docs
│ └── run_evaluation.py
├── docker-compose.yml
├── Dockerfile
├── requirements.txt
├── requirements-dev.txt
├── .env.example
├── README.md
├── DEPLOYMENT.md
├── CHANGELOG.md
└── metrics-report.md
Step-by-Step Integration Guide
Step 1: Initial setup (5 min)
mkdir -p rag-project/app/{api,ingestion,retrieval,generation,cache}
mkdir -p rag-project/tests/{unit,integration,performance,evaluation}
cd rag-project
Create requirements.txt:
fastapi>=0.104.0
uvicorn[standard]>=0.24.0
chromadb>=0.4.0
openai>=1.0.0
httpx>=0.24.0
pydantic-settings>=2.0.0
prometheus-client>=0.19.0
tenacity>=8.2.0
python-dotenv>=1.0.0
Step 2: Configuration (10 min)
# app/config.py
import os
from pydantic_settings import BaseSettings
class Settings(BaseSettings):
chroma_host: str = os.getenv("CHROMA_HOST", "localhost")
chroma_port: int = int(os.getenv("CHROMA_PORT", "8001"))
chroma_collection: str = os.getenv("CHROMA_COLLECTION", "rag_docs")
openai_api_key: str = os.getenv("OPENAI_API_KEY", "")
chunk_size: int = 512
chunk_overlap: int = 64
top_k: int = 5
class Config:
env_file = ".env"
settings = Settings()
Step 3: Ingestion pipeline (15 min)
Implement app/ingestion/chunking.py, pipeline.py, and loaders.py following Capsule 03. The pipeline must:
- Load documents (or generate 1000+ test ones)
- Chunk with
chunk_size=512,overlap=64 - Generate embeddings with OpenAI
- Insert into ChromaDB with stable IDs
Step 4: Retrieval and Generation (15 min)
Implement app/retrieval/retriever.py and app/generation/generator.py following Capsule 04. The contract:
retrieve(question, collection, top_k=5)→ documents + metadatasgenerate_answer(question, docs)→ answer + sources
Step 5: FastAPI API (15 min)
# app/main.py
from fastapi import FastAPI
from app.api.routes import ingest, search, ask, health
from app.metrics import setup_metrics
app = FastAPI(title="RAG API", version="1.0.0")
app.include_router(health.router, tags=["health"])
app.include_router(ingest.router, prefix="/ingest", tags=["ingest"])
app.include_router(search.router, prefix="/search", tags=["search"])
app.include_router(ask.router, prefix="/ask", tags=["ask"])
setup_metrics(app)
Step 6: Docker and docker-compose (10 min)
Copy the Dockerfile and docker-compose.yml from Capsule 06. Adjust paths if your structure differs.
Step 7: Tests (20 min)
Copy the test structure from Capsule 05. Make sure you have:
- Unit: chunking, filters
- Integration:
/health,/search,/ask - Performance: p95 < 2s, throughput > 20 QPS
- Accuracy: golden set > 90%
Step 8: Hardening (15 min)
Apply what's in Capsule 07:
- Retries for ChromaDB and OpenAI
- Fallbacks in
/ask - Rate limiting
- README and DEPLOYMENT.md
Step 9: Final evaluation (10 min)
Run:
docker-compose up -d
pytest tests/ -v --tb=short
python scripts/run_evaluation.py
Generate metrics-report.md with the results.
Complete Integration Code (Summary)
app/main.py (skeleton)
from fastapi import FastAPI
from app.config import settings
from app.api.routes import health, search, ask, ingest
app = FastAPI(title="RAG API", version="1.0.0", docs_url="/docs")
app.include_router(health.router)
app.include_router(search.router, prefix="/search")
app.include_router(ask.router, prefix="/ask")
app.include_router(ingest.router, prefix="/ingest")
app/api/routes/ask.py (complete example)
from fastapi import APIRouter, HTTPException, Depends
from pydantic import BaseModel, Field
from app.retrieval.retriever import retrieve
from app.generation.generator import generate_answer
from app.config import settings
from app.deps import get_collection
router = APIRouter()
class AskPayload(BaseModel):
question: str = Field(..., min_length=1, max_length=500)
@router.post("")
async def ask_endpoint(payload: AskPayload, collection=Depends(get_collection)):
docs = await retrieve(payload.question, collection, top_k=settings.top_k)
if not docs or not docs.get("documents") or not docs["documents"][0]:
return {"answer": "I didn't find enough information.", "sources": [], "confidence": 0}
answer = await generate_answer(payload.question, docs["documents"][0])
return {
"answer": answer,
"sources": docs.get("metadatas", [[]])[0],
"confidence": 0.85,
}
Suggested Approval Criteria
| Criterion | Threshold |
|---|---|
| Accuracy on the golden set | ≥ 85% (90% target) |
p95 latency /ask | < 2.5s (2s target) |
Throughput /search | ≥ 20 QPS |
| Main endpoints | /health, /search, /ask operational |
| Failure recovery | Fallbacks manually validated |
| Observability | Structured logs, /metrics accessible |
Recommended Closing Rubric
| Area | Criterion | Status |
|---|---|---|
| Functionality | Ingestion, search, and ask operational | ⬜ |
| Quality | Accuracy and errors within threshold | ⬜ |
| Operations | Observability and minimal runbooks | ⬜ |
| Resilience | Fallbacks and documented rollback | ⬜ |
| Security | Auth + rate limiting + validation | ⬜ |
| Documentation | README, API reference, deployment | ⬜ |
Example Project Result
## RAG Project Result
- **Accuracy:** 0.87 (threshold 0.85) ✅
- **p95 /ask:** 1.9s (threshold 2.5s) ✅
- **Throughput:** 24 QPS (target 20) ✅
- **Error rate:** 0.6% (threshold 1%) ✅
- **Final status:** Approved for controlled pilot
### Open risks
- Dependence on the LLM provider for traffic spikes
- Missing 10x traffic load test
### Next iteration
- Semantic caching of results
- Per-tenant observability improvements
What You Learned Throughout the Guide
Upon completing the 8 modules of the Vector Databases Fundamentals guide, you can now:
-
Explain why RAG needs vector databases — SQL/NoSQL don't scale for similarity search; numpy doesn't manage millions of vectors in memory.
-
Understand the internal architecture — indexing layer (HNSW, IVF), query engine, storage. You know what M and efConstruction do, and when they matter.
-
Master ChromaDB — local setup, vector CRUD, metadata filtering, batch ingestion, persistence. You built a system that indexes 1,000+ documents.
-
Compare the landscape — Pinecone, Weaviate, Qdrant, Milvus. You know managed vs self-hosted, pricing, and when to migrate.
-
Decide which DB to use — You applied a decision framework (cost, scale, features) to choose technology.
-
Prepare RAG for production — scaling, backups, monitoring, migrations, cost optimization.
-
Build a complete RAG system — ingestion → ChromaDB → retrieval → generation → REST API, with Docker, tests, observability, and hardening.
What's missing (and comes in Guide #8):
- ChromaDB → Pinecone migration (managed cloud)
- Re-ranking with cross-encoders
- Query optimization (expansion, rewriting)
- Advanced chunking (recursive, semantic)
- Systematic RAG evaluation (retrieval + generation metrics)
Completeness Checklist
Check each item as you complete it:
Functionality
- Ingestion pipeline processes 1,000+ documents
- ChromaDB persists data in a volume
-
/searchreturns results with scores and metadata -
/askgenerates answers with sources -
/ingestaccepts documents via API or script
Quality
- Accuracy ≥ 85% on the golden set
- p95 latency
/ask< 2.5s - Error rate < 1%
Operations
- Docker Compose brings everything up with one command
-
/healthverifies ChromaDB -
/metricsexposes Prometheus - Structured logs (JSON) with a trace_id
Resilience
- Retries on ChromaDB and OpenAI
- Fallbacks when retrieval or generation fail
- Documented rollback plan
Security
- Optional API key in headers
- Rate limiting on
/ask - Input validation (Pydantic)
Documentation
- README with architecture, setup, API reference
- DEPLOYMENT.md with instructions
- CHANGELOG with relevant decisions
- metrics-report.md with evaluation results
Connection with Guide #8 (Advanced RAG Techniques)
This project is the direct base for Guide #8. It's not throwaway code: it's the foundation that evolves.
In Guide #8 you'll do:
| Transformation | Description |
|---|---|
| ChromaDB → Pinecone | Migration to a managed vector DB in the cloud |
| Retrieval + Re-ranking | Cross-encoders to improve top-k precision |
| Query optimization | Expansion, rewriting, decomposition |
| Advanced chunking | Recursive, semantic chunking |
| RAG evaluation | Retrieval metrics (MRR, recall) + generation (faithfulness, relevance) |
Prerequisites for Guide #8:
- Stable, versioned project base (Git)
- Minimal pilot metrics recorded
- Improvements list prioritized by impact
- Preliminary decision on migration (whether Pinecone fits your case)
Project Exercises with Detailed Solutions
Exercise 1: Ingestion script for 1,000 synthetic documents
Goal: Create scripts/ingest_sample_docs.py that generates 1,000 simulated Wikipedia documents and indexes them in ChromaDB.
Solution:
# scripts/ingest_sample_docs.py
import chromadb
from chromadb.utils import embedding_functions
import os
categories = ["science", "history", "technology", "arts", "sports"]
ef = embedding_functions.OpenAIEmbeddingFunction(api_key=os.getenv("OPENAI_API_KEY"))
client = chromadb.PersistentClient(path="./chroma_data")
collection = client.get_or_create_collection("rag_docs", embedding_function=ef)
docs, metadatas, ids = [], [], []
for i in range(1000):
cat = categories[i % len(categories)]
text = f"Article about {cat} topic {i}. This document contains information relevant to {cat}."
docs.append(text)
metadatas.append({"category": cat, "doc_id": i})
ids.append(f"doc_{i}")
batch_size = 100
for i in range(0, len(docs), batch_size):
collection.add(documents=docs[i:i+batch_size], metadatas=metadatas[i:i+batch_size], ids=ids[i:i+batch_size])
print(f"Ingested {min(i+batch_size, len(docs))}/{len(docs)}")
print(f"Done. Total: {collection.count()} documents")
Exercise 2: Generate metrics-report.md automatically
Goal: A script that runs the evaluation and writes metrics-report.md with a results table.
Solution:
# scripts/run_evaluation.py
import httpx
import time
import json
def run_eval():
base = "http://localhost:8000"
latencies = []
for _ in range(50):
s = time.perf_counter()
r = httpx.post(f"{base}/ask", json={"question": "What is RAG?"}, timeout=10)
latencies.append(time.perf_counter() - s)
latencies.sort()
p95 = latencies[int(0.95 * len(latencies))]
# Accuracy: assume the golden set in tests; simplified here
report = f"""# Metrics Report
| Metric | Value | Threshold | Status |
|---------|-------|--------|--------|
| p95 /ask | {p95:.2f}s | <2.5s | {'✅' if p95 < 2.5 else '❌'} |
"""
with open("metrics-report.md", "w") as f:
f.write(report)
print(report)
if __name__ == "__main__":
run_eval()
Exercise 3: README with an architecture diagram
Goal: A complete README with an ASCII or Mermaid diagram, setup in 5 steps, and an API table.
Solution:
# RAG API with ChromaDB
Production-ready RAG system: 1,000+ docs, FastAPI, Docker, tests.
## Architecture
\`\`\`
┌─────────┐ ┌──────────┐ ┌─────────┐ ┌───────────┐ ┌────────┐
│Documents│──▶│ Chunking │──▶│Embeddings│──▶│ ChromaDB │──▶│Retrieval│
└─────────┘ └──────────┘ └─────────┘ └───────────┘ └────┬────┘
│
┌─────────┐ ┌──────────┐ ┌─────────┐ │
│ Response │◀──│ LLM │◀──│ Context │◀───────────────────────┘
└─────────┘ └──────────┘ └─────────┘
\`\`\`
## Setup (5 steps)
1. Clone: \`git clone <repo>\`
2. Copy env: \`cp .env.example .env\` and add \`OPENAI_API_KEY\`
3. Build: \`docker-compose build\`
4. Up: \`docker-compose up -d\`
5. Test: \`curl http://localhost:8000/health\`
## API Reference
| Endpoint | Method | Description |
|----------|--------|-------------|
| /health | GET | Health + ChromaDB status |
| /search?q=&top_k=5 | GET | Semantic search |
| /ask | POST | {\"question\": \"...\"} |
| /ingest | POST | Batch ingestion |
| /metrics | GET | Prometheus |
Project Troubleshooting Guide
| Symptom | Probable cause | Action |
|---|---|---|
/health returns 503 | ChromaDB unreachable | Verify chromadb is up in docker-compose; check CHROMA_HOST |
/ask takes >10s | LLM timeout or slow embeddings | Check OPENAI_API_KEY; reduce top_k |
| Accuracy < 85% | Inadequate chunking or poor corpus | Adjust chunk_size/overlap; expand the golden set |
| Docker build fails | Dependencies or memory | docker system prune; increase memory for Docker |
| Integration tests fail | API not running | docker-compose up -d before pytest |
| ChromaDB empty after restart | Non-persistent volume | Verify the volume is in docker-compose and docker-compose down -v is not used |
Technical Decisions to Document (DECISIONS.md)
Include in your project a DECISIONS.md file with:
- Why ChromaDB: Free, local, sufficient for 1K-10K docs; migration to Pinecone planned for scale.
- Chunk size 512: Balance between context and granularity; validated with recall on the golden set.
- top_k = 5: Sufficient for most questions; acceptable latency.
- Embedding model: text-embedding-3-small for cost/quality for the MVP.
- LLM: GPT-3.5-turbo for generation; GPT-4 optional for complex cases.
- No Redis initially: In-memory cache for development; Redis in the next iteration.
Example CHANGELOG.md
# Changelog
## [1.0.0] - 2026-03-13
### Added
- Ingestion pipeline for 1,000+ documents
- Endpoints /health, /search, /ask, /ingest
- Docker deployment with docker-compose
- Test suite (unit, integration, performance, accuracy)
- Prometheus metrics and structured logging
- Retry logic and fallbacks for ChromaDB and OpenAI
- Rate limiting and input validation
### Decisions
- ChromaDB as the initial vector store (migration to Pinecone in Guide #8)
- chunk_size=512, overlap=64
- Thresholds: accuracy ≥85%, p95 <2.5s
Portfolio Quality Criteria
Your project is ready for a portfolio if:
- A recruiter can clone and run it in < 5 minutes
- The README clearly explains what it does and how to use it
- There is evidence of tests (badge or mention in the README)
- The code is organized with minimal types/documentation
- There are documented technical decisions
- You explicitly connect to "next step: Guide #8"
Pre-Delivery Verification Script
Run before marking the project as completed:
#!/bin/bash
# scripts/pre_submit_check.sh
set -e
echo "1. Docker Compose..."
docker-compose up -d
sleep 10
echo "2. Health check..."
curl -sf http://localhost:8000/health | jq .
echo "3. Search..."
curl -sf "http://localhost:8000/search?q=vector&top_k=3" | jq '.documents | length'
echo "4. Ask..."
curl -sf -X POST http://localhost:8000/ask \
-H "Content-Type: application/json" \
-d '{"question":"What is RAG?"}' | jq '.answer, .sources'
echo "5. Metrics..."
curl -sf http://localhost:8000/metrics | head -20
echo "6. Tests..."
pytest tests/ -v --tb=short -x
echo "✅ Pre-submit check passed"
docker-compose down
Integration with Previous Capsules
| Capsule | What it contributes to this project |
|---|---|
| 01-02 | Architecture and flow diagram |
| 03 | Ingestion pipeline, chunking, batch |
| 04 | Retrieval, generation, API contract |
| 05 | Fixtures, unit/integration/performance/accuracy tests |
| 06 | Dockerfile, docker-compose, Prometheus, logs |
| 07 | Retries, fallbacks, rate limit, README |
| 08 | Full integration and closing checklist |
Recommended Delivery Format
Minimal structure to share (GitHub, portfolio):
project/
├── app/
├── tests/
├── scripts/
├── docker-compose.yml
├── Dockerfile
├── README.md # Architecture, setup, API, troubleshooting
├── DEPLOYMENT.md # Staging, production, rollback
├── CHANGELOG.md # Decisions and versions
├── metrics-report.md # Final metrics table
└── .env.example
Closing Troubleshooting
"We met functionality, failed on operations"
Don't close the project until you cover the minimums of observability and resilience. A system without health checks or fallbacks is not production-ready.
"Correct metrics on the test set, not on real traffic"
Incorporate real feedback (logs of failed questions) and recalibrate thresholds. The golden set is an approximation; real traffic can reveal edge cases.
"The team wants to move to the next guide already"
Close the critical hardening debt first. Migrating to Pinecone with a fragile system will drag problems along, multiplied.
"We don't have 1,000 real documents"
Use the synthetic documents script from Exercise 1. The goal is to validate that the pipeline scales; the content can be simulated.
"Docker build fails due to memory"
Reduce batch_size in ingestion or use a machine with more RAM for the build. In CI, consider building on a remote server.
Suggested Next Steps
- Define an improvements backlog — Top 5 prioritized by impact (e.g. caching, re-ranking, more documents).
- Prioritize retrieval evaluation — Recall@k, MRR with human or LLM-as-judge judgments.
- Prepare the transition to Guide #8 — Review the prerequisites, have a Pinecone API key if applicable.
Summary
- You completed the capstone project of the Vector Databases Fundamentals guide.
- You have a RAG system with ChromaDB, FastAPI, Docker, tests, observability, and hardening.
- You know what you learned throughout the guide and what comes in Guide #8 (Advanced RAG).
- You have a solid base to evolve toward advanced RAG techniques: migration to Pinecone, re-ranking, query optimization, systematic evaluation.
Congratulations! You built a system an AI Engineer would show in an interview. Continue with Guide #8 to take it to the next level.
Extended golden_set.json Template
For complete coverage, use at least 40 questions in your golden set:
[
{"question": "What is a vector database?", "expected_keywords": ["vector", "embedding", "search"], "category": "frequent"},
{"question": "How does HNSW work?", "expected_keywords": ["graph", "approximate", "neighbor"], "category": "frequent"},
{"question": "When to use ChromaDB?", "expected_keywords": ["local", "development", "RAG"], "category": "frequent"},
{"question": "What is RAG?", "expected_keywords": ["retrieval", "generation", "documents"], "category": "frequent"},
{"question": "What is the difference between HNSW and IVF?", "expected_keywords": ["graph", "clustering"], "category": "difficult"},
{"question": "What happened on March 15, 2030 on Mars?", "expected_keywords": ["i don't have", "evidence", "unknown"], "category": "out_of_coverage"}
]
Recommended categories: 20 frequent, 10 difficult, 10 out_of_coverage.
Comparison: Before vs After the Guide
| Aspect | Before the guide | After Module 8 |
|---|---|---|
| Vector DB | You didn't know when or why | You understand the architecture, you use ChromaDB |
| RAG | Theoretical concept | Complete system with ingestion, retrieval, generation |
| Production | "Works on my machine" | Docker, tests, metrics, hardening |
| Technology decision | Intuition | Documented decision framework |
| Next step | Uncertain | Guide #8: Pinecone, re-ranking, evaluation |
Additional Resources
- GitHub README Best Practices
- Keep a Changelog — CHANGELOG format
- Guide #8: Advanced RAG Techniques — Next step
- ChromaDB Documentation — Reference
- FastAPI Deployment — Deploy options
- RAGAS Evaluation — RAG metrics
- Pinecone Getting Started — For Guide #8
- Semantic Chunking — Advanced chunking
Final Project FAQ
Can I use another LLM instead of OpenAI?
Yes. Replace app/generation/generator.py with the integration for Anthropic, a local LLM (Ollama), etc. The contract (question + docs → answer) stays the same.
Is ChromaDB enough for production?
For 1K-100K docs and moderate traffic, yes. For millions of vectors or multi-tenant at scale, Guide #8 with Pinecone is the way.
Do I need Redis for the cache?
It's not mandatory. You can start with an in-memory cache. Redis adds persistence and sharing the cache between replicas.
How do I add more documents after deploy?
Use POST /ingest with the new batch. The IDs must be unique. If you use deterministic IDs (e.g. content hash), re-ingestion is idempotent.
What do I do if accuracy doesn't reach 90%?
Review: (1) chunk_size and overlap, (2) top_k, (3) corpus quality, (4) the generation prompt. Add failed cases to the golden set and iterate.
Suggested Implementation Timeline
If you have 3-4 hours for the complete project:
| Block | Duration | Activity |
|---|---|---|
| 1 | 45 min | Setup, config, ingestion pipeline, 1000-docs script |
| 2 | 45 min | Retrieval, generation, API endpoints |
| 3 | 45 min | Docker, docker-compose, health, metrics |
| 4 | 45 min | Tests (unit, integration), golden set, accuracy |
| 5 | 30 min | Hardening (retries, fallbacks, rate limit) |
| 6 | 30 min | README, DEPLOYMENT.md, CHANGELOG, final evaluation |
Adjust to your priorities. The critical thing: that it works end-to-end and is in Docker before refining details.
Transition Checklist to Guide #8
Before starting Guide #8 (Advanced RAG Techniques), verify:
- Project in Git with coherent commits
- README updated with the current status
- Pilot metrics (accuracy, latency) recorded
- Improvements list prioritized (top 5)
- Pinecone account created (if you're going to migrate)
- You understand what problems re-ranking and query optimization will solve
Estimated time: 60-90 minutes (complete integration)
Next guide: Advanced RAG Techniques — Migration to a more advanced stack and retrieval optimizations.
Final Message
You completed the 8 modules of the Vector Databases Fundamentals guide. You went from "what is a vector?" to "I have a RAG system deployed with ChromaDB, Docker, tests, and monitoring". That's a real achievement.
The project you built is not an academic exercise. It's a reusable base for Guide #8, where you'll migrate to Pinecone, add re-ranking, and evaluate your RAG systematically. Every decision you documented (chunk_size, top_k, ChromaDB vs managed) will help you justify changes in interviews and in production.
Continue with Guide #8 when you're ready. The AI Engineering path is iterative: what's "production-ready" today will be "an MVP we evolve" tomorrow. What matters is that you now know how to build that base.
Summary of Deliverables per Capsule
| Capsule | Key deliverable |
|---|---|
| 01-02 | Architecture diagram, contracts between components |
| 03 | Ingestion pipeline for 1,000+ docs, validations |
| 04 | /search, /ask endpoints with a stable contract |
| 05 | Fixtures, unit/integration/performance/accuracy tests |
| 06 | Dockerfile, docker-compose, Prometheus, logging |
| 07 | Retries, fallbacks, rate limit, README |
| 08 | Full integration, checklist, Guide #8 connection |
Each deliverable is verifiable: you can mark the capsule as completed when the corresponding item works in your project.
Quick Verification Commands
Before considering the project closed, run:
docker-compose up -d && sleep 15
curl -s http://localhost:8000/health | jq
curl -s -X POST http://localhost:8000/ask -H "Content-Type: application/json" -d '{"question":"What is RAG?"}' | jq '.answer'
pytest tests/ -v --tb=line -q
If the three commands pass, your system is ready for delivery.