ローカルLLMでRAGを構築する方法【Ollama+ベクトルDB】

ローカルLLM

「ローカルLLMに自分のドキュメントを読み込ませて質問したい」という場面で役に立つのが RAG(Retrieval Augmented Generation) という仕組みです。ChatGPTのような外部クラウドAPIを使わず、手元のUbuntu環境でOllamaとベクトルDBを組み合わせるだけで、自分のファイルを「知っている」AIチャットを作れます。

本記事では、Ubuntu 24.04 LTS(Docker公式イメージ)で実際にセットアップした結果を載せています。ChromaDB 1.5.9・Ollama 0.30.8・Qdrant v1.18.2 のバージョン、および類似検索スコアはすべて 2026-06-14〜15 時点の実測値です。

この記事のポイント

  • RAGとは「外部文書を検索してLLMに渡す」仕組み。ファインチューニングなしで知識を追加できる
  • ベクトルDBには ChromaDB(Pythonインメモリ、学習用)と Qdrant(Docker対応、本番向け)の2種類を紹介
  • Ollamaは docker run -d -p 11434:11434 ollama/ollama でAPI起動できる(バージョン 0.30.8 実測)
  • ChromaDB 1.5.9 の類似検索は collection.query() だけ。3つのクエリすべてで正解文書をスコア 0.62〜0.70 で最上位に返した(実測)
  • Qdrant は http://localhost:6333/dashboard でGUIダッシュボードが使える

RAGとは何か:なぜローカルで構築するのか

RAGは「Retrieval Augmented Generation(検索拡張生成)」の略で、次の2ステップで動きます。

  1. ユーザーの質問に似た文書をベクトルDB から検索して取得する
  2. 取得した文書をコンテキストとして添えてLLMに質問する

これによって、LLMが本来「知らない」情報(社内マニュアル・個人のメモ・最新ドキュメント)を正確に答えられるようになります。ファインチューニングと違い、文書を追加・削除するだけで知識を更新できるのが最大の利点です。

ローカルで構築するメリットは3つあります。

  • 機密文書がインターネットに出ない(社内情報を安全に使える)
  • APIコストがゼロ(回数無制限)
  • ネット環境なしで動く(オフライン環境でも稼働)
ローカルLLM+RAG処理フロー(Ollama + Qdrant 構成、概念図)
ローカルLLM+RAG処理フロー(Ollama + Qdrant 構成、概念図)

動作確認済み環境

項目 環境・バージョン
OS Ubuntu 24.04.1 LTS(Docker公式イメージ ubuntu:24.04
Python 3.12.3(Ubuntu 24.04 デフォルト)
Ollama 0.30.8(Docker ollama/ollama:latest
ChromaDB 1.5.9(pip install chromadb)
Qdrant v1.18.2(Docker qdrant/qdrant:latest
LangChain 1.3.9 / langchain-community 0.4.2(2026-06-15 実測)
確認日 2026-06-14〜15

注意

本記事のコマンドは Ubuntu 24.04 LTS で検証しています。Ubuntu 22.04 でも同じ手順で動作しますが、Python のバージョン(3.10)が異なるため、パッケージのバージョン番号が変わる場合があります。

Python環境とパッケージをインストールする

手順1:Python仮想環境を作る

Ubuntu 24.04 はシステムのPython環境が保護されているため(PEP 668)、RAG用に仮想環境を作るのが正しい方法です。




ubuntu@linuxlab: ~
$ sudo apt update && sudo apt install -y python3-pip python3-venv
Reading package lists… Done
Setting up python3-pip (24.0+dfsg-1ubuntu1.3) …
Setting up python3-venv (3.12.3-0ubuntu2.1) …
$ python3 -m venv rag-env
$ source rag-env/bin/activate
(rag-env) $ python3 –version
Python 3.12.3

手順2:RAG用パッケージをインストールする

今回使うパッケージは3つです。chromadb(ベクトルDB)、langchain(LLMフレームワーク)、langchain-community(Ollama・ChromaDB連携)。




ubuntu@linuxlab: ~
(rag-env) $ pip install chromadb langchain langchain-community
Collecting chromadb
Collecting langchain
Collecting langchain-community
Successfully installed chromadb-1.5.9 langchain-1.3.9 langchain-community-0.4.2
(および依存パッケージ多数)
apt + pip インストール実ログ(Ubuntu 24.04 実測)
apt + pip インストール実ログ(Ubuntu 24.04 実測)
RAG用Pythonパッケージ一覧(実測バージョン、2026-06-14)
RAG用Pythonパッケージ一覧(実測バージョン、2026-06-14)

OllamaをDockerで起動する

Ollamaは公式Dockerイメージで簡単に起動できます。GPUがない環境でもCPUモードで動作します。




ubuntu@linuxlab: ~
$ docker run -d –name ollama -p 11434:11434 ollama/ollama
Unable to find image ‘ollama/ollama:latest’ locally
latest: Pulling from ollama/ollama
Status: Downloaded newer image for ollama/ollama:latest
$ docker exec ollama ollama –version
ollama version is 0.30.8
$ curl http://localhost:11434/api/tags
{“models”:[]}

起動できたら、使用するモデルをダウンロードします。今回は軽量な llama3.2:1b を使います(1GBモデルで最も手軽です)。




ubuntu@linuxlab: ~
$ docker exec ollama ollama pull llama3.2:1b
pulling manifest
pulling b6ff…: 100% ▕████████████████████▏ 1.3 GB
success
$ docker exec ollama ollama list
NAME ID SIZE MODIFIED
llama3.2:1b baf6a787fdff 1.3 GB 23 seconds ago

モデルサイズの目安

llama3.2:1b(1.3GB)は最小構成で高速ですが精度はやや低め。精度を上げたい場合は llama3.2:3b(2.0GB)や qwen2.5:7b(4.7GB)が選択肢です。空きRAMが8GB以上あれば 7b 系モデルを推奨します。

ChromaDBで最初のRAGを動かす

まずは一番シンプルな構成として、ChromaDBのインメモリクライアントを使ったRAGパイプラインを試します。ファイルに保存する設定は後述します。

手順1:文書をベクトルDBに登録する




rag_demo.py
import chromadb

client = chromadb.EphemeralClient() # インメモリ(再起動で消える)
collection = client.create_collection(
name=”linux_knowledge”,
metadata={“hnsw:space”: “cosine”} # コサイン類似度で検索
)

docs = [
“Ollamaはローカル環境でLlama3やMistralなどのLLMを動かすツールです。”,
“RAGとは、LLMの回答生成時に外部知識を取得して文脈に追加する手法です。”,
“ChromaDBはPythonで使えるオープンソースのベクトルデータベースです。”,
… (以降、登録したい文書を追加)
]
collection.add(documents=docs, ids=[f”doc{i+1}” for i in range(len(docs))])

手順2:類似検索で関連文書を取得する




rag_demo.py(続き)
results = collection.query(
query_texts=[“OllamaでLLMをインストールする方法は?”],
n_results=2 # 上位2件を取得
)
for doc, dist in zip(results[“documents”][0], results[“distances”][0]):
print(f” [スコア:{1-dist:.3f}] {doc[:60]}”)

実際に Ubuntu 24.04(Docker公式イメージ)の仮想環境で chromadb 1.5.9 を動かし、7件の文書に対して3つのクエリを投げた実測結果が下の図です。「OllamaでLLMをインストールする方法は?」というクエリに対しては スコア 0.699 で正しい文書(ollama pull の説明)が最上位にヒットしました。「本番運用に向いたベクトルDBは?」では Qdrant の説明文がスコア 0.704、「Ubuntu 24.04でpipが使えないのはなぜ?」では PEP 668 の文書がスコア 0.622 と、3問すべてで意図した正解文書が1位になっています。

埋め込みモデルは ChromaDB が自動でダウンロードする all-MiniLM-L6-v2(約79MB)を使っています。日本語の文章でもコサイン類似度で 0.6 台後半のスコアが出ており、シンプルなFAQ検索なら十分実用になる精度です。

ChromaDB RAGデモ実行結果(実測:3クエリとも正解文書がスコア0.62〜0.70で最上位)
ChromaDB RAGデモ実行結果(実測:3クエリとも正解文書がスコア0.62〜0.70で最上位)

ChromaDBをファイルに永続保存する

本番用途では EphemeralClient() の代わりに PersistentClient(path="./chroma_db") を使います。




ubuntu@linuxlab: ~/rag-project
import chromadb

client = chromadb.PersistentClient(path=”./chroma_db”)
# 以降は EphemeralClient と同じ使い方
collection = client.get_or_create_collection(“linux_knowledge”)

Qdrantをサーバーモードで使う(本番構成)

ChromaDB はシンプルですが、大量のデータや本番運用では Qdrant が有力な選択肢です。Dockerで起動でき、ブラウザで使えるGUIダッシュボードが標準搭載されています。

ベクトルDB比較表(2026-06-15 時点)
ベクトルDB比較表(2026-06-15 時点)

手順1:QdrantをDockerで起動する




ubuntu@linuxlab: ~
$ docker run -d –name qdrant -p 6333:6333 qdrant/qdrant
latest: Pulling from qdrant/qdrant
Status: Downloaded newer image for qdrant/qdrant:latest
# ダッシュボードの確認
$ curl -s http://localhost:6333/collections | python3 -m json.tool
{“result”: {“collections”: []}, “status”: “ok”}

起動したら http://localhost:6333/dashboard をブラウザで開きます。

GUIダッシュボードでコレクションを確認する

Qdrant v1.18.2 のダッシュボードでは、コレクション(テーブルに相当)の状態をリアルタイムに確認できます。下の画像は実際に linux_docs コレクションに5件のベクトルを投入した状態のスクリーンショットです。

Qdrantダッシュボード:コレクション一覧(実測、linux_docs=5件)
Qdrantダッシュボード:コレクション一覧(実測、linux_docs=5件)

各コレクションをクリックすると、保存されているPointのペイロード(元のテキスト)とベクトルの次元数が確認できます。下の画像では、linux_docs の各Pointに textsource のペイロードが入り、ベクトルが格納されている様子が見えます(この動作確認では検証用に小さな4次元ベクトルを投入しています。実際に nomic-embed-text を使う場合は後述のとおり768次元になります)。

linux_docs コレクション詳細(実測:ペイロードと4次元のデモベクトル)
linux_docs コレクション詳細(実測:ペイロードと4次元のデモベクトル)

手順2:Python から Qdrant にベクトルを登録する




ubuntu@linuxlab: ~/rag-project
(rag-env) $ pip install qdrant-client
Successfully installed qdrant-client-1.18.0

from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams

client = QdrantClient(host=”localhost”, port=6333)
client.create_collection(
collection_name=”linux_docs”,
vectors_config=VectorParams(size=768, distance=Distance.COSINE)
)
著者アイコン
著者アイコン

ベクトルの size(次元数)は使う埋め込みモデルに合わせる必要があります。Ollamaの nomic-embed-text なら768次元、all-MiniLM-L6-v2 なら384次元です。ここを間違えると insert 時にエラーが出るので注意してください。

Ollama の埋め込みモデルと繋げる(LangChain利用)

Ollama には nomic-embed-text という埋め込み専用モデルがあります。このモデルを使えば、テキストのベクトル化もローカル完結で行えます。




ubuntu@linuxlab: ~
$ docker exec ollama ollama pull nomic-embed-text
pulling manifest
success

LangChain を使うとOllama の埋め込みと ChromaDB / Qdrant を数行で接続できます。ただし LangChain 1.x では連携モジュールが専用パッケージに分離されたため、langchain-ollama(Ollama連携)と langchain-chroma(Chroma連携)を追加でインストールします。下のインポートは Ubuntu 24.04 + langchain 1.3.9 / langchain-ollama 1.1.0 / langchain-chroma 1.1.0 で実際に解決することを確認済みです。




ubuntu@linuxlab: ~/rag-project
(rag-env) $ pip install langchain langchain-ollama langchain-chroma
Successfully installed langchain-1.3.9 langchain-ollama-1.1.0 langchain-chroma-1.1.0



rag_langchain.py
from langchain_ollama import OllamaEmbeddings, OllamaLLM
from langchain_chroma import Chroma

embeddings = OllamaEmbeddings(model=”nomic-embed-text”)
vectorstore = Chroma(embedding_function=embeddings, persist_directory=”./chroma_db”)

llm = OllamaLLM(model=”llama3.2:1b”)
# 質問に近い文書を検索して、文脈として渡す
retriever = vectorstore.as_retriever(search_kwargs={“k”: 3})
docs = retriever.invoke(“OllamaでRAGを構築するには?”)
context = “\n”.join(d.page_content for d in docs)
print(llm.invoke(f”次の情報を参考に答えて:\n{context}\n\n質問: OllamaでRAGを構築するには?”))

テキストをチャンク分割して登録する

長い文書はそのままでは検索精度が落ちます。RecursiveCharacterTextSplitter を使って500〜1000文字のチャンクに分割してから登録するのがベストプラクティスです。




rag_split.py
from langchain_text_splitters import RecursiveCharacterTextSplitter

text = open(“./my_document.txt”, encoding=”utf-8″).read()

splitter = RecursiveCharacterTextSplitter(chunk_size=500, chunk_overlap=50)
chunks = splitter.create_documents([text])
print(f”チャンク数: {len(chunks)}”) # 例: チャンク数: 24

vectorstore.add_documents(chunks)

よくあるエラーと解決策

① pip install で「externally-managed-environment」エラー

Ubuntu 24.04 では PEP 668 により pip3 install が直接使えなくなっています。




ubuntu@linuxlab: ~
error: externally-managed-environment

# 解決策: 仮想環境を使う(推奨)
$ python3 -m venv rag-env && source rag-env/bin/activate
(rag-env) $ pip install chromadb # 仮想環境内は制限なし

② ChromaDB が ONNX モデルのダウンロードに時間がかかる

ChromaDB 1.5.9 は初回実行時に埋め込みモデル all-MiniLM-L6-v2(約79MB)を自動ダウンロードします。正直、最初は「フリーズしたのかな?」と思うほど長く感じます。プログレスバーが出るまで待ってください。キャッシュ後は即座に起動します。

③ Qdrant の REST API で「404 Not Found」

http://localhost:6333/collections は正常ですが、http://localhost:6333/ は 404 を返します。これはQdrantの仕様です。ダッシュボードは http://localhost:6333/dashboard でアクセスしてください。

④ Ollama の API 接続エラー(Dockerネットワーク)

Dockerコンテナから localhost:11434 に接続しようとすると失敗します。コンテナ間通信には host.docker.internal:11434(macOS/Windows)または同一ネットワークのコンテナ名を使ってください。




ubuntu@linuxlab: ~
# Python スクリプト内での接続設定
llm = Ollama(base_url=”http://host.docker.internal:11434″, model=”llama3.2:1b”)

まとめ

今回試した構成のポイントをまとめます。

  • RAGは「ベクトル検索で文書を取得 → LLMに渡す」という2ステップ。ファインチューニングなしで知識を追加できる
  • ChromaDB 1.5.9(pip install chromadb)はゼロ設定で動く。学習・プロトタイプに最適
  • Qdrant v1.18.2(Docker起動)はブラウザGUI付き。本番環境や大規模データ向け
  • Ollama 0.30.8 は docker run -d -p 11434:11434 ollama/ollama で起動。GPUなしでも動作する
  • LangChain 1.3.9 を使えば Ollama + ChromaDB / Qdrant の接続が数行で書ける(langchain-ollama / langchain-chroma を併用)
  • Ubuntu 24.04 では必ず仮想環境(python3 -m venv)を作ってからパッケージをインストールする

VPS上でOllamaを動かしてRAGを構築すれば、チーム全員がブラウザからアクセスできる社内AIを作れます。Vultrの東京リージョンなら月$5〜からSSDサーバーを借りられます。

Ollamaのインストール手順はこちらの記事でも詳しく解説しています。

[LINK_ollama-install-guide_ARTICLE]

LLMをVPS上で動かす具体的な構成例はこちらもどうぞ。

[LINK_local-llm-guide_ARTICLE]

コメント

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