オタク式ゆるRAG解説 - 「てかRAGってなんスか?(笑)」にゆるく答えます -
オタク式ゆるRAG解説 - 「てかRAGってなんスか?(笑)」にゆるく答えます -
オタクの前置きは長い
こんにちは。
最近(もう最近ってほどでもないけれど)なにかとAI(ってかLLM)に仕事をさせる機運が高まっていますね。それに伴いRAGという言葉を耳にする機会も多くなって来たんじゃないかと思います。
「どうもRAGとかいうのを導入すれば社内のあれこれがすっきりまとまるらしいぞ?」
とかそんな感じで。
ただ、耳にする機会は多いものの、それが何なのかまではわからない方が大半なんじゃないかな。
「あ~RAGね。はいはい、RAGね。いいよねRAG。俺もドンキで見かけたわ。」 みたいな理解から脱したいけど、堅苦しい解説文章を読んでも目が滑るし眠くなる。ドーパミンが出ない。
そんな勤勉で悩めるポタクのために、本記事ではRAGの全体像をざっくり、冗長に、カジュアルに、ゆるく、オタク特有の薄ら寒いノリをまといつつ解説していきます。ノリがきつくなければポタク以外も是非読んでってくれや。我ながら結構わかりやすく書けたと思うので。
蛇足ですが、実は既に同じノリでLLMの解説記事を書いているんですよね。ただ、そっちはカジュアルな文体で誤魔化しきれないほど “ガチ” になっちゃった……
その反省を活かし、今回は詳細な話やら実装やら数学的なあれこれは置いといて 「そもそもRAGって何がしたいの?」 「要するにどういう仕組みなの?」 を掴むためのゆる~い解説を行います。 “ガチ” のやつはまた今度ね。
それでは早速、やっていきを開始しましょう。
LLMだって神様じゃない
LLM(大規模言語モデル)は賢い。とても賢い。困ったらチャッピーに聞けば何でも教えてくれる。
冷蔵庫の中身を相談すればいい感じに献立考えてくれるし、大学のレポートも代筆してくれるし、果ては占いまでやってくれます。AI万歳。
といっても、そんなLLMにだって限界はあります。教えられてないこと、調べられないことはわからないのです。
そりゃそうだ。
身も蓋もないけど純然たる事実。
LLMの知識は訓練データで打ち止め。訓練データに含まれない情報は知りません。そんなLLMはインターネット上の公開データで訓練されている。自社の業務マニュアル、社内規定、顧客データなんかは当然知らない。知る由もない。
すっぴんのLLMくんに「うちの有給休暇の申請方法を教えて」と質問しても、帰ってくるのは適当なウソか「一般的にはこうなっています」的なお茶濁しか、せいぜい回答拒否です。使えね~~~
といっても、ここで正しく答えてきた場合のほうが問題ですけども。ネット上に社内の情報が漏洩していることになるので
「ダラェモーン!!手元の非公開情報をネット公開することなくAIに喰わせられる仕組みを出してよォ~!」
ここでRAGの出番って寸法。
RAGとは何か
RAG = Retrieval-Augmented Generation(検索拡張生成)
とまあ、単に略語を開いただけじゃいまいちピンときませんよね。一言でいえばRAGってのは LLMに回答させる前に、関連する文書を検索して渡してあげる仕組み のことです。
LLMを再訓練するのはコストも時間もかかる。おまけに難しい。訓練し直さなくても最新の情報や社内データを使えるようにするにはどうすればいいか? 答えはシンプルで、質問のたびに関連する文書を探してきて「これ読んで答えて」とLLMに渡せばいいのサ。
特にローカル環境などweb検索不可な状況で運用されているLLMにとってユーザーとの会話は暗記テストのようなもの。LLMくんは自分の記憶(訓練データ)に頼って答えを手繰り寄せるしかない。RAGはそれを持ち込み可のテストにしてあげるようなもので、LLMの推論能力はそのままに参照資料を与えることで回答の質を底上げしてくれる。
RAGパイプライン全体像
さて、RAGの処理フローは大きく2つのフェーズに分かれます。
まず、専用のフォルダ(ナレッジベース)に喰わせたい文書をぶち込みます。何はともあれドキュメントをぶん投げなきゃ始まらない。そうしてナレッジ文書群が出来上がる。
ナレッジ文書群をいい感じ(多次元ベクトル情報)に加工して、専用のDBにぶち込むまでが事前準備フェーズ。
実際にユーザーから質問を投げられた際、いい感じに関係ありそうな文書を引っ張ってきて、それをもとに返事をするまでが応答フェーズ。
てことで、それぞれのステージを簡単に紹介していくわよ。
1. チャンキング(分割)
チャンキングはナレッジとなるドキュメントを適切なサイズに分割する処理。
「これからドキュメントをいろいろと加工していきますよ」 ってときに、生のドキュメントをそのまま扱うのは非効率。例えば100ページのPDFがあったとして、それをひとまとめにどうこうするって、まあ筋が悪そうでしょ?
肉を調理する際、動物を丸ごと調理するより事前に調理しやすいよう切っておくよね?そういう理解でOKです。
チャンキングにはいろんな切り方や配分があって、最適な手法は扱う題材によって異なったりする。何事も最初が肝心だし、これ自体も結構大変な作業なんです。これ。
2. Embedding(ベクトル化)
Embeddingは文書をベクトル(数値の配列)に変換する処理。
序盤に出てくる癖にここが一番難しい。いきなりラスボスです。
といってもそれは “ガチ” で解説するときの話で、ゆる解説ではさらっと簡潔に行きます。
で、Embeddingがなにしてるかっていうと、人間にとっての文章の意味をコンピュータが比較可能な数値表現に落とし込む的なことをしています。人語を解さないLLMくんに自然言語は通用しないのだ。南無三。
イメージとしては、文書ごとに意味空間上の座標を割り振るような感じかな。似た意味の文書は近い座標に、関係ない文書は遠い座標になる。
事前準備フェーズではナレッジベースの全文書を事前にベクトル化してベクトルDBに格納しておく。応答フェーズではユーザーの質問文もベクトル化するよ。
3. Retrieval(検索)
Retrievalはユーザーの質問ベクトルとナレッジベースの各文書ベクトルを比較して意味的に近い文書を探し出す処理。ベクトル同士の近さ(類似度)を測って、特に近い上位k件を引っ張ってくる。「この質問に関係ありそうな文書はこれとこれとこれ」というのを探る感じ。
これも距離で関係を測ったり、向いてる方向で関係を測ったり、そもそも厳密に探すのをやめてみたり、ベクトルとか全然関係なかったり、色々なアプローチがあります。詳細は “ガチ” のやつを書くときに紹介します。
4. Augmentation(プロンプト補強)
Augmentationは検索で見つけた文書をLLMへのプロンプトに組み込む処理。
やっていることははちゃめちゃに単純で、「以下の資料を参考にして質問に答えてください」というプロンプトテンプレートに検索結果の文書を詰め込むだけ。
ただしLLMには一度に読めるトークン数の上限があるので、何をどれだけ詰めるかの設計判断が地味に重要だったりする。技術的にはシンプルだけど結構奥深いのよ。
5. Generation(回答生成)
GenerationはLLMが補強されたプロンプト(質問 + 検索された文書)を読んで回答を生成する処理。
ぶっちゃけここはLLMの仕事なんだけど、RAG固有のテクニックもある。プロンプト設計(「資料に書いてないことは答えるな」等の制約指示)やグラウンディング(回答の根拠を引用させる)あたりが関わってくるわね。
ここでLLMの仕事は「自分の記憶から思い出す」から「渡された資料を読んで答える」に変わる。 これによりハルシネーションのリスクが下がり、最新の情報や社内データに基づいた回答が可能になります。
LLMなおもて神に非ず いわんやRAGをや
と、ここまでいろいろRAGくんの恰好いいところを語ってきたけれど、RAGってのはとりあえず導入しただけで何もかも上手くいくような魔法の杖ではありません。
作りたいものによりますが、こいつを設計するのは普通に難しいし、そもそもRAGが常に正解とは限らない。データ量が少ない場合やデータの性質によっては、RAGが最適解ではないこともある。
例えば 「1つのエクセルファイルでキャッシュフローを管理してます!うちのローカルAIくんに支払い期日の近い請求書や特定の月の特定の銀行口座での収支やらを答えさせたいなあ!」 という望みはRAGで解決すべき問題ではなかったりする(解決できる問題でもない)。
ということでね、 「RAGピー鬼つえ~~!このまま業務効率化に逆らう課題を全部解決してこうぜ~!」 みたいな安易なノリには染まらないようにしましょう。
終わりとそれから
はい。RAGの全体像はこんな感じです。
概念自体は極めてシンプルで「関連文書を探してきてLLMに渡す」ってだけ。
ただ、そのシンプルな仕組みの裏側にはEmbeddingという重たい数理があり、Retrievalという検索設計があり、Augmentationというプロンプト設計があり、それぞれのステージに奥行きがある。それが面白い。
本記事が、そんな面白いRAGを学ぶ一助になれば幸いです。
さようなら。