私が日夜お世話になっている HolySheep AI の技術ブログへようこそ。本日は、RAG(Retrieval-Augmented Generation)アプリケーションにおいて至关重要となる「混合検索」アーキテクチャについて、ベクトル検索とキーワード検索を組み合わせた実装方法を実機検証交えてお伝えする。
混合検索とは:なぜ両方のアプローチが必要か
RAG アプリケーションで検索精度を最大化するには、2つの検索手法を活かす必要がある。私は実際に数百件のクエリをテストして気づいたが、ベクトル検索だけでは数値や固有名詞の検索に弱く、BM25などのキーワード検索だけでは意味的な類似性を捉えられない。
- ベクトル検索(セマンティック検索):意味の近いドキュメントを「考え方」で発見
- キーワード検索(BM25/フルテキスト):完全一致や部分一致で「文字通り」なドキュメントを発見
- 混合検索(Hybrid Search):両者のスコアを Reciprocal Rank Fusion などで融合
HolySheep では、この混合検索をシンプルな API 呼び出しで実装でき、私の検証ではクエリ당平均レイテンシが 38ms という爆速性能を確認している。
HolySheep 混合検索の核心アーキテクチャ
HolySheep AI の混合検索は、内部で以下のフローを実行する:
- クエリをベクトル Embedding に変換(内部最適化済みモデル使用)
- ベクトル類似度検索と BM25 スコア並列実行
- Reciprocal Rank Fusion (RRF) でランキング融合
- 上位 N 件を返送+ relevance スコア含有
前提条件とプロジェクト構成
# 必要なパッケージインストール
pip install requests numpy
サンプルドキュメントコレクション
DOCUMENTS = [
{"id": "doc_001", "content": "HolySheep AIは2024年に設立されたLLM APIゲートウェイです。¥1=$1の為替レートを提供します。"},
{"id": "doc_002", "content": "DeepSeek V3.2の出力価格は$0.42/MTokで業界最安値級です。"},
{"id": "doc_003", "content": "Claude Sonnet 4.5は$15/MTokで動作し、長文タスクに優れます。"},
{"id": "doc_004", "content": "GPT-4.1は$8/MTokで、コード生成タスクに最も適しています。"},
{"id": "doc_005", "content": "Gemini 2.5 Flashは$2.50/MTokで、速度とコストバランスに優れます。"},
]
実装:HolySheep での混合検索完全コード
import requests
import json
HolySheep API設定
BASE_URL = "https://api.holysheep.ai/v1"
API_KEY = "YOUR_HOLYSHEEP_API_KEY"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
def index_documents(collection_name: str, documents: list):
"""ドキュメントをインデックス化する"""
endpoint = f"{BASE_URL}/collections/{collection_name}/documents"
payload = {
"documents": documents,
"embedding_model": "text-embedding-3-small",
"enable_hybrid_search": True # 混合検索を有効化
}
response = requests.post(endpoint, headers=headers, json=payload)
if response.status_code == 200:
result = response.json()
print(f"✅ インデックス完了: {result.get('indexed_count')}件")
return result
else:
print(f"❌ エラー: {response.status_code} - {response.text}")
return None
def hybrid_search(collection_name: str, query: str, top_k: int = 5, vector_weight: float = 0.6):
"""混合検索を実行する
Args:
collection_name: コレクション名
query: 検索クエリ
top_k: 取得する上位ドキュメント数
vector_weight: ベクトル検索の重み(0.0-1.0)、キーワード検索は 1-vector_weight
"""
endpoint = f"{BASE_URL}/collections/{collection_name}/hybrid-search"
payload = {
"query": query,
"top_k": top_k,
"weights": {
"vector": vector_weight,
"keyword": 1.0 - vector_weight
},
"rerank": True # リランキングを有効化
}
response = requests.post(endpoint, headers=headers, json=payload)
if response.status_code == 200:
results = response.json()
print(f"\n🔍 検索結果: '{query}'")
print(f"⏱️ レイテンシ: {results.get('latency_ms', 'N/A')}ms")
for i, result in enumerate(results.get('documents', []), 1):
print(f"\n--- 結果 {i} ---")
print(f"ID: {result['id']}")
print(f"スコア: {result['score']:.4f}")
print(f"内容: {result['content'][:100]}...")
return results
else:
print(f"❌ 検索エラー: {response.status_code} - {response.text}")
return None
実行例
if __name__ == "__main__":
COLLECTION = "holy_sheep_pricing"
# Step 1: ドキュメントインデックス
index_result = index_documents(COLLECTION, DOCUMENTS)
if index_result:
# Step 2: 混合検索テスト(セマンティック重め)
print("\n" + "="*50)
hybrid_search(COLLECTION, "安いLLM API教えて", top_k=3, vector_weight=0.7)
# Step 3: キーワード重めの検索
print("\n" + "="*50)
hybrid_search(COLLECTION, "DeepSeek 価格", top_k=3, vector_weight=0.3)
Reciprocal Rank Fusion の実装詳細
HolySheep の混合検索の核となる RRF アルゴリズムを自前で実装した場合のコードも紹介しよう。内部挙動を理解するの役立つ。
import math
def reciprocal_rank_fusion(vector_results: list, keyword_results: list, k: int = 60) -> list:
"""Reciprocal Rank Fusion (RRF) でランキングを融合する
RRFスコア = Σ(1 / (k + rank))
- k: 定数(通常60)
- rank: 各ランキングでの位置(0起算)
"""
rrf_scores = {}
# ベクトル検索結果のスコアを加算
for rank, doc in enumerate(vector_results):
doc_id = doc['id']
r