Advanced Retrieval Patterns
By the Syncfusion DevTutorials team · Last updated
Handling questions that need several steps: decomposition, stepwise and multi-hop retrieval, agentic RAG with tool loops and stop rules, Self-RAG reflection, and GraphRAG entity graphs and community summaries.
Some questions can be answered with one search. Other questions require information from several sources.
For example, imagine investigating who had access to a room where a letter was found. First, you need to identify the room. Next, you need to find who had access to it. Finally, you need to compare the available information before reaching a conclusion.
Each answer creates the next question that must be searched.
Basic RAG usually performs one search and uses the retrieved information to generate an answer. Advanced retrieval patterns allow the system to perform several searches, divide a complex question into smaller questions, check the retrieved information, and combine related facts before answering.
The main idea: decompose complex questions into steps, and retrieve step by step, using each answer to shape the next search (multi-hop). Agentic RAG lets the model decide when and what to search, in a loop with a step limit. Self-RAG-style reflection grades retrieval and answers and retries when they're weak. GraphRAG builds a graph of entities and relationships, so you can answer "big picture" and connection questions that no single chunk answers.
A Real-World Example
Brightgrid found that some customer questions could not be answered with a single search.
For example:
“How many lights can the device used with Apple Home connect?” The system must first find that Apple Home requires the Brightgrid Hub. It must then search again to learn that the Hub supports 50 lights.
“How many more schedules does the Plus plan provide than the free plan?” The system must retrieve the schedule limits for both plans and compare the two values.
“Which Brightgrid products depend on the Hub?” The answer requires information about several products and their connections to the Hub.
Brightgrid added an agent loop for these complex questions. An agent loop allows the system to search, review the results, decide what information is still missing, and search again. Before answering, the system checks that each fact is supported by the retrieved sources.
For questions about relationships between products, features, and integrations, Brightgrid also uses an entity graph. An entity graph stores important items and the connections between them. For example, it can record that Apple Home connects through the Brightgrid Hub and that certain lamps depend on that Hub.
Simple questions still use a single search. The agent loop and entity graph are used only when the question requires several steps or connected facts.
In simple words: some questions need a plan, several searches, and a check at each step.
What You Will Learn
In this lesson, you will learn:
- Query decomposition: question decomposition, stepwise retrieval, multi-hop retrieval and complex question splitting.
- Agentic RAG: letting the model decide when and what to search, tool loops, and stop rules.
- Self-RAG-style reflection: grading retrieval and answers, and retrying.
- GraphRAG: entity graphs, community summaries, and when graphs beat vectors.
The RAG Lab answers in one pass. You can still act like an agent: ask the first sub-question, read the answer, and use it to write the next search. The cells below show the same loops in code, with a scripted "model" so the results are repeatable.
An agentic RAG loop: the model plans, searches, reads and reflects on whether the evidence is enough; it searches again with a sharper query or answers, within a step limit. GraphRAG adds a graph of entities for connection questions.
Query Decomposition
Question Decomposition
Question decomposition means dividing a complex question into smaller questions that are easier to search and answer.
The smaller questions may be handled in two ways:
Parallel questions can be answered independently. For example, “How much is Brightgrid Plus, and how do I set up the Glow Strip?” can be divided into one question about pricing and another about setup. The system can search for both answers separately (Lesson 14's sub-queries).
Sequential questions must be answered in order because a later search depends on an earlier answer. For example, the system must first identify which device works with Apple Home. It can then search for how many lights that device supports.
A language model can help create the smaller questions and decide their order. The RAG system then searches for each answer and combines the supported information into a final response.
Stepwise Retrieval
In stepwise retrieval, you search for step 1, read the answer, then use it in the step 2 search, and so on:
Step 2 depends on step 1
// Stepwise retrieval: the answer to step 1 decides what to search in step 2.
const kb = {
"which hub works with apple home":
"Apple Home is supported through the Brightgrid Hub.",
"brightgrid hub how many lights": "The Brightgrid Hub connects up to 50 lights.",
};
const search = (q) =>
kb[
Object.keys(kb).find(
(k) => k.split(" ").filter((w) => q.toLowerCase().includes(w)).length >= 3,
)
];
const question = "How many lights can the device I need for Apple Home connect?";
const step1 = search("which hub works with apple home");
console.log("step 1:", step1);
const device = step1.match(/through the (.+?)\./)[1]; // "Brightgrid Hub"
const step2 = search(`${device} how many lights`);
console.log("step 2:", step2);
console.log(`answer: The ${device} connects up to ${step2.match(/(\d+)/)[1]} lights.`);
Expected output:
step 1: Apple Home is supported through the Brightgrid Hub.
step 2: The Brightgrid Hub connects up to 50 lights.
answer: The Brightgrid Hub connects up to 50 lights.
Multi-Hop Retrieval
Multi-hop retrieval finds an answer through several connected searches.
An important item mentioned in the information, such as a product, person, place, or code, is called an entity. The system can use an entity found in one search to decide what to search for next. Each search step is called a hop.
For example, the first search may find that the Glow Strip connects through the Brightgrid Hub. The next search uses Brightgrid Hub to find the required pairing instructions.
Follow entities across chunks
// Multi-hop retrieval: follow a link (an entity) from one chunk to the next.
const chunks = [
{
id: "glow-strip-setup#2",
text: "The Glow Strip pairs through the Brightgrid Hub.",
entities: ["Glow Strip", "Brightgrid Hub"],
},
{
id: "hub-pairing#2",
text: "To pair, hold the device's button for 5 seconds.",
entities: ["Brightgrid Hub"],
},
{ id: "energy-use#1", text: "The Lumo Lamp uses 9 watts.", entities: ["Lumo Lamp"] },
];
function hops(startEntity, maxHops) {
const seen = new Set();
let frontier = [startEntity];
const path = [];
for (let h = 0; h < maxHops && frontier.length; h++) {
const next = [];
for (const c of chunks) {
if (!seen.has(c.id) && c.entities.some((e) => frontier.includes(e))) {
seen.add(c.id);
path.push(`hop ${h + 1}: ${c.id}`);
next.push(...c.entities.filter((e) => !frontier.includes(e)));
}
}
frontier = next;
}
return path;
}
console.log('Question: "How do I pair the Glow Strip?"');
console.log(hops("Glow Strip", 2).join("\n"));
Expected output:
Question: "How do I pair the Glow Strip?"
hop 1: glow-strip-setup#2
hop 2: hub-pairing#2
Complex Question Splitting
Practical rules for splitting:
- Split only when needed. Most questions are single-hop, and splitting adds latency.
- Keep 2–4 steps. Longer chains compound errors.
- Carry forward only the facts found, with their citations, not whole chunks.
- Answer the original question at the end, citing every step.
Agentic RAG
The Model Decides When and What to Search
In agentic RAG, retrieval becomes a tool the model can call. Instead of "search once, then answer", the model works in a loop:
- Think: what do I still need to know?
- Act: call
search("…"), or another tool like a calculator or an order lookup. - Observe: read the results.
- Repeat, or answer when the evidence is enough.
This is the same tool-calling pattern taught in the MCP course: the model picks a tool and arguments, and your code runs it and returns the result.
An agent loop with a step limit
// Agentic RAG: the model decides each step (search again, or answer), within a step limit.
// Here a scripted "policy" stands in for the model's decisions.
const kb = {
plus: "Brightgrid Plus costs $3.99 a month and adds unlimited schedules.",
schedules: "Free accounts can create up to 5 schedules.",
};
function policy(question, notes) {
if (!notes.length) {
return { action: "search", query: "plus" };
}
if (question.includes("free") && !notes.some((n) => n.includes("Free"))) {
return { action: "search", query: "schedules" };
}
return { action: "answer" };
}
const question = "How many more schedules do I get with Plus than on a free account?";
const notes = [];
const MAX_STEPS = 4;
for (let step = 1; step <= MAX_STEPS; step++) {
const d = policy(question, notes);
console.log(`step ${step}: ${d.action}${d.query ? ` "${d.query}"` : ""}`);
if (d.action === "answer") {
console.log("answer: Plus has unlimited schedules; free accounts have 5.");
break;
}
notes.push(kb[d.query]);
if (step === MAX_STEPS) {
console.log("stopped: step limit reached");
}
}
Expected output:
step 1: search "plus"
step 2: search "schedules"
step 3: answer
answer: Plus has unlimited schedules; free accounts have 5.
Stop Rules
Agents need firm limits, or they wander, repeat searches and run up costs:
- A maximum number of steps (for example 4) and a time or token budget.
- Stop when the same search repeats or when no new chunks appear.
- Answer with what you have, and say what's missing, when the limit is reached.
- Read-only tools by default. Any tool that changes something, like issuing a refund, needs explicit user approval.
Agentic RAG multiplies everything: model calls, latency, cost and injection risk. Each retrieved chunk can try to steer the next step. Use agents only for questions that need them, route simple questions to one-shot RAG (Lesson 14), and keep tools limited and permissioned.
Self-RAG and Reflection
Self-RAG (self-reflective RAG) and corrective RAG add checks inside the loop:
- Is retrieval needed? Some questions, like greetings, need no search.
- Is each retrieved chunk relevant? Drop or re-search if not (Lesson 11's corrective retrieval).
- Is the draft answer supported? Check each claim against its source (Lesson 18).
- Is the answer useful? Does it actually answer the question?
The original Self-RAG research trained a model to emit special "reflection" tokens. In practice, most teams build the same idea with grader prompts or small classifiers at each step.
Grade retrieval and the draft, retry if weak
// Self-RAG style reflection: grade the retrieval, then grade the draft answer.
function gradeRetrieval(question, chunk) {
const q = question
.toLowerCase()
.split(" ")
.filter((w) => w.length > 3);
return q.filter((w) => chunk.toLowerCase().includes(w)).length / q.length;
}
function gradeAnswer(answer, chunk) {
const nums = answer.match(/\d+/g) ?? [];
return nums.every((n) => chunk.includes(n)) ? "supported" : "not supported";
}
const question = "how long does standard shipping take";
const attempts = [
{
chunk: "Express shipping takes 1 to 2 business days.",
draft: "Standard shipping takes 1 to 2 days.",
},
{
chunk: "Standard shipping takes 3 to 5 business days.",
draft: "Standard shipping takes 3 to 5 business days.",
},
];
for (const [i, a] of attempts.entries()) {
const r = gradeRetrieval(question, a.chunk);
const g = gradeAnswer(a.draft, a.chunk);
const sameTopic = a.chunk.toLowerCase().includes("standard");
console.log(
`attempt ${i + 1}: relevance ${r.toFixed(2)}, mentions "standard": ${sameTopic}, draft ${g}`,
);
if (sameTopic && g === "supported") {
console.log("accepted:", a.draft);
break;
}
console.log(" -> rejected, retrieve again with a sharper query");
}
Expected output:
attempt 1: relevance 0.40, mentions "standard": false, draft supported
-> rejected, retrieve again with a sharper query
attempt 2: relevance 0.60, mentions "standard": true, draft supported
accepted: Standard shipping takes 3 to 5 business days.
The first attempt found a chunk about express shipping. Its draft was "supported" by that chunk, but it answered the wrong question. The relevance check caught it.
GraphRAG
Entity Graphs
GraphRAG builds a knowledge graph from your documents:
- Extract entities (products, features, integrations, people) and relationships ("pairs through", "requires", "supports") from each chunk, usually with a language model.
- Store them as nodes and edges, with links back to the source chunks.
- At question time, find the entities in the question and walk the graph to related entities and their chunks.
Build a small entity graph and walk it
// GraphRAG in miniature: build an entity graph from chunks, then answer a "big picture"
// question by walking the graph instead of matching one chunk.
const chunks = [
["Lumo Lamp", "Wi-Fi"],
["Lumo Lamp", "Brightgrid App"],
["Glow Strip", "Brightgrid Hub"],
["Brightgrid Hub", "Apple Home"],
["Brightgrid Hub", "Brightgrid App"],
["Brightgrid Plus", "Brightgrid App"],
];
const graph = new Map();
for (const [a, b] of chunks) {
for (const [x, y] of [
[a, b],
[b, a],
]) {
if (!graph.has(x)) {
graph.set(x, new Set());
}
graph.get(x).add(y);
}
}
// Which entity connects the most things? (A simple "hub" measure.)
const ranked = [...graph]
.map(([e, n]) => [e, n.size])
.sort((a, b) => b[1] - a[1] || a[0].localeCompare(b[0]));
console.log(
"most connected:",
ranked
.slice(0, 3)
.map(([e, n]) => `${e} (${n})`)
.join(", "),
);
console.log("Brightgrid Hub links:", [...graph.get("Brightgrid Hub")].join(", "));
console.log(
"Summary: the app ties products together; the hub links the Glow Strip and Apple Home.",
);
Expected output:
most connected: Brightgrid App (3), Brightgrid Hub (3), Lumo Lamp (2)
Brightgrid Hub links: Glow Strip, Apple Home, Brightgrid App
Summary: the app ties products together; the hub links the Glow Strip and Apple Home.
Community Summaries
For "big picture" questions, like "What are the main themes in our support tickets?" or "How do our products fit together?", GraphRAG groups densely connected nodes into communities, and writes a summary of each one ahead of time. A global question is answered from these summaries, not from a handful of top-k chunks.
When Graphs Beat Vectors
| Question type | Better approach |
|---|---|
| A single fact ("How long is the warranty?") | Vector or hybrid search |
| Connections ("Which products depend on the Hub?") | Graph traversal |
| Multi-hop chains through named entities | Graph, or an agent loop with search |
| Whole-corpus themes and summaries | GraphRAG community summaries |
| Rapidly changing content | Vectors (graphs cost more to keep updated) |
GraphRAG is powerful but expensive: building the graph needs many model calls, and the graph must be updated when documents change. Try it when you have many connection or summary questions that your gold set shows plain RAG can't answer.
Common mistakes
- Over-engineering: agents and graphs for questions one search answers.
- No stop rule, which leads to repeated searches, high cost and slow answers.
- Losing citations between steps, so the final answer can't be checked.
- Reflection that only checks support, not relevance, so answers are "supported" by the wrong chunk.
- Stale graphs that no longer match the documents.
Exercises
Each exercise ends with a value on the last line. Press Check to compare it with the expected answer.
What to Remember
- Decompose complex questions into parallel parts or sequential steps. Stepwise and multi-hop retrieval use each answer to shape the next search.
- Agentic RAG makes search a tool the model calls in a loop. Set step, time and token limits, detect repeats, and keep tools read-only unless approved.
- Self-RAG-style reflection checks whether retrieval is needed, whether chunks are relevant, and whether the answer is supported and useful, then retries.
- GraphRAG builds an entity graph and community summaries for connection and big-picture questions. It's costly to build and keep fresh.
- Route simple questions to one-shot RAG, and use advanced patterns only where they pay off.
Next: RAG Security, permissions, injection defense and privacy.