Atmosphere Engineering Lab.

LLMエージェントの設計パターンを選ぶ — RAG・ツール呼び出し・マルチエージェントの使い分け

はじめに

LLMアプリケーションの設計では、RAG・ツール呼び出し・マルチエージェントといった用語が次々に出てきます。 これらは互いに排他的な選択肢ではなく、実際のシステムでは組み合わせて使うのが普通です。 にもかかわらず「流行っているから」「事例が多いから」という理由で構成を決めてしまうと、不要な複雑さだけが増えて、精度もコストも悪化することがよくあります。

判断の起点にすべきは、パターンの名前ではなく「LLM単体では何が足りないのか」です。 この記事では、LLM単体の限界を3種類に分け、それぞれに対応するパターンとしてRAG・ツール呼び出し・マルチエージェントを位置づけ、適用条件と限界を整理します。

LLM単体の限界 — 何が足りないのか

LLM単体(プロンプトを与えて応答を返すだけの状態)が抱える制約は、大きく3つに分けられます。

  • 知識が足りない: 学習データのカットオフ以降の情報や、社内文書のような非公開情報を知らない
  • 行動できない: テキストを生成するだけで、外部のシステムを検索・操作したり、計算を実行したりできない
  • 1回の呼び出しでは手に負えない: コンテキストウィンドウに収まらない量の情報や、性質の異なる複数の役割を1つの文脈で同時にこなすのが苦手

この3つは独立した軸なので、どれが問題になっているかによって足すべき仕組みが変わります。 知識が足りないのにマルチエージェント化しても解決しませんし、行動が必要なのに知識だけ足しても実行はできません。

知識が足りない場合 — RAG

RAG(Retrieval-Augmented Generation)は、質問に関連する文書をあらかじめ検索し、その内容をプロンプトに埋め込んでからLLMに答えさせる方式です。

文書をチャンクに分割して埋め込みベクトルに変換し、インデックスに保存しておきます。 質問が来たら同様に埋め込みに変換し、コサイン類似度が高い上位 kk 件を取り出します。

sim(q,d)=qdqd\text{sim}(q, d) = \frac{q \cdot d}{\lVert q \rVert \, \lVert d \rVert}

取り出した文書をコンテキストに含めることで、学習データにない情報や社内固有の情報にもとづいた回答が可能になります。 社内ドキュメントQA、サポートbot、FAQ自動応答のように、根拠となる文書群がある程度まとまっており、かつ頻繁に更新されるケースに向いています。

RAGの精度は生成モデルの賢さより検索の精度に律速されることが多く、チャンクの切り方・埋め込みモデルの選定・再ランキングの有無がボトルネックになります。 また、RAGは「答えるための材料」を渡す仕組みであって、LLMに新しい能力を与えるものではありません。 何かを実行させたい場合は、次のツール呼び出しが必要になります。

行動が必要な場合 — ツール呼び出し

ツール呼び出し(function calling / tool use)は、LLMに「この名前とスキーマの関数を、こういう引数で呼びたい」という構造化出力をさせ、実際の実行はアプリケーション側が担う仕組みです。 LLM自身がコードを実行するわけではなく、呼び出す関数を選び、引数を組み立てるところまでを担当します。

これを1回で終わらせず、ツールの実行結果を再びコンテキストに戻して次の判断をさせる、という往復を繰り返すのがいわゆるエージェントループ(ReActパターン)です。

  1. 現在の状況から次に何をすべきか(応答するか、ツールを呼ぶか)を判断する
  2. ツールを呼ぶ場合は実行し、結果をコンテキストに追加する
  3. タスクが完了するまで1に戻る

社内システムに散らばるツールを毎回個別に定義するのは負担が大きいため、ツールとリソースの公開方法を標準化するMCP(Model Context Protocol)のようなプロトコルを使い、既存のMCPサーバー群をそのままエージェントに接続する構成も増えています。

DB検索、外部APIの呼び出し、社内システムへの書き込みのように、実行結果が最新の状態やこれから起こす変化に依存する処理はこちらの担当です。 一方で、ツール選択や引数生成はLLMの推論に依存するため決定的ではなく、特にデータの書き込みや削除のような不可逆な操作をツール化する場合は、実行前の確認ステップや権限による制限など、失敗を前提としたガードレールが必須になります。

役割を分けたい場合 — マルチエージェント

RAGとツール呼び出しを備えた1つのエージェントでも、タスクが大きくなるとうまく回らなくなる場面があります。 コンテキストが肥大化して古い情報に埋もれる、計画を立てる役割と個々の作業を実行する役割が同じ文脈に混在して精度が落ちる、といった状態です。

マルチエージェントは、これを複数のエージェントに分割することで対応します。 代表的なのは、全体の計画を立てて作業を割り振るオーケストレーターと、割り振られた作業だけに集中する複数のワーカーに分ける構成です。 各ワーカーは自分の担当範囲に絞ったツールと短いコンテキストだけを持てばよいため、個々のエージェントの精度は上がりやすくなります。

ただし、エージェントの数だけLLM呼び出しとコストが増え、エージェント間の情報の受け渡し(どこまでをオーケストレーターに返すか)の設計を誤ると、かえって精度が落ちることもあります。 デバッグの難易度も単一エージェントより明確に上がります。 1つのエージェントに適切なツールとRAGを与えれば済むタスクにマルチエージェントを持ち込むのは、複雑さに見合いません。 コンテキストの肥大化や役割の衝突が実際にボトルネックになっているかどうかを確認してから導入するのが妥当です。

整理すると

足りないもの対応パターン典型的な用途
知識(非公開・最新の情報)RAG社内ドキュメントQA、サポートbot
行動(外部システムの検索・操作)ツール呼び出し(MCP等)DB検索、API連携、社内システムの操作
役割分担・タスクの規模マルチエージェント大規模タスクの分割、専門化したサブエージェント

おわりに

RAG・ツール呼び出し・マルチエージェントは、それぞれ「知識が足りない」「行動できない」「1つの文脈では手に負えない」という別々の限界に対する答えです。 実際のシステムの多くは、RAGとツール呼び出しを組み合わせた1つのエージェントで足り、マルチエージェントが要るのはそれでもなお役割やコンテキストの衝突が残る場合に限られます。

設計に着手するときは、まずLLM単体で何が足りないのかを切り分け、そのうえで必要なパターンだけを足していくという順番を崩さないようにしています。 パターンの名前から入ると、要らない複雑さまで一緒に持ち込んでしまいます。