0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【備忘録】Windows11で日本語PDFを使ったRAGを構築(LangChain + PGVector + Ollama)

Last updated at Posted at 2025-05-04

はじめに

日本語の文章を扱うRAG(Retrieval-Augmented Generation)システムを、Windows 11環境で構築したときの備忘録です。
主な構成は以下の通り:

  • LLM: Ollama(TokyoTech Swallow 8B)
  • Embeddingモデル: mxbai-embed-large
  • ベクトルデータベース: PostgreSQL + PGVector
  • ドキュメント: 日本語のpdf(検証用の創作物語)

1. 環境構築(Ollama, PostgreSQL + PGVector)

Ollama や PostgreSQL + PGVector の導入手順は以下の外部記事を参考にしました。

Ollamaのインストール方法

PostgreSQL + PGVector のインストール方法

使用モデル:

  • LLM:hf.co/mmnga/tokyotech-llm-Llama-3.1-Swallow-8B-Instruct-v0.3-gguf:latest

  • 埋め込みモデル:mxbai-embed-large

データベース設定(例):

データベース名:postgres
ユーザー名:postgres
パスワード:pass


2. 必要モジュールのインストール

以下のコマンドで必要なパッケージをインストールします:

pip install langchain langchain-community langchain-postgres langchain-ollama 
pip install "psycopg[binary]"  unstructured[all-docs]


3. コード①:PDFの読み込みとベクトルデータベースへの登録

日本語PDFを読み込み、テキストを分割し、Ollamaでベクトル化した上で、PGVectorに保存します。

from langchain.document_loaders import UnstructuredFileLoader
from langchain_text_splitters import CharacterTextSplitter
from langchain_postgres import PGVector
from langchain_ollama import OllamaEmbeddings, ChatOllama

# LLMの初期化(Ollamaに接続)
llm = ChatOllama(
    model="hf.co/mmnga/tokyotech-llm-Llama-3.1-Swallow-8B-Instruct-v0.3-gguf:latest",
    base_url="http://localhost:11434",
    temperature=0,
    seed=0,
)

# PDFファイルの読み込み(日本語対応・ページ単位)
loader = UnstructuredFileLoader("./test.pdf", mode='paged', languages=['ja'])
documents = loader.load()

# テキストをチャンク(分割)に分ける
text_splitter = CharacterTextSplitter(
    chunk_size=600,       # 1チャンクあたりの文字数
    chunk_overlap=20,     # チャンク同士の重複(文脈保持のため)
    separator="\n"        # 改行で分割
)
docs = text_splitter.split_documents(documents)

# Embeddingモデルの設定
embeddings = OllamaEmbeddings(model='mxbai-embed-large')

# PostgreSQL + PGVector に接続
connection = "postgresql+psycopg://postgres:pass@localhost:5432/postgres"
collection_name = "test"

# インデックスを新規作成
vectorstore = PGVector(
    embeddings=embeddings,
    collection_name=collection_name,
    connection=connection,
    use_jsonb=True,
    pre_delete_collection=True,
)

# ドキュメントをベクトルDBに追加
vectorstore.add_documents(docs)

📌補足:

PyPDFLoader ではpdfファイルによっては文字化けが発生したため、UnstructuredFileLoader を使用しました。

from langchain_community.document_loaders import PyPDFLoader
loader = PyPDFLoader(file_path='test.pdf')

ちなみにpdfの中身は架空の人物"Kタロウ"の物語を適当に制作したもの。

📄 使用したPDFの中身(ばs)

知恵者Kタロウの物語。
昔々、京の都の西にある小さな山村に、「Kタロウ」という名の若者が住んでおった。
年は二十歳を少し超えたばかり。村の者たちは皆、...

🗄 データベースの中身

テーブル:langchain_pg_embedding に保存されます。

image.png

4. コード②:質問応答チェーンの構築と実行

保存したベクトル情報を使い、LLMを通じて質問に答える処理を実装します。

from langchain_postgres import PGVector
from langchain.chains.retrieval import create_retrieval_chain
from langchain.chains.combine_documents import create_stuff_documents_chain
from langchain_ollama import OllamaEmbeddings, ChatOllama
from langchain import hub

# LLMの設定(前と同様)
llm = ChatOllama(
    model="hf.co/mmnga/tokyotech-llm-Llama-3.1-Swallow-8B-Instruct-v0.3-gguf:latest",
    base_url="http://localhost:11434",
    temperature=0,
    seed=0,
)


# Embeddingの再設定
embeddings = OllamaEmbeddings(model='mxbai-embed-large')

# PGVectorに接続
connection = "postgresql+psycopg://postgres:pass@localhost:5432/postgres"
collection_name = "test"
vectorstore = PGVector.from_existing_index(
    embedding=embeddings,
    collection_name=collection_name,
    connection=connection,
    use_jsonb=True
)

# LangChain Hubから質問応答用のプロンプトテンプレートを取得
retrieval_qa_chat_prompt = hub.pull("langchain-ai/retrieval-qa-chat")

# ドキュメントを統合するチェーンを作成
combine_docs_chain = create_stuff_documents_chain(llm, retrieval_qa_chat_prompt)

# RAGの質問応答チェーンを構築
retrieval_chain = create_retrieval_chain(vectorstore.as_retriever(), combine_docs_chain)

# 質問を投げる
res = retrieval_chain.invoke({"input": "Kタロウに関して教えてください。"})

# 回答を出力
print(res["answer"])

得られた回答は以下の通り。pdfの内容を参照して回答してくれていることを確認しました。

✅ 出力結果

Kタロウについて、以下の情報が分かっています。

* **知恵者:** 村人から「知恵者K」と呼ばれるほど、頭が良く、問題解決能力に優れている。
* **謎の事件を解決:** 村の田畑に現れた謎の黒い影(実は夜猿)の正体を見破り、その原因と対策を提示した。
* **村のために尽力:**  村の発展のために、様々な難問を解き続け、「東山の賢者」として広く知られるようになった。... 

6. おわりに

RAGの構築に際して、Ollama + LangChain + PGVectorの構成は思ったよりシンプルでした。ローカルで完結する点も安心材料です。GUIも試してみたいと思います。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?