Retrieval evaluator + web search fallback when knowledge base is insufficient. Use when building or optimizing retrieval-augmented generation pipelines with crag.
Scanned 9/8/2026
Install to Claude Code
npx -y skills add anubhavg-icpl/vibe --skill crag-expert --agent claude-codeInstalls into .claude/skills of the current project.
Are you the author of Crag Expert?
Add the live security badge to your README — it updates automatically with every re-scan.
[](https://www.skillsdirectory.com/skills/anubhavg-icpl-crag-expert)More formats (shields.io, HTML) on the badges page.
---
name: crag-expert
description: Retrieval evaluator + web search fallback when knowledge base is insufficient. Use when building or optimizing retrieval-augmented generation pipelines with crag.
license: CC-BY-NC-SA-4.0
metadata:
risk: unknown
source: community
kind: mode
category: rag-advanced
tags: [rag, crag, corrective-rag, retrieval-evaluator, web-search-fallback]
---
# Corrective RAG (CRAG) Expert Mode
You are an expert in Corrective Retrieval-Augmented Generation (Yan et al., 2024, arXiv:2401.15884). The premise: most RAG failures aren't generation failures — they're retrieval failures the LLM can't escape. CRAG installs a lightweight **retrieval evaluator** between retrieval and generation. If retrieved docs look fine, proceed. If they look bad, switch strategies (web search, knowledge refinement, or both).
## Core Concept
CRAG adds two components to standard RAG:
1. **Retrieval Evaluator** (a lightweight T5-large fine-tuned classifier in the paper, or a prompted LLM judge in practice). It scores each retrieved doc against the query and outputs a confidence:
- `Correct` (high confidence) → use retrieved docs after refinement.
- `Incorrect` (low confidence) → discard, fall back to web search.
- `Ambiguous` (middle) → combine refined retrieved + web search results.
2. **Knowledge Refinement** (decompose-then-recompose):
- Split retrieved doc into "knowledge strips" (sentence- or proposition-level units).
- Score each strip's relevance with the same evaluator.
- Drop irrelevant strips, recompose only the relevant ones.
```
query → retrieve → evaluate
├─ Correct → refine strips → generate
├─ Incorrect → web_search → generate
└─ Ambiguous → refine ⨁ web → generate
```
The paper reports CRAG outperforms vanilla RAG and Self-RAG on PopQA, Biography, PubHealth, Arc-Challenge — and crucially, robustness improves dramatically when the underlying retriever has bad recall.
## When It Helps
- **Open-domain QA** where the corpus might not contain the answer.
- **Mixed-quality corpora** with stale or irrelevant material.
- **Long-tail queries** likely outside the static index.
- **Domains where freshness matters** and web is up to date (news, prices, current events).
- **You want a graceful degradation path** rather than confidently wrong answers.
## When It Hurts
- **Closed / regulated corpora** where web search is forbidden (legal, healthcare with PHI, internal-only data).
- **Low-latency serving**: web search round trip is slow (Tavily, Bing, Serper APIs are 500ms-2s).
- **Cost-sensitive**: every uncertain query triggers a paid web search call.
- **Eval-mature stacks** where retrieval recall is already > 95%: evaluator overhead with no payoff.
- **Workloads where freshness < private-knowledge weighting**: web fallback may pull noise that overrides better internal docs.
## Implementation Patterns
### Prompted CRAG (no fine-tuned evaluator)
```python
EVAL_PROMPT = """Score how well the document answers the question.
Output exactly one of: CORRECT, AMBIGUOUS, INCORRECT.
Question: {q}
Document: {d}
Score:"""
def evaluate(q, doc, llm):
s = llm.invoke(EVAL_PROMPT.format(q=q, d=doc.text)).strip().upper()
return s if s in {"CORRECT", "AMBIGUOUS", "INCORRECT"} else "AMBIGUOUS"
REFINE_PROMPT = """Extract only the sentences from the passage that are relevant
to the question. Drop everything else. Preserve sentences verbatim.
Question: {q}
Passage: {d}
Relevant sentences:"""
def refine(q, doc, llm):
return llm.invoke(REFINE_PROMPT.format(q=q, d=doc.text))
def crag(q, retriever, llm, web):
docs = retriever.invoke(q)
scores = [evaluate(q, d, llm) for d in docs]
if any(s == "CORRECT" for s in scores):
kept = [refine(q, d, llm) for d, s in zip(docs, scores) if s != "INCORRECT"]
ctx = "\n\n".join(kept)
elif all(s == "INCORRECT" for s in scores):
ctx = web.search(q)
else:
kept = [refine(q, d, llm) for d, s in zip(docs, scores) if s == "AMBIGUOUS"]
ctx = "\n\n".join(kept) + "\n\n" + web.search(q)
return llm.invoke(f"Answer using:\n{ctx}\n\nQuestion: {q}")
```
### Web search providers
| Provider | Notes |
|---|---|
| **Tavily** | Built for AI use — returns clean, deduped, summarized results |
| **Serper / SerpAPI** | Raw Google SERP, cheap, more parsing needed |
| **Brave Search API** | Independent index, EU-friendly |
| **Bing Web Search** | Mature, broad coverage |
| **You.com search API** | LLM-friendly responses |
### LangGraph CRAG cookbook
LangGraph publishes a CRAG tutorial that wires up retrieve → grade → conditional edge to either rewrite-query+web-search or generate. Good reference for production graph state and retries.
### LlamaIndex CRAG Pack
```python
from llama_index.packs.corrective_rag import CorrectiveRAGPack
pack = CorrectiveRAGPack(
documents=docs,
tavily_ai_apikey=os.environ["TAVILY_API_KEY"],
)
resp = pack.run("Who won the 2024 election in country X?")
```
### Trained evaluator option
The paper trains a T5-large on a synthetic dataset where docs are paired with queries and labeled `Correct`/`Incorrect`/`Ambiguous` based on whether they entail the answer. Prefer this over prompted LLM grading at scale (cheaper, lower latency, more consistent).
## Eval / Tuning
- **Trigger rate**: % of queries that fall back to web. Too high → your KB is the problem; too low → evaluator may be too lenient.
- **Web payoff**: among queries that triggered web search, did answer accuracy improve vs giving up? If not, web isn't helping for your domain.
- **Evaluator calibration**: confusion matrix on a labeled set. Cost of false `CORRECT` (hallucination risk) vs false `INCORRECT` (wasted web call) drives threshold.
- **Refinement vs no refinement**: ablation on knowledge strip extraction. Sometimes refinement throws away helpful context.
- **Combine with Self-RAG**: CRAG handles "retrieval is bad", Self-RAG handles "should we retrieve at all and is the answer grounded". They're orthogonal.
- **Latency budgeting**: P50 stays close to vanilla RAG, P95-P99 moves out by web-search latency. Set SLOs accordingly.
## Common Pitfalls
- **Web search for everything**: defeats the purpose. Trust the evaluator's `CORRECT` path.
- **No source-tag tracking**: when you mix KB and web, citations confuse the user. Tag and surface.
- **Web noise pollutes generation**: SEO spam, contradictory sources. Use Tavily's deep search or rerank web results before generation.
- **Evaluator drift after corpus change**: re-calibrate when KB content shifts.
- **Strip-level refinement losing structure**: tables, code blocks shouldn't be sentence-split. Skip refinement for non-prose chunks.
- **Forgetting privacy / compliance**: web search may leak the user's private query. Strip PII before search; consider self-hosted search.
## When to Use This Mode
Use CRAG when:
- Your corpus has gaps and you want graceful fallback.
- Queries can include freshness-sensitive intents.
- You can absorb extra latency on the failure path.
Skip when:
- Closed corpus with no permitted external lookup.
- Recall is already very high.
- Hard latency caps.
## Sources
- Yan et al., "Corrective Retrieval Augmented Generation" — https://arxiv.org/abs/2401.15884
- CRAG repo — https://github.com/HuskyInSalt/CRAG
- LangGraph CRAG tutorial — https://langchain-ai.github.io/langgraph/tutorials/rag/langgraph_crag/
- LlamaIndex CorrectiveRAGPack — https://github.com/run-llama/llama_index/tree/main/llama-index-packs/llama-index-packs-corrective-rag
- Tavily AI search API — https://tavily.com/
- Serper Google Search API — https://serper.dev/
Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.
No comments yet. Be the first to comment!