agentic-rag-patterns

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Agentic RAG Patterns

Agent化RAG模式

Build self-correcting retrieval systems with LLM-driven decision making.
LangGraph 1.0.6 (Jan ): langgraph-checkpoint 4.0.0, compile-time checkpointer validation, namespace sanitization.
构建由LLM驱动决策的自修正检索系统。
LangGraph 1.0.6 (Jan ): langgraph-checkpoint 4.0.0, compile-time checkpointer validation, namespace sanitization.

Architecture Overview

架构概述

Query → [Retrieve] → [Grade] → [Generate/Rewrite/Web Search] → Response
              ↓           ↓
         Documents    Quality Check
                   Route Decision:
                   - Good docs → Generate
                   - Poor docs → Rewrite query
                   - No docs → Web fallback
Query → [Retrieve] → [Grade] → [Generate/Rewrite/Web Search] → Response
              ↓           ↓
         Documents    Quality Check
                   Route Decision:
                   - Good docs → Generate
                   - Poor docs → Rewrite query
                   - No docs → Web fallback

Self-RAG State Definition

Self-RAG状态定义

python
from langgraph.graph import StateGraph, START, END
from typing import TypedDict, List, Annotated
from langchain_core.documents import Document
import operator

class RAGState(TypedDict):
    """State for agentic RAG workflows."""
    question: str
    documents: Annotated[List[Document], operator.add]
    generation: str
    web_search_needed: bool
    retry_count: int
    relevance_scores: dict[str, float]
python
from langgraph.graph import StateGraph, START, END
from typing import TypedDict, List, Annotated
from langchain_core.documents import Document
import operator

class RAGState(TypedDict):
    """State for agentic RAG workflows."""
    question: str
    documents: Annotated[List[Document], operator.add]
    generation: str
    web_search_needed: bool
    retry_count: int
    relevance_scores: dict[str, float]

Core Retrieval Node

核心检索节点

python
def retrieve(state: RAGState) -> dict:
    """Retrieve documents from vector store."""
    question = state["question"]
    documents = retriever.invoke(question)
    return {"documents": documents, "question": question}
python
def retrieve(state: RAGState) -> dict:
    """Retrieve documents from vector store."""
    question = state["question"]
    documents = retriever.invoke(question)
    return {"documents": documents, "question": question}

Document Grading (Self-RAG Core)

文档评分(Self-RAG核心)

python
from pydantic import BaseModel, Field

class GradeDocuments(BaseModel):
    """Binary score for document relevance."""
    binary_score: str = Field(
        description="Relevance score 'yes' or 'no'"
    )

def grade_documents(state: RAGState) -> dict:
    """Grade documents for relevance - core Self-RAG pattern."""
    question = state["question"]
    documents = state["documents"]

    filtered_docs = []
    relevance_scores = {}

    for doc in documents:
        score = retrieval_grader.invoke({
            "question": question,
            "document": doc.page_content
        })
        doc_id = doc.metadata.get("id", hash(doc.page_content))
        relevance_scores[doc_id] = 1.0 if score.binary_score == "yes" else 0.0

        if score.binary_score == "yes":
            filtered_docs.append(doc)

    # Trigger web search if too many docs filtered out
    web_search_needed = len(filtered_docs) < len(documents) // 2

    return {
        "documents": filtered_docs,
        "web_search_needed": web_search_needed,
        "relevance_scores": relevance_scores
    }
python
from pydantic import BaseModel, Field

class GradeDocuments(BaseModel):
    """Binary score for document relevance."""
    binary_score: str = Field(
        description="Relevance score 'yes' or 'no'"
    )

def grade_documents(state: RAGState) -> dict:
    """Grade documents for relevance - core Self-RAG pattern."""
    question = state["question"]
    documents = state["documents"]

    filtered_docs = []
    relevance_scores = {}

    for doc in documents:
        score = retrieval_grader.invoke({
            "question": question,
            "document": doc.page_content
        })
        doc_id = doc.metadata.get("id", hash(doc.page_content))
        relevance_scores[doc_id] = 1.0 if score.binary_score == "yes" else 0.0

        if score.binary_score == "yes":
            filtered_docs.append(doc)

    # Trigger web search if too many docs filtered out
    web_search_needed = len(filtered_docs) < len(documents) // 2

    return {
        "documents": filtered_docs,
        "web_search_needed": web_search_needed,
        "relevance_scores": relevance_scores
    }

Query Transformation

查询转换

python
def transform_query(state: RAGState) -> dict:
    """Transform query for better retrieval."""
    question = state["question"]

    better_question = question_rewriter.invoke({
        "question": question,
        "feedback": "Rephrase to improve retrieval. Be specific."
    })

    return {
        "question": better_question,
        "retry_count": state.get("retry_count", 0) + 1
    }
python
def transform_query(state: RAGState) -> dict:
    """Transform query for better retrieval."""
    question = state["question"]

    better_question = question_rewriter.invoke({
        "question": question,
        "feedback": "Rephrase to improve retrieval. Be specific."
    })

    return {
        "question": better_question,
        "retry_count": state.get("retry_count", 0) + 1
    }

Web Search Fallback (CRAG)

网页搜索回退(CRAG)

python
def web_search(state: RAGState) -> dict:
    """Fallback to web search when documents insufficient."""
    question = state["question"]

    web_results = tavily_client.search(
        question,
        max_results=5,
        search_depth="advanced"
    )

    web_docs = [
        Document(
            page_content=r["content"],
            metadata={"source": r["url"], "type": "web"}
        )
        for r in web_results
    ]

    return {"documents": web_docs, "web_search_needed": False}
python
def web_search(state: RAGState) -> dict:
    """Fallback to web search when documents insufficient."""
    question = state["question"]

    web_results = tavily_client.search(
        question,
        max_results=5,
        search_depth="advanced"
    )

    web_docs = [
        Document(
            page_content=r["content"],
            metadata={"source": r["url"], "type": "web"}
        )
        for r in web_results
    ]

    return {"documents": web_docs, "web_search_needed": False}

Generation Node

生成节点

python
def generate(state: RAGState) -> dict:
    """Generate answer from documents."""
    question = state["question"]
    documents = state["documents"]

    context = "\n\n".join([
        f"[{i+1}] {doc.page_content}"
        for i, doc in enumerate(documents)
    ])

    generation = rag_chain.invoke({
        "context": context,
        "question": question
    })

    return {"generation": generation}
python
def generate(state: RAGState) -> dict:
    """Generate answer from documents."""
    question = state["question"]
    documents = state["documents"]

    context = "\n\n".join([
        f"[{i+1}] {doc.page_content}"
        for i, doc in enumerate(documents)
    ])

    generation = rag_chain.invoke({
        "context": context,
        "question": question
    })

    return {"generation": generation}

Conditional Routing

条件路由

python
def route_after_grading(state: RAGState) -> str:
    """Route based on document quality."""
    if state["web_search_needed"]:
        if state.get("retry_count", 0) < 2:
            return "transform_query"  # Try rewriting first
        return "web_search"  # Fallback to web
    return "generate"  # Documents are good

workflow.add_conditional_edges(
    "grade",
    route_after_grading,
    {
        "generate": "generate",
        "transform_query": "transform_query",
        "web_search": "web_search"
    }
)
python
def route_after_grading(state: RAGState) -> str:
    """Route based on document quality."""
    if state["web_search_needed"]:
        if state.get("retry_count", 0) < 2:
            return "transform_query"  # Try rewriting first
        return "web_search"  # Fallback to web
    return "generate"  # Documents are good

workflow.add_conditional_edges(
    "grade",
    route_after_grading,
    {
        "generate": "generate",
        "transform_query": "transform_query",
        "web_search": "web_search"
    }
)

Complete CRAG Workflow

完整CRAG工作流

python
def build_crag_workflow() -> StateGraph:
    """Build Corrective-RAG workflow with web fallback."""
    workflow = StateGraph(RAGState)

    # Add nodes
    workflow.add_node("retrieve", retrieve)
    workflow.add_node("grade", grade_documents)
    workflow.add_node("generate", generate)
    workflow.add_node("web_search", web_search)
    workflow.add_node("transform_query", transform_query)

    # Define edges
    workflow.add_edge(START, "retrieve")
    workflow.add_edge("retrieve", "grade")

    # Conditional routing based on document quality
    workflow.add_conditional_edges(
        "grade",
        route_after_grading,
        {
            "generate": "generate",
            "transform_query": "transform_query",
            "web_search": "web_search"
        }
    )

    # After query transform, retry retrieval
    workflow.add_edge("transform_query", "retrieve")

    # Web search leads to generation
    workflow.add_edge("web_search", "generate")

    workflow.add_edge("generate", END)

    return workflow.compile()
python
def build_crag_workflow() -> StateGraph:
    """Build Corrective-RAG workflow with web fallback."""
    workflow = StateGraph(RAGState)

    # Add nodes
    workflow.add_node("retrieve", retrieve)
    workflow.add_node("grade", grade_documents)
    workflow.add_node("generate", generate)
    workflow.add_node("web_search", web_search)
    workflow.add_node("transform_query", transform_query)

    # Define edges
    workflow.add_edge(START, "retrieve")
    workflow.add_edge("retrieve", "grade")

    # Conditional routing based on document quality
    workflow.add_conditional_edges(
        "grade",
        route_after_grading,
        {
            "generate": "generate",
            "transform_query": "transform_query",
            "web_search": "web_search"
        }
    )

    # After query transform, retry retrieval
    workflow.add_edge("transform_query", "retrieve")

    # Web search leads to generation
    workflow.add_edge("web_search", "generate")

    workflow.add_edge("generate", END)

    return workflow.compile()

Pattern Comparison

模式对比

PatternWhen to UseKey Feature
Self-RAGNeed adaptive retrievalLLM decides when to retrieve
CRAGNeed quality assuranceDocument grading + web fallback
GraphRAGEntity-rich domainsKnowledge graph + vector hybrid
AgenticComplex multi-stepFull plan-route-act-verify loop
模式适用场景核心特性
Self-RAG需要自适应检索由LLM决定何时执行检索
CRAG需要质量保障文档评分 + 网页回退
GraphRAG实体密集型领域知识图谱 + 向量混合检索
Agent化复杂多步骤任务完整的规划-路由-执行-验证循环

Key Decisions

关键决策建议

DecisionRecommendation
Grading thresholdBinary (yes/no) simpler than scores
Max retries2-3 for query rewriting
Web searchUse as last resort (latency, cost)
Fallback orderRewrite → Web → Abstain
决策项推荐方案
评分阈值二元(是/否)比分值更简单
最大重试次数查询重写设置2-3次
网页搜索作为最后手段(考虑延迟、成本)
回退顺序重写 → 网页搜索 → 放弃回答

Common Mistakes

常见错误

  • No fallback path (hangs on bad queries)
  • Infinite rewrite loops (no retry limit)
  • Web search on every query (expensive)
  • Not tracking relevance scores (can't debug)
  • 未设置回退路径(遇到无效查询时停滞)
  • 无限重写循环(未设置重试限制)
  • 每次查询都触发网页搜索(成本高昂)
  • 未跟踪相关性分数(无法调试)

Related Skills

相关技能

  • rag-retrieval
    - Basic RAG patterns this enhances
  • langgraph-routing
    - Conditional edge patterns
  • langgraph-state
    - State design with reducers
  • contextual-retrieval
    - Anthropic's context-prepending
  • reranking-patterns
    - Post-retrieval reranking
  • rag-retrieval
    - 本技术所增强的基础RAG模式
  • langgraph-routing
    - 条件边模式
  • langgraph-state
    - 结合Reducer的状态设计
  • contextual-retrieval
    - Anthropic的上下文前置技术
  • reranking-patterns
    - 检索后重排序

Capability Details

能力详情

self-rag

self-rag

Keywords: self-rag, adaptive retrieval, reflection tokens Solves:
  • Build self-correcting RAG systems
  • Implement adaptive retrieval logic
  • Add reflection tokens for quality
关键词: self-rag, adaptive retrieval, reflection tokens 解决问题:
  • 构建自修正RAG系统
  • 实现自适应检索逻辑
  • 添加反射令牌提升质量

corrective-rag

corrective-rag

Keywords: crag, document grading, web fallback Solves:
  • Implement CRAG workflows
  • Grade document relevance
  • Add web search fallback
关键词: crag, document grading, web fallback 解决问题:
  • 实现CRAG工作流
  • 对文档相关性评分
  • 添加网页搜索回退机制

knowledge-graph-rag

knowledge-graph-rag

Keywords: graphrag, neo4j, entity extraction Solves:
  • Combine KG with vector search
  • Entity-based retrieval
  • Multi-hop reasoning
关键词: graphrag, neo4j, entity extraction 解决问题:
  • 结合知识图谱与向量搜索
  • 基于实体的检索
  • 多跳推理

adaptive-retrieval

adaptive-retrieval

Keywords: query routing, multi-source, orchestration Solves:
  • Route queries to optimal sources
  • Multi-retriever orchestration
  • Dynamic retrieval strategies
关键词: query routing, multi-source, orchestration 解决问题:
  • 将查询路由至最优数据源
  • 多检索器编排
  • 动态检索策略