ChromaDB と Ollama を使用したローカル RAG:チュートリアル Python
ChromaDB、Ollama、Python を使ってローカルで RAG を構築するには、3 つの要素を組み合わせます。データをディスクに永続保存するベクトルストア(ChromaDB)、テキストのチャンクをベクトルに変換する埋め込みモデル(Ollama 経由の nomic-embed-text)、そして検索で見つかった文章をもとに回答するチャット LLM です。API キーは不要で、データが外部に漏れることもありません。本ガイドでは、未加工の PDF から、出典を引用するチャットボットを 22 分で作成するまでの手順を紹介します。
#なぜローカルRAGにこのスタックを採用するのか
多くのRAGチュートリアルは、LangChainやLlamaIndexから始まります。これらのフレームワークは強力ですが、内部で何が起きているかが見えにくくなります。ここでは、依存ライブラリを3つだけ使い、パイプラインを自分で書きます。各ステップを理解し、後で何を最適化すべきかも分かるようになります。
- ChromaDB
- オープンソースのベクトルストア、純粋なPythonで構成、永続モード(SQLite + HNSWインデックス)を内蔵。サーバーを起動する必要はありません。
- Ollama
- 埋め込みモデル(nomic-embed-text)とチャット LLM(Qwen 3.5、Granite 4.2、Gemma 4)の両方を提供します。localhost:11434 上の単一の HTTP エンドポイント。
- ネイティブPython
- いくつかの関数だけで、フレームワークは使いません。必要になれば後からLangChainを組み込めますが、始める段階では不要です。
#前提条件
このガイドでモデルの導入まで、キットでエディタ内でコードを書くコパイロットの導入まで進められます。
- 永久に利用できるオンラインスペース
- PDF + ファイル
- 生涯アップデート
- Python 3.10+
- ChromaDBは3.10以上が必要です。python --version で確認してください。
- Ollamaがインストールされ、起動されている
- デーモンはデフォルトで http://localhost:11434 で接続を待ち受けます。初めて設定する場合は、まずOllamaのインストールガイドに従ってください。
- 8 GB の RAM
- 16 GBあれば余裕があります。9BのチャットモデルはQ4で約6 GB、埋め込みモデルは約300 MBのメモリを使用します。
- GPUは必須ではありません
- CPUでも推論は動作しますが、速度は遅くなります。大規模なコーパスを取り込む際は、6 GB以上のメモリを搭載したGPUがあると、埋め込みの計算を大幅に高速化できます。
#1. ChromaDBをインストールし、Ollamaを準備する
クリーンな仮想環境を作成し、必要な3つのライブラリをインストールし、Ollama側でモデルをダウンロードします。
3つのパッケージ:ベクトルストア用のchromadb、公式Pythonクライアント用のollama、PDFの読み取り用のpypdf。これだけです。
nomic-embed-text は137Mのパラメータを持つ、マルチ言語の埋め込みモデルで、次元768のベクトルを生成します。軽量で高速であり、フランス語に優れています。Qwen 3.5 9B(6.6 GB、256kのコンテキスト、マルチ言語、Apache 2.0)はチャットの最終段階で使用されます。2026年では8 GBがデフォルト設定です。granite4.2:8b(より節約)またはgemma4:12bに置き換えることも可能です。コードの変更は一切必要ありません。
#2. エンベディングモデルの設定
埋め込みとは、テキストの意味を表すベクトルです。意味が近い2つのテキストは、ベクトルも近くなります。これがRAGの仕組みの核です。質問の埋め込みに最も似た埋め込みを持つチャンクを検索します。
「Dimension du vecteur : 768」と表示されるはずです。model not foundというエラーで失敗する場合は、ollama pull nomic-embed-textが実行されていないことが原因です。
#3. フランス語PDFの取り込み
インジェストは 3 つのことをします。PDF のページを読み取り、テキストを適切なサイズのチャンクに分割し、各チャンクとその埋め込みを ChromaDB に永続モードで保存します。
チャンカーはテキストを800文字のブロックに分割し、隣接するブロック間で100文字を重複させます。これは、小さすぎて文脈が不足することも、大きすぎて重要な情報が埋もれることもない、出発点となる設定です。情報密度が非常に高い法律関連の内容では500文字に減らし、余白が多くゆったりとした構成の技術マニュアルでは1200文字に増やしてください。
ドキュメントが入ったフォルダ ./pdfs/ を対象に、データの取り込みを開始してください:
#4. ChromaDBにおけるtop-k検索
チャンクをインデックス化した後の検索では、まず質問を埋め込みベクトルに変換し、次にコサイン距離が最も近いk個のベクトルをChromaに要求します。チャンクが10万個あっても、検索は瞬時に完了します。
k=4は適切なデフォルト値です。小さすぎると関連するコンテキストを取りこぼし、大きすぎるとLLMがノイズに埋もれ、コンテキストウィンドウの上限を超えてしまいます。対象が非常に絞られた質問ならk=2で十分です。横断的な質問では6に上げてください。
#5. 引用付きチャットループ
ここからは各処理を組み合わせます。関連するチャンクを検索し、そのコンテキストを使ってプロンプトを作成し、Ollama経由でQwen 3.5に送信して、モデルに出典を引用するよう求めます。
重要な3つの詳細があります。第一に、temperature=0.2です。創造的な回答ではなく、事実ベースの回答を求めています。第二に、num_ctx=8192です。Ollamaのデフォルトウィンドウ(2048)は、800文字のチャンクを4つ注入すると短すぎます。第三に、システムプロンプトは、モデルが幻覚を起こす代わりに「わかりません」と言うことを強制します。これはRAGにおける幻覚防止の主な安全策です。
#6. 具体例:契約書を扱う法務チャットボット
ある事務所が、PDF 形式の業務委託契約書200件について質問したいとします。上記の構成を使えば、1時間もかからずに、次のような質問に答えるアシスタントを用意できます。
- よくある質問
- 「契約終了後の競業避止期間が12か月を超える条項を含む契約はどれですか?」
- 何が起こるか
- 質問の埋め込みを使って、意味的に近いキーワード(競業避止、契約終了後、期間)を含むチャンクを検索します。Qwen 3.5はこの4つの箇所を読み、関連するファイル名を添えて回答します。
- プライバシーの保証
- データが端末の外に出ることはありません。APIキーも不要です。テレメトリもありません。これが、ローカルRAGとOpenAIのラッパーを区別する点です。
#トラブルシューティング
- ChromaDBへのデータ取り込みが遅い
- ボトルネックはほとんどがOllamaへのembedding呼び出しです。nomic-embed-textがGPU上で動作しているかをollama psで確認してください。CPUでは約50チャンク/秒、GPUでは約500チャンク/秒です。
- 「model not found」
- Ollamaがnomic-embed-textを見つけられません。ollama pull nomic-embed-textを再実行し、ollama listで確認してください。
- 出典を捏造する回答
- 9Bモデルは今でも時折ハルシネーションを起こします。十分なVRAMがあるなら、mistral-small(24B、約14GB、フランス語で非常に優れています)またはqwen3.8:27bに切り替えてください。あるいは、ChromaDBの後段にリランカー(クロスエンコーダー)を追加して、偽陽性を除外してください。
- フランス語での埋め込み品質が低い
- nomic-embed-textは多言語対応ですが、フランス語のみのコンテンツには最適ではありません。法律や医療に関するコンテンツには、Solon-embeddings-large-0.1またはbge-m3を試してください(Ollamaではなく、sentence-transformersで読み込みます)。
- ChromaDBのサイズが際限なく増える
- 各リインデックス処理により重複が発生します。PDFを再インポートする前に、collection.delete(where={"source": name}) を実行して以前のチャンクを削除してください。
#さらに詳しく
これで、正常に動作するRAGができました。さらに発展させるために、次に取り組むとよい項目は以下のとおりです。
- フランス語向けの埋め込みモデルを比較する
- 当サイトのガイド「フランス語向けのおすすめ埋め込みモデル」では、フランス語コンテンツを使って BGE、E5、Solon、nomic を比較しています。
- チャンク分割を改善する
- 「チャンキング戦略」では、意味に基づく分割、Markdown の見出しによる分割、段落ごとの分割を詳しく解説しています。こうした工夫が、精度の向上に最も大きくつながることがよくあります。
- rerankerを追加
- 「パイプラインにリランカーを追加する」:Chromaの後にクロスエンコーダーを配置することで、関連性が15%向上します。次に進むステップとして自然な選択です。
- ハイブリッド検索
- 「BM25+ベクトルのハイブリッド検索」は、語句に基づく検索と意味に基づく検索を組み合わせたもので、専門用語や固有名詞が多い場合には不可欠です。
ご意見、誤りのご指摘、補足はありますか?ぜひお知らせください。皆さんにとってより良いガイドにするために役立ちます。