コンテンツにスキップ

F-11: LLM に推論 vs ツール/コードに委譲

この相反は何か

AI エージェントが処理すべきタスクの各ステップについて、「LLM に自然言語で推論させるか、それとも従来のコードやツールに委譲するか」という二択が F-11 の相反です。これはエージェントシステム設計における最も根源的な責務分割の問題です。

この選択が排他的になる理由は、ある処理単位の実行主体が LLM かコードかで、信頼性・再現性・コストの特性が質的に異なるためです。LLM は確率的であり、同じ入力に対して異なる出力を返す可能性があります。コードは決定論的であり、同じ入力に対して常に同じ出力を返します。両者を同じ処理単位に混ぜることはできません---ある計算を LLM にやらせるか、コードにやらせるかは、混合できない二者択一です。

AI エージェント固有の文脈では、LLM は「何をすべきか」の判断(計画・解釈・分類)に優れ、コードは「どうやるか」の実行(計算・検索・データ変換)に優れるという非対称性があります。この非対称性を適切に活用することが、エージェントシステムの信頼性とコスト効率を決定づけます。

選択肢A:LLM に推論させる

LLM に推論を委ねるとは、自然言語の入力に対して LLM が思考・判断・生成を行い、その結果を次のステップに渡す方式です。意図の解釈、あいまいな要件の具体化、自由形式テキストからの情報抽出、創造的な文章生成などが典型的なユースケースです。

LLM の強みは曖昧さの解消と柔軟性にあります。事前にすべてのケースを列挙できない分類タスク、文脈に応じて判断基準が変わる意思決定、自然言語の解釈などは、ルールベースのコードでは対応しきれません。LLM は学習済みの広範な知識を活用して、事前定義されていない状況にも対応できます。

一方で、LLM に任せるデメリットは再現性の欠如とコストです。同じ入力に対して結果が変わりうるため、テストが困難になります。また、単純な計算やデータ変換でも推論トークンを消費するため、コードで瞬時に処理できる計算を LLM に行わせるのはトークンの浪費です。さらに、LLM は算術演算や正確な文字列操作が苦手であることが知られており、これらの処理を任せると誤りの原因になります。

LLM に任せるべき処理の見極め方は「決定論的に記述できるか」です。ルール・手順・アルゴリズムで完全に記述できるなら、その処理は LLM に任せるべきではありません。

選択肢B:ツール/コードに委譲する

コード委譲とは、LLM の推論を介さず、従来のプログラミングで書かれたコード、API 呼び出し、データベースクエリ、数式計算などに処理を任せる方式です。税額計算、在庫数の集計、日付の比較、スキーマ検証、外部 API からのデータ取得などが典型です。

コード委譲の最大の強みは決定論性と効率性です。同じ入力に対して常に同じ出力を返すため、テストが容易で、バグの再現と修正が可能です。実行コストは LLM 推論と比較して桁違いに低く、レイテンシも極めて小さいです。また、型システムやコンパイラによる静的検証が可能であり、実行前にエラーを検出できます。

デメリットは柔軟性の欠如です。事前に想定していないケースには対応できず、自然言語の解釈や曖昧な要件の具体化は不可能です。新しいケースが出現するたびにコードの追加・修正が必要になります。

実務上、コードに委譲すべき処理は「答えが一意に決まるか」で判別できます。入力が決まれば出力が一意に決まる処理は、すべてコードに委譲するのが原則です。計算、検索、フォーマット変換、バリデーション、データベース操作はすべてこちらに分類されます。

選定基準

この相反の選定は [failure_cost][cost_sensitivity] の二つの駆動変数で決まります。

コードに委譲すべき条件:

  • その処理が決定論的に記述可能な場合。アルゴリズム、数式、ルールで完全に表現できるなら、コードの方が信頼性・速度・コストのすべてで優れます。
  • [failure_cost] が高い場合。計算結果の誤りが許されない金融計算、在庫管理、権限判定などは、確率的な LLM に任せるべきではありません。
  • [cost_sensitivity] が高い場合。大量のリクエストを処理する場合、コードで処理できる部分を LLM に任せると、トークンコストが不必要に膨らみます。

LLM に推論させるべき条件:

  • 入力が自然言語であり、意図の解釈が必要な場合。ユーザーの曖昧な要求を構造化する処理は LLM の得意分野です。
  • [task_variability] が高く、事前にすべてのケースを列挙できない場合。分類のカテゴリが動的に変わる、判断基準が文脈依存であるといった状況です。
  • 生成・要約・翻訳など、創造性を伴う処理。これらはコードでは実現できません。

判定のヒューリスティック:処理を「if-else で書けるか」と自問します。書けるならコードに委譲します。書けないなら LLM に任せます。

デフォルトとハイブリッド

デフォルト決定論的に解ける処理はコードに委譲するのがデフォルトです。LLM はコストが高く、結果が不安定で、デバッグが困難です。LLM に任せるのは「コードでは解けない」処理に限定します。これは B1 Deterministic Shell, Probabilistic Core パターンの根幹思想と一致します。

ハイブリッド:LLM が計画・分類・解釈を担当し、コードが計算・検証・実行を担当する分業構成が最も一般的なハイブリッドです。LLM が「何をすべきか」を判断し、コードが「どうやるか」を実行します。たとえば、ユーザーの自然言語リクエストを LLM が解析してツール呼び出しの引数を構成し、実際の計算や API 呼び出しはコードが行い、結果を LLM が自然言語で要約する、という流れです。

判断を誤ったときの症状

LLM に任せすぎた場合の症状:

  • 単純な計算結果が誤っている事例が散見されます。たとえば、税額計算、日付計算、集計値の不整合などです。
  • 同じ入力に対して異なる結果が返り、ユーザーから「前回と結果が違う」というクレームが来ます。
  • トークン消費量が想定を大幅に超えており、コスト分析をすると大部分がコードで代替可能な処理に費やされています。
  • テストのフレーク率(ランダムに失敗するテスト)が高く、CI/CD パイプラインが不安定です。

コードに任せすぎた場合の症状:

  • 新しいタイプのリクエストが来るたびに、分類ルールやパーサーの追加が必要になり、開発速度が低下します。
  • 自然言語入力の解釈精度が低く、「理解してもらえない」というユーザー不満が増えます。
  • エッジケースの処理が if-else の積み重ねで肥大化し、保守が困難になっています。
  • 想定外の入力に対して一律にエラーを返してしまい、本来対応可能な要求を棄却しています。

関連パターン

  • B1 Deterministic Shell, Probabilistic Core --- この相反の「コード委譲」側を体系化した最も基本的なパターン。状態遷移・検証・権限をコードに、判断を LLM に分離します。
  • B2 Workflow Backbone --- ワークフローの骨格をコードで固定し、各ノードの判断のみ LLM に委ねる構成です。
  • B4 Planner-Executor-Verifier --- 計画は LLM、実行はコード/ツールという分業の具体的な構成です。
  • E2 Policy as Code --- ポリシー判定をコードに委譲する具体的手法です。