Dockerでpgvectorを導入|既存PostgreSQLをRAG対応ベクトルDBに拡張する手順
はじめに
RAG構築でpgvectorが採用される理由
「RAGを導入したいけれど、どのベクトルDBを選べばいいのか分からない」そんな声を多く聞くようになりました。生成AIの普及により、企業でもRAG構築が急速に進んでいます。
中でも、PostgreSQLの拡張機能であるpgvectorは、多くの現場で採用が進むベクトルDBとなっています。
理由はシンプルで、既存のRDS(PostgreSQL)環境と自然に統合できる点です。
新しい専用DBを増やさず、既存の業務システムにベクトル検索を組み込めます。
SQLベースで扱えるため、開発・運用チームでも導入しやすく、コストを抑えつつ柔軟に拡張できます。
PineconeやFaiss、AWSのOpenSearchやKendra、AzureのAI Searchなど、さまざまな構成が存在しますが、PostgreSQLは企業での導入実績が豊富なため、「まずは試してみたい」「自社のRDS環境を活かしたい」というケースで特に選ばれやすいと感じています。
Pinecone / Faiss / OpenSearch / Kendra / AI Searchとの立ち位置比較
それぞれのベクトルDBには得意分野があります。
目的に応じて選択肢を変えることで、より効率的にRAGを構築できます。
ユースケース | おすすめDB | 特徴 |
---|---|---|
まずはPoCで検証したい | Pinecone | APIで手軽に使え、embeddingモデルの比較にも最適 |
高速な類似検索を重視したい | Faiss | C++実装で非常に高速、ローカル向けの軽量選択肢 |
インフラを意識せずに使いたい | OpenSearch / Kendra / AI Search | フルマネージドでスケールしやすく、AWS/Azureとの親和性が高い |
既存のPostgreSQL資産を活かしたい | pgvector | RDSに拡張導入でき、通常DBと統合して運用可能 |
こうして見ると、pgvectorは「既存環境を活かしつつベクトル検索を導入したい企業」にとって、最もバランスの取れた選択肢と言えるでしょう。
実務で3現場連続採用されている背景
私自身、これまで3つの現場でRAG構築を担当してきましたが、すべてpgvectorが採用されていました。
その理由として大きかったのは、以下の3点です。
- 既存のPostgreSQLに拡張導入できるため、新しいDB基盤を増やさずに済む
- コストを抑えてRAGを構築できる(Pineconeなどの従量課金に比べて安価)
- DB運用の一元化が可能で、監視やバックアップも既存の仕組みを活かせる
結果として、開発・運用両面での安心感が高く、RAGの実装を素早く進められる点が評価されています。
これらの経験からも、pgvectorは今後さらに採用が増えると感じています。特に、RAGの商用実装が増える中で「既存DBと共存できる」点は今後ますます重要になっていくでしょう。
Dockerでpgvector環境を構築
Docker Composeでpgvectorが入っていないPostgreSQLを立ち上げる
まずはDocker Composeで、pgvectorなしのPostgreSQLを立ち上げます。
docker-compose.yml(pgvectorなし)
services:
postgres:
image: postgres:16
container_name: postgres
restart: unless-stopped
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret-password
POSTGRES_DB: appdb
TZ: Asia/Tokyo
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
Dockerを立ち上げた状態で、上記のファイルを現在のディレクトリに配置し、下記を実行。
# 起動
docker compose up -d
# 動作確認(psql で接続)
docker exec -it postgres psql -U app -d appdb
ここまでで、PostgreSQLコンテナへの接続確認が完了です。
pg_available_extensionsで利用可能か確認
ログイン状況で下記を確認し、利用できない状態なので、0行が返ってくればOK。
SELECT name, default_version, installed_version FROM pg_available_extensions WHERE name='vector';
※「postgres:16」ではpgvectorが利用できないので、「pgvector/pgvector:pg16」に切り替える必要がある。
※移行前にまずはDBのバックアップを取っておく。
docker exec -i postgres pg_dump -U app -d appdb > backup_$(date +%Y%m%d%H%M%S).sql
※現在のディレクトリにSQLファイルが保存されている。
Docker Composeのイメージの変更。以下に差し替え
services:
postgres:
image: pgvector/pgvector:pg16 #ここが変わった。
container_name: postgres
restart: unless-stopped
environment:
POSTGRES_USER: app
POSTGRES_PASSWORD: secret-password
POSTGRES_DB: appdb
TZ: Asia/Tokyo
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata:
※下記公式HPに、「マイナーリリースは内部ストレージ形式を変更することはなく、同じメジャーバージョン番号の以前のマイナーリリースと常に互換性があります。」と記載あり。
入れ替え起動を実施する
# イメージをpull
docker compose pull
# 起動
docker compose up -d
# 起動確認
docker compose logs -f postgres | sed -n '1,120p'
# 以下のログが出ていればOK
## database system is ready to accept connections
コンテナ内でCREATE EXTENSION vector;を実行
再度DBに接続する
# 動作確認(psql で接続)
docker exec -it postgres psql -U app -d appdb
# vectorが使えるようになっているので1行レコードが返る。
SELECT name, default_version, installed_version FROM pg_available_extensions WHERE name='vector';
# vectorを使えるようにする。
CREATE EXTENSION vector;
サンプルデータ登録とベクトル検索を試す
まずはベクトルDBを作成する。
CREATE TABLE docs (
id SERIAL PRIMARY KEY,
title TEXT NOT NULL,
category TEXT,
embedding VECTOR(3) -- 次元数は、各埋め込みモデルの次元数によって変化させる。
);
ダミーデータの作成
INSERT INTO docs (title, category, embedding) VALUES
('社内規程の改定', 'policy', '[0.9, 0.1, 0.0]'),
('有給申請の手順', 'policy', '[0.85, 0.05, 0.05]'),
('請求書のテンプレート', 'finance', '[0.1, 0.9, 0.1]'),
('経費精算のルール', 'finance', '[0.1, 0.85, 0.15]'),
('VPN接続トラブル対応', 'it', '[0.05, 0.05, 0.95]'),
('PCセットアップ手順', 'it', '[0.1, 0.1, 0.9]');
検索の実施
WITH q AS (SELECT '[0.95,0.05,0.0]'::vector AS v)
SELECT id, title, category, embedding <=> (SELECT v FROM q) AS cosine_dist
FROM docs
ORDER BY embedding <=> (SELECT v FROM q)
LIMIT 3;
カテゴリで絞って検索
WITH q AS (SELECT '[0.95,0.05,0.0]'::vector AS v)
SELECT
id,
title,
category,
embedding <=> (SELECT v FROM q) AS cosine_dist
FROM docs
WHERE category = 'policy'
ORDER BY embedding <=> (SELECT v FROM q)
LIMIT 3;
ベクトル検索がどう動くかを体感
pgvectorでは、ベクトル同士の「距離(類似度)」を計算することで、
テキストやドキュメント間の意味的な近さを求めます。
今回の例では、演算子 <=>
を使って cosine距離(cosine distance) を計算しています。
距離が小さいほど、クエリベクトルに“意味的に近い”データと判断されます。
このようにpgvectorでは、SQLだけで「意味的に近い文書検索」を実現できます。
RAG構築では、ここで取得した上位文書をLLMに渡すことで、より文脈に沿った回答生成が可能になります。
RAG連携の比較
コスト・運用・速度比較表
RAG構築では、どのベクトルDBを使うかによって運用コストや速度が大きく変わります。
ここでは、実務で利用される pgvector / Pinecone / Faiss / OpenSearch / Kendra / AI Search を比較します。
項目 | pgvector | Pinecone | Faiss | OpenSearch | Kendra / AI Search |
---|---|---|---|---|---|
導入難易度 | 低(PostgreSQL拡張で即導入可) | 低(APIベース) | 中(ビルドやメモリ設定必要) | 中(Elasticsearch互換) | 低(マネージド) |
コスト | 低(自社運用のみ) | 中〜高(従量課金) | 低(ローカル利用前提) | 中 | 高(マネージド課金+検索課金) |
検索速度 | 中(CPU依存、インデックス調整で改善) | 高(GPU/分散対応) | 高(C++実装で超高速) | 中(スケール構成で調整) | 中(チューニング不可) |
pgvectorは特に、「既存のPostgreSQL資産を活かしながらベクトル検索を追加したい」というニーズに最適です。
一方で、大量データを扱う本番RAGや分散検索を重視する場合は、PineconeやOpenSearchを検討するのも有効です。
「PostgreSQLを活かしたRAG構築」 のメリット整理
pgvectorを使う最大の利点は、「既存のPostgreSQLをそのままRAG基盤にできる」ことです。
新しいサービスやインフラを増やさず、既存DBの監視・バックアップ運用の仕組みを流用できます。
メリット | 説明 |
---|---|
導入が容易 | 既存PostgreSQLにCREATE EXTENSION vector; を実行するだけ |
低コスト | 外部サービス費用が不要で、RDSでも利用可能 |
SQLで扱える | ベクトル検索も既存のSQL文に組み込みやすい |
移行が容易 | 本番DBとの互換性を保ちながら徐々に拡張できる |
このように、pgvectorは「RAGを社内環境で完結させたい企業」に最適な選択肢といえます。
まとめ
-
pgvectorは既存PostgreSQLの拡張として導入しやすく、移行リスクが低い
-
Dockerで検証 → 運用DBに導入 という2段階構成が最も安全
-
コストを抑えたRAG構築の実現手段として有力
Discussion