AIエージェントとツール利用・MCP の基礎

LLMに外部ツールを使わせる仕組み(tool use)、エージェントループの構造、MCP(Model Context Protocol)の役割、設計時の注意点。

#ツール利用(Tool Use / Function Calling)

LLMは本来テキストしか出せないが、「このツールをこの引数で呼びたい」 という構造化された要求を出させ、アプリ側で実行して結果を返すことで、外部世界と接続できる。

1. アプリ: ツール定義(名前・説明・引数スキーマ)と質問を送る
2. モデル: 「get_weather(city="東京") を呼びたい」と返す(stop_reason: tool_use)
3. アプリ: 実際に関数を実行し、結果を tool_result として送る
4. モデル: 結果を踏まえて最終回答を生成

#ツール定義の例

const tools: Anthropic.Tool[] = [
  {
    name: "get_weather",
    description: "指定した都市の現在の天気を取得する。都市名は日本語でも可。",
    input_schema: {
      type: "object",
      properties: {
        city: { type: "string", description: "都市名(例: 東京)" },
      },
      required: ["city"],
      additionalProperties: false,
    },
    strict: true, // 引数がスキーマ通りであることを保証
  },
];

ヒント

description はモデルがツールを選ぶ唯一の手がかり。「いつ使うべきか」「何を返すか」「使ってはいけない場面」を書く。

#エージェントループ

エージェント = 「ツール呼び出しが終わるまでループするLLM」。

let messages: Anthropic.MessageParam[] = [{ role: "user", content: task }];

while (true) {
  const res = await client.messages.create({ model, max_tokens, tools, messages });
  messages.push({ role: "assistant", content: res.content });
  if (res.stop_reason !== "tool_use") break;

  const results = [];
  for (const block of res.content) {
    if (block.type === "tool_use") {
      const output = await runTool(block.name, block.input);
      results.push({ type: "tool_result", tool_use_id: block.id, content: output });
    }
  }
  messages.push({ role: "user", content: results }); // 複数結果は1メッセージにまとめる
}

SDK には、このループを肩代わりする Tool Runner ヘルパーがある(Python の @beta_tool、TypeScript の betaZodTool など)。自前で書くのは制御を細かくしたいときだけでよい。

#設計上の注意

  • 並列ツール呼び出し: 1回の応答に複数の tool_use が入る。結果は 1つのユーザーメッセージ にまとめて返す
  • エラーも返す: 失敗時は is_error: true を付けて返す。黙って落とすとモデルは状況を理解できない
  • 停止条件: 最大ターン数、トークン予算、時間制限を必ず設ける
  • 承認ゲート: 送信・削除・決済など不可逆な操作は人間の確認を挟む

#サーバー側ツール

プロバイダが提供する、アプリ側の実装が不要なツール。

  • Web検索 / Webフェッチ
  • コード実行(サンドボックス)
  • ファイル操作、メモリ

宣言するだけで使え、結果は同じ応答内のブロックとして返る。

#MCP(Model Context Protocol)

ツール・データソースをLLMアプリに接続するための共通規格。MCPサーバーがツールを公開し、MCPクライアント(Claude Code、デスクトップアプリ、自作エージェントなど)がそれを利用する。

[LLMアプリ (MCPクライアント)] ←→ [MCPサーバー: GitHub] 
                              ←→ [MCPサーバー: Slack]
                              ←→ [MCPサーバー: 社内DB]

利点:

  • ツールを一度サーバーとして作れば、複数のAIアプリから再利用できる
  • 公開されている既製サーバー(GitHub、Google Drive、ブラウザ操作など)をすぐ接続できる

注意:

  • MCPサーバーは 信頼できるものだけ 接続する(ツールの説明文経由でプロンプトインジェクションが起きうる)
  • 接続するツールが多いとコンテキストを圧迫する。必要なものだけ、または遅延読み込みを使う

#エージェント設計のチェックリスト

  • ツールは必要最小限か。汎用ツール(bash など)で代替できないか
  • 各ツールの description に「いつ使うか」が書いてあるか
  • エラー時の挙動をモデルに伝えているか
  • 停止条件(ターン数・予算・時間)があるか
  • 不可逆操作に承認ゲートがあるか
  • 長い実行に備えてコンテキスト管理(要約・古いツール結果の削除)があるか
  • 評価用タスクセットで成功率を測っているか

#まとめ

  • ツール利用 = モデルが構造化された呼び出し要求を出し、アプリが実行して返す
  • エージェント = ツール呼び出しが終わるまでのループ。停止条件と承認ゲートが必須
  • MCP はツール接続の共通規格。信頼できるサーバーだけを最小限接続する