論文概要(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検索パイプライン の深掘りです。
情報源
- arXiv ID: 2502.03073
- URL: https://arxiv.org/abs/2502.03073
- 著者: Bo-Ru Lu, Nikita Haduong, Chia-Hsuan Lee, et al.
- 発表年: 2025
- 分野: cs.CL, cs.AI
背景と動機(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スコア + セマンティック類似度 | 最新情報、ドメイン知識 |
| 構造化KB | Wikidata 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-180 | Lambda + Bedrock + DynamoDB |
| Medium | ~30,000 (1,000/日) | Hybrid | $350-900 | Lambda + ECS Fargate + ElastiCache |
| Large | 300,000+ (10,000/日) | Container | $2,500-5,500 | EKS + 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 RAG | Self-RAG | Adaptive-RAG | Smart RAG | 改善率 |
|---|---|---|---|---|---|
| PopQA | 48.3% | 52.1% | 53.7% | 57.4% | +3.7% |
| HotpotQA | 67.2% | 70.3% | 71.8% | 75.1% | +3.3% |
| MuSiQue | 38.1% | 41.7% | 43.2% | 47.6% | +4.4% |
| WebQ | 51.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実装に直接統合可能です。
- 分類器の統合: Zenn記事の
route_query()関数をSmart RAGの3クラス分類に拡張 - 分解の統合: Complex判定時にClaude Sonnet 4.6のadaptive thinkingでサブクエリを生成し、各サブクエリを
keyword_search/semantic_search/chunk_readの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