はじめに
こんにちは!
Dirbatoの社内横断技術支援組織「Backbeat」に所属している繁田です。
前回のOllamaの話に続けて、今回はより実用的な秘書をノーコードで、さくっと作ってみます!
まずは経緯から
エンジニアの悩みは2種類あります。
- さくっと解けるやつ(いつでも解ける技術課題)
- 苦労して解けたやつ(昨日の自分が苦労してメモを残した技術課題)
後者、「どこだっけ?」ってなってません?
~/Desktop/メモ_final_final_ほんとにfinal.md~/Downloads/手順(2)_まじで直したやつ.txt-
~/Documents/運用/運用/運用/…(階層が地獄)
検索で見つからない。見つかっても最新かわからない。人間は忘れる。
そこで思ったのです。
「質問したら過去の自分のメモから答えてほしい」
そう、RAGです。
まずRAGとは何か
RAG(Retrieval-Augmented Generation)は、ざっくりいうとAIにカンペを渡して答えさせる方法。
- 質問を受ける(Query)
- 質問に関係するメモを探す(Retrieve)
- カンペとしてLLMに渡す(Augment)
- 回答する(Generate)
全部学習させる必要はなく、必要な情報だけを都度引っ張る点が特長。
セキュリティのためローカル完結へ
多くのRAG実装は外部APIへデータを送りますが、
個人メモや社内資料を外に出さず、ローカルで完結したい。
ぶっちゃけ、
あんなこと、こんなこと、人様にぜっっったい言えないドキュメントも、ローカルRAGなら入れてしまえます。
(もちろんセキュリティには注意。自分だけが見られる環境を確保しましょう)
そこで使うのが:
- Ollama → ローカルLLM実行環境(詳しくは前回の記事参照)
- Qdrant → 高性能ベクトルストア(メモを入れておく引き出し)
- n8n → ワークフローオーケストレーション(自動化してくれるツール)
環境構築:docker-compose
さっそく手元のPCで環境構築します!
以下のdocker-composeで環境を作ってみます。
重要:以下は全て
localhostバインド設定で、LANやインターネットには公開にはしないでください!あなたの秘密が漏れますよ
services:
ollama:
image: ollama/ollama
container_name: ollama
ports:
- "11434:11434"
restart: "no"
volumes:
- ./ollama/data:/root/.ollama
networks:
- rag_network
n8n:
image: n8nio/n8n:latest
container_name: n8n
ports:
- "5678:5678"
restart: "no"
volumes:
- ./n8n/data:/home/node/.n8n-files
networks:
- rag_network
qdrant:
image: qdrant/qdrant:latest
container_name: qdrant
ports:
- "6333:6333"
restart: "no"
volumes:
- ./qdrant/data:/qdrant/storage
networks:
- rag_network
networks:
rag_network:
driver: bridge
RAGのワークフロー
続けてRAGを作ります!
n8nの公式サイトにRAGの使い方がご丁寧に紹介されています。
基本をそのまま使えますが、今回は秘密のドキュメントも入れられるように、AIはOpenAIではなくOllama、ベクタストアはPinecodeではなくQdrantで代用します。
※ベクタストアはデータの類似具合を図るデータベースだと思ってください。
1. RAGへのデータ投入
ドキュメントの入力→チャンク化→Qdrantへのデータ投入と進みます。
1.1. ドキュメントの入力
- まずはドキュメントをワークフローに渡します
- n8nではGoogle DriveノードやOutlookノードなど様々なアプリとの連携が組み込まれています。今回は、ReadWrite Filesノードでローカルディスク上のテキストデータを読み込ませます
1.2. チャンク化
- チャンク化では、ドキュメントの文章を検索できるように細かく分断します
- チャンクのサイズは、先ほどのn8nのサイトを参考にしてください
- 今回は公式の案内どおり、1000文字単位、200文字オーバーラップあり、で分割します
- チャンク化には、Ollamaの公式サイトでembeddings用のモデルを選びます
- 今回は軽量なnomic-embed-textを試しに使ってみます
1.3. Qdrantへのデータ投入
- Qdrantのコンテナイメージ内に適当なcollections(秘密のドキュメントを入れる箱)を作成します
- 768次元でないと動かないのでご注意を!次元とは、 情報を表す「項目の数」だと思ってください
例:
身長だけ → 1次元([身長])
身長・体重 → 2次元([身長, 体重])
身長・体重・年齢 → 3次元([身長, 体重, 年齢])など - 秘密のドキュメントの検索には、よく使われるコサイン類似度を使います
# 自分のPC上にtechnotesという情報を入れる箱を作る
curl -X PUT http://localhost:6333/collections/technotes \
-H "Content-Type: application/json" \
-d '{
"vectors": {
"size": 768,
"distance": "Cosine"
}
}'
# 箱ができたか確認する
curl http://localhost:6333/collections
以下のようなワークフローになっているかと思います。
あとは、指定の場所に秘密のデータを入れて、ワークフローをポチっと動かしてください。
PDFやExcelを読み込ませたい場合も、IFノードで拡張子をみて処理を分岐させればできるかと思います。
ここまででRAGへのデータ登録は完了です!
2. RAGへの問い合わせ
質問の入力→メモの検索→LLMにメモを渡す→回答生成と進みます。
2.1. 質問の入力(Query)
- メッセージ入力を受け付けるノードを使います
2.2. 類似する言葉を検索(Retrieve)
- QdrantのVector Store Retrieverノードを使います
- Vector Store Retrieverノードには、EmbeddingモデルのローカルLLM、秘密のドキュメントを登録したQdrantを指定します
- すると、秘密のドキュメントと、入力された質問の類似度合をみて、類似した秘密のドキュメントを取得してくれます
2.3. カンペとしてLLMに渡す(Augment)
- Q&Aノードを使います。Q&Aノードでは、Vector Store RetrieverノードとローカルLLMのチャットモデルを指定します
- ローカルLLMはEmbeddingモデルではなく、チャットモデルを選択する必要があるので注意です!
2.4. 回答生成(Ollama)
- あとはQ&Aノードに向けて質問を入力しましょう
- 秘密のドキュメントから関連したメモを参考に、ローカルLLMが回答を生成してくれます
完成系は以下のようなワークフローになるかと思います。
モデル選定やチャンクサイズなどチューニングは必要ですが、動くかと思います。
モデルライセンス確認
Ollamaにpullする各モデルは前回の私の記事を参考に選択してください。
モデルごとの商用利用可否や制限は必ず公式ページで確認してくださいね。
まとめ
- RAGは「AIにカンペを渡して答えさせる」技術
- 外部に出せないデータもローカルで安全運用
- Qdrant × n8n × Ollamaで簡単かつ強力なRAG基盤が作れる
- ただし、この構成はあくまでローカル前提です。外部ネットワークからアクセスされない設定を確認してから利用してください
こんな感じで、あなたのPCに、あなただけの「秘書」が出来上がります。

