【超軽量RAG】外部ベクトルDB不要! SQLite-vecと全文検索(FTS5)で構築するローカルナレッジベース アイキャッチ

Icons: Lobe Icons(MIT)

マニュアル
公開: 2026.09.02読了目安 8分

【超軽量RAG】外部ベクトルDB不要! SQLite-vecと全文検索(FTS5)で構築するローカルナレッジベース

PineconeやQdrantなどの高価な外部ベクトルDBを契約せず、単一のSQLiteファイル内でベクトル検索とBM25キーワード検索を組み合わせた超軽量ハイブリッドRAGの実装法を解説します。

はじめに:RAGインフラの「肥大化」と「複雑性」を解消する

RAG(検索拡張生成)システムを構築する際、外部のマネージドベクトル検索サービス(Pinecone、Qdrant、Milvus等)を導入すると、インフラコストの増加やネットワークレイテンシ、セキュリティ上の懸念が生じます。

SQLiteの公式拡張 sqlite-vec と標準の全文検索エンジン FTS5 を組み合わせることで、単一のSQLiteファイル(数MB〜数GB)だけで完結する超高速ハイブリッドRAGを構築できます。


1. ハイブリッド検索(ベクトル + BM25)の優位性

  • ベクトル検索(埋め込み): 概念や意味の類似性(「安い宿」→「格安ホテル」)を捉えるのが得意。
  • BM25全文検索(FTS5): 固有の型番、専門用語、JANコード(「C3000HG」「4969363045300」)の完全一致に強い。
  • ハイブリッド融合(RRF: Reciprocal Rank Fusion): 両方の検索スコアを統合し、圧倒的な検索精度を実現。

2. Pythonでの実装例

import sqlite3
import sqlite_vec
from sentence_transformers import SentenceTransformer

# 1. DB接続と拡張のロード
db = sqlite3.connect("knowledge.db")
db.enable_load_extension(True)
sqlite_vec.load(db)
db.enable_load_extension(False)

# 2. テーブル作成(ベクトルテーブル + FTS5テーブル)
db.execute("CREATE VIRTUAL TABLE IF NOT EXISTS vec_docs USING vec0(embedding float[384])")
db.execute("CREATE VIRTUAL TABLE IF NOT EXISTS fts_docs USING fts5(doc_id, content)")

# 3. ドキュメントの登録
model = SentenceTransformer("intfloat/multilingual-e5-small")
doc_text = "シマノ 24ヴァンフォード C3000HG は超軽量な汎用スピニングリールです。"
embedding = model.encode(doc_text).tolist()

cur = db.cursor()
cur.execute("INSERT INTO fts_docs(doc_id, content) VALUES (1, ?)", (doc_text,))
cur.execute("INSERT INTO vec_docs(rowid, embedding) VALUES (1, ?)", (embedding,))
db.commit()

# 4. ハイブリッド検索クエリ
query = "ヴァンフォードの型番"
q_emb = model.encode(query).tolist()

# ベクトル近傍検索
res_vec = cur.execute("SELECT rowid, distance FROM vec_docs WHERE embedding MATCH ? ORDER BY distance LIMIT 5", (q_emb,)).fetchall()
# FTS5キーワード検索
res_fts = cur.execute("SELECT doc_id, rank FROM fts_docs WHERE fts_docs MATCH ? ORDER BY rank LIMIT 5", (query,)).fetchall()

サーバーレス・ローカル環境でミリ秒単位で動作するため、デスクトップアプリやエッジ環境でのRAG実装に最適です。