powered by TechFeed
表示モード
Deep Dive

RAGは「何を答えるか」、ファインチューニングは「どう答えるか」 — LLMカスタマイズ2大手法の本当の使い分け

7月13日、Towards Data Scienceが「RAG vs Fine-Tuning Explained: What They Actually Do and When to Use Each」と題した記事を公開した。RAGとファインチューニングがそれぞれ何を解決する技術なのかを整理し、実務での使い分け基準を示している。

7月13日、Towards Data Scienceが「RAG vs Fine-Tuning Explained: What They Actually Do and When to Use Each」と題した記事を公開した。RAGとファインチューニングがそれぞれ何を解決する技術なのかを整理し、実務での使い分け基準を示している。


GPT-4o-miniに代表されるコスト効率の高いLLMが普及し、自社プロダクトへのAI組み込みが現実的な選択肢になった今、エンジニアが直面するのが「どうモデルを自社ドメインに適応させるか」という問題だ。その答えとして真っ先に名前が挙がるのがRAGとファインチューニングの2択である。ネット上では「どちらが優れているか」という比較論が多いが、この記事はその前提を否定するところから始まる。RAGとファインチューニングは競合技術ではなく、異なる問題を異なるレイヤーで解決する技術だ、というのが主張の核心だ。そして実務では、両者を組み合わせるのが最もよくあるパターンだという点が、この記事の最も重要なインサイトである。

RAGが解決するのは「知識の欠如」

RAG(Retrieval-Augmented Generation)は、推論時に外部ドキュメントを検索してプロンプトに注入する手法だ。モデル自体は一切変更されない。変わるのはモデルへの入力だけである。

記事が示すミニマルな実装例では、OpenAI Embeddings APIでドキュメントをベクトル化し、コサイン類似度(※ベクトル間の角度をもとに意味的な近さを0〜1のスコアで表す指標)でクエリに近いチャンクを取得し、それをシステムプロンプトに差し込む流れをわずか数十行で実現している:

from openai import OpenAI
import numpy as np
client = OpenAI(api_key="your_api_key")

documents = [
    "pialgorithms is an AI-powered document management platform.",
    "pialgorithms allows teams to search, extract, and automate document workflows.",
    "pialgorithms was founded in Athens, Greece.",
]

def embed(texts):
    response = client.embeddings.create(
        model="text-embedding-3-small",
        input=texts
    )
    return [r.embedding for r in response.data]

doc_embeddings = embed(documents)
query = "Where is pialgorithms based?"
query_embedding = embed([query])[0]

def cosine_similarity(a, b):
    return np.dot(a, b) / (np.linalg.norm(a) * np.linalg.norm(b))

similarities = [cosine_similarity(query_embedding, doc_emb) for doc_emb in doc_embeddings]
best_match = documents[np.argmax(similarities)]

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[
        {"role": "system", "content": f"Answer the user's question using only the following context:\n\n{best_match}"},
        {"role": "user", "content": query}
    ]
)
print(response.choices[0].message.content)
# pialgorithms is based in Athens, Greece.

埋め込みベクトルの検索基盤としては、PineconepgvectorといったベクトルDBが実運用で広く使われている。

RAGが得意なのは以下の場面だ:

  • モデルが学習していないドキュメントや社内データへのQ&A
  • 再学習なしに知識を最新状態に保つ
  • 「どのチャンクを根拠にしたか」が追跡可能な回答の生成
  • 機密・プロプライエタリな情報をモデルに含めず安全に扱う

逆に、RAGがやらないことも明確だ。モデルの口調、推論スタイル、出力フォーマットには一切影響しない。

ファインチューニングが解決するのは「振る舞いの問題」

ファインチューニングは、事前学習済みモデルのウェイト(※ニューラルネットワーク内部の数値パラメータ群。モデルの「知識」と「振る舞い」を規定する)を追加の学習データで更新する手法だ。RAGが入力を変えるのに対し、ファインチューニングはモデル自体を変える。OpenAIのファインチューニングAPIについては公式ドキュメントに詳細がまとめられている。

典型的なユースケースは入出力ペアの学習例を用意するところから始まる:

training_examples = [
    {
        "messages": [
            {"role": "system", "content": "You are a concise technical assistant. Always respond in one sentence."},
            {"role": "user", "content": "What is a vector database?"},
            {"role": "assistant", "content": "A vector database stores and retrieves data as high-dimensional numerical vectors, enabling fast semantic similarity search."}
        ]
    },
    # 実運用では最低50〜100件の例が必要
]

学習後にOpenAIから返ってくるのはft:gpt-4o-mini-2024-07-18:your-org:your-suffix:abc123の形式のモデルIDで、以降は通常モデルと同じAPIで呼び出せる。このモデルは、毎回システムプロンプトで指示しなくても「1文で簡潔に答える」という振る舞いを内在化している。

ファインチューニングが得意なのは:

  • 一貫した出力フォーマット、トーン、スタイルの定着
  • 常に有効なJSONを返す、常に3行で要約するといった特定タスクへの性能向上
  • 長い繰り返しのシステムプロンプトを不要にすること
  • ドメイン固有の語彙や用語の習得

ここで重要な誤解を記事は明示的に否定している。「社内ドキュメントでファインチューニングすれば、モデルがその内容を記憶して答えてくれる」という期待は、ほとんどの場合裏切られる。特定の事実がたまたまウェイトに焼き込まれることはあっても、それは脆弱で信頼性がない。むしろ、学習例に登場したトピックについてモデルがハルシネーション(※事実と異なる内容をもっともらしく生成してしまう現象)を起こす可能性の方が高い。知識の検索が必要ならRAGが正解であり、ファインチューニングではない。

実務での判断フレームワーク

記事はシンプルな判断基準を提示している:「知識の問題ならRAG、振る舞いの問題ならファインチューニング、両方ならその両方」だ。

両者を組み合わせるのは実は本番システムで最もよくあるパターンだという。LLMアプリの要件は「正確な知識に基づく回答」と「一貫したブランドボイス」の両立を求めることが多く、どちらか一方だけでは片方の課題が残る。例として挙げられているのはソフトウェア製品のカスタマーサポートボットで:

  1. ブランドに合ったトーンと出力フォーマットで常に応答する → ファインチューニング
  2. 最新のプロダクトドキュメントに基づいた正確な回答を返す → RAG

コードレベルでの組み合わせも示されている:

response = client.chat.completions.create(
    model="ft:gpt-4o-mini-2024-07-18:your-org:support-style:abc123",  # 振る舞いをファインチューニング済み
    messages=[
        {
            "role": "system",
            "content": f"You are a helpful support assistant for pialgorithms. "
                       f"Use only the following documentation to answer:\n\n{retrieved_context}"  # RAGで取得したコンテキスト
        },
        {"role": "user", "content": user_question}
    ]
)

ファインチューニングは「どう答えるか」を決め、RAGは「何を答えるか」を提供する。この一文が記事全体の結論を最もうまく言い表している。LLMの普及とAPIコストの低下が進む中、この使い分けの解像度を上げることは、実用的なAIアプリ開発において今後ますます重要な判断軸になるだろう。


詳細はRAG vs Fine-Tuning Explained: What They Actually Do and When to Use Eachを参照していただきたい。