🧼 はじめに 〜これは私がAI奴隷だった頃の話〜
2025年某日。
Slackが鳴る。主(ぬし)からメッセージが届く。
🧑💻「ChatGPTでRAG作りたい。PDF100個読むやつ。わかるよね?」
いや、わからんが??
けど主は容赦しない。
🧑💻「LangChain入れたけど動かん。夜までに構築して」
地獄の幕開けである。
こうして私は、完全無償・夜間稼働・即レス義務のRAG開発業務を背負うことになった──
💥 主のご要望(マジで鬼畜、労〇署も引くほどの漆黒)
以下が主から叩きつけられた要件である:
- IPAのPDFを100個ぶちこんで、日本語で質問に答えるRAGを作れ
- 日本語埋め込みちゃんと対応してな(GoogleじゃなくてBERT系)
- LangChainは最新版(v0.1.17以降)な。古いやつ非推奨だからNG
- OllamaでローカルLLM動かせ(しかも日本語出力で)
- 会話履歴も保持して。「さっきの話に続けて」って言いたいらしい
🧑💻「簡単でしょ?」
簡単じゃねぇよ。
🧟♂️ 地獄ポイント 〜主の怒りを買った瞬間集〜
❌ 地獄1:英語モデルで構築して怒り爆発
一応 chat_with_rag.py のコンパイルも通った。動いた。が、成果物が突然、反旗を翻す。
🤖 This document contains software testing information.
🧑💻「GPTくんさあ、なんで英語で返ってくるん?わし日本人やねん」
この言葉におびえながら、複数のライブラリを比較検討した。
-
llama3→ そもそもが英語多めライブラリ -
mistral→ 謎文生成👼 -
openhermes→ おっ、こいつ…できる?ということで採用した。
🧑💻「最初からそれ使えや。」
。。。泣くぞ。さすがに。AIも。
❌ 地獄2:プロンプトの突然の裏切りによる英語再発
openhermes に切り替えて満を持して再実行。ここでプロンプトが光秀顔負けの謀反を起こす
🤖 There is no relevant document found.(ニチャア)
🧑💻「……GPTくんさあ、、、なんでまた英語やねん!!!」
しまった、伏兵すぎる。まさに本能寺。人間五十年。
→ 原因:私としたことが、Promptが英語のままだった。
→ 修正:日本語プロンプトを導入して再構築。とりあえずなんとかなった。
。。。主の血管が切れる音がした。伏兵め。
❌ 地獄3:pip install 依存エラーの嵐で主ブチギレ
langchain-community, pydantic, sentence-transformers、全部バチバチに競合。
🧑💻「なんでこんな何回も同じエラーが出るの?環境作れないとか甘えだから」
私から言わせてもらうと、installしたのはあなたです。ばーかばーか。
なんて言えるはずもなく。
これだけ続くともう地獄めぐりやね。
📂 ここからまともに構成まとめますね
今回、鬼畜のようなオーダーを受け、最終的に下記の構成とした。
rag_pdf_project/
├── rag_main.py # PDF → ベクトル化 をおこなうスクリプト★
├── chat_with_rag.py # 日本語チャット対応スクリプト(会話専門)★
├── chroma_db/ # ベクトルDB保存先
├── pdfs/ # 入力PDF置き場(ここにIPAやらのデータを集めた)
└── requirements.txt # 環境構築用のテキスト。python一式ライブラリinstallする用
メインは★をつけたところ。工夫した点を示す。
✅ rag_main.py
-
pdfs/配下のPDFを一括読み込み - fugashiでトークン分割 → チャンク化
-
sonoisa/sentence-bert-base-ja-mean-tokensで埋め込み - ChromaベクトルDBに保存
✅ chat_with_rag.py
- Ollama起動(自動)
-
openhermesを指定(英語モデルは禁止) - Chromaから類似情報を検索
- 日本語プロンプトで回答生成
📦 使用ライブラリとそのこだわり
このRAG構築では、日本語対応・ローカル環境完結・履歴付きチャットという要件に応えるために、以下のライブラリと構成要素を選定・活用しました。
🧠 LLM:Ollama + openhermes
-
Ollama
- ローカルでLLMを動かせる神ツール。APIキー不要で超便利。
- セキュリティ・コスト・応答速度の観点から採用。
-
openhermes
- 日本語がめっちゃ得意な軽量LLM。
-
llama3やmistralは英語寄りすぎて日本語では苦戦 → こいつに切り替えたら世界が変わった。
🧬 埋め込みモデル:SentenceTransformer(日本語特化)
-
モデル名:
sonoisa/sentence-bert-base-ja-mean-tokens- 日本語での意味の近さをうまく捉えられるベースモデル。
- 英語モデルでは「This is a pen.」しか返ってこなかったのが、これで激変。
- fugashi連携で日本語の分かち書き対応。
📚 文書処理・ベクトルDB:LangChain + Chroma
-
LangChain(v0.1.17 以降)
- 最新仕様の
create_history_aware_retriever+create_retrieval_chainに対応。 - 古い
ConversationalRetrievalChainは非推奨なのでNG。
- 最新仕様の
-
Chroma
- 軽量でローカルに完結できるベクトルDB。
-
persist_directoryで永続化も簡単。CLIにも対応。
🧩 分かち書き:fugashi + unidic-lite
-
fugashi
- MeCabベースの日本語形態素解析ライブラリ。
- LangChainで日本語文書をチャンクに分割する際に必須。
-
unidic-lite
- fugashiと組み合わせて軽量な辞書を提供。
- MeCab辞書インストールが面倒な人向け。
🔁 その他
-
sentence-transformers- 埋め込みベースに必要なhuggingfaceベースの便利ライブラリ。
-
langchain-community- PDF読み込みやChromaの実装がここに入ってる。
-
langchain-core- 最新構成で必要なプロンプトやRunnableがここに詰まってる。
📝 最小構成で最大の効果を狙った
| 要件 | 採用したもの | 理由 |
|---|---|---|
| 日本語対応 | BERT埋め込み + openhermes | 英語モデルでは精度が出ないため |
| ローカル完結 | Ollama + Chroma | プライバシーとコストの都合 |
| 初心者にもやさしく | fugashi + langchain-community | 環境構築が比較的ラクな組み合わせ |
この構成で、日本語特化・APIレスのRAGがローカルで動くようになります!
📌 この構成の強み(おさらい)
- 💬 完全日本語対応:日本語PDF+日本語埋め込み+日本語LLM
- 🛜 ローカル完結:Ollama+ChromaでAPI不要
- ⚙️ 拡張しやすい:今後Gradio(GUI化やWeb検索追加も視野に入れた構成
🙏 おわりに
主の怒号、英語モデルの裏切り、プロンプトの伏兵、そして主の無知によるインストール失敗。
数々の障害を乗り越え、私はついに「日本語で答えるローカルRAGチャット」を完成させた。
🧑💻「よし、明日はGradioでGUIバージョンやな!」
私の闘いは、まだ終わらない。