LLMの一番大きな弱点は「学習データ以降のことを知らない」こと。GPT-4のカットオフ日は2023年12月。今日のニュースを聞いても「すみません、私の知識は…」ってなる。あと、学習データにない専門知識(社内文書とか)も当然知らない。
この問題を解決するのがRAG(Retrieval-Augmented Generation)。簡単に言うと、「質問が来たら、まず外部データベースから関連文書を検索して、それをプロンプトに付け加えてから回答を生成する」って仕組みだ。LLMに「カンニングペーパー」を渡すイメージ。
RAGの処理の流れはこう:
- 文書を細かく分割(チャンキング) — 大量の文書を数百〜数千文字の「チャンク」に切る。この分割の仕方で検索精度が大きく変わるから意外と奥が深い。
- ベクトル化(Embedding) — 各チャンクをベクトル(数字の羅列)に変換してデータベースに保存。似た意味の文書はベクトル空間上で近くに配置される。
- 検索(Retrieval) — ユーザーの質問も同じようにベクトル化して、データベース内で一番近いチャンクを探す(近似最近傍探索)。
- 回答生成(Generation) — 見つけた関連チャンクをプロンプトに埋め込んでLLMに回答させる。「以下の情報を参考に答えてください:…」って感じ。
実際にRAGを組むならLangChainかLlamaIndexが定番。僕は個人プロジェクトで両方試したけど、LlamaIndexの方がシンプルでとっつきやすかった。LangChainは機能が多すぎて「全部入りツール」感が強い。
RAGの弱点は検索精度。ベクトル検索は「キーワード検索」とは違うから、質問の言い回しによっては的外れなチャンクを拾ってしまう。このへんはハイブリッド検索(ベクトル+キーワード)で改善できる。
参考:LlamaIndex | LangChain