Home 論文解説: Smart RAG — クエリ分解×知識源評価×適応生成でRAG精度を段階的に改善
投稿
キャンセル

📄 論文解説: Smart RAG — クエリ分解×知識源評価×適応生成でRAG精度を段階的に改善

論文概要(Abstract)

Smart RAG(Lu et al., 2025)は、RAGシステムを3つのコンポーネント(クエリ分解・知識源評価・適応的生成)で強化するフレームワークです。従来のRAGが全クエリに同一の検索戦略を適用する「ワンサイズフィッツオール」の問題を、クエリ複雑度に応じた段階的な処理で解決します。HotpotQAで75.1%(Adaptive-RAG比+3.3%)、MuSiQueで47.6%(+4.4%)を、検索呼び出し増加わずか15%で達成しています。

この記事は Zenn記事: LangGraph×Claude Sonnet 4.6で実装する階層的Agentic RAG検索パイプライン の深掘りです。

情報源

背景と動機(Background & Motivation)

従来のRAGシステムは、クエリの種類や複雑度に関係なく同一の検索戦略を適用します。これにより2つの問題が発生します。(1)単純なクエリでは不要な検索がノイズを導入し、(2)複雑なマルチホップクエリでは1回の検索では必要な情報が不足します。

Zenn記事で紹介されているクエリ複雑度ルーター(Haiku 4.5でsimple / moderate / complexを分類)は、Smart RAGと同じ発想に基づいています。Smart RAGはこの発想をさらに発展させ、分類だけでなくサブクエリ分解知識源評価も統合した包括的フレームワークを提案します。

主要な貢献(Key Contributions)

  • 貢献1: Query Decomposition — 複雑なクエリをサブクエリに分解し、逐次的に情報を収集する仕組み
  • 貢献2: Knowledge Source Assessment — 内部知識・検索結果・構造化KBの3つの知識ソースをスコアリングし、最適ソースを動的に選択
  • 貢献3: Adaptive Generation — クエリ複雑度とソース品質に基づいて生成戦略を切り替える効率的なパイプライン

技術的詳細(Technical Details)

コンポーネント1: クエリ複雑度分類器

Smart RAGはまず、クエリを3つの複雑度レベルに分類します。

レベル定義処理
Simple単一ホップの事実質問分解不要「Pythonの最新バージョンは?」
Complexマルチホップ、分解が必要サブクエリに分解「GPT-4の学習データで訴訟になったものは?」
Ambiguousスコープが不明確確認生成「AIの影響について教えて」

分類器はBERTベースの軽量モデル(89%の分類精度)で、ファインチューニングが必要です。

\[\text{class}(q) = \arg\max_{c \in \{S, C, A\}} \sigma(\mathbf{W} \cdot \text{BERT}(q) + \mathbf{b})_c\]

ここで$\sigma$はsoftmax、$\mathbf{W}$と$\mathbf{b}$は分類ヘッドのパラメータです。

Zenn記事のHaiku 4.5ルーターとの比較:

  • Smart RAGのBERT分類器: 89%精度、ファインチューニング必要、レイテンシ数ms
  • Zenn記事のHaiku 4.5: プロンプトベースで学習不要、レイテンシ数十ms、分類精度はプロンプト品質に依存

コンポーネント2: クエリ分解

Complex判定されたクエリは、LLMのfew-shot promptingでサブクエリに分解されます。

\[q \rightarrow \{q_1, q_2, \ldots, q_n\}\]

サブクエリは逐次的に実行され、各結果が次のサブクエリのコンテキストとして渡されます。

\[e_i = \text{Retrieve}(q_i \oplus e_1 \oplus \cdots \oplus e_{i-1})\]

この逐次実行パターンは、CoRAGの検索チェーンやA-RAGの反復検索と同じ着想ですが、Smart RAGの特徴は明示的なサブクエリ分解を行う点です。A-RAGではエージェントが暗黙的に次の検索を決定しますが、Smart RAGではサブクエリが事前に生成されます。

コンポーネント3: 知識源評価

Smart RAGは3つの知識ソースを評価してスコアリングします。

知識ソース評価方法適するケース
内部LLM知識Self-Consistency(複数回生成の一致度)広く知られた事実
検索ドキュメントBM25スコア + セマンティック類似度最新情報、ドメイン知識
構造化KBWikidata API(オプション)エンティティの関係性

最適ソースの選択:

\[s^* = \arg\max_{s \in \{I, R, K\}} \text{score}(s, q)\]

ここで$I$は内部知識、$R$は検索結果、$K$は構造化KBです。

この知識源評価は、Zenn記事の検索結果グレーディング(DocumentGradeによるis_relevant / confidence / missing_infoの評価)と直接対応します。Smart RAGはグレーディングを検索前に行う(どのソースを使うかを事前判断する)点が特徴的です。

コンポーネント4: 適応的生成

複雑度と知識源スコアの組み合わせで、生成戦略を動的に選択します。

複雑度知識源生成戦略
Simple + 高い内部知識確信度内部知識検索なしで直接回答
Complex + 良好な検索結果検索ドキュメントマルチステップRAG
Ambiguous-確認質問を生成

LangGraphでの実装パターン

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
from typing import TypedDict, Literal

from langgraph.graph import StateGraph, START, END
from langchain_anthropic import ChatAnthropic


class SmartRAGState(TypedDict):
    """Smart RAGの状態スキーマ"""
    query: str
    complexity: str  # simple / complex / ambiguous
    sub_queries: list[str]
    current_sub_query_idx: int
    accumulated_context: str
    source_scores: dict[str, float]
    final_answer: str


def classify_complexity(state: SmartRAGState) -> dict:
    """クエリ複雑度を分類(Haiku 4.5で実装)"""
    llm = ChatAnthropic(model="claude-haiku-4-5-20251001", max_tokens=256)
    # Smart RAGのBERT分類器をプロンプトベースで近似
    result = llm.invoke([
        {"role": "system", "content": (
            "Classify the query complexity:\n"
            "- simple: single-hop factual\n"
            "- complex: multi-hop, needs decomposition\n"
            "- ambiguous: unclear scope\n"
            "Reply with ONLY the class name."
        )},
        {"role": "user", "content": state["query"]},
    ])
    return {"complexity": result.content.strip().lower()}


def decompose_query(state: SmartRAGState) -> dict:
    """Complexクエリをサブクエリに分解"""
    llm = ChatAnthropic(model="claude-sonnet-4-6", max_tokens=1024)
    result = llm.invoke([
        {"role": "system", "content": (
            "Break down this complex question into 2-4 "
            "simpler sub-questions that can be answered "
            "individually. Return one question per line."
        )},
        {"role": "user", "content": state["query"]},
    ])
    sub_queries = [
        line.strip()
        for line in result.content.strip().split("\n")
        if line.strip()
    ]
    return {"sub_queries": sub_queries, "current_sub_query_idx": 0}


def route_by_complexity(
    state: SmartRAGState,
) -> Literal["decompose", "search", "clarify"]:
    """複雑度に基づくルーティング"""
    if state["complexity"] == "complex":
        return "decompose"
    elif state["complexity"] == "simple":
        return "search"
    return "clarify"


def build_smart_rag_graph() -> StateGraph:
    """Smart RAGグラフを構築"""
    graph = StateGraph(SmartRAGState)

    graph.add_node("classify", classify_complexity)
    graph.add_node("decompose", decompose_query)
    graph.add_node("search", search_and_assess)  # 検索+ソース評価
    graph.add_node("generate", adaptive_generate)  # 適応的生成
    graph.add_node("clarify", generate_clarification)

    graph.add_edge(START, "classify")
    graph.add_conditional_edges(
        "classify",
        route_by_complexity,
        {"decompose": "decompose", "search": "search", "clarify": "clarify"},
    )
    graph.add_edge("decompose", "search")
    graph.add_edge("search", "generate")
    graph.add_edge("generate", END)
    graph.add_edge("clarify", END)

    return graph.compile()

実装のポイント(Implementation)

分類器のプロンプトベース近似

Smart RAGのBERT分類器(89%精度)をデプロイするには、ファインチューニング済みモデルのホスティングが必要です。Zenn記事のようにClaude Haiku 4.5をプロンプトベースで使う方法は、精度はやや劣る可能性がありますが、追加のモデルデプロイが不要で運用が簡単です。

サブクエリ分解の品質

分解品質はLLMの能力に大きく依存します。Claude Sonnet 4.6のadaptive thinkingは、クエリの複雑度に応じて分解の深さを自動調整するため、Smart RAGのサブクエリ分解に適しています。

ソース評価のオーバーヘッド

知識源評価は約200msの追加レイテンシを生みます。多段階検索でこのオーバーヘッドが累積するため、以下の最適化が有効です。

  • Simple判定の高速パス: ソース評価をスキップし、即座に検索
  • キャッシュ: 同一ソースへの評価結果をキャッシュ(TTL: 5分)
  • 並列評価: 3つのソースを同時に評価(asyncio活用)

Production Deployment Guide

AWS実装パターン(コスト最適化重視)

Smart RAGの3コンポーネントパイプラインをAWSで本番運用する際の構成を示します。

トラフィック量別の推奨構成:

規模月間リクエスト推奨構成月額コスト主要サービス
Small~3,000 (100/日)Serverless$60-180Lambda + Bedrock + DynamoDB
Medium~30,000 (1,000/日)Hybrid$350-900Lambda + ECS Fargate + ElastiCache
Large300,000+ (10,000/日)Container$2,500-5,500EKS + Karpenter + EC2 Spot

Small構成の詳細 (月額$60-180):

  • Lambda: 分類+分解+検索+生成の4ステップパイプライン ($25/月)
  • Bedrock: Haiku 4.5(分類)+ Sonnet 4.6(分解・生成)の2モデル使用 ($100/月)
  • DynamoDB: ソース評価キャッシュ、On-Demand ($10/月)
  • ElastiCache Redis: 検索結果キャッシュ(Medium以上で推奨) ($0 Small / $15 Medium)

コスト削減テクニック:

  • 分類にHaiku 4.5使用(Sonnet比1/3コスト)で年間約$200節約
  • Simple判定の高速パス(ソース評価スキップ)でSimple比率60%の場合、評価コスト60%削減
  • Prompt Caching有効化でシステムプロンプト部分30-90%削減

コスト試算の注意事項:

  • 上記は2026年2月時点のAWS ap-northeast-1(東京)リージョン料金に基づく概算値
  • Smart RAGの複雑度分類によりSimple/Complex/Ambiguousの比率が異なるため、実コストはクエリ分布に依存
  • 最新料金は AWS料金計算ツール で確認してください

Terraformインフラコード

Small構成 (Serverless): Lambda + Bedrock + DynamoDB

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# --- IAMロール(最小権限) ---
resource "aws_iam_role" "smart_rag_lambda" {
  name = "smart-rag-lambda-role"
  assume_role_policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Action = "sts:AssumeRole"
      Effect = "Allow"
      Principal = { Service = "lambda.amazonaws.com" }
    }]
  })
}

resource "aws_iam_role_policy" "bedrock_multi_model" {
  role = aws_iam_role.smart_rag_lambda.id
  policy = jsonencode({
    Version = "2012-10-17"
    Statement = [{
      Effect   = "Allow"
      Action   = ["bedrock:InvokeModel"]
      Resource = [
        "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-3-5-haiku*",
        "arn:aws:bedrock:ap-northeast-1::foundation-model/anthropic.claude-sonnet-4-6*"
      ]
    }]
  })
}

# --- Lambda: 分類 + 分解パイプライン ---
resource "aws_lambda_function" "smart_rag_classifier" {
  filename      = "classifier_lambda.zip"
  function_name = "smart-rag-classifier"
  role          = aws_iam_role.smart_rag_lambda.arn
  handler       = "index.handler"
  runtime       = "python3.12"
  timeout       = 30  # 分類は軽量
  memory_size   = 512
  environment {
    variables = {
      CLASSIFIER_MODEL = "anthropic.claude-3-5-haiku-20241022-v1:0"
      DECOMPOSE_MODEL  = "anthropic.claude-sonnet-4-6-20260210-v1:0"
    }
  }
}

# --- DynamoDB: ソース評価キャッシュ ---
resource "aws_dynamodb_table" "source_cache" {
  name         = "smart-rag-source-cache"
  billing_mode = "PAY_PER_REQUEST"
  hash_key     = "source_key"

  attribute {
    name = "source_key"
    type = "S"
  }

  ttl {
    attribute_name = "expire_at"
    enabled        = true
  }
}

運用・監視設定

CloudWatch Logs Insights クエリ:

1
2
3
4
5
6
7
-- クエリ複雑度分布と平均レイテンシ
fields @timestamp, complexity, duration_ms, sub_query_count
| stats count(*) as total,
        avg(duration_ms) as avg_latency,
        avg(sub_query_count) as avg_decomposition
  by complexity
| sort total desc

コスト最適化チェックリスト

  • 分類モデル: Haiku 4.5使用(Sonnet比1/3コスト)
  • Simple高速パス: ソース評価スキップ設定済み
  • ソース評価キャッシュ: DynamoDB TTL 5分設定済み
  • 並列ソース評価: asyncioで3ソース同時評価
  • Prompt Caching: システムプロンプト固定部分のキャッシュ有効化
  • Bedrock Batch API: 非リアルタイム処理に50%割引適用
  • コスト異常検知: AWS Budgets + CloudWatch アラーム設定済み

実験結果(Results)

データセットNaive RAGSelf-RAGAdaptive-RAGSmart RAG改善率
PopQA48.3%52.1%53.7%57.4%+3.7%
HotpotQA67.2%70.3%71.8%75.1%+3.3%
MuSiQue38.1%41.7%43.2%47.6%+4.4%
WebQ51.4%54.2%55.6%59.3%+3.7%

分析ポイント:

  • Adaptive-RAGに対して全データセットで一貫した改善(+3.3%〜+4.4%)
  • 検索呼び出し増加はNaive RAG比+15%のみ。効率的な改善
  • Ablation: 分解除去で-4.2% (HotpotQA)、-5.1% (MuSiQue)。マルチホップQAでの分解の重要性が顕著
  • Ablation: ソース評価除去で-2.8% (PopQA)。知識源の適切な選択が精度に寄与

実運用への応用(Practical Applications)

Smart RAGの3コンポーネントは、Zenn記事のLangGraph実装に直接統合可能です。

  1. 分類器の統合: Zenn記事のroute_query()関数をSmart RAGの3クラス分類に拡張
  2. 分解の統合: Complex判定時にClaude Sonnet 4.6のadaptive thinkingでサブクエリを生成し、各サブクエリをkeyword_search / semantic_search / chunk_readの3層検索で処理
  3. ソース評価の統合: Zenn記事のgrade_document()関数を、検索前の知識源評価にも適用

特にMuSiQueでの+4.4%改善は、社内ナレッジベースの横断検索(複数部門のドキュメントを跨ぐ質問)で効果が期待できます。

関連研究(Related Work)

  • Adaptive-RAG (Jeong et al., 2024): クエリ複雑度に応じた検索戦略切り替えの先行研究。Smart RAGはAdaptive-RAGの分類に加え、分解とソース評価を統合
  • Self-RAG (Asai et al., 2023): 検索の必要性を自己判断する手法。Smart RAGの知識源評価はSelf-RAGの自己判断を体系化したもの
  • IRCoT (Trivedi et al., 2022): 検索と推論のインターリービング。Smart RAGのサブクエリ逐次実行はIRCoTの拡張形

まとめと今後の展望

Smart RAGは、クエリ複雑度分類・サブクエリ分解・知識源評価の3つのコンポーネントにより、わずか15%の追加検索コストで全ベンチマークを改善しました。Zenn記事の階層的パイプラインとの統合により、検索前のクエリ最適化(Smart RAG)と検索中のツール選択(A-RAG/LangGraph)を組み合わせた強力なシステムが構築可能です。

参考文献

  • arXiv: https://arxiv.org/abs/2502.03073
  • Related Zenn article: https://zenn.dev/0h_n0/articles/a4cd3a7f1cf4ce
  • Jeong et al. (2024): Adaptive-RAG: Learning to Adapt Retrieval-Augmented Large Language Models through Question Complexity
  • Asai et al. (2023): Self-RAG: Learning to Retrieve, Generate, and Critique Through Self-Reflection
  • Trivedi et al. (2022): Interleaving Retrieval with Chain-of-Thought Reasoning
この投稿は CC BY 4.0 でライセンスされています。

論文解説: Multi-Agent Collaboration Mechanisms — LLMマルチエージェント協調の分類体系と設計指針

論文解説: LLMエージェント評価・ベンチマークの包括的サーベイ(KDD 2025)