Chapter 18 · RAG Advanced: Agentic RAG and Hybrid Retrieval
Learning objectives: Distinguish between Agentic RAG and Traditional RAG, and master three key techniques for improving retrieval quality: chunking strategies, metadata filtering, and rerankers.
18.1 Agentic RAG vs. Traditional RAG
The example from the previous chapter was Agentic RAG: the model receives a search_knowledge_base tool and decides for itself "whether to search and with what query," and can even rewrite the query and perform multi-round supplementary retrieval. Traditional RAG, on the other hand, is a fixed pipeline — every question triggers a retrieval first, and the results are injected directly into the prompt:
from agno.agent import Agent
# Traditional RAG: retrieve before every request; references auto-appended to user message
traditional = Agent(
model=model,
knowledge=knowledge,
add_knowledge_to_context=True, # Retrieved results directly added to context
)
# Agentic RAG: model autonomously decides whether/how to retrieve (default behavior)
agentic = Agent(
model=model,
knowledge=knowledge,
search_knowledge=True, # Register retrieval tool; leave decisions to the model
)| Dimension | Traditional RAG | Agentic RAG |
|---|---|---|
| Retrieval timing | Always retrieves | Model decides on demand |
| Latency & cost | Low and predictable | One extra tool-call round |
| Complex questions | Single retrieval may be insufficient | Can rewrite queries, retrieve multiple times |
| Suitable scenarios | Simple Q&A, low-latency requirements | Knowledge work requiring multi-step reasoning |
Selection guidance
For customer-service FAQ "one question, one answer" scenarios, traditional RAG is sufficient; for research and analysis tasks, use Agentic RAG. Both can coexist in the same project.
18.2 Chunking Strategies: The First Factor Determining Recall Ceiling
The smallest unit stored in a vector DB is a chunk. Cut too large, and irrelevant content in a single snippet dilutes similarity; cut too small, and semantics become incomplete. Agno ships multiple built-in Chunking strategies wired through the Reader:
from agno.knowledge.chunking.fixed import FixedSizeChunking
from agno.knowledge.chunking.recursive import RecursiveChunking
from agno.knowledge.chunking.document import DocumentChunking
from agno.knowledge.reader.pdf_reader import PDFReader
from agno.knowledge.knowledge import Knowledge
# Fixed-size: simple and blunt; suitable for uniformly formatted text
fixed_reader = PDFReader(chunking_strategy=FixedSizeChunking(size=1500))
# Recursive: falls back through paragraph → sentence → character delimiters; best general-purpose choice
recursive_reader = PDFReader(chunking_strategy=RecursiveChunking())
# Document-structure: cuts at title/section boundaries; preserves chapter integrity
doc_reader = PDFReader(chunking_strategy=DocumentChunking())
knowledge = Knowledge(vector_db=vector_db)
knowledge.insert(path="handbook.pdf", reader=recursive_reader)Selection experience: structured chunking for Markdown/HTML, Code Chunking for code, Recursive Chunking as the starting point for unstructured long-form text; try Semantic Chunking (sentence-break based on embedding similarity) only if initial results are unsatisfactory.
18.3 Metadata Filtering: Making Retrieval "Targeted"
Tag入库内容 with metadata, then filter by tag at query time to shrink the search scope from "the entire library" to "this user / this year / this type":
# Attach metadata at insert time
knowledge.insert(
path="resumes/",
metadata={"department": "engineering", "year": 2025},
)
# Method 1: Agent-level fixed filter — this Agent only ever sees engineering docs
agent = Agent(
model=model,
knowledge=knowledge,
search_knowledge=True,
knowledge_filters={"department": "engineering"},
)
# Method 2: Per-call temporary filter; multiple conditions combine with AND logic
agent.print_response(
"Summarize the highlights of engineers hired in 2025",
knowledge_filters={"year": 2025},
)
# Direct retrieval also supports filters
results = knowledge.search(query="Python experience", filters={"department": "engineering"})You can also enable enable_agentic_knowledge_filters=True to let the model auto-infer filter conditions from the user's question (e.g., extracting user_id=jordan from "Jordan's skills"); this requires pairing with Contents DB to record available filter keys.
18.4 Reranker: The Final Gate of Precision Ranking
Vector retrieval returns a "coarse rank." Reranker uses a heavier but more accurate cross-encoding model to score and re-sort each candidate snippet, pushing truly relevant ones to the top:
import os
from agno.knowledge.reranker.cohere import CohereReranker
from agno.vectordb.lancedb import LanceDb, SearchType
knowledge = Knowledge(
vector_db=LanceDb(
uri="tmp/lancedb",
table_name="docs",
search_type=SearchType.hybrid, # Hybrid retrieval: dual signals from vectors + keywords
embedder=embedder,
reranker=CohereReranker(model="rerank-v3.5"), # Precision ranking model
),
)The three components divide labor: hybrid retrieval captures both semantic similarity and exact keyword-match signals; reranking then performs fine-grained relevance sorting on those candidates. This is the standard trio for production-grade RAG.
18.5 How to Evaluate Retrieval Quality
Parameter tuning can't rely on gut feeling — build the smallest evaluation loop:
- Prepare 20–50 labeled pairs of「question → expected hit content」;
- Run them in batch with
knowledge.search()and compute recall rate (whether the correct snippet appears in top-k); - Re-run and compare after every adjustment to chunk size, Embedding model, or reranker addition.
def hit_rate(kb, cases, k=5):
hits = sum(
any(c["keyword"] in r.content for r in kb.search(q=c["q"], top_k=k))
for c in cases
)
return hits / len(cases) # e.g. 0.85 means 85% of questions retrieved the target snippetChapter Summary
- Agentic RAG (
search_knowledge=True, model-driven retrieval) and Traditional RAG (add_knowledge_to_context=True, retrieve-then-answer) each have their own suitable scenarios; - Chunking strategies are configured via the Reader's
chunking_strategy; Recursive Chunking is the general-purpose starting point; knowledge_filtersenables metadata filtering;enable_agentic_knowledge_filters=Truelets the model auto-infer filter conditions;SearchType.hybrid+ Reranker is the production-standard retrieval combo;- Use a small labeled set to quantitatively evaluate the impact of every tuning pass.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. What is the core difference between Agentic RAG and Traditional RAG?
2. Regarding chunking, which statement is correct?
3. If you set knowledge_filters={"year": 2025} and then pass {"dept": "sales"}, how do the two conditions interact?
4. What role does the Reranker play in the retrieval pipeline?
🛠️ Hands-On Exercises
- Index the same PDF into two separate tables using
FixedSizeChunking(size=1000)andRecursiveChunking()respectively; comparesearch()recall differences with the same set of questions. - Tag knowledge base content with
{"lang": "zh"/"en"}metadata; implement a bilingual query where Chinese questions only retrieve Chinese corpus and English questions only retrieve English corpus. - Write a 10-case
hit_rateevaluation script for your knowledge base and record the baseline score.
Next up: Chapter 19: Reasoning, where the model learns to "think before answering."