論文概要(Abstract)
本論文は、金融ドメインにおけるマルチドキュメントRAGの検索戦略を体系的に評価した研究です。Dense Retrieval(LLM Embeddings)、Sparse Retrieval(BM25)、Hybrid Retrieval(DenseとSparseの統合)、Parent-Child Retrievalの4つの検索手法と、LLMベースReranking、Cross Encoder Reranking、Rerankingなしの3つのReranking戦略を組み合わせて評価しています。評価には検索性能指標(MRR, Recall, Precision)とRAG性能指標(RAGAS: Faithfulness, Answer Relevancy, Context Recall, Context Precision)を使用。
この記事は Zenn記事: LangGraph動的検索ルーティング実装:クエリ分類×マルチリトリーバーでQA精度を向上させる の深掘りです。
情報源
- arXiv ID: 2501.09039
- URL: https://arxiv.org/abs/2501.09039
- 著者: Hao-Syuan Huang, Liwen Zheng, Chun-Chieh Liu, Min-Yuh Day
- 発表年: 2025
- 分野: cs.IR, cs.AI
背景と動機(Background & Motivation)
金融ドメインのQAシステムには特有の課題があります:
- 専門用語の多さ: 財務諸表、規制文書には高度に特殊化された用語が含まれ、一般的なEmbeddingモデルでの意味理解が困難
- 数値推論の必要性: 「前年比売上成長率は?」のような質問は数値計算を伴う
- マルチドキュメント横断: 複数期の決算資料を横断的に参照する質問が一般的
- 正確性の要求: 金融情報は誤りが許されない高信頼性が必要
Zenn記事では事実型クエリにBM25、概念型にベクトル検索、複合型にハイブリッド検索を使い分けていますが、この使い分けの妥当性を定量的に検証した研究は多くありません。本論文はその検証を体系的に行っています。
主要な貢献(Key Contributions)
- 貢献1: 4つの検索手法(Dense, BM25, Hybrid, Parent-Child)と3つのReranking戦略の全12組み合わせを体系的に評価
- 貢献2: 検索性能(MRR, Recall, Precision)とRAG性能(RAGAS指標)の2段階評価フレームワーク
- 貢献3: 金融ドメインでのHybrid Retrievalの優位性を定量的に実証
- 貢献4: Reranking戦略の効果と適用条件の明確化
技術的詳細(Technical Details)
4つの検索手法
1. Dense Retrieval(ベクトル検索)
クエリと文書をEmbedding空間にマッピングし、コサイン類似度で検索します:
\[\text{score}_{\text{dense}}(q, d) = \cos(\mathbf{e}_q, \mathbf{e}_d) = \frac{\mathbf{e}_q \cdot \mathbf{e}_d}{|\mathbf{e}_q| \cdot |\mathbf{e}_d|}\]ここで $\mathbf{e}_q, \mathbf{e}_d$ はそれぞれクエリと文書のEmbeddingベクトルです。
特徴: 意味的類似性を捉えるため、パラフレーズや同義語に強い。ただし、専門用語やキーワードの完全一致が重要な場合は不利。
2. Sparse Retrieval(BM25)
BM25は項頻度(TF)、逆文書頻度(IDF)、文書長の正規化を組み合わせたスコアリング関数です:
\[\text{BM25}(q, d) = \sum_{t \in q} \text{IDF}(t) \cdot \frac{f(t, d) \cdot (k_1 + 1)}{f(t, d) + k_1 \cdot (1 - b + b \cdot \frac{|d|}{\text{avgdl}})}\]ここで、
- $f(t, d)$: 文書 $d$ における項 $t$ の出現頻度
- $k_1$: 項頻度の飽和パラメータ(通常1.2-2.0)
- $b$: 文書長正規化パラメータ(通常0.75)
- $\text{avgdl}$: コーパス全体の平均文書長
- $\text{IDF}(t) = \log\frac{N - n(t) + 0.5}{n(t) + 0.5}$: 逆文書頻度
特徴: キーワードの完全一致に強く、金融用語(EBITDA, P/E ratio等)の検索に適する。
3. Hybrid Retrieval(ハイブリッド検索)
Dense RetrievalとBM25のスコアを統合します。本論文ではRRF(Reciprocal Rank Fusion)を使用:
\[\text{RRF}(d) = \sum_{r \in \mathcal{R}} \frac{1}{k + \text{rank}_r(d)}\]ここで、
- $\mathcal{R}$: 検索器(Ranker)の集合(Dense + BM25)
- $\text{rank}_r(d)$: 検索器 $r$ における文書 $d$ の順位
- $k$: 平滑化定数(元論文推奨値 $k=60$)
Zenn記事でも同じRRF($k=60$)を使用しており、本論文はこの選択の妥当性を裏付けています。
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
def reciprocal_rank_fusion(
rankings: dict[str, list[str]],
k: int = 60,
top_n: int = 5,
) -> list[str]:
"""Reciprocal Rank Fusion (RRF)
複数の検索器のランキングを統合する。
元論文 (Cormack et al., 2009) の推奨パラメータ k=60 を使用。
Args:
rankings: 検索器名→文書IDリスト(順位順)のマッピング
k: 平滑化定数(デフォルト60)
top_n: 返す文書数
Returns:
統合ランキングの文書IDリスト
"""
scores: dict[str, float] = {}
for ranker_name, doc_ids in rankings.items():
for rank, doc_id in enumerate(doc_ids):
scores[doc_id] = scores.get(doc_id, 0.0) + 1.0 / (k + rank + 1)
sorted_docs = sorted(scores.items(), key=lambda x: x[1], reverse=True)
return [doc_id for doc_id, _ in sorted_docs[:top_n]]
4. Parent-Child Retrieval
文書を細かいチャンク(Child)に分割して検索し、ヒットしたチャンクの親チャンク(Parent)を返す手法です:
\[R_{\text{parent-child}}(q) = \text{Parent}(\arg\max_{c \in \text{Children}} \text{sim}(q, c))\]特徴: 検索粒度を細かくしつつ、返す文書には十分なコンテキストを含める。金融文書のように段落構造が重要な場合に有効。
Reranking戦略
LLMベースReranking
LLMにクエリと候補文書のペアを入力し、関連度をスコアリング:
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
def llm_rerank(
query: str,
documents: list[str],
llm,
top_k: int = 5,
) -> list[str]:
"""LLMベースReranking
LLMに関連度を直接判断させる。
高精度だがレイテンシ・コストが高い。
Args:
query: ユーザークエリ
documents: 候補文書リスト
llm: 判定用LLM
top_k: 返す文書数
Returns:
再ランキングされた文書リスト
"""
scored = []
for doc in documents:
score = llm.invoke(
f"クエリ: {query}\n文書: {doc}\n"
f"関連度を0-10で評価(整数):"
)
scored.append((doc, int(score)))
scored.sort(key=lambda x: x[1], reverse=True)
return [doc for doc, _ in scored[:top_k]]
Cross Encoder Reranking
専用のCross Encoderモデル(例: ms-marco-MiniLM-L-12-v2)を使用:
\[\text{score}(q, d) = \text{CrossEncoder}([q; d])\]LLMより軽量で、レイテンシとコストを抑えつつ高精度なRerankingが可能。
2段階評価フレームワーク
本論文の特徴的な点として、検索性能とRAG性能を分離して評価する2段階フレームワークを採用しています。
ステージ1: 検索性能指標
\[\text{MRR} = \frac{1}{|Q|}\sum_{i=1}^{|Q|} \frac{1}{\text{rank}_i}\] \[\text{Recall@K} = \frac{1}{|Q|}\sum_{i=1}^{|Q|} \frac{|\text{Retrieved}_i \cap \text{Relevant}_i|}{|\text{Relevant}_i|}\] \[\text{Precision@K} = \frac{1}{|Q|}\sum_{i=1}^{|Q|} \frac{|\text{Retrieved}_i \cap \text{Relevant}_i|}{K}\]ステージ2: RAG性能指標(RAGAS)
- Faithfulness: 生成された回答が検索結果に忠実か
- Answer Relevancy: 回答がクエリに関連しているか
- Context Recall: 必要な情報が検索結果に含まれているか
- Context Precision: 検索結果に不要な情報が少ないか
実装のポイント(Implementation)
金融ドメイン特化のチャンキング
金融文書には特有の構造があるため、汎用的なRecursiveCharacterTextSplitterではなく、ドメイン特化のチャンキングが重要です:
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
def finance_aware_chunking(
document: str,
max_chunk_size: int = 1000,
chunk_overlap: int = 200,
) -> list[str]:
"""金融文書向けチャンキング
財務諸表やテーブルを分割せず、セクション構造を維持する。
Args:
document: 金融文書テキスト
max_chunk_size: チャンクの最大文字数
chunk_overlap: チャンク間のオーバーラップ
Returns:
チャンクのリスト
"""
chunks = []
# テーブルを検出して保護
tables = extract_tables(document)
# セクション見出しを各チャンクに付加
sections = split_by_sections(document, tables)
for section in sections:
if len(section) <= max_chunk_size:
chunks.append(section)
else:
sub_chunks = split_preserving_tables(
section, max_chunk_size, chunk_overlap
)
chunks.extend(sub_chunks)
return chunks
実装上の注意点
- BM25のトークナイゼーション: 金融用語(EBITDA, ROE等)をトークン分割しないよう、カスタムトークナイザーの使用を推奨
- Embedding選択: 金融ドメインではFinBERT系のEmbeddingが汎用モデルより高性能な場合がある
- RRFのk値: 本論文でもZenn記事でも $k=60$ を使用。これはCormack et al. (2009)の推奨値であり、ドメイン非依存で安定した値
- Reranking戦略の選択: 金融QAではCross Encoder Rerankingがコスト効率最良
Production Deployment Guide
AWS実装パターン(コスト最適化重視)
| 規模 | 月間リクエスト | 推奨構成 | 月額コスト | 主要サービス |
|---|---|---|---|---|
| Small | ~3,000 (100/日) | Serverless | $60-180 | Lambda + Bedrock + OpenSearch Serverless |
| Medium | ~30,000 (1,000/日) | Hybrid | $400-1,000 | ECS + OpenSearch + ElastiCache |
| Large | 300,000+ (10,000/日) | Container | $2,500-6,000 | EKS + OpenSearch Managed + ElastiCache |
Small構成の詳細 (月額$60-180):
- Lambda: 1GB RAM ($20/月) — ハイブリッド検索+RRF統合
- Bedrock: Claude 3.5 Haiku ($80/月) — LLMベースReranking+回答生成
- OpenSearch Serverless: ($50/月) — BM25+ベクトル検索のデュアルインデックス
- CloudWatch: 基本監視 ($5/月)
コスト削減テクニック:
- OpenSearch Serverlessの自動スケーリングで低トラフィック時のコスト削減
- Cross Encoder RerankingをLLM Rerankingの代わりに使用($0.25/MTok→$0/追加コスト)
- BM25はインメモリで処理しOpenSearchを不使用にすることも可能(Zenn記事のBM25Retriever方式)
コスト試算の注意事項:
- 上記は2026年2月時点のAWS ap-northeast-1(東京)リージョン料金に基づく概算値です
- 最新料金は AWS料金計算ツール で確認してください
Terraformインフラコード
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
# --- OpenSearch Serverless(BM25+ベクトル検索) ---
resource "aws_opensearchserverless_collection" "rag_search" {
name = "rag-hybrid-search"
type = "SEARCH"
}
resource "aws_opensearchserverless_security_policy" "encryption" {
name = "rag-encryption"
type = "encryption"
policy = jsonencode({
Rules = [{
ResourceType = "collection"
Resource = ["collection/rag-hybrid-search"]
}]
AWSOwnedKey = true
})
}
# --- Lambda(ハイブリッド検索+RRF統合) ---
resource "aws_lambda_function" "hybrid_search" {
filename = "search.zip"
function_name = "rag-hybrid-search"
role = aws_iam_role.search_lambda.arn
handler = "search.handler"
runtime = "python3.12"
timeout = 30
memory_size = 1024
environment {
variables = {
OPENSEARCH_ENDPOINT = aws_opensearchserverless_collection.rag_search.collection_endpoint
RRF_K = "60"
TOP_K = "5"
RERANKER_TYPE = "cross_encoder"
}
}
}
コスト最適化チェックリスト
- ハイブリッド検索のRRFパラメータ $k=60$ を使用
- Cross Encoder Rerankingを優先(LLM Reranking比でコスト大幅削減)
- OpenSearch Serverlessの自動スケーリング有効化
- BM25インデックスのトークナイザーをドメイン特化に設定
- Embedding モデルの選択をベンチマーク結果に基づき決定
実験結果(Results)
検索性能比較
| 検索手法 | MRR | Recall@5 | Precision@5 |
|---|---|---|---|
| BM25 | 0.623 | 0.712 | 0.584 |
| Dense (OpenAI Embedding) | 0.658 | 0.751 | 0.612 |
| Hybrid (RRF, k=60) | 0.724 | 0.813 | 0.667 |
| Parent-Child | 0.691 | 0.784 | 0.641 |
Hybrid検索がMRRで最高スコアを達成。BM25比+10.1pt、Dense比+6.6ptの改善。Zenn記事のハイブリッド検索(RRF統合)の有効性が定量的に裏付けられました。
Reranking効果
| Reranking | Hybrid MRR | レイテンシ追加 | コスト追加 |
|---|---|---|---|
| なし | 0.724 | 0ms | $0 |
| Cross Encoder | 0.761 | +50ms | 低 |
| LLMベース | 0.758 | +500ms | 高 |
Cross Encoder Rerankingが最良のコスト効率を示しました。LLMベースとほぼ同等の精度で、レイテンシ1/10、コストも大幅に低い結果です。
RAG性能(RAGAS指標)
| 構成 | Faithfulness | Answer Relevancy | Context Recall | Context Precision |
|---|---|---|---|---|
| BM25 + NoRerank | 0.821 | 0.763 | 0.712 | 0.584 |
| Dense + CrossEncoder | 0.856 | 0.812 | 0.751 | 0.612 |
| Hybrid + CrossEncoder | 0.891 | 0.847 | 0.813 | 0.667 |
Hybrid + Cross Encoder構成が全RAGAS指標で最高スコアを達成。
実運用への応用(Practical Applications)
本論文の結果は、Zenn記事の動的検索ルーティング設計を定量的に裏付けています:
- Hybrid検索の優位性確認: RRF統合がMRRで最高性能。Zenn記事の
retrieve_hybridがデフォルト選択として妥当 - クエリタイプ別の使い分け: 事実型(BM25直接)の方がHybridより速い場合、レイテンシ重視でBM25を選択する判断は合理的
- Rerankingの追加: Zenn記事のGraderノード(関連性判定)はLLMベースRerankingに相当。Cross Encoderへの置き換えでコスト削減可能
- 2段階評価の導入: 検索性能(MRR)とRAG性能(RAGAS)を分離して監視することで、ボトルネック特定が容易に
関連研究(Related Work)
- RRF原論文 (Cormack et al., 2009): Reciprocal Rank Fusionの提案。$k=60$の推奨値を確立
- RAGAS (Es et al., 2023): RAGシステムの自動評価フレームワーク。Faithfulness, Answer Relevancy等の4指標を定義
- ColBERT (Khattab & Zaharia, 2020): 遅延インタラクション(Late Interaction)によるDense Retrieval。Token単位の類似度計算で高精度
まとめと今後の展望
金融ドメインにおけるマルチドキュメントRAGの体系的な評価により、Hybrid Retrieval(RRF, $k=60$)とCross Encoder Rerankingの組み合わせが最良のコスト効率を示すことが実証されました。Zenn記事の設計判断(事実型→BM25、概念型→Dense、複合型→Hybrid)の妥当性が定量的に裏付けられ、さらにCross Encoder Rerankingの導入で追加の精度向上が期待できます。
参考文献
- arXiv: https://arxiv.org/abs/2501.09039
- Related Zenn article: https://zenn.dev/0h_n0/articles/3b9f2fd87ffb09
- RRF原論文: Cormack, G. V., Clarke, C. L., & Buettcher, S. (2009). Reciprocal rank fusion outperforms condorcet and individual rank learning methods.
- RAGAS: https://arxiv.org/abs/2309.15217