Skip to content
JavaAgentic

Type at least two characters. Try “RAG”, “pgvector” or “tool calling”.

Agentic RAG — Advanced Patterns

Advanced RAG where the model controls retrieval: self-RAG, corrective RAG, adaptive retrieval and query planning — when to let an agent decide whether and what to retrieve, in Java.

Advanced4 min readUpdated
On this page

Basic RAG retrieves once with the raw question and answers. That fails on multi-hop questions, questions that need no retrieval, and cases where the first retrieval was poor. Agentic RAG lets the model control the retrieval process. This tutorial covers the main patterns and when they are worth the added cost.

Key Takeaways

  • Agentic RAG lets the model decide whether, what, and how many times to retrieve.
  • Self-RAG reflects on relevance and support; corrective RAG falls back when retrieval is poor.
  • Query planning decomposes multi-hop questions into sequential retrievals.
  • It costs extra model calls — use it only when basic RAG genuinely falls short.

Where basic RAG breaks

Basic RAG handles only the first case well. Agentic RAG handles the others.

Basic RAG assumes every question needs exactly one retrieval with the raw wording. Real questions violate that constantly.

Self-RAG: reflect on retrieval

The model judges its own retrieval and answer, retrieving again or abstaining when needed:

Self-RAG loop
public Answer selfRag(String question) {
    // 1. Does this even need retrieval?
    if (!retrievalDecider.needsRetrieval(question)) {
        return answerer.answerDirectly(question);
    }
 
    for (int attempt = 0; attempt < MAX_RETRIEVALS; attempt++) {
        List<Document> docs = retriever.retrieve(question);
 
        // 2. Are the retrieved passages actually relevant?
        List<Document> relevant = docs.stream()
                .filter(d -> relevanceJudge.isRelevant(question, d))
                .toList();
 
        if (relevant.isEmpty()) {
            question = queryRewriter.rephrase(question);   // try a better query
            continue;
        }
 
        Answer answer = answerer.answer(question, relevant);
 
        // 3. Is the answer supported by the passages?
        if (supportJudge.isSupported(answer, relevant)) {
            return answer;
        }
    }
    // Abstain rather than answer from unsupported context.
    return Answer.insufficient();
}

Corrective RAG: fall back when retrieval fails

When the knowledge base has gaps, corrective RAG detects poor retrieval and takes a different route:

Corrective RAG
public Answer correctiveRag(String question) {
    List<Document> docs = retriever.retrieve(question);
    RetrievalQuality quality = evaluator.assess(question, docs);
 
    return switch (quality) {
        // Good: answer from the knowledge base.
        case STRONG -> answerer.answer(question, docs);
        // Weak: supplement with a broader or web search before answering.
        case AMBIGUOUS -> answerer.answer(question, merge(docs, webSearch.search(question)));
        // None: do not answer from irrelevant context.
        case POOR -> Answer.notFound(question);
    };
}

This makes RAG robust to the reality that your vector store does not contain everything — instead of confidently answering a gap from whatever weak matches came back.

Query planning for multi-hop questions

Some questions require chaining retrievals: "which of our suppliers is in a country affected by the new tariff?" needs the tariff list, then the supplier list, then a join. An agent plans this:

Multi-hop query planning
public Answer multiHop(String question) {
    List<SubQuery> plan = planner.decompose(question);
 
    Map<String, List<Document>> gathered = new LinkedHashMap<>();
    for (SubQuery sub : plan) {
        // Each sub-query can use results from earlier ones.
        String resolved = resolveReferences(sub, gathered);
        gathered.put(sub.id(), retriever.retrieve(resolved));
    }
    return synthesiser.answer(question, gathered);
}

Adaptive retrieval

Not every question needs the same retrieval effort. Adaptive RAG routes by question complexity:

return switch (complexityClassifier.classify(question)) {
    case SIMPLE -> answerer.answerDirectly(question);       // no retrieval
    case SINGLE_HOP -> basicRag(question);                  // one retrieval
    case MULTI_HOP -> multiHop(question);                   // planned retrievals
};

This spends retrieval budget where it is needed and saves it where it is not — cheaper on average than running the full agentic pipeline on every question.

Choosing the pattern

SituationPattern
Single-retrieval questions answered wellBasic RAG
Need honest "I don't know"Self-RAG
Knowledge base has gapsCorrective RAG (with fallback)
Multi-hop questionsQuery planning
Mixed question complexityAdaptive routing

Next

Frequently Asked Questions

What is agentic RAG?
RAG where the model decides whether to retrieve, what to search for, and whether the results are sufficient — rather than always retrieving once with the raw question. It handles questions that need multiple retrievals, questions that need no retrieval, and cases where the first retrieval was poor, at the cost of extra model calls and complexity.
What is self-RAG?
A pattern where the model reflects on retrieval: it decides if retrieval is needed, judges whether retrieved passages are relevant, and assesses whether its answer is supported by them — retrieving again or abstaining if not. It reduces both hallucination and needless retrieval, at the cost of the extra reflection calls.
What is corrective RAG?
A pattern that evaluates retrieved documents and takes corrective action when they are poor — for example falling back to a web search or a broader query when the vector store returns nothing relevant. It makes RAG robust to gaps in the knowledge base rather than confidently answering from irrelevant context.
When should I use agentic RAG instead of basic RAG?
When basic RAG is not enough: questions that require several retrievals to answer, a knowledge base with gaps that need fallbacks, or a mix of questions where some need retrieval and some do not. If your questions are answered well by a single retrieval, basic RAG is simpler, cheaper and the right choice — do not add agentic complexity you do not need.

Related tutorials