Overview
Agentic RAG gives the LLM autonomous control over the retrieval process. The model decides:
- ▸When to retrieve (is current knowledge sufficient?)
- ▸What to search for (formulate sub-queries)
- ▸How to combine results (synthesis strategy)
Pattern #12 in the 37 RAG Patterns Collection
Architecture
graph TB
A[User Query] --> B{Agent: Need Retrieval?}
B -->|Yes| C[Agent: Plan Search Strategy]
B -->|No| G[Direct Answer]
C --> D[Execute Searches]
D --> E{Agent: Sufficient?}
E -->|No| C
E -->|Yes| F[Agent: Synthesize]
F --> G[Final Response]
H[Tools: Search, Retrieve, Filter] --> D
style A fill:#f9f,stroke:#333
style B fill:#ff9,stroke:#333
style E fill:#ff9,stroke:#333
style G fill:#9f9,stroke:#333Core Capabilities
1. Autonomous Retrieval Decision
def should_retrieve(query, llm_knowledge):
"""Agent decides if retrieval is needed"""
prompt = f"""Query: {query}
Based on your knowledge, can you answer this accurately without additional information?
Respond with JSON:
{{
"needs_retrieval": true/false,
"reasoning": "explanation",
"confidence": 0-100
}}"""
decision = llm.invoke(prompt, schema=DECISION_SCHEMA)
return decision['needs_retrieval']2. Dynamic Query Formulation
def formulate_searches(query):
"""Agent creates optimal search strategy"""
prompt = f"""Query: {query}
Break this into targeted search queries that would find the needed information.
Return JSON:
{{
"searches": [
{{"query": "...", "type": "vector/keyword/graph"}},
...
],
"reasoning": "why these searches"
}}"""
return llm.invoke(prompt, schema=SEARCH_SCHEMA)3. Iterative Refinement
def iterative_retrieval(query, max_iterations=3):
"""Agent refines search based on results"""
context = []
for i in range(max_iterations):
# Evaluate current context
evaluation = llm.invoke(f"""
Context gathered: {context}
Original query: {query}
Is this sufficient to answer accurately?
If not, what additional information is needed?
""", schema=EVAL_SCHEMA)
if evaluation['sufficient']:
break
# Get more information
new_searches = formulate_searches(evaluation['gaps'])
new_results = execute_searches(new_searches)
context.extend(new_results)
return contextComplete Implementation
class AgenticRAG:
def __init__(self, llm, retriever, tools):
self.llm = llm
self.retriever = retriever
self.tools = tools # search, filter, rank, etc.
def query(self, user_query):
# Phase 1: Assess need
if not self.should_retrieve(user_query):
return self.llm.generate(user_query)
# Phase 2: Plan strategy
plan = self.create_search_plan(user_query)
# Phase 3: Execute with autonomy
context = []
for step in plan['steps']:
# Agent chooses tool and parameters
tool = self.select_tool(step)
results = tool.execute(step['parameters'])
# Agent evaluates results
if self.are_results_useful(results, user_query):
context.extend(results)
# Agent decides: continue or done?
if self.has_sufficient_info(context, user_query):
break
# Phase 4: Synthesize
return self.synthesize_answer(context, user_query)
def select_tool(self, step):
"""Agent chooses best tool for the task"""
prompt = f"""Task: {step['description']}
Available tools: {self.tools.keys()}
Which tool is best? Return tool name and parameters."""
selection = self.llm.invoke(prompt, schema=TOOL_SCHEMA)
return self.tools[selection['tool']]Complete Notebook
🚀 Run the full implementation:
Includes:
- ▸Complete agent framework
- ▸Tool selection logic
- ▸Iterative refinement
- ▸Multi-step reasoning examples
- ▸Performance benchmarks
Comparison
| Feature | Agentic RAG | Standard RAG |
|---|---|---|
| Autonomy | Full | None |
| Adaptability | Dynamic | Fixed pipeline |
| Accuracy | 90%+ | 70% |
| Latency | Variable (0.5-5s) | Fixed (~300ms) |
| Cost | $0.18-0.50 | $0.08 |
| Complexity | High | Low |
When to Use
Best For
- ▸Complex research questions requiring multi-step reasoning
- ▸Open-ended queries without clear retrieval strategy
- ▸Dynamic domains where fixed pipelines fail
- ▸High-value applications where accuracy justifies cost
Avoid When
- ▸Simple Q&A (unnecessary complexity)
- ▸Strict latency requirements (unpredictable timing)
- ▸Budget constraints (multiple LLM calls)
- ▸Production at scale (complex failure modes)
Agent Tools
Common tools provided to agentic RAG:
AGENT_TOOLS = {
"vector_search": VectorSearchTool(),
"keyword_search": KeywordSearchTool(),
"graph_traverse": GraphTraversalTool(),
"web_search": WebSearchTool(),
"filter": FilterTool(),
"rerank": RerankingTool(),
"summarize": SummarizationTool(),
}Example Flow
Query: "Compare the economic impact of renewable energy adoption in Germany vs China from 2015-2025"
Agent's Decision Process
- ▸Assess: "This requires specific data I don't have → need retrieval"
- ▸Plan:
- ▸Search: "Germany renewable energy economic impact 2015-2025"
- ▸Search: "China renewable energy economic impact 2015-2025"
- ▸Search: "renewable energy economics comparison methodology"
- ▸Execute:
- ▸Run searches → get initial results
- ▸Evaluate: "Missing GDP impact data" → refine search
- ▸Add search: "Germany GDP renewable energy contribution"
- ▸Evaluate: "Now have sufficient data" → stop
- ▸Synthesize: Compare findings, structure answer
Optimization Tips
1. Limit Iterations
MAX_ITERATIONS = 3 # Prevent infinite loops
MAX_SEARCHES_PER_ITERATION = 5 # Control fanout2. Budget Management
def query_with_budget(query, max_cost=0.50):
spent = 0
context = []
while spent < max_cost:
step_cost = estimate_cost(next_action)
if spent + step_cost > max_cost:
break
# Execute and track
result = execute_step(next_action)
spent += step_cost
context.append(result)
return synthesize(context, query)3. Fallback Strategy
def agentic_with_fallback(query, timeout=5.0):
try:
with timeout_context(timeout):
return agentic_rag(query)
except TimeoutError:
# Fall back to standard RAG
return simple_rag(query)Related Papers
- ▸ReAct: Reasoning + Acting (2022)
- ▸Toolformer: Models Using Tools (2023)
- ▸AutoGPT: Autonomous Agents (2023)
Next Steps
- ▸Try it: Run the Agentic RAG notebook
- ▸Combine: Use with Self-RAG (#14) for quality checks
- ▸Scale: Try Tree of Thoughts (#15) for complex reasoning
- ▸Deploy: Use Production RAG (#35) patterns
Part of: 37 RAG Patterns Collection
See also: Visual Architecture Guide