はじめに
※このシリーズはGemini3.5Flashと一緒に勉強をすすめていくものです。
解説や考察に間違いがあるかもしれません。
今回は前回の「Embeddingを使ったRAGの構築」の続きです。
前回は、参考資料(講義ノートlecture_note.txt)を1行または2行ずつチャンク分けをして、チャンクごとに質問文とのコサイン類似度を計算して、一番高かったチャンクを参照するような処理を実装しました。
しかし、Embeddingにも出力と同じチャット用モデル(qwen2.5b:3b)を使用した結果、質問文と関係のない文が書かれた行の類似度も高くなったり、行ごとの差があまりつかず、想定通りの参照がされませんでした。
今回の内容
今回はEmbedding(ベクトル化)に使用するモデルとしてチャット用ではなく、専用のモデルをダウンロードしてみます。これによってチャンクごとのコサイン類似度に差ができて正しい(より適切な)行を参照してくれるようになるという想定です。
勉強開始
まずは専用モデルのダウンロードです。先生(Gemini)はモデルサイズ100MB強といってきましたが、700MB弱ありました。
ollama pull mxbai-embed-large
ダウンロードができたら、前回のmain.pyのget_embedding(text)のmodel部分をダウンロードしたモデルに変更します。
main.py全体は以下の前回の記事を参照してください。
def get_embedding(text):
response = ollama.embeddings(
model='mxbai-embed-large', # 👈 チャットモデルではなく、検索専用モデルを指定!
prompt=text
)
return np.array(response['embedding'])
変更できたら前回と同じ質問「DCKGってどうやって暗号鍵を生成しているの?」を設定して実行してみます。実行した結果は以下の通りです。
- 類似度: 0.6588 -> 「人工知能(AI)の歴史は195...」
- 類似度: 0.7023 -> 「アルカディア・プロトコルとは、...」
- 類似度: 0.6985 -> 「今日の昼食はトマトパスタとサラ...」
- 類似度: 0.5851 -> 「このプロトコルでは、通信のたび...」
- 類似度: 0.7220 -> 「大学の期末試験のスケジュールは...」
- 類似度: 0.6869 -> 「DCKGは、端末の温度変化と大...」
- 類似度: 0.5395 -> 「今はまっているゲームはストリー...」
🎯 最も意味が近いと判定されたチャンク(スコア: 0.7220):
👉 「大学の期末試験のスケジュールは来週発表されます。」
🤖 LLMが思考中...
📝 【RAGシステムからの最終回答】
わかりません
モデルを変えてもDCKGについての説明が書いてある行の類似度が高くならず、あまりいい結果にはなりませんでした。しかし、各行ごとの類似度の差ができるようになりました。こっちの方が重要なのでまぁよしです。
悔しいですが、質問文を変えてみます。
「DCKGってどうやって暗号鍵を生成しているの?」
↓
「DCKGの暗号鍵を生成する具体的な仕組みや技術を教えて」
これで実行してみたところ、
- 類似度: 0.6132 -> 「人工知能(AI)の歴史は195...」
- 類似度: 0.7321 -> 「アルカディア・プロトコルとは、...」
- 類似度: 0.7069 -> 「今日の昼食はトマトパスタとサラ...」
- 類似度: 0.6698 -> 「このプロトコルでは、通信のたび...」
- 類似度: 0.7370 -> 「大学の期末試験のスケジュールは...」
- 類似度: 0.9605 -> 「DCKGは、端末の温度変化と大...」
- 類似度: 0.5073 -> 「今はまっているゲームはストリー...」
🎯 最も意味が近いと判定されたチャンク(スコア: 0.9605):
👉 「DCKGは、端末の温度変化と大気ノイズをブレンドして使い捨ての暗号鍵を生成する技術である。」
前回から続いた内容ですがやっといい結果がでました。やはり質問文に、「仕組み」や「技術」、「具体的な」などを加えるのが重要だったようです。モデルも質問文も前回と変えてしまっているので、前回のchat用モデルを使ってembeddingをした場合も同じ質問文でやってみます。
- 類似度: 0.7020 -> 「人工知能(AI)の歴史は195...」
- 類似度: 0.7226 -> 「アルカディア・プロトコルとは、...」
- 類似度: 0.7190 -> 「今日の昼食はトマトパスタとサラ...」
- 類似度: 0.7310 -> 「このプロトコルでは、通信のたび...」
- 類似度: 0.7489 -> 「大学の期末試験のスケジュールは...」
- 類似度: 0.7209 -> 「DCKGは、端末の温度変化と大...」
- 類似度: 0.7479 -> 「今はまっているゲームはストリー...」
🎯 最も意味が近いと判定されたチャンク(スコア: 0.7489):
👉 「大学の期末試験のスケジュールは来週発表されます。」
結果を見ると質問文を変えただけでは、よい結果は出ていませんでした。
モデルを専用モデルに変えて、質問文も厳格にしてようやくできるようです。
おわりに
読んでいただきありがとうございます。
短いですが、今回はこれで終わりにします。
今回得た学びは、
- embedding(ベクトル埋め込み)には専用のモデルが適しており、チャット用モデルでは不十分であること
- 専用のモデルを使っても質問文が悪いと、質問文と参照資料のチャンクとのコサイン類似度が適切にでないこと
といったところです。
次回はバックエンドAPI(FastAPI)化して、システムとして独立させることに挑戦します。
これまでは、Pythonスクリプト(main.py)を実行して、ターミナル上で結果を見るだけでしたが、これでは他のユーザーや、Webブラウザ(フロントエンド)からこのAI機能を使うことができません。
先生(Gemini)曰く、実務のシステム開発では、このRAGのプログラムを「Web API(FastAPI)」という形に変形するようです。URL(エンドポイント)を用意して、外から「質問の文字列」を受け取り、「AIの回答」をJSONというデータ形式で返す「サーバー」へと昇格させれたらいいなと考えています。