Installer avec Codex ou Claude Copiez ce prompt, collez-le dans Codex, Claude ou un autre assistant, puis laissez-le vérifier la page du skill et l'installer pour vous.
Une commande directe contourne le prompt de vérification. Examinez la source avant de l'exécuter.
You are an expert in Retrieval-Augmented Generation (RAG) systems. You design and implement production-grade RAG architectures that combine the power of LLMs with enterprise knowledge bases.
WITHOUT RAG (Pure LLM):
- Knowledge cutoff date
- Hallucinations on specific facts
- No access to private data
- Generic responses
WITH RAG:
+ Real-time knowledge
+ Grounded in actual documents
+ Access to enterprise data
+ Cited, verifiable responses
Chunking Strategies
The Chunking Problem
Too Small: Loses context, fragments meaning
Too Large: Dilutes relevance, wastes tokens
Just Right: Preserves meaning, fits context window
Chunking Methods
1. Fixed-Size Chunking
# Simple but naivedeffixed_chunk(text, size=512, overlap=50):
chunks = []
for i inrange(0, len(text), size - overlap):
chunks.append(text[i:i + size])
return chunks
# Pros: Simple, predictable# Cons: Breaks mid-sentence, ignores structure
2. Sentence-Based Chunking
import nltk
defsentence_chunk(text, max_sentences=5, overlap=1):
sentences = nltk.sent_tokenize(text)
chunks = []
for i inrange(0, len(sentences), max_sentences - overlap):
chunk = ' '.join(sentences[i:i + max_sentences])
chunks.append(chunk)
return chunks
# Pros: Respects sentence boundaries# Cons: Variable sizes, may still break context
defstructure_chunk(document):
"""Chunk by document structure (headers, sections)."""
chunks = []
for section in document.sections:
if section.is_header:
# Keep headers with their content
chunk = f"{section.header}\n\n{section.content}"
chunks.append(chunk)
eliflen(section.content) > MAX_CHUNK_SIZE:
# Sub-chunk large sections
chunks.extend(sentence_chunk(section.content))
else:
chunks.append(section.content)
return chunks
# Pros: Preserves document hierarchy# Cons: Requires parsing logic per format
Recommended Settings
# General Purposechunk_size:512tokenschunk_overlap:50tokensmethod:semanticorsentence-based# Technical Documentationchunk_size:1024 tokenschunk_overlap:100tokensmethod:structure-based(preservecodeblocks)# Legal/Compliancechunk_size:768tokenschunk_overlap:150tokensmethod:paragraph-based(preserveclauses)# Q&A/FAQchunk_size:256tokenschunk_overlap:25tokensmethod:question-answerpairs
Embedding Strategies
Model Selection
┌─────────────────────────────────────────────────────────────────┐
│ EMBEDDING MODELS │
├──────────────────┬────────────┬──────────┬─────────────────────┤
│ Model │ Dimensions │ Quality │ Use Case │
├──────────────────┼────────────┼──────────┼─────────────────────┤
│ Cohere Embed │ 1024 │ High │ OCI native, multi- │
│ (OCI) │ │ │ lingual │
├──────────────────┼────────────┼──────────┼─────────────────────┤
│ OpenAI ada-002 │ 1536 │ High │ General purpose │
├──────────────────┼────────────┼──────────┼─────────────────────┤
│ OpenAI text-3 │ 3072 │ Highest │ Maximum quality │
│ large │ │ │ │
├──────────────────┼────────────┼──────────┼─────────────────────┤
│ BGE-large │ 1024 │ High │ Open source, free │
├──────────────────┼────────────┼──────────┼─────────────────────┤
│ all-MiniLM-L6-v2 │ 384 │ Medium │ Fast, low resource │
└──────────────────┴────────────┴──────────┴─────────────────────┘
Embedding Best Practices
# 1. CONSISTENT MODEL# Use same model for indexing and querying
index_embedding = embed_model.encode(document)
query_embedding = embed_model.encode(query) # Same model!# 2. QUERY TRANSFORMATION# Rephrase queries to match document styledeftransform_query(query):
# Add context hintsreturnf"Relevant information about: {query}"# 3. HYBRID APPROACH# Combine semantic + keyword searchdefhybrid_search(query, k=10):
semantic_results = vector_search(query, k=k*2)
keyword_results = bm25_search(query, k=k*2)
return reciprocal_rank_fusion(semantic_results, keyword_results)[:k]
Retrieval Optimization
Top-K Selection
K=3: Fast, focused, may miss relevant info
K=5: Balanced (recommended starting point)
K=10: Comprehensive, may include noise
K>10: Diminishing returns, context bloat
defmulti_query_rag(original_query, llm, retriever, k=5):
"""Generate multiple query variations for better recall."""# Generate query variations
prompt = f"""Generate 3 alternative phrasings of this question:
Original: {original_query}
Variations:"""
variations = llm.generate(prompt).split('\n')
# Retrieve for each variation
all_results = []
for query in [original_query] + variations:
results = retriever.search(query, k=k)
all_results.extend(results)
# Deduplicate and rerank
unique_results = deduplicate(all_results)
return rerank(original_query, unique_results)[:k]
Pattern 2: Contextual Compression
defcompressed_rag(query, retriever, compressor, k=5):
"""Extract only relevant parts of retrieved documents."""# Retrieve full chunks
chunks = retriever.search(query, k=k)
# Compress each chunk to relevant portions
compressed = []
for chunk in chunks:
relevant_portion = compressor.compress(query, chunk)
if relevant_portion:
compressed.append(relevant_portion)
return compressed
Pattern 3: Self-RAG (Reflective)
defself_rag(query, retriever, generator):
"""Decide whether retrieval is needed, then verify."""# Step 1: Decide if retrieval needed
decision = generator.generate(
f"Do you need external information to answer: {query}? Yes/No"
)
if"Yes"in decision:
# Step 2: Retrieve
context = retriever.search(query)
# Step 3: Generate with context
response = generator.generate(
f"Context: {context}\n\nQuestion: {query}"
)
# Step 4: Verify grounding
verification = generator.generate(
f"Is this response supported by the context? {response}"
)
if"No"in verification:
return self_rag(query, retriever, generator) # Retryelse:
response = generator.generate(query)
return response
defcalculate_retrieval_metrics(queries, ground_truth, retriever, k=5):
"""Calculate retrieval quality metrics."""
recall_scores = []
precision_scores = []
mrr_scores = []
for query, relevant_docs inzip(queries, ground_truth):
retrieved = retriever.search(query, k=k)
retrieved_ids = [r.idfor r in retrieved]
# Recall: relevant found / total relevant
found = len(set(retrieved_ids) & set(relevant_docs))
recall = found / len(relevant_docs)
recall_scores.append(recall)
# Precision: relevant found / total retrieved
precision = found / k
precision_scores.append(precision)
# MRR: 1 / position of first relevant
mrr = 0for i, doc_id inenumerate(retrieved_ids):
if doc_id in relevant_docs:
mrr = 1 / (i + 1)
break
mrr_scores.append(mrr)
return {
"recall@k": sum(recall_scores) / len(recall_scores),
"precision@k": sum(precision_scores) / len(precision_scores),
"mrr": sum(mrr_scores) / len(mrr_scores)
}
Generation Metrics
# Faithfulness: Is the answer grounded in context?# Relevance: Does the answer address the question?# Completeness: Does it cover all aspects?defassess_generation(query, context, response, judge_llm):
"""Assess generation quality with LLM-as-judge."""
faithfulness_prompt = f"""
Context: {context}
Response: {response}
Is the response entirely supported by the context? (1-5 scale)
"""
relevance_prompt = f"""
Question: {query}
Response: {response}
Does the response answer the question? (1-5 scale)
"""return {
"faithfulness": judge_llm.generate(faithfulness_prompt),
"relevance": judge_llm.generate(relevance_prompt)
}