Django + pgvector + LlamaIndexでRAG構築【PGVectorStore importエラー対応】

pika1.0で作成した動画の画像 New Challenge
pika1.0で作成した動画の画像




「from llama_index.vector_stores.pgvector import PGVectorStore」
で ImportError が発生する。


あるいは、
Django と PostgreSQL(pgvector) を組み合わせた RAG 構築で、
LlamaIndex のバージョン差異に苦しんでいる。


近年の LlamaIndex は急速に内部構造が変化しており、
2024 年以降はパッケージ分離が進んだことで、
以前のサンプルコードがそのままでは動かないケースが急増しました。


特に、
「requirements.txt 通りに入れたのに import が通らない」
「vector_stores 系が見つからない」
「Django 側では動くが Celery で落ちる」
「pgvector は入っているのに embedding が保存されない」
といった問題は、
実際の開発現場で非常に多く発生しています。


本記事では、
私が実際に Django + PostgreSQL(pgvector) + LlamaIndex を用いて
RAG システムを構築した経験をもとに、

  • PGVectorStore の正しい import 方法
  • 動作確認済み requirements.txt
  • pip install 手順
  • バージョン依存問題の回避方法
  • Django モデルとの統合
  • LlamaIndex による RAG 実装
  • Celery を用いた非同期化
  • 実運用で発生したエラー対策


までを、
「実際に動かした構成」をベースに整理して解説します。


単なる理論解説ではなく、
“実際に ImportError を解消しながら RAG を動かした記録”
としてまとめているため、
同じ問題で詰まっている方にとって、
かなり再現性の高いロードマップになるはずです。



Django とベクトル検索の関係を俯瞰する──なぜ今 pgvector なのか


まず最初に、
なぜ現在の生成 AI 開発において
「Django + pgvector」という構成が注目されているのかを整理します。


従来の全文検索は、
Elasticsearch や MeiliSearch のような
キーワードベース検索が主流でした。


しかし、
生成 AI の普及によって、
検索対象は単なる単語一致ではなく、
「意味的に近い情報」を取り出す必要が出てきました。


そこで重要になるのが、
ベクトル検索です。


ベクトル検索では、
文章を数百〜数千次元の数値ベクトルへ変換し、
その距離を計算することで、
意味的類似性を評価します。

1.1 ベクトル検索とは何か──キーワード検索との違い


キーワード検索は、
文字列一致をベースに動作します。


一方、
ベクトル検索は
「意味の近さ」を評価します。


そのため、
同じ単語を含んでいなくても、
意味的に近い文章を取得できます。


類似度 = cos(ベクトルA, ベクトルB)

検索方式特徴メリット
キーワード検索文字列一致を評価高速・単純
ベクトル検索意味の近さを評価曖昧検索・自然文検索に強い

1.2 なぜ pgvector が注目されているのか


pgvector は PostgreSQL の拡張として提供されるため、
既存の Django + PostgreSQL 環境へ
自然に統合できます。


つまり、
新しい検索エンジンを別途構築せずに、
現在の DB 基盤をそのまま活用できます。


これは実運用上、
非常に大きなメリットです。

  • バックアップを一元化できる
  • 認証・権限管理を統合できる
  • インフラコストを増やさずに済む
  • Django ORM と自然に連携できる


特に、
「まず RAG を小規模導入したい」
というフェーズでは、
pgvector のシンプルさは非常に強力です。



PGVectorStore ImportError対策──requirements.txtと環境構築


ここが、
現在もっとも検索需要が高いポイントです。


LlamaIndex は
2024〜2026 年にかけて大規模なパッケージ分離が進み、
以前の import パスでは動かないケースが増えました。


特に以下のコードは、
古い環境ではそのまま動きません。


from llama_index.vector_stores.pgvector import PGVectorStore


ImportError が発生する原因は、
主に以下の4つです。

  • llama-index 本体しか install していない
  • vector_store 系パッケージが分離された
  • 古い記事の import 文を流用している
  • requirements.txt が固定されていない

2.1 動作確認済み requirements.txt


以下は、
実際に Django + pgvector + LlamaIndex 構成で
動作確認した requirements.txt の一例です。


django==5.1.0
psycopg2-binary==2.9.9
pgvector==0.2.5

llama-index==0.10.30
llama-index-vector-stores-pgvector==0.1.8

openai==1.30.1
tiktoken==0.7.0

celery==5.4.0
redis==5.0.4


重要なのは、
「llama-index 本体だけでは不十分」
という点です。


現在は、
vector store 系が別パッケージになっています。

2.2 pip install 手順


pip install -r requirements.txt


あるいは、
個別インストールでも構いません。


pip install llama-index
pip install llama-index-vector-stores-pgvector

2.3 現在の正しい import 方法


from llama_index.vector_stores.pgvector import PGVectorStore


LlamaIndex は更新速度が非常に速く、
GitHub や古い記事のコードが
数ヶ月で動かなくなるケースもあります。


そのため、
requirements.txt を固定して、
環境ごと再現できるようにすることが
非常に重要です。

2.4 実際によく遭遇するエラー


ModuleNotFoundError:
No module named
'llama_index.vector_stores'


このエラーは、
ほぼ確実に
「追加パッケージ不足」です。


逆に、
以下のエラーが出る場合は、
バージョン衝突の可能性があります。


ImportError:
cannot import name PGVectorStore


この場合は、
仮想環境を作り直したほうが
早く解決するケースも多いです。



pgvector を用いた Django データモデル設計


次に、
実際の Django モデル側を構築します。


pgvector は PostgreSQL 拡張なので、
Django ORM と非常に相性が良いです。

3.1 ベクトルフィールドの定義


from pgvector.django import VectorField

class Document(models.Model):
    title = models.CharField(max_length=255)
    content = models.TextField()
    embedding = VectorField(dimensions=1536)


1536 次元は、
OpenAI embedding 系でよく利用されるサイズです。


モデルによって次元数は異なるため、
embedding モデル変更時は
dimensions の再設計が必要になります。

3.2 pgvector 拡張を有効化する


CREATE EXTENSION IF NOT EXISTS vector;


この SQL を実行しないと、
VectorField は正常動作しません。

3.3 類似検索クエリ


query_embedding = embed("検索したい文章")

Document.objects.order_by(
    "embedding__cosine_distance"
)


pgvector は
cosine_distance や l2_distance を
内部最適化しています。


さらに HNSW インデックスを利用すると、
数万〜数十万件規模でも
高速検索が可能になります。



LlamaIndex による RAG 構築


ここから、
実際に LlamaIndex と pgvector を接続します。

4.1 PGVectorStore の設定


from llama_index.vector_stores.pgvector import PGVectorStore

vector_store = PGVectorStore.from_params(
    database="mydb",
    table="document",
    dimensions=1536,
)


この時点で、
Django 側の PostgreSQL と
LlamaIndex が統合されます。

4.2 ドキュメント投入


from llama_index.core import (
    SimpleDirectoryReader,
    VectorStoreIndex
)

docs = SimpleDirectoryReader("docs").load_data()

index = VectorStoreIndex.from_documents(
    docs,
    vector_store=vector_store
)


RAG の品質は、
単に embedding を作るだけでは決まりません。


文書分割、
メタデータ、
chunk サイズ、
前処理品質が非常に重要です。

4.3 クエリ実行


query_engine = index.as_query_engine(
    similarity_top_k=5
)

response = query_engine.query(
    "この製品の保証期間は?"
)

print(response)


similarity_top_k を調整することで、
検索範囲を制御できます。



Celery による非同期 embedding 生成


embedding 生成は、
同期処理にすると非常に重くなります。


そのため、
Celery による非同期化は
実運用ではほぼ必須です。

5.1 Celery タスク例


@app.task
def generate_embedding(doc_id):

    doc = Document.objects.get(id=doc_id)

    doc.embedding = embed(doc.content)

    doc.save()


これにより、
ユーザー操作と embedding 生成を
分離できます。

5.2 retry による再実行


@app.task(bind=True, max_retries=5)
def generate_embedding(self, doc_id):

    try:
        ...

    except Exception as e:
        raise self.retry(
            exc=e,
            countdown=30
        )


OpenAI API は
レート制限や通信失敗があるため、
retry 設計は非常に重要です。



Google検索で“表示されるのにクリックされない”理由


実は今回のテーマは、
検索ニーズ自体は非常に強いです。


実際、


from llama_index.vector_stores.pgvector import PGVectorStore


というエラー系クエリは、
かなりピンポイントな技術課題です。


しかし、
表示されるのにクリックされない場合、
Google 上で
「解決記事っぽく見えていない」
可能性があります。

6.1 現在の問題点

  • タイトルが抽象的
  • ImportError 解決記事と一瞬で分からない
  • requirements.txt があることが見えない
  • 「動いた環境」が強調されていない

6.2 CTR改善に効くタイトル例


【解決】
from llama_index.vector_stores.pgvector
import PGVectorStore の ImportError対策

Django + pgvector + LlamaIndex
動作確認済み構成


技術記事では、
「動いた」
「解決した」
「実際に通った」
という表現が非常に強力です。

6.3 メタディスクリプション改善例


以下のように、
“ImportError 解決”
を前半へ持ってくると CTR が改善しやすいです。


from llama_index.vector_stores.pgvector
import PGVectorStore の ImportError を、
Django + pgvector + LlamaIndex の
動作確認済み環境で解決。
requirements.txt、
pip install、
RAG 構築コードまで実例付きで解説。


Google 検索では、
「この記事を開けば今のエラーが止まりそう」
と瞬時に伝わることが非常に重要です。



まとめ:Django × pgvector × LlamaIndex は実運用レベルへ入った


本記事では、
Django + PostgreSQL(pgvector) + LlamaIndex を用いた
RAG 構築について、
ImportError 対策から実運用設計までを整理しました。


特に現在の LlamaIndex は、
パッケージ分離が激しく、
古いサンプルコードが動かないケースが非常に増えています。


そのため、
requirements.txt ごと環境固定すること、
そして「実際に動作確認した構成」を参照することが、
以前より重要になっています。


また、
pgvector は単なる実験用途ではなく、
本番 RAG システムの基盤として
十分実用的な段階に入りました。


Django と組み合わせることで、
既存 Web システムへ
自然に AI 検索を統合できます。


ぜひ本記事をベースに、
あなた自身の RAG システム構築へ挑戦してみてください。



〆最後に〆


以上、
間違い・ご意見は
以下アドレスまでお願いします。


全て返信できていませんが、
見ています。


適時、
改定を行っています。


nowkouji226@gmail.com

全体の纏め記事に戻る

タイトルとURLをコピーしました