Chuyển đến nội dung chính

レッスン 3: ベクトル データベース — Chroma、Qdrant、Pinecone、Weaviate

最も一般的な 4 つの DB ベクトル (セットアップ、API、パフォーマンス、価格) を比較します。 HNSW インデックス、体外受精、PQ。ハイブリッド検索 (ベクトル + キーワード)。メタデータのフィルタリング。 ChromaDB と Qdrant の実践。

🧠 AI と ML — レッスン 2 レッスン 3: ベクトル データベース — Chroma、Qdrant、 松ぼっくり、織り手

リアルバトルRAG:基礎から上級まで

パート 1: RAG プラットフォーム

xdev.asia

ベクトル データベースの比較: Chroma、Qdrant、Pinecone、Weaviate

はじめに

前のレッスンでは、テキストをベクトルに変換しました。次の質問: ベクトルを保存する場所と検索方法

従来のデータベース (MySQL、PostgreSQL) は、完全一致 (「SELECT WHERE id = 5」) 向けに設計されています。しかし、ベクトルの場合は、最近傍、つまり「クエリ ベクトルに最も近いベクトルはどれか?」を見つける必要があります。だからこそ Vector Database が必要なのです。


1. ベクターデータベースとは何ですか?

1.1 簡単な比較

SQL データベースベクトルデータベース
何を保存するか行と列ベクトル (一連の数字) + メタデータ
クエリWHERE name = "Minh"NEAREST(query_vector, k=5)
検索完全一致近似最近傍 (ANN)
使用例従来の CRUDセマンティック検索、RAG、レコメンデーション

1.2 最も人気のある 4 つのベクトル データベース

DBタイプホスティング主な利点価格 (無料利用枠)
ChromaDB埋め込みローカル非常にシンプルでプロトタイピングに最適完全無料
クドラントクライアントサーバーセルフホスト / クラウド高性能、強力なフィルタリング無料 (自己ホスト型)
松ぼっくりマネージドクラウドクラウドのみゼロオペレーション、簡単なスケーリング無料 (100K ベクター)
ウィアビエイトクライアントサーバーセルフホスト / クラウドGraphQL API、マルチモーダル無料 (自己ホスト型)

2. ChromaDB — 5 分で始められます

ChromaDB は 初心者にとって最適な選択肢です。Python で直接実行でき、サーバーのセットアップは必要ありません。

2.1 基本セットアップと CRUD

pip install chromadb
"""ChromaDB: Vector DB đơn giản nhất"""
import chromadb

# === 1. Khởi tạo ===
# In-memory (tạm thời, mất khi tắt)
client = chromadb.Client()

# Persistent (lưu disk, giữ lại)
# client = chromadb.PersistentClient(path="./chroma_data")

# === 2. Tạo Collection (giống "table" trong SQL) ===
collection = client.create_collection(
    name="company_docs",
    metadata={"description": "Internal company documents"}
)

# === 3. Thêm documents ===
collection.add(
    documents=[
        "Chính sách nghỉ phép: 15 ngày/năm cho nhân viên full-time",
        "Quy trình xin phép: gửi đơn trước 3 ngày làm việc",
        "Lương thưởng: review mỗi 6 tháng, KPI-based",
        "Chế độ bảo hiểm: BHXH + bảo hiểm tư nhân Bảo Việt",
        "Giờ làm việc: 8:30-17:30, thứ 2-6, flexible ±1 giờ",
    ],
    ids=["doc1", "doc2", "doc3", "doc4", "doc5"],
    metadatas=[
        {"category": "leave", "department": "HR"},
        {"category": "leave", "department": "HR"},
        {"category": "compensation", "department": "HR"},
        {"category": "benefits", "department": "HR"},
        {"category": "policy", "department": "Admin"},
    ]
)
print(f"Added {collection.count()} documents")

# === 4. Tìm kiếm (semantic search) ===
results = collection.query(
    query_texts=["nghỉ phép bao nhiêu ngày?"],
    n_results=3  # Top 3 gần nhất
)

print("\n🔍 Query: 'nghỉ phép bao nhiêu ngày?'")
for doc, distance in zip(results["documents"][0], results["distances"][0]):
    relevance = 1 - distance  # Chuyển distance → relevance
    print(f"  [{relevance:.2%}] {doc[:60]}...")

# === 5. Filtering theo metadata ===
filtered = collection.query(
    query_texts=["chế độ cho nhân viên"],
    n_results=3,
    where={"category": "benefits"}  # Chỉ tìm trong "benefits"
)
print(f"\n🔍 Filtered (benefits only): {filtered['documents'][0]}")

2.2 ChromaDB をいつ使用するか?

✅ 次の場合に使用します❌ 次の場合は使用しないでください。
プロトタイプ/POC生産 100 万以上のベクター
< 100K documentsMulti-user concurrent
Jupyter/ローカルで使用モニタリング/メトリクスが必要
1 開発者チームには共有 DB が必要

3. Qdrant — Production-Ready Vector DB

3.1 Setup

# Chạy Qdrant server bằng Docker
docker run -p 6333:6333 qdrant/qdrant

# Hoặc dùng Qdrant Cloud (free tier)
pip install qdrant-client

3.2 Hands-on

"""Qdrant: Production vector DB"""
from qdrant_client import QdrantClient
from qdrant_client.models import (
    PointStruct, VectorParams, Distance, Filter,
    FieldCondition, MatchValue
)
from openai import OpenAI

openai = OpenAI()
qdrant = QdrantClient(url="http://localhost:6333")

# === 1. Tạo collection ===
qdrant.create_collection(
    collection_name="company_docs",
    vectors_config=VectorParams(
        size=1536,              # text-embedding-3-small dimension
        distance=Distance.COSINE
    )
)

# === 2. Embed + Insert ===
documents = [
    {"text": "Chính sách nghỉ phép: 15 ngày/năm", "category": "leave"},
    {"text": "Lương review mỗi 6 tháng theo KPI", "category": "salary"},
    {"text": "Bảo hiểm Bảo Việt cho toàn bộ nhân viên", "category": "insurance"},
]

# Embed tất cả cùng lúc (batch)
texts = [d["text"] for d in documents]
response = openai.embeddings.create(
    model="text-embedding-3-small",
    input=texts
)
embeddings = [r.embedding for r in response.data]

# Insert vào Qdrant
points = [
    PointStruct(
        id=i,
        vector=emb,
        payload={"text": doc["text"], "category": doc["category"]}
    )
    for i, (doc, emb) in enumerate(zip(documents, embeddings))
]
qdrant.upsert(collection_name="company_docs", points=points)

# === 3. Search ===
query_emb = openai.embeddings.create(
    model="text-embedding-3-small",
    input=["bảo hiểm sức khỏe"]
).data[0].embedding

results = qdrant.search(
    collection_name="company_docs",
    query_vector=query_emb,
    limit=3
)

print("🔍 Search: 'bảo hiểm sức khỏe'")
for r in results:
    print(f"  [{r.score:.4f}] {r.payload['text']}")

# === 4. Filtered Search ===
filtered = qdrant.search(
    collection_name="company_docs",
    query_vector=query_emb,
    query_filter=Filter(
        must=[FieldCondition(key="category", match=MatchValue(value="insurance"))]
    ),
    limit=3
)

3.3 Qdrant vs ChromaDB

FeatureChromaDBQdrant
セットアップPython の 1 行ドッカー / クラウド
パフォーマンス良い (< 100K)優れた (百万)
フィルタリング基本非常に強力 (ネスト、範囲)
Multi-tenancy❌✅
REST API❌✅
Monitoring❌✅ Dashboard
ProductionPOC✅ Production-ready

💡 演習 3: ChromaDB を使用して、(FAQ、ドキュメント、または記事から) 20 個のドキュメントを追加します。 10 個の異なる質問をします。カウント: 上位 1 位の結果は何回正解ですか? →これが検索精度です。


4. 4 つの Vector DB の詳細な比較

4.1 総合比較表

特長クロマDBクドラント松ぼっくり回避する
言語パイソンさび管理行く
ホスティング埋め込みセルフ/クラウドクラウドのみセルフ/クラウド
インデックスの種類ニューサウスウェールズ州ニューサウスウェールズ州独自のニューサウスウェールズ州
最大ベクトル~1M数百万10億以上数百万
フィルタリング基本上級上級グラフQL
ハイブリッド検索❌✅✅✅
マルチモーダル❌❌❌✅
無料利用枠無制限自己ホスト型100K ベック自己ホスト型
良いことプロトタイプ制作エンタープライズマルチモーダル

4.2 推奨事項

Bạn đang ở giai đoạn nào?

├── Prototype / Học tập
│   └── → ChromaDB ✅ (đơn giản, miễn phí)
│
├── Production (startup / team nhỏ)
│   ├── Self-hosted OK → Qdrant ✅ (mạnh, miễn phí)
│   └── Không muốn ops → Pinecone (managed, trả phí)
│
└── Enterprise (scale lớn)
    ├── Cần multimodal → Weaviate
    └── Cần đơn giản → Pinecone

5. ハイブリッド検索 — ベクトル + キーワードの組み合わせ

5.1 なぜハイブリッドが必要なのでしょうか?

セマンティック検索 (ベクトル) は、類似した意味を見つけることには 得意ですが、次の点では 苦手です。

  • 個人名: 「Nguyen Van Binh」 (完全一致が必要です)
  • コード: "ERR_404" (キーワードが必要です)
  • データ: 「2025 年第 3 四半期」 (正確である必要があります)

ハイブリッド検索 = ベクター検索 + BM25 キーワード検索、両方の利点を活用してください。

5.2 相互ランク融合 (RRF)

"""Hybrid Search: Vector + Keyword"""
from rank_bm25 import BM25Okapi
import numpy as np

documents = [
    "Chính sách nghỉ phép 2026: 15 ngày/năm cho full-time",
    "Ticket ERR_404: Server timeout lúc 3AM ngày 15/3",
    "Meeting Q3-2025: doanh thu tăng 23% so với Q2",
    "Nhân viên Nguyễn Văn Bình: đánh giá KPI quý 4",
]

# BM25 keyword search
tokenized = [doc.lower().split() for doc in documents]
bm25 = BM25Okapi(tokenized)

query = "ticket ERR_404"

# Keyword scores
keyword_scores = bm25.get_scores(query.lower().split())

# Vector scores (giả lập — thực tế dùng embedding)
vector_scores = np.array([0.3, 0.7, 0.2, 0.1])  # Từ vector search

# RRF fusion
def rrf_score(rank, k=60):
    return 1 / (k + rank)

# Combine rankings
keyword_ranks = np.argsort(-keyword_scores) + 1
vector_ranks = np.argsort(-vector_scores) + 1

final_scores = []
for i in range(len(documents)):
    kr = np.where(keyword_ranks == i+1)[0][0] + 1
    vr = np.where(vector_ranks == i+1)[0][0] + 1
    score = rrf_score(kr) + rrf_score(vr)
    final_scores.append(score)

# Sort by combined score
ranked = sorted(enumerate(final_scores), key=lambda x: -x[1])

print(f"Query: '{query}'\n")
for rank, (idx, score) in enumerate(ranked, 1):
    print(f"  #{rank} [{score:.4f}] {documents[idx][:50]}...")

💡 演習 5: ベトナム語 + コード + 個人名を組み合わせた 10 個の文書を作成します。テスト: (a) ベクトル検索のみ、(b) キーワード検索のみ、(c) ハイブリッド。それぞれの手法の精度は?


概要

コンセプト覚えておいてください
ベクター DBベクトルを保存し、最近傍をすばやく検索
ChromaDBプロトタイプ、シンプル、組み込み、無料
クドラントプロダクション、Rust、強力、セルフホスト
松ぼっくりマネージド クラウド、ゼロオペレーション、エンタープライズ
ハイブリッド検索ベクトル + キーワード = ほとんどの場合に最適
メタデータ フィルタリング最も近いベクトルを検索 + カテゴリ/日付でフィルター

一般的な演習

  1. ✅ 小さな演習 (3、5) を完了する
  2. ChromaDB RAG: ChromaDB + OpenAI を使用して、実際の PDF ファイル用の RAG を構築します。 10 個の質問をテストします。
  3. Qdrant のセットアップ: Docker を使用して Qdrant を実行し、ChromaDB からデータを移行します。検索速度を比較します。
  4. メタデータ設計: ナレッジ ベース (FAQ、ドキュメント) を基に、メタデータ スキーマを設計します。フィルタリングが必要なフィールドはどれですか? (カテゴリ、日付、著者、部門...)

次の記事: ドキュメントの読み込み — PDF、DOCX、Web、YouTube、コード リポジトリを処理して、RAG 用のデータを準備します。