3秒でわかる
質問に答える前に社内文書などを検索し、見つけた文章ごと AI に渡す仕組み。学習し直さずに、最新の情報や社外に出せない資料を回答へ反映できます。
30秒図解
もう少し詳しく
どういうものか
RAG (Retrieval-Augmented Generation) は、検索と生成を組み合わせた作りです。利用者の質問をそのまま大規模言語モデルへ渡すのではなく、まず自前の文書群から関連する箇所を取り出し、その本文を質問と一緒にプロンプトへ入れて答えさせます。
検索には多くの場合ベクトル検索を使います。文書を段落程度に分割し、意味を数値の並びに変換して保存しておくと、単語が一致しなくても意味が近い段落を拾えます。「有給の申請方法」と書かれた質問から「休暇届の提出手順」の段落を見つけられるのがこの方式の利点です。
なぜ必要か
言語モデルは学習した時点までの一般的な知識しか持たず、自社の就業規則も昨日の障害報告も知りません。知らないことを聞かれると、それらしい嘘を作ってしまいます。追加学習で覚えさせる手もありますが、費用と時間がかかるうえ、規則が変わるたびにやり直しになります。RAG なら文書を差し替えるだけで回答が変わります。出典の段落を一緒に表示できるため、利用者が答えの正しさを自分で確かめられる点も実務では大きい利点です。
具体例
# 1. 文書を分割してベクトル化し、保存しておく
chunks = split_text(open("kitei.md").read(), size=500, overlap=50)
store.add([(c, embed(c)) for c in chunks])
# 2. 質問が来たら、近い段落を取り出す
question = "有給休暇は何日前までに申請しますか"
docs = store.search(embed(question), top_k=3)
# 3. 取り出した本文ごとモデルへ渡す
prompt = f"""次の資料だけを根拠に答えてください。
資料に無いことは「資料に記載がありません」と答えてください。
資料
{chr(10).join(docs)}
質問
{question}"""
print(llm(prompt))つまずきやすいところ
回答が的外れなとき、原因の大半はモデルではなく検索側にあります。分割が大きすぎて 1 件に話題が混ざる、逆に小さすぎて主語が失われる、というのがよくある形です。まず取り出された段落を目で見て、そこに答えが載っているかを確かめます。
もう 1 つは、資料に無いことを答えさせない指示の欠落です。指示が無いとモデルは一般知識で補ってしまい、社内規則と違う回答が混ざります。
似た用語との違い
ファインチューニングはモデル自体の重みを更新する方法で、口調や出力形式を揃える用途に向きます。事実を覚えさせる用途には不向きです。知識を足したいなら RAG、振る舞いを変えたいならファインチューニング、と分けて考えます。
覚え方
「閉じた本での試験ではなく、資料持ち込み可の試験にする」。これが RAG の発想です。