Source router (default)
All steps
Internal docs first, then the web
No retrieval needed
Parts of this pattern
- Question Input / output
- The user's question, e.g. 'What is our current parental leave policy?', which starts the retrieval loop.
- Agent LLM call
- Each hop it decides to search or answer, picks a source and rewrites the query; answers once context suffices.
- Source router Router
- Plain code: looks up step.source in the SOURCES table and forwards the rewritten query to that backend.
- Vector DB Memory
- Internal document index. Returns the top matching chunks for the agent's rewritten query.
- Web search Tool
- Live web search, used when internal chunks are stale or missing the answer. Returns snippets.
- SQL Tool
- Structured database the agent can query for exact figures, via run_query on a generated query.
- Answer Input / output
- The final cited answer, written once the agent judges its context sufficient.
- Question → Agent
- The user's question enters the agent, along with any context gathered so far (empty on hop one).
Question: What is our current parental leave policy for new hires?
- Agent → Source router
- The agent's chosen step: which source to search and the query rewritten for that source.
{"action": "search", "source": "vectordb", "query": "parental leave policy 2025 new hires"}
- Source router → Vector DB
- The router forwards the standalone query to the vector database when the agent picked vectordb.
search_vectors("parental leave policy 2025 new hires")
- Source router → Web search
- The router forwards the query to web search when the agent picked web.
search_web("company parental leave policy update 2026")
- Source router → SQL
- The router forwards a query to the SQL source when the agent picked sql.
run_query("SELECT leave_weeks FROM policies WHERE type = 'parental'")
- Vector DB → Agent
- Retrieved chunks are appended to the agent's context for the next hop.
3 chunks: "HR Handbook v3 (2023): 12 weeks paid parental leave..." (out of date)
- Web search → Agent
- Web snippets are appended to the agent's context for the next hop.
Snippet: "From Jan 2026 the company extends paid parental leave to 16 weeks." (hr.example.com/news)
- SQL → Agent
- Query rows come back as context for the agent's next decision.
rows: [{"leave_weeks": 16}]
- Agent → Answer
- Once context is enough the agent stops searching and sends its cited answer out.
{"action": "answer", "answer": "New hires get 16 weeks of paid parental leave [web: hr.example.com/news]."}
Interleaved (IRCoT)
One retriever is searched again after every sentence of reasoning, and each new sentence becomes the next search query.
All steps
Parts of this pattern
- Question Input / output
- A multi-hop question, such as 'In which country was the director of the film Lisbon Story born?'.
- Retriever Memory
- A single document index, searched first with the question and then with each new reasoning sentence.
- Reasoner LLM call
- Reads the paragraphs found so far and writes exactly one next sentence of reasoning each step.
- Answer Input / output
- The answer, taken from the sentence that starts 'So the answer is'.
- Question → Retrieverfirst query
- The question itself is the first search query.
In which country was the director of the film Lisbon Story born?
- Retriever → Reasonerparagraphs
- The top paragraphs join the pool that the reasoner reads before writing its next sentence.
Lisbon Story is a 1994 film written and directed by Wim Wenders...
- Reasoner → Retrievernext query
- Each new reasoning sentence is used as the next search query, so retrieval follows the chain of thought.
Lisbon Story was directed by Wim Wenders.
- Reasoner → Answeranswer
- When a sentence contains 'So the answer is', the loop ends and the answer is returned.
Wim Wenders was born in Düsseldorf, West Germany. So the answer is: Germany.
Adaptive by complexity
A classifier rates each question's complexity first, then answers with no retrieval, one retrieval, or an iterative multi-step loop.
All steps
A multi-step question
A simple question
Parts of this pattern
- Question Input / output
- The user's question, simple or multi-step, such as 'Where was the director of Lisbon Story born?'.
- Classifier Router
- A small model trained to label each question A (no retrieval), B (one search) or C (multi-step).
- Retriever Memory
- The document index: searched once for B questions and repeatedly for C questions.
- LLM LLM call
- Writes the answer; for C questions it may instead write a follow-up query and loop.
- Answer Input / output
- The final answer, from whichever strategy the classifier picked.
- Question → Classifier
- Every question is classified before any retrieval happens.
Simple: What is the capital of Portugal? Multi-step: Where was the director of the film Lisbon Story born?
- Classifier → LLMA: none
- Simple questions go straight to the model with no retrieval at all.
Q: What is the capital of Portugal? -> label A, no retrieval
- Classifier → RetrieverB/C: search
- Questions that need facts are searched once (B) or iteratively (C).
Q: Where was the director of Lisbon Story born? -> label C, multi-step
- Retriever → LLMdocs
- Retrieved documents are added to the model's context.
Lisbon Story is a 1994 film written and directed by Wim Wenders...
- LLM → Retrievernext query
- For C questions only, the model writes a follow-up query and the search repeats until it can answer.
Follow-up query: Wim Wenders birthplace
- LLM → Answer
- The model's answer, once its strategy has gathered what it needs.
Wim Wenders was born in Düsseldorf, so the answer is Germany.
← → neighboursesc atlas
Agentic RAG
Also known as Retrieval agent · Tool-based retrieval
The agent decides whether to retrieve, from which source, and with what rewritten query, and repeats until it has enough context.
Source router: No single inventor · see source
This survey systematizes agentic RAG but does not coin it; the term was in use before it, and no single originator was found.
Interleaved (IRCoT): Introduced by Trivedi et al. (2022) · Stony Brook University & Allen Institute for AI
IRCoT: Interleaving Retrieval with Chain-of-Thought Reasoning for Knowledge-Intensive Multi-Step Questions (ACL 2023).
Adaptive by complexity: Introduced by Jeong et al. (2024) · KAIST
Adaptive-RAG: Learning to Adapt Retrieval-Augmented Large Language Models through Question Complexity (NAACL 2024).
Measured over one run
Source router
- Nodes
- 7. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 3. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 1. Messages sent to a tool node in the first scenario.
- Steps
- 4. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 2. Distinct example runs you can switch between on the diagram.
- Loop
- no. Whether the flow cycles back on itself until a condition is met.
- Parallel
- no. Whether two or more messages are in flight at the same time.
- Branch
- yes. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- medium. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- medium. Relative token spend per request.
- Latency
- medium. Relative wall-clock time per request.
Interleaved (IRCoT)
- Nodes
- 4. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 4. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 3. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 1. Distinct example runs you can switch between on the diagram.
- Loop
- yes. Whether the flow cycles back on itself until a condition is met.
- Parallel
- no. Whether two or more messages are in flight at the same time.
- Branch
- yes. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- medium. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- medium. Relative token spend per request.
- Latency
- medium. Relative wall-clock time per request.
Adaptive by complexity
- Nodes
- 5. Boxes in the diagram: models, tools, stores, people and plain code.
- LLM calls
- 4. Model invocations in the first scenario: each time a model or agent node starts thinking, plus each branch it decides.
- Tool calls
- 0. Messages sent to a tool node in the first scenario.
- Steps
- 3. Steps in the first scenario, with repeated steps counted every time they run.
- Scenarios
- 2. Distinct example runs you can switch between on the diagram.
- Loop
- yes. Whether the flow cycles back on itself until a condition is met.
- Parallel
- no. Whether two or more messages are in flight at the same time.
- Branch
- yes. Whether the flow takes one path out of several, chosen at run time.
- Human in the loop
- no. Whether a person appears as a node, to approve, correct or answer.
- Autonomy
- medium. How much the model decides the control flow itself, from fixed code paths (low) to open-ended (high).
- Cost
- medium. Relative token spend per request.
- Latency
- medium. Relative wall-clock time per request.
Counted from the first scenario's timeline when the site is built.
Problem
Classic retrieval-augmented generation always retrieves once, from one index, using the user’s raw question. That fails in three ways. Some questions need no retrieval at all. Some need a different source, such as a SQL table of orders instead of a wiki. And some need several lookups, where the first result tells you what to ask next.
How it works
Hand retrieval to an agent as a set of tools. On each hop the agent reads the question and everything gathered so far, then chooses one of two moves: answer, or search. A search names a source and a query rewritten for that source. A source router sends it to the vector database for internal documents, to web search for fresh facts, or to SQL for structured records.
Whatever comes back is appended to the agent’s context and the loop runs again. A question like “Did our refund policy change after the March incident?” might hit the vector database for the policy, find that the chunks predate March, then query the web or an incident log with a sharper question. When the agent judges the context sufficient, it writes the answer with citations.
Two narrower designs appear as tabs. Interleaved retrieval (IRCoT) uses a single index and searches again after every sentence of reasoning. Adaptive-RAG classifies each question’s complexity first and runs no retrieval, one retrieval or a multi-step loop to match.
When to use
- Questions span several knowledge sources with different strengths.
- A single query rarely finds everything, so follow-up searches matter.
- Many questions need no retrieval, and you want to skip the cost on those.
When to avoid
- One well-tuned index answers nearly everything. Plain RAG is cheaper and easier to debug.
- You need predictable latency. The number of hops varies per question.
- The agent has no way to tell good context from bad. Add a grader, as in Corrective RAG.
Trade-offs
Each hop is a model call plus a search, so latency and cost grow with the hop count and vary per question. In exchange you get better recall and the ability to cover several sources. The agent’s tool descriptions become part of your retrieval quality: vague source descriptions produce wrong routing.
Failure modes
- Over-searching: the agent keeps retrieving when it already has enough. Cap the hops and force an answer at the cap.
- Under-searching: it answers from memory when it should have looked. Instruct it to cite context, and reject uncited factual claims.
- Query drift: each rewrite wanders from the original intent. Keep the original question in every prompt.
- Wrong source: it queries SQL for something that lives in docs. Describe each source’s contents and limits precisely.
Build it with your AI
Source router
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Agentic RAG pattern in this codebase, using the LLM client and language we already use.
## Goal
Answer a question by letting a model decide, hop by hop, whether to search, which source to search and with what rewritten query, until the context it has gathered is enough for a cited answer.
## How it works
1. Describe each source (vector index, web search, SQL) in one line, and keep a table from each source name to the function that searches it.
2. Call the model with the Retrieval agent prompt, filling in the question, the context gathered so far (empty at first) and the source descriptions, and parse its JSON step.
3. If action is answer, return the answer with its citations.
4. If action is search, look up the named source in the table, run the rewritten query, and append the top results to the context, each tagged with its source.
5. If the JSON does not parse or names an unknown source, retry the call once with the error appended; if it fails again, answer from the context so far.
6. If a search fails or times out, append a note saying that source failed, so the model can choose another, and loop.
## Prompts
### Retrieval agent prompt
```markdown
You answer the user's question. You may search before answering.
<question>{{question}}</question>
<context_so_far>{{context}}</context_so_far>
Sources you can search: {{source_descriptions}}
Decide the next step. Respond in JSON:
{"action": "search" | "answer",
"source": "<one of the sources>",
"query": "a standalone search query, rewritten for that source",
"answer": "only when action is answer; cite the context you used"}
Answer as soon as the context is enough. Never invent facts that are not in the context.
```
## Stop rule
Stop when the model answers, or after 4 search hops. At the cap, call the model once more with search removed from the allowed actions and return that answer, flagged as having hit the hop limit.
## Requirements
- Make the hop cap (default 4) and the results per search (default 3 chunks or rows) parameters.
- Route with plain code, never a model call: the model names the source and the table dispatches the query.
- Give the SQL source a read-only connection, a timeout and a row limit.
- Log every hop: the chosen source, the rewritten query and the ids of the results.
- Add a test with a stub LLM that searches vectordb, then web, then answers; assert one call to each of those two backends, none to SQL, and that the answer cites the web result.
Interleaved (IRCoT)
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Agentic RAG pattern (Interleaved (IRCoT) variant) in this codebase, using the LLM client and language we already use.
## Goal
Answer a multi-hop question by alternating one sentence of reasoning with one retrieval, using each new sentence as the next search query.
## How it works
1. Search the index with the question and put the top 4 paragraphs in a paragraph pool.
2. Call the model with the Step-by-step reasoner prompt, filling in the question, the pool and the reasoning so far; keep only the first sentence of its reply.
3. If the sentence contains 'So the answer is:', return the text after it, with the reasoning and the ids of the paragraphs used.
4. Otherwise search the index with that sentence, add any new paragraphs to the pool, append the sentence to the reasoning, and call the model again.
5. If a search fails, keep the pool as it is and continue; the next sentence becomes the next query.
## Prompts
### Step-by-step reasoner prompt
```markdown
Answer the question by reasoning one step at a time, using the paragraphs.
<paragraphs>{{paragraphs}}</paragraphs>
<question>{{question}}</question>
<reasoning_so_far>{{reasoning}}</reasoning_so_far>
Write exactly one next sentence of reasoning.
When you know the answer, write that sentence as: So the answer is: <answer>
```
## Stop rule
Stop when a sentence contains the answer marker, or after 6 sentences. At the cap, ask the model for the answer directly from the pool and return it, flagged as having hit the step limit.
## Requirements
- Make the sentence cap (default 6), the paragraphs per search (default 4) and the pool cap (default 15 paragraphs) parameters.
- De-duplicate paragraphs by id before adding them, and drop the oldest when the pool is full.
- Cut the model's reply to its first sentence, so a reply that runs ahead cannot skip retrievals.
- Log each sentence with the paragraph ids its search returned.
- Add a test with a stub LLM that writes 'X was directed by Y.' and then 'So the answer is: Z'; assert two searches, the second with the query 'X was directed by Y.', and the answer 'Z'.
Adaptive by complexity
Paste this into Claude Code, Cursor, ChatGPT or any AI coding assistant.
Implement the Agentic RAG pattern (Adaptive by complexity variant) in this codebase, using the LLM client and language we already use.
## Goal
Spend retrieval only where it pays off: classify each question as needing no retrieval, one retrieval or iterative multi-step retrieval, then run the matching strategy.
## How it works
1. Send the question to a small classifier that returns one label: A (no retrieval), B (single-step) or C (multi-step).
2. For A, call the model with the question alone and return its answer.
3. For B, search the index once with the question, then call the model with the question and the top 5 documents.
4. For C, loop: search, call the model with the Retrieval agent prompt (with the index as the only source) and every document so far, and either return its answer or search again with the follow-up query it writes.
5. If the classifier fails or returns an unknown label, treat the question as B. If a search fails, answer from the documents so far (for B, from the question alone) and flag the answer.
## Prompts
### Retrieval agent prompt
```markdown
You answer the user's question. You may search before answering.
<question>{{question}}</question>
<context_so_far>{{context}}</context_so_far>
Sources you can search: {{source_descriptions}}
Decide the next step. Respond in JSON:
{"action": "search" | "answer",
"source": "<one of the sources>",
"query": "a standalone search query, rewritten for that source",
"answer": "only when action is answer; cite the context you used"}
Answer as soon as the context is enough. Never invent facts that are not in the context.
```
## Stop rule
A and B end after one model call. C ends when the model answers, or after 4 searches; at the cap, answer from the documents gathered and flag the answer as having hit the limit.
## Requirements
- Make the search cap for C (default 4) and the documents per search (default 5) parameters.
- Train or prompt the classifier on labelled examples of all three classes, and track how often each label is chosen.
- Log the label, the strategy run, its search count and its latency for every question.
- Add a test with a stub classifier that returns A and a stub retriever; assert the retriever is never called and the model is called exactly once.
Prompt templates
Source router · Adaptive by complexity
You answer the user's question. You may search before answering.
<question>{{question}}</question><context_so_far>{{context}}</context_so_far>
Sources you can search: {{source_descriptions}}
Decide the next step. Respond in JSON:{"action": "search" | "answer", "source": "<one of the sources>", "query": "a standalone search query, rewritten for that source", "answer": "only when action is answer; cite the context you used"}Answer as soon as the context is enough. Never invent facts that are not in the context.Interleaved (IRCoT)
Answer the question by reasoning one step at a time, using the paragraphs.
<paragraphs>{{paragraphs}}</paragraphs><question>{{question}}</question><reasoning_so_far>{{reasoning}}</reasoning_so_far>
Write exactly one next sentence of reasoning.When you know the answer, write that sentence as: So the answer is: <answer>Related patterns
Composes well with:
Sources
From the Agentic Atlas by Joran Kikke · Edit on GitHub · Suggest a correction