初めてのRAGアプリケーション開発
これまでLLMについて学んできたものの、ゼロから自分でRAGアプリケーションを作成したことがなかったので、今回初めて開発してみました。
Next.js + ベクトルDB + LlamaでシンプルなRAGアプリを構築したので、メモを残しておきます✍️ RAGが気になるけれどまだつくったことがない、という私と似た状況の方の参考になれば幸いです!
香水RAGシステムの全体像
テーマに選んだのは「香水」。いくつかの条件を入れたら香水を探せるアプリケーションをつくることにしました。
香水に関する情報をベクトルデータベースに格納し、ユーザーの質問に対して関連性の高い情報を検索・提供するRAG(Retrieval Augmented Generation)システムです。
どこがRAG?
- Retrieval(検索):ユーザーのクエリをベクトル化し、データベースから類似度の高い香水情報を検索
- Augmentation(拡張):検索で得られた情報をフォーマットし、ユーザークエリと合わせてコンテキスト豊かなプロンプトを生成
- Generation(生成):拡張されたプロンプトを LLM に送信し、回答を生成(ここだけLLMの仕事)
システムの処理フロー
-
データの準備
- 香水情報をJSON形式で収集・整理
- 各香水情報をembeddingモデルでベクトル化
- ベクトルとメタデータをChromaデータベースに格納
-
ユーザークエリの処理
- ユーザーからの質問・キーワードを受け取る
- クエリをembeddingモデルでベクトル化
- ベクトルDBで類似度の高い香水情報を検索
-
コンテキスト拡張とLLM応答生成
- 検索結果をプロンプトのコンテキストとして整形
- 「あなたは香水の専門家です。以下の情報に基づいて質問に答えてください」といった指示と共に検索結果とクエリをLLMに送信
- LLMからの応答を整形してユーザーに表示
開発してみた感想
ぴかぴかのRAGビギナーとしての気持ちを忘れないうちにメモ。
"RAG"である価値を持たせる
RAG = Retrieval Augmented Generationですが、使う人に意味ある形で"RAG"全てを成立させる視点(もしくは不要ならRAG全てを使わずに、必要なものだけを取り入れる)が重要だなと思いました。
初めてRAGをつくってみると、最初はつい「検索(RAGの"R")」に引っ張られました。データが構造化されていて、なおかつ単純に情報を取得したいケースであれば、検索だけでも成立するんですよね。今回は(うっかり)完全に構造化されたデータ(json)を用意したので、"R"だけで十分かも、という気持ちに。
とはいえ今回は「"RAG"として成立させたい」という技術要件が先にあったので「生成(RAGの"G")」も取り入れましたが、以下に書いたようにLLMを挟むと難しい部分が途端に増えるので、データが完全に構造化されている場合は検索だけでも価値を提供できそう、と思いました。
Rは合っていてもGがずれてしまう
RAGは、Rで検索して情報を取得し、Aで検索結果を構造化してLLMへのプロンプトに統合、Gで初めてLLMを呼び出す仕組みです。で、やっぱりLLMを呼び出すと、生成で思うような出力を得るのが難しい。
あと"R"と"A"だけなら、入力に対して得られる結果が自分の求めていた情報かどうか判定しやすいので、結果を見ながら検索条件を調整していくのが楽しかったです。"G"が入ると途端に、何を調整すればどういう結果が得られるのか理解が難しくなりますね。
プロンプトの調整は難しい
今回はOllamaを使ってローカルで複数のLLMを試してみて、最後はLlama3.2で動かしました。ただもう、ハルシネーションが激しい……!ローカルLLMは今後も試し続けたいですが、世に出すものとしてはAPIに手を出してしまった(動作動画の撮影時はAnthropicのAPIを使用しました)。
LLMの1ユーザーとしてはGUIばかり使ってきて、開発者として、オープンソースの無料で使えるモデルとAPI経由で使える有料モデルの性能がこれほどまでに違うと実感するのは初めてだったので、いい経験になりました。
学んだことまとめ
つまり、本当によく言われていることですが、「学ぶこと」と「つくること」は全然違うな〜と心から実感しました。講義で学んでいるだけでは「RAG便利〜」くらいの理解で終了していましたが(浅い)、小さくても手を動かしてみると、RAGを実務に入れるにはどういう観点が必要なのかを考えることができました。
さあ、手を動かそう!!
次にやってみたいこと
次は非構造化されたデータでチャレンジしてみたいです。実際に企業に取り入れる場合はきっと非構造化データのほうがよっぽど多いのではないかと思いますし、「構造化されていないデータでもなんとか回答を生成できるのがRAGの真骨頂なのでは」という意見も聞いたので、真骨頂を体験したい。
おわりに
今回のアプリケーションのコードはこちらに公開しています。サンプルデータを入れてあるので、ローカルでllamaを動かせればそのままコードが使えるようにしました。
ちょっとコードを変更すれば、香水以外の検索にも使えると思います。どなたかのお役に立てば幸いです🙏
Discussion