メインコンテンツまでスキップ

RAG with Hybrid Search

VeloDBのハイブリッド検索を使用してRAG(Retrieval-Augmented Generation)アプリケーションを構築します。転置インデックスとBM25スコアリングによる全文検索と、ベクトルインデックスによる類似検索を、単一のSQLクエリで組み合わせます。

警告

ベクトルインデックスによるハイブリッド検索は、VeloDB 26.xで利用可能です。

構築するもの

このチュートリアルを完了すると、インタラクティブなAgno UIを持つ動作するRAGチャットボットが完成します:

RAG Chatbot with Agno UI

ハイブリッド検索の仕組み:

  • 全文検索は正確なキーワード(「Kafka」、「streaming」)を含むドキュメントを検索
  • 類似検索は意味的に類似したドキュメント(messaging、events、pipelines)を検索
  • RRF融合は両方のランキングを結合 → 両方のリストに現れるドキュメントが最も高くランク付け

RAGにおける検索品質が重要な理由

RAGアプリケーションは、LLMレスポンスのコンテキストを提供するために関連ドキュメントを検索します。検索の品質が悪いと以下の問題が発生します:

  • 幻覚 - LLMがもっともらしいが間違った回答を生成
  • 不完全な回答 - 関連するコンテキストが不足
  • 無関係なレスポンス - 間違ったドキュメントが検索される

VeloDBは3つの検索方法を単一のSQLクエリで組み合わせることで、この問題を解決します。

3つの検索方法

1. 全文検索(BM25スコアリング付き)

最適な用途:正確な用語マッチング、技術的なクエリ、製品名、コード

-- Create table with inverted index for full-text search
CREATE TABLE documents (
id BIGINT NOT NULL AUTO_INCREMENT,
content TEXT,
INDEX idx_content(content) USING INVERTED PROPERTIES("parser"="english")
) DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1;

-- Insert sample documents
INSERT INTO documents (content) VALUES
('Apache Kafka was first released in 2011 as an open-source distributed event streaming platform.'),
('Michael Faraday discovered electromagnetic induction in 1831.'),
('The International Space Station orbits Earth at 400km altitude.');

-- Full-text search using MATCH
SELECT id, content
FROM documents
WHERE content MATCH 'electromagnetic induction'
LIMIT 5;

結果: 正確なキーワードが含まれているため、Faradayドキュメントを返します。

制限: 意味的に関連するコンテンツを見逃します。「electricity discoveries」のクエリでは「electromagnetic induction」にマッチしません。

2. 類似性検索(ベクトル)

最適な用途: 自然言語クエリ、概念マッチング、類似した意味の検索

-- Create table with vector index for similarity search
CREATE TABLE documents_with_vectors (
id BIGINT NOT NULL AUTO_INCREMENT,
content TEXT,
embedding ARRAY<FLOAT>,
INDEX idx_embedding(embedding) USING INVERTED
) DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1;

-- Insert documents with embeddings (simplified 5-dim vectors for demo)
INSERT INTO documents_with_vectors (content, embedding) VALUES
('Apache Kafka was first released in 2011 as an open-source distributed event streaming platform.', [0.8, 0.2, 0.1, 0.5, 0.3]),
('Michael Faraday discovered electromagnetic induction in 1831.', [0.1, 0.9, 0.7, 0.2, 0.4]),
('The International Space Station orbits Earth at 400km altitude.', [0.3, 0.1, 0.2, 0.9, 0.8]);

-- Similarity search: find documents similar to "streaming data" [0.7, 0.3, 0.2, 0.4, 0.2]
SELECT id, content,
1 - cosine_distance(embedding, [0.7, 0.3, 0.2, 0.4, 0.2]) AS similarity
FROM documents_with_vectors
ORDER BY cosine_distance(embedding, [0.7, 0.3, 0.2, 0.4, 0.2]) ASC
LIMIT 5;

結果: キーワードの重複がなくても概念的に類似した文書を見つける。

制限: ユーザーが期待する正確なキーワードマッチを持つ文書を見逃す可能性がある。

3. Hybrid Search (Full-text + Vector + Filter + RRF)

最適な用途: 精度と再現率の両方を必要とするRAGアプリケーション

Hybrid searchは**Reciprocal Rank Fusion (RRF)**を使用して全文検索と類似性検索を組み合わせる:

-- Create table with BOTH indexes
CREATE TABLE rag_documents (
id BIGINT NOT NULL AUTO_INCREMENT,
content TEXT,
embedding ARRAY<FLOAT>,
-- Vector index for similarity search
INDEX idx_embedding(embedding) USING INVERTED,
-- Inverted index for full-text search
INDEX idx_content(content) USING INVERTED PROPERTIES("parser"="english")
) DUPLICATE KEY(id)
DISTRIBUTED BY HASH(id) BUCKETS 1
PROPERTIES ("replication_num" = "1");

-- Insert sample documents with embeddings (simplified 5-dim vectors for demo)
INSERT INTO rag_documents (content, embedding) VALUES
('Apache Kafka was first released in 2011 as an open-source distributed event streaming platform.', [0.8, 0.2, 0.1, 0.5, 0.3]),
('Michael Faraday discovered electromagnetic induction in 1831.', [0.1, 0.9, 0.7, 0.2, 0.4]),
('The International Space Station orbits Earth at 400km altitude.', [0.3, 0.1, 0.2, 0.9, 0.8]);
ヒント

実際の埋め込みベクトルは通常1536次元です。DockerデモではOpenAIのtext-embedding-3-smallを使用して本番品質のベクトルを生成します。

RRF融合を使用したハイブリッド検索クエリ:

-- Search for "Kafka streaming" with embedding [0.7, 0.3, 0.2, 0.4, 0.2]
WITH vector_results AS (
-- Similarity search: find conceptually similar documents
SELECT
id, content,
1 - cosine_distance(embedding, [0.7, 0.3, 0.2, 0.4, 0.2]) AS vector_score,
ROW_NUMBER() OVER (ORDER BY cosine_distance(embedding, [0.7, 0.3, 0.2, 0.4, 0.2]) ASC) AS vector_rank
FROM rag_documents
ORDER BY cosine_distance(embedding, [0.7, 0.3, 0.2, 0.4, 0.2]) ASC
LIMIT 10
),
text_results AS (
-- Full-text search: find exact term matches
SELECT
id, content,
1.0 AS text_score,
ROW_NUMBER() OVER (ORDER BY id) AS text_rank
FROM rag_documents
WHERE content MATCH 'Kafka streaming'
LIMIT 10
),
combined AS (
-- Combine results from both methods
SELECT
COALESCE(v.id, t.id) AS id,
COALESCE(v.content, t.content) AS content,
COALESCE(v.vector_score, 0) AS vector_score,
COALESCE(t.text_score, 0) AS text_score,
COALESCE(v.vector_rank, 999) AS vector_rank,
COALESCE(t.text_rank, 999) AS text_rank
FROM vector_results v
FULL OUTER JOIN text_results t ON v.id = t.id
)
-- RRF fusion: combine rankings with 1/(k + rank) formula
SELECT
id, content, vector_score, text_score,
(0.5 / (60 + vector_rank) + 0.5 / (60 + text_rank)) AS hybrid_score
FROM combined
ORDER BY hybrid_score DESC
LIMIT 5;

RRFの仕組み:

  • 各検索手法がランク付きリストを生成
  • RRF式: score = Σ (weight / (k + rank)) ここでk=60が標準
  • 両方のリストに現れる文書がブーストされる
  • 一方のリストのみに現れる文書も貢献する

検索手法の比較

クエリタイプ全文検索類似性検索ハイブリッド
"electromagnetic induction"✅ 完全一致✅ 概念一致✅ 両方の長所
"electricity discoveries"❌ キーワード不一致✅ Faradayを発見✅ Faradayを発見
"Kafka 2011"✅ 完全一致⚠️ ランクが下がる可能性✅ トップ結果
"event streaming platforms"⚠️ 部分一致✅ 意味的一致✅ 両方の長所

重要な洞察: ハイブリッド検索は、いずれかの手法単独では失敗するケースを捉える。

完全なRAGアプリケーション

以下はAgnoによって駆動されるインタラクティブなチャットUIを備えた完全なRAGアプリケーションです。

Dockerでのクイックスタート

単一のコマンドで完全なデモを実行:

docker run -p 3001:3001 -p 7777:7777 \
-e VELODB_HOST=your-cluster.velodb.io \
-e VELODB_USER=admin \
-e VELODB_PASSWORD=your-password \
-e VELODB_DATABASE=rag_demo \
-e OPENROUTER_API_KEY=sk-or-v1-your-key \
velodb/rag-tutorial:1.0

http://localhost:3001 を開いてチャットを開始してください。

これらのクエリを試してください

1. ハイブリッド検索のテスト(キーワード + セマンティック)

Who invented the device that blocks electromagnetic fields?

ハイブリッド検索がBM25キーワードマッチング(「electromagnetic」、「fields」)とベクトル意味理解(「invented」、「device」、「blocks」)を組み合わせて、Faraday cageドキュメントを見つける方法をご覧ください。

2. セマンティック理解をテストする

What streaming platform was created by a social media company?

ベクトル検索がLinkedInをソーシャルメディア企業として理解し、Kafkaドキュメントを見つけていることに注目してください。

3. キーワード精度のテスト

electromagnetic induction

BM25は高い信頼性で正確なキーワードマッチングを提供します。

4. 独自のドキュメントを追加する

Add this to the knowledge base: Apache Kafka is a distributed event streaming platform used for high-performance data pipelines and streaming analytics.

次に質問します:What is Kafka used for?

トラブルシューティング

問題解決方法
接続タイムアウトVeloDBホストとポート9030にアクセス可能か確認してください
検索結果が空最初にドキュメントが取り込まれていることを確認してください
埋め込みエラーOpenRouter APIキーにクレジットがあることを確認してください
MATCHクエリが失敗するcontentカラムに転置インデックスが存在するか確認してください

さらに学ぶ