ストーリー
田
田中VPoE
Step 2でドキュメント処理パイプラインを設計した。Step 3ではベクトルDBのセットアップと検索パイプラインの構築に入る
あなた
Step 1でベクトルDBの概要は学びました。今回は実際の設計に踏み込むんですね
あ
田
田中VPoE
そうだ。インデックス設計、スキーマ設計、パフォーマンスチューニング — 本番運用を見据えた設計を行う。ベクトルDBの設計ミスは後から修正するのが困難だ。最初にしっかり設計しよう
田
田中VPoE
Step 1の検討結果を踏まえて、Qdrantをセルフホストで採用する。HNSWインデックス、メタデータフィルタリング、ハイブリッド検索に対応しており、うちの要件に合っている
コレクション設計
コレクション分割戦略
| 戦略 | 説明 | メリット | デメリット |
|---|
| 単一コレクション | 全ドキュメントを1つのコレクションに格納 | シンプル、横断検索が容易 | メタデータフィルタのコスト増 |
| ドキュメント種別で分割 | 技術文書/議事録/FAQを別コレクションに | 種別ごとの最適化が可能 | 横断検索に追加実装が必要 |
| ドメイン別に分割 | プロジェクト/チーム単位で分割 | アクセス制御が容易 | コレクション数が増大 |
NetShop社の設計
コレクション設計:
netshop_knowledge(単一コレクション)
├── doc_type = "技術文書" でフィルタ
├── doc_type = "議事録" でフィルタ
└── doc_type = "FAQ" でフィルタ
理由:
- 38,000件は単一コレクションで十分な規模
- 横断検索のユースケースが多い
- メタデータフィルタでドキュメント種別を絞り込める
インデックス設計
HNSWパラメータ
| パラメータ | 説明 | 推奨値 | トレードオフ |
|---|
| m | グラフの接続数 | 16〜64 | 大: 精度向上、メモリ増加 |
| ef_construction | インデックス構築時の探索幅 | 100〜200 | 大: インデックス品質向上、構築時間増加 |
| ef | 検索時の探索幅 | 64〜256 | 大: 検索精度向上、レイテンシ増加 |
パラメータ選定の目安:
データ件数: 〜100万件
├── m = 16, ef_construction = 128, ef = 128
├── 想定メモリ: ベクトル次元 × データ件数 × 4bytes × 1.5(オーバーヘッド)
└── 例: 1536次元 × 200,000チャンク × 4 × 1.5 ≒ 1.8GB
NetShop社の場合:
38,000件 × 平均5チャンク = 190,000チャンク
1536次元 × 190,000 × 4 × 1.5 ≒ 1.7GB → EC2 r6g.large(16GB RAM)で十分
距離メトリクスの選定
| メトリクス | 用途 | Qdrant設定 |
|---|
| コサイン類似度 | 最も一般的。テキストEmbeddingに推奨 | Cosine |
| ユークリッド距離 | 画像や音声の特徴ベクトル | Euclid |
| 内積 | 正規化済みベクトル(コサインと同等) | Dot |
スキーマ設計
Qdrantのコレクション定義
コレクション設定:
{
"collection_name": "netshop_knowledge",
"vectors": {
"size": 1536, // text-embedding-3-small の次元数
"distance": "Cosine"
},
"optimizers_config": {
"indexing_threshold": 20000 // この件数を超えるとインデックスを最適化
},
"hnsw_config": {
"m": 16,
"ef_construct": 128
}
}
ペイロード(メタデータ)のインデックス
メタデータインデックス設計:
フィルタに頻繁に使うフィールドにインデックスを作成:
1. doc_type(keyword) → ドキュメント種別でのフィルタ
2. department(keyword) → 部門でのフィルタ
3. updated_at(datetime) → 日付範囲でのフィルタ
4. tags(keyword[]) → タグでのフィルタ
5. tech_stack(keyword[])→ 技術スタックでのフィルタ
インデックスを作成しないフィールド:
- content(テキスト) → 大きすぎるためインデックス不要
- summary(テキスト) → 表示用、フィルタには使わない
- source_url(テキスト) → フィルタには使わない
パフォーマンスチューニング
チューニングポイント
| 項目 | 調整方法 | 効果 |
|---|
| メモリ割り当て | ベクトルデータがメモリに収まるようにRAMを確保 | 検索速度の大幅向上 |
| バッチサイズ | Upsert時のバッチサイズを100〜500に設定 | 書き込みスループット向上 |
| 並列度 | 検索時の並列リクエスト数を調整 | スループット向上 |
| キャッシュ | 頻出クエリの結果をアプリケーション側でキャッシュ | レイテンシ削減、DB負荷軽減 |
| セグメント | コレクションのセグメント数を調整 | 書き込みと読み込みのバランス |
本番運用のベストプラクティス
| 項目 | 推奨 |
|---|
| バックアップ | スナップショットを日次で取得(S3保存) |
| レプリケーション | 本番環境ではレプリカを1つ以上設定 |
| ヘルスチェック | /healthz エンドポイントの監視 |
| ログ | 検索クエリのレイテンシと結果件数をログ記録 |
| 容量計画 | 月次でデータ増加量を確認し、容量を予測 |
「ベクトルDBは”設定して終わり”ではない。データ量の増加に伴ってパフォーマンス特性が変わる。定期的なチューニングレビューが必要だ」 — 田中VPoE
まとめ
| ポイント | 内容 |
|---|
| コレクション設計 | 規模と検索パターンに応じて分割戦略を決定 |
| インデックス設計 | HNSWパラメータの調整でメモリ/精度/速度のバランスを取る |
| スキーマ設計 | フィルタ用メタデータにインデックスを作成 |
| パフォーマンス | メモリ確保、バッチサイズ調整、キャッシュ活用 |
チェックリスト
次のステップへ
次は「ハイブリッド検索」を学びます。ベクトル検索とキーワード検索を組み合わせることで、検索精度を大幅に向上させる手法を理解しましょう。
推定読了時間: 30分