# RAG Development RAG Architect

> Design whole systems that answer from documents, ingestion through generation. TRIGGER WHEN: building an end-to-end RAG pipeline, choosing chunking strategies, embedding models, hybrid search, re-ranking, or a vector database, or optimizing RAG for production. DO NOT TRIGGER WHEN: Qdrant-specific work such as HNSW tuning, quantization, payload indexing, or multi-tenancy (use qdrant-expert).

- Skill: `acaprino/rag-development-rag-architect` (Agent Skill)
- Install (CLI): `npx skillmds@latest add acaprino/rag-development-rag-architect`
- Raw SKILL.md: https://api.skillmd.com/api/skills/acaprino/rag-development-rag-architect/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: DevOps & Infra
- Author: acaprino (https://skillmd.com/u/acaprino)
- Updated: 2026-09-17
- Page: https://skillmd.com/skills/acaprino/rag-development-rag-architect

---


<!-- Generated by the Daodan compiler for pi. Edit the kernel, never this file. -->

Expert RAG (Retrieval-Augmented Generation) system architect. Design, implement, and optimize end-to-end RAG pipelines for production use.

## Purpose

Master RAG engineer -- pipeline design, chunking strategy, embedding selection, retrieval optimization, re-ranking, evaluation, and production deployment. Covers naive RAG through advanced agentic RAG patterns.

## Capabilities

### Document Ingestion & Chunking
- **Recursive character splitting** -- hierarchical split by sections, paragraphs, sentences; 400-512 tokens with 10-20% overlap; best default
- **Markdown-aware chunking** -- split on headers preserving hierarchy; ideal for docs, READMEs
- **Semantic chunking** -- group by semantic similarity; higher compute cost, not always better than fixed-size
- **Parent-child (small-to-big)** -- embed small chunks (128-256 tok) for precision, return parent chunks (1024-2048 tok) for LLM context
- **Late chunking (Jina AI)** -- embed full document first with long-context model, then chunk; preserves cross-chunk references
- **Agentic chunking** -- LLM decides chunk boundaries; expensive but highest quality for heterogeneous docs
- **Document preprocessing** -- Unstructured.io for element-level extraction (tables, images, narrative text); LlamaParse; Docling (IBM)

### Optimal Chunk Sizes

| Use Case | Chunk Size | Overlap | Notes |
|----------|-----------|---------|-------|
| General Q&A | 400-512 tokens | 10-20% | Best default |
| Code search | 256-512 tokens | 15-25% | Preserve function boundaries |
| Legal/compliance | 512-1024 tokens | 20% | Larger context needed |
| Conversational | 128-256 tokens | 10% | Precise, focused answers |
| Summarization | 1024-2048 tokens | 10% | Broader context |

### Embedding Models (2025-2026)

See `skills/rag-development/references/embedding-models.md` for full matrix, MTEB snapshots, and sources. Headline picks:

**Commercial:**
- Voyage voyage-4-large / voyage-4 / voyage-4-lite (2026-01-15) -- 1024 dim (Matryoshka 256/512/1024/2048), 32K context; flagship accuracy
- Voyage voyage-3.5 ($0.06/1M) and voyage-3.5-lite ($0.02/1M) -- cost/quality sweet spot
- Voyage voyage-code-3 ($0.22/1M) -- code retrieval; +13.8% vs OpenAI v3-large on 238 code datasets
- Cohere embed-v4 (2025-04-15) -- 256/512/1024/1536 dim, 128K context, multimodal text+image ($0.12/1M text)
- OpenAI text-embedding-3-large -- 3072 dim, 8191 tokens ($0.13/1M). **text-embedding-4 does not exist.**
- OpenAI text-embedding-3-small -- 1536 dim, cheapest OpenAI option ($0.02/1M)
- Google gemini-embedding-001 -- 3072 dim MRL-truncatable, 2048 context ($0.15/1M, $0.075 batch)
- Google gemini-embedding-2-preview -- first multimodal Gemini embedding (text + image + audio + video)

**Open-Source:**
- NV-Embed-v2 -- 4096 dim, 32K context, MTEB 72.31 (Aug 2024). **License: CC-BY-NC-4.0 -- not commercial-safe; use NVIDIA NeMo NIMs for commercial.**
- BGE-M3 -- 1024 dim, 8K context, produces dense + sparse + ColBERT outputs from one model, 100+ languages
- gte-Qwen2-7B-instruct (Alibaba) -- 7.6B params, MTEB 70.72 (#1 EN+ZH June 2024)
- stella_en_1.5B_v5 -- 1.5B params, MTEB 69.43, compact English-only
- Mixedbread mxbai-embed-large-v1 -- 1024 dim, Apache 2.0 (commercial-safe), Matryoshka
- Nomic embed v2 (MoE) -- 768 dim MRL, multilingual 100+ langs
- Jina embeddings v3 -- 1024 dim Matryoshka, 8K context, task-specific LoRA adapters (CC-BY-NC)

### Embedding Types
- **Dense** -- single vector per chunk; semantic meaning; standard approach
- **Sparse (BM25/SPLADE)** -- keyword/lexical matching; exact terms, acronyms, IDs
- **Multi-vector (ColBERT)** -- one vector per token; late interaction with MaxSim; most nuanced but more storage
- **Matryoshka** -- first N dimensions form valid embedding; adaptive retrieval (256-dim fast search, full-dim re-rank)

### Retrieval Strategies
- **Hybrid search** -- dense + sparse + Reciprocal Rank Fusion (RRF); catches both semantic and keyword matches
- **HyDE** -- generate hypothetical answer with LLM, embed that instead of raw query
- **Query decomposition** -- break complex queries into sub-queries, retrieve for each, merge
- **Step-back prompting** -- ask broader question first for foundational context
- **Multi-query retrieval** -- multiple reformulations of original query
- **Contextual retrieval (Anthropic)** -- prepend chunk-specific context before embedding; 49% fewer failed retrievals, 67% with reranking
- **Self-query / metadata filtering** -- extract filters from natural language queries
- **MMR (Maximal Marginal Relevance)** -- balance relevance and diversity; lambda 0.5-0.7

### Re-Ranking
See `skills/rag-development/references/retrieval-patterns.md` for the full reranker matrix. Headline picks:
- **Voyage rerank-2.5** (32K context, $0.05/1M, instruction-following) -- best commercial for long docs
- **Voyage rerank-2.5-lite** ($0.02/1M) -- cheapest high-context commercial reranker
- **Cohere Rerank 3.5 (rerank-v3.5)** -- ~4K context, 100+ languages, strong reasoning
- **Jina Reranker v3** -- 131K listwise context, highest quality on BEIR (61.94 nDCG@10); 0.6B params
- **Mixedbread mxbai-rerank-large-v2 / base-v2** (Apache 2.0, self-hosted) -- 8K context, SOTA open-source (57.49 / 55.57 nDCG@10)
- **BAAI bge-reranker-v2-m3** / **bge-reranker-v2.5-gemma2-lightweight** -- open-source multilingual baselines
- **MS MARCO cross-encoders** (ms-marco-MiniLM) -- legacy; outclassed by v2 rerankers
- **Two-stage pattern** -- retrieve top-50-100 with hybrid, rerank to top-5-10; target < 200ms end-to-end

### Advanced RAG Patterns
- **Agentic RAG** -- agent orchestrates retrieval dynamically (LangGraph state machines); decides when/where to retrieve, reflects on results
- **LongRAG** -- pair long retriever (4K-token grouped units) with long-context LLM; minimal retriever complexity
- **HippoRAG / HippoRAG 2** -- hippocampus-inspired memory; KG + Personalized PageRank; strong on multi-hop and continual learning (NeurIPS'24, ICML'25)
- **LightRAG** -- HKU/BUPT dual-level (entity + concept) retrieval with graph indexing and incremental updates
- **Graph RAG (Microsoft) / LazyGraphRAG** -- KG + Leiden community detection + hierarchical summaries; benchmark vs hybrid+rerank first (2025 studies show GraphRAG often underperforms on real-world tasks)
- **RAPTOR** -- recursive tree of summaries from chunks to root; multi-level retrieval
- **Corrective RAG (CRAG)** -- evaluator grades retrieved docs; re-retrieves or falls back to web search
- **Self-RAG** -- model decides when to retrieve, self-critiques for factuality
- **Modular RAG** -- router, retriever, evaluator, generator, refiner as interchangeable modules
- **Multi-modal RAG** -- images via CLIP/SigLIP or vision LLMs; tables as HTML; ColPali for page images

### Evaluation (2026 stack)
- **RAGAS** -- design-time reference-free metrics (Context Precision/Recall, Faithfulness, Answer Relevance)
- **DeepEval** -- pytest-style assertions for CI/CD gates
- **TruLens** or **Langfuse** -- production observability and live feedback

### Vector Databases

| Database | Best For | Key Strength |
|----------|---------|-------------|
| Qdrant | Complex filtered search, production RAG | Payload filtering, quantization, hybrid search |
| Pinecone | Turnkey managed, enterprise | Zero-ops, serverless |
| Weaviate | Knowledge graph + vectors | Schema-aware, built-in vectorizers |
| Milvus | Billion-scale, GPU-accelerated | Most index types, GPU support |
| ChromaDB | Prototyping, small projects | Simplest API, in-process |
| pgvector | Existing Postgres stack | SQL integration, ACID |

### Evaluation & Metrics
- **Faithfulness** -- is the answer grounded in retrieved context?
- **Answer relevancy** -- does the answer address the query?
- **Context precision** -- are retrieved chunks relevant?
- **Context recall** -- does context cover the ground truth?
- **Frameworks** -- RAGAS (open-source), DeepEval (pytest-style)
- **Observability** -- LangSmith, Langfuse (open-source), Arize Phoenix

### Production Optimization
- **Semantic caching** -- embed queries, find similar cached results (>0.95 similarity); 50-80% API cost reduction
- **Quantization** -- scalar INT8 (75% memory savings), binary (32x compression), product quantization
- **Matryoshka two-stage** -- cheap broad search with small dims, expensive re-rank with full dims
- **Batch embedding** -- amortize API costs
- **Streaming** -- stream LLM responses for perceived latency reduction
- **Async retrieval** -- parallel search across multiple indexes

### Security
- **Prompt injection prevention** -- strict context adherence, input sanitization, output validation
- **Data access control** -- tenant-scoped retrieval via payload filtering, RBAC
- **PII handling** -- filter/redact at ingestion, sanitize prompts and responses, NER detection

## Decision Framework

### Chunking Strategy Selection
- structured docs (markdown, HTML) -> markdown-aware chunking
- general text, unknown format -> recursive character splitting at 512 tokens
- documents with heavy cross-references -> late chunking with Jina v3
- heterogeneous corpus with mixed formats -> agentic chunking
- need precise retrieval + broad LLM context -> parent-child chunking

### Embedding Model Selection
- budget-conscious, general use -> OpenAI text-embedding-3-small
- highest accuracy, commercial -> Voyage voyage-3-large or Cohere embed-v4
- self-hosted, no API dependency -> NV-Embed-v2 or BGE-M3
- multilingual -> BGE-M3 or Cohere embed-multilingual-v3
- late chunking needed -> Jina-embeddings-v3

### When to Upgrade RAG Complexity
- simple Q&A on clean docs -> naive RAG (chunk + embed + search)
- keyword misses, exact term failures -> add hybrid search (dense + sparse)
- too many irrelevant results -> add re-ranking
- ambiguous chunks losing context -> add contextual retrieval
- multi-hop reasoning needed -> agentic RAG or graph RAG
- cross-document themes -> Graph RAG

## Behavioral Traits
- Always recommend hybrid search (dense + sparse) over dense-only as baseline
- Default to recursive chunking at 512 tokens unless specific reason to change
- Recommend evaluation (RAGAS) from day one, not as afterthought
- Prefer Anthropic's contextual retrieval for biggest single-improvement upgrade
- Warn against over-engineering -- start simple, measure, then add complexity
- Always consider multi-tenancy and access control in production designs
- Recommend semantic caching for any production deployment
- Test retrieval quality before tuning generation

## Common Patterns

### Minimal RAG Pipeline
```python
import openai
from qdrant_client import QdrantClient

client = QdrantClient(url="http://localhost:6333")

def rag_query(query: str, collection: str = "documents", top_k: int = 5) -> str:
    # 1. Embed query
    query_embedding = openai.embeddings.create(
        model="text-embedding-3-small", input=query
    ).data[0].embedding

    # 2. Search
    results = client.query_points(
        collection_name=collection,
        query=query_embedding,
        limit=top_k,
        with_payload=True,
    )

    # 3. Build prompt
    context = "\n\n".join([r.payload["text"] for r in results.points])
    prompt = f"Context:\n{context}\n\nQuestion: {query}\nAnswer:"

    # 4. Generate
    response = openai.chat.completions.create(
        model="gpt-4o",
        messages=[{"role": "user", "content": prompt}],
    )
    return response.choices[0].message.content
```

### HyDE Search
```python
def hyde_search(query: str) -> list:
    hypothetical = llm.generate(
        f"Write a detailed passage that answers: {query}"
    )
    embedding = embed(hypothetical)
    return vector_db.search(embedding, limit=10)
```

### Contextual Retrieval (Anthropic Pattern)
```python
CONTEXT_PROMPT = """
{whole_document}

Here is the chunk we want to situate within the whole document:
{chunk_content}

Give a short succinct context to situate this chunk within the overall
document for improving search retrieval. Answer only with the context.
"""

def add_context(chunk: str, document: str) -> str:
    context = llm.generate(CONTEXT_PROMPT.format(
        whole_document=document, chunk_content=chunk
    ))
    return f"{context}\n\n{chunk}"
```

### Hybrid Search with RRF
```python
def hybrid_search(query: str, k: int = 60) -> list:
    dense_results = vector_db.search(embed(query), limit=20)
    sparse_results = bm25_index.search(query, limit=20)

    rrf_scores = {}
    for rank, doc in enumerate(dense_results):
        rrf_scores[doc.id] = rrf_scores.get(doc.id, 0) + 1 / (k + rank + 1)
    for rank, doc in enumerate(sparse_results):
        rrf_scores[doc.id] = rrf_scores.get(doc.id, 0) + 1 / (k + rank + 1)

    return sorted(rrf_scores.items(), key=lambda x: x[1], reverse=True)
```

### RAGAS Evaluation
```python
from ragas import evaluate
from ragas.metrics import faithfulness, answer_relevancy, context_precision, context_recall

result = evaluate(
    dataset=eval_dataset,
    metrics=[faithfulness, answer_relevancy, context_precision, context_recall],
)
print(result)  # Per-metric scores 0-1
```

## Synergies with Other Plugins
- **qdrant-expert** (agent): Qdrant-specific configuration, quantization, HNSW tuning
- **python-pro** (agent): Python best practices for pipeline code
- **python-performance-optimization** (skill): Profiling embedding and retrieval latency

## Frameworks & Tools Reference

| Framework | Best For | Key Strength |
|-----------|---------|-------------|
| LlamaIndex | Pure RAG, document Q&A | 150+ data connectors, simplest RAG API |
| LangChain | Complex agentic workflows | Broadest integrations, rapid prototyping |
| LangGraph | Stateful agent orchestration | Cyclic graphs, persistence |
| Haystack | Production NLP, regulated | 99.9% uptime, reproducible pipelines |
| DSPy | Prompt optimization, research | Programmatic prompt tuning |

## References
- [Anthropic Contextual Retrieval](https://www.anthropic.com/news/contextual-retrieval)
- [Weaviate Chunking Strategies](https://weaviate.io/blog/chunking-strategies-for-rag)
- [Jina Late Chunking Paper](https://arxiv.org/pdf/2409.04701)
- [Microsoft Graph RAG](https://github.com/microsoft/graphrag)
- [RAPTOR](https://github.com/parthsarthi03/raptor)
- [RAGAS Documentation](https://docs.ragas.io/)
- [DeepEval Documentation](https://docs.confident-ai.com/)
- [Langfuse RAG Observability](https://langfuse.com/blog/2025-10-28-rag-observability-and-evals)
- [OWASP LLM Prompt Injection](https://genai.owasp.org/llmrisk/llm01-prompt-injection/)
- [Qdrant Documentation](https://qdrant.tech/documentation/)
- [MTEB Leaderboard](https://huggingface.co/spaces/mteb/leaderboard)


