dspy-rag-pipeline — Claude Code skill: RAG with ColBERTv2
Builds retrieval-augmented generation pipelines powered by ColBERTv2 that can be systematically optimized. Use when questions require searching across your own document corpus and grounding answers in retrieved facts.
npx skills add OmidZamani/dspy-skills --skill dspy-rag-pipeline -a claude-codeWhat dspy-rag-pipeline does
This skill combines retrieval over a ColBERTv2 index with answer generation into a single module. It takes a question and retrieval count k as input, returning both the discovered passages and a generated response. The implementation uses dspy.Retrieve for semantic search and dspy.ChainOfThought for reasoning during generation.
The pipeline follows four phases: configuring the retriever (connecting ColBERTv2), defining input-output signatures, assembling the RAG module with a forward method, and running it on a question. Examples include a basic RAG setup, a production version with logging and error handling, and multi-hop RAG that refines queries across retrieval steps.
You'll need access to ColBERTv2; the examples connect to a public server at http://20.102.90.50:2017/wiki17_abstracts. The skill requires DSPy 3.2.1 and grants access to Read, Write, Glob, and Grep tools.
What it helps with
- retrieve relevant passages from a large document collection
- generate answers grounded in retrieved context
- optimize retrieval and generation jointly using few-shot examples
- debug multi-step queries that require query refinement
Example prompts for the agent
- Embed RAG for knowledge-base questions: initialize
RAG(num_passages=3)and pass a user question - Optimize your pipeline on a dataset: apply
BootstrapFewShotwith a grounding metric - Handle complex questions with multi-hop search: create
MultiHopRAG(num_hops=2)and provide the original query
How to install dspy-rag-pipeline
1Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-rag-pipeline -a claude-code2Manually: put the files in place
~/.claude/skills/dspy-rag-pipeline/SKILL.mdCopy the whole skill folder; for one project use .claude/skills/dspy-rag-pipeline/
1Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-rag-pipeline -a codex2Manually: put the files in place
.agents/skills/dspy-rag-pipeline/SKILL.mdFor all projects use ~/.agents/skills/
1Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-rag-pipeline -a cursor2Manually: put the files in place
.cursor/skills/dspy-rag-pipeline/SKILL.mdCursor also reads .agents/skills/ and .claude/skills/
1GitHub CLI
gh skill install OmidZamani/dspy-skills dspy-rag-pipeline2Manually: put the files in place
.github/skills/dspy-rag-pipeline/SKILL.md1Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-rag-pipeline -a gemini-cli2Platform CLI
gemini skills install https://github.com/OmidZamani/dspy-skills --path skills/dspy-rag-pipelineManually: put the files in place
.devin/skills/dspy-rag-pipeline/SKILL.mdThe legacy .windsurf/skills/ path still works
Skills CLI (Vercel)
npx skills add OmidZamani/dspy-skills --skill dspy-rag-pipeline -a opencodeClaude.ai
Zip the folder and upload it in Settings → Capabilities → Skills
Step by step, with commands for each platform: How to install skills in Claude Code: five ways
Questions about dspy-rag-pipeline
How do I install dspy-rag-pipeline in Claude Code?
Run npx skills add OmidZamani/dspy-skills --skill dspy-rag-pipeline -a claude-code, then open ~/.claude/skills/dspy-rag-pipeline/SKILL.md to confirm.
What does dspy-rag-pipeline do?
It performs semantic search over a text corpus via ColBERTv2 and generates answers grounded in the retrieved passages. Supports single-hop and multi-hop retrieval, optimization through few-shot learning, and validation of answer grounding.
What DSPy version is required?
The skill is compatible with DSPy 3.2.1. Ensure you have this version or later installed.
Source text
SKILL.md · MIT
---
name: dspy-rag-pipeline
version: "1.0.0"
dspy-compatibility: "3.2.1"
tags: ["retrieval"]
requires-extras: []
description: Use for RAG pipelines, retrieval augmented generation, ColBERTv2, context retrieval, multi-hop RAG, and grounded DSPy answers.
allowed-tools:
- Read
- Write
- Glob
- Grep
---
# DSPy RAG Pipeline
## Goal
Build retrieval-augmented generation pipelines with ColBERTv2 that can be systematically optimized.
## When to Use
- Questions require external knowledge
- You have a document corpus to search
- Need grounded, factual responses
- Want to optimize retrieval + generation jointly
## Related Skills
- Optimize this pipeline: [dspy-miprov2-optimizer](../dspy-miprov2-optimizer/SKILL.md), [dspy-bootstrap-fewshot](../dspy-bootstrap-fewshot/SKILL.md)
- Build local semantic retrieval: [dspy-embedding-retrieval](../dspy-embedding-retrieval/SKILL.md)
- Evaluate results: [dspy-evaluation-suite](../dspy-evaluation-suite/SKILL.md)
- Design signatures: [dspy-signature-designer](../dspy-signature-designer/SKILL.md)
## Inputs
| Input | Type | Description |
|-------|------|-------------|
| `question` | `str` | User query |
| `k` | `int` | Number of passages to retrieve |
| `rm` | `dspy.Retrieve` | Retrieval model (ColBERTv2) |
## Outputs
| Output | Type | Description |
|--------|------|-------------|
| `context` | `list[str]` | Retrieved passages |
| `answer` | `str` | Generated response |
## Workflow
### Phase 1: Configure Retrieval
```python
import dspy
# Configure LM and retriever
colbert = dspy.ColBERTv2(url='http://20.102.90.50:2017/wiki17_abstracts')
dspy.configure(
lm=dspy.LM("openai/gpt-4o-mini"),
rm=colbert
)
```
### Phase 2: Define Signature
```python
class GenerateAnswer(dspy.Signature):
"""Answer questions with short factoid answers."""
context: list[str] = dspy.InputField(desc="May contain relevant facts")
question: str = dspy.InputField()
answer: str = dspy.OutputField(desc="Often between 1 and 5 words")
```
### Phase 3: Build RAG Module
```python
class RAG(dspy.Module):
def __init__(self, num_passages=3):
super().__init__()
self.retrieve = dspy.Retrieve(k=num_passages)
self.generate = dspy.ChainOfThought(GenerateAnswer)
def forward(self, question):
context = self.retrieve(question).passages
pred = self.generate(context=context, question=question)
return dspy.Prediction(context=context, answer=pred.answer)
```
### Phase 4: Use
```python
rag = RAG(num_passages=3)
result = rag(question="What is the capital of France?")
print(result.answer) # Paris
```
## Production Example
```python
import dspy
from dspy.teleprompt import BootstrapFewShot
from dspy.evaluate import Evaluate
import logging
logger = logging.getLogger(__name__)
class GenerateAnswer(dspy.Signature):
"""Answer questions using the provided context."""
context: list[str] = dspy.InputField(desc="Retrieved passages")
question: str = dspy.InputField()
answer: str = dspy.OutputField(desc="Concise factual answer")
class ProductionRAG(dspy.Module):
def __init__(self, num_passages=5):
super().__init__()
self.num_passages = num_passages
self.retrieve = dspy.Retrieve(k=num_passages)
self.generate = dspy.ChainOfThought(GenerateAnswer)
def forward(self, question: str):
try:
# Retrieve
retrieval_result = self.retrieve(question)
context = retrieval_result.passages
if not context:
logger.warning(f"No passages retrieved for: {question}")
return dspy.Prediction(
context=[],
answer="I couldn't find relevant information."
)
# Generate
pred = self.generate(context=context, question=question)
return dspy.Prediction(
context=context,
answer=pred.answer,
reasoning=getattr(pred, 'reasoning', None)
)
except Exception as e:
logger.error(f"RAG failed: {e}")
return dspy.Prediction(
context=[],
answer="An error occurred while processing your question."
)
def validate_answer(example, pred, trace=None):
"""Check if answer is grounded and correct."""
if not pred.answer or not pred.context:
return 0.0
# Check correctness
correct = example.answer.lower() in pred.answer.lower()
# Check grounding (answer should relate to context)
context_text = " ".join(pred.context).lower()
grounded = any(word in context_text for word in pred.answer.lower().split())
return float(correct and grounded)
def build_optimized_rag(trainset, devset):
"""Build and optimize a RAG pipeline."""
# Configure
colbert = dspy.ColBERTv2(url='http://20.102.90.50:2017/wiki17_abstracts')
dspy.configure(
lm=dspy.LM("openai/gpt-4o-mini"),
rm=colbert
)
# Build
rag = ProductionRAG(num_passages=5)
# Evaluate baseline
evaluator = Evaluate(devset=devset, metric=validate_answer, num_threads=8)
baseline = evaluator(rag)
logger.info(f"Baseline: {baseline:.2%}")
# Optimize
optimizer = BootstrapFewShot(
metric=validate_answer,
max_bootstrapped_demos=4,
max_labeled_demos=4
)
compiled = optimizer.compile(rag, trainset=trainset)
optimized = evaluator(compiled)
logger.info(f"Optimized: {optimized:.2%}")
compiled.save("rag_optimized.json")
return compiled
```
## Multi-Hop RAG
```python
class MultiHopRAG(dspy.Module):
"""RAG with iterative retrieval for complex questions."""
def __init__(self, num_hops=2, passages_per_hop=3):
super().__init__()
self.num_hops = num_hops
self.retrieve = dspy.Retrieve(k=passages_per_hop)
self.generate_query = dspy.ChainOfThought("context, question -> search_query")
self.generate_answer = dspy.ChainOfThought(GenerateAnswer)
def forward(self, question):
context = []
for hop in range(self.num_hops):
# First hop: use original question
# Later hops: generate refined query
if hop == 0:
query = question
else:
query = self.generate_query(
context=context,
question=question
).search_query
# Retrieve and accumulate
new_passages = self.retrieve(query).passages
context.extend(new_passages)
# Generate final answer
pred = self.generate_answer(context=context, question=question)
return dspy.Prediction(context=context, answer=pred.answer)
```
## Best Practices
1. **Tune k carefully** - More passages = more context but also noise
2. **Signature descriptions matter** - Guide the model with field descriptions
3. **Validate grounding** - Ensure answers come from retrieved context
4. **Consider multi-hop** - Complex questions may need iterative retrieval
## Limitations
- Retrieval quality bounds generation quality
- ColBERTv2 requires hosted index
- Context length limits affect passage count
- Latency increases with more passages
## Official Documentation
- **DSPy Documentation**: https://dspy.ai/
- **DSPy GitHub**: https://github.com/stanfordnlp/dspy
- **RAG Tutorial**: https://dspy.ai/tutorials/rag/
- **ColBERTv2 API**: https://dspy.ai/api/tools/ColBERTv2/
© OmidZamani · MIT · OmidZamani/dspy-skills