はじめに:LLM連携における「黒箱」の正体と本記事の目的

LLM連携における「黒箱」とは、モデルそのものではなく、モデルの出力と実際の実行の間に位置するレイヤーである。多くのエンジニアがTool Callingを「ツール定義を追加すれば自動的に動作するAPI呼び出し」として捉えているが、プロダクション環境で問題が生じるのはまさにこの境界面だ。フレームワークが内部処理を抽象化しているため、モデルが不正なJSONを返したのか、フレームワークのパーサーがエッジケースで失敗したのか、実行レイヤーがエラーを適切に伝播させたのかを特定するのが困難になることがある。

本記事では、フレームワークを介さずHTTP/JSONレベルでTool Callingの実装プロセスを追う。モデルが返すレスポンスの構造を直接解釈し、ループ制御やエラーハンドリングを自前のコードで実装する際の設計判断を、トレードオフを明示しながら解説する。対象読者は、LLMアプリケーションの統合基盤やカスタムツールチェーンを設計する上級エンジニアであり、表面的なSDK利用ではなく内部構造の理解と制御権の確保を目的とする。

Tool Callingの本質:モデルはコードを実行しない

堅牢な実装と脆弱な実装を分ける最も重要な認識は、モデルは何も実行しないという事実である。AIモデルが生成するのは、ツールを直接呼び出すコマンドではなく、構造化されたリクエスト、すなわち「このツールをこれらのinputsで呼び出したい」というメモに過ぎない(Tool Callingの解説記事)。実際の関数呼び出しは、そのメモを読み取り判断するあなたのコードが担う。

この分離構造には設計上の重要な含意がある。第一に、モデルの出力がJSON Schemaに従わない場合、それは「モデルのバグ」ではなく、あなたのパイプラインにおけるデータバリデーションの問題として捉えられる。この問題定義の転換により、カスタムパーサーの実装、スキーマ違反時のフォールバック戦略、リトライロジックの設計がフレームワークの制約に縛られずに可能になる。第二に、生成と実行が分離されていることで、両者の間にセキュリティチェックや監査ログの記録、入力バリデーションを挟み込むことができる。モデル側もツール側も修正せずに、中間レイヤーのみを変更して制御を強化できる点が、単一プロセス内で完結する設計と比較した際の利点となり得る。

従来のプロンプトエンジニアリングとの決定的な違いもここにある。プロンプトエンジニアリングでは自然言語で指示を出し、モデルの解釈に依存する。Tool Callingでは、スキーマという形式契約が生成と実行の間に存在し、モデルの出力は実行前にスキーマ検証の対象となる。予測可能性は向上するが、その分、スキーマ定義の誤りがプロダクションインシデントの原因になる可能性がある。スキーマ設計の責任はモデルベンダーではなく、実装者にある。

基本フローとAPI定義:ツール情報をモデルに注入する

Tool Callingの基本的なフローは4ステップで構成される(Tool Callingの解説記事)。ユーザーの質問とツールの説明をモデルへ送信し、モデルがツール使用を決定して構造化リクエストを返す。あなたのコードがその関数を実行し、結果をモデルに戻す。この4ステップが1回で完結する単純なケースから、複数ツールを連鎖的に呼び出す複雑なケースまで、制御フローの設計はすべてこの基本単位の上に構築される。

Amazon BedrockのConverse APIでは、toolConfigパラメータを使用してモデルに利用可能なツールを定義する(Tool Callingの解説記事)。ツールをモデルに説明するには、ツールの名前、平易な英語での説明、および引数の入力スキーマの3つの要素が必要である(Tool Callingの解説記事)。この3要素の設計品質が、モデルの出力安定性に影響を与えることがある。

特にスキーマ定義の曖昧さは問題の原因になり得る。フィールドの型をstringnumberの両方許容するような定義にすると、モデルは呼び出しごとに異なる型で値を生成し、下流のバリデーションロジックが分岐を処理せざるを得なくなる。OpenAPI仕様やJSON Schemaを厳密に記述し、requiredフィールドやenum制約を明示的に設定することが、出力の再現性を高める手段となり得る。

ツール名と説明は、モデルがどのツールを選択すべきかを判断するための手がかりとなる。2つのツールの説明が意味的に重なる場合、モデルの選択は非決定論的になる可能性がある。これは検索エンジンのキーワード最適化と同様の発想で設計すべきであり、各ツールの説明には「このツールが他のツールと異なるのは何か」を1文で含めることが有効な場合がある。

要素モデルの判断への影響設計上の注意点
名前(name)出力JSONのキーとして直接参照される。一意性が必要蛇名命名などで統一し、意味的曖昧さを避ける
説明(description)ツール選択の根拠。類似ツールとの区別が曖昧だと選択が不安定になる可能性がある「何をするか」だけでなく「いつ使うか」の条件も明記する
入力スキーマ(inputSchema)引数の型・必須・制約を決定。曖昧な定義は出力の型不一致を招く可能性があるenum・required・formatを明示し、型推論に頼らない

制御フロー設計:単一呼び出しからループ処理へ

単一のツール呼び出しでは処理が直線的に完了するが、複数のツールを連鎖的に使用する場面や、条件分岐が必要な場合は、モデルが最終回答を返すまでループを回す必要がある。例えば「東京の天気を確認して、雨が降っていれば屋外イベントの予約をキャンセルする」という指示には、天気取得→条件判定→予約キャンセルの3ステップが走る。このループ制御をフレームワークに委ねると、タイムアウトの粒度や再試行ポリシーの調整がフレームワークの仕様次第になることがある。自前のコントローラーで実装すれば、各ステップごとに個別のタイムアウトを設定したり、特定のツール呼び出しのみに指数バックオフを適用したりできる場合がある。

ループの終端条件とガードレール

無限ループを防ぐため、最大ステップ数(例えば10回)をハードリミットとして設定する。これを超えた場合はエラーを返すか、モデルに「今までの処理を要約して回答せよ」と追加プロンプトを送るかの2択になる。前者は予測可能性が高いがユーザー体験が粗く、後者は自然だが追加コストが発生する。プロダクションでは前者を基本にし、後者をフォールバックとして用意するのが安全な場合がある。

また、コンテキストウィンドウの超過もループ制御の重要な制約になり得る。各ステップでツール実行結果をコンテキストに追加していくと、トークン数が単調増加する。対策としては、直近Nステップの結果のみ保持しそれ以前を要約で置換するスライディングウィンドウ方式、あるいはツール結果の長さをバイト数で切り詰める方式がある。切り詰め時にJSONの構造を壊さないよう、文字列値の内部で省略記号を挿入する実装が安全な場合がある。

モデルがツールを使わずに直接回答できる場合と、ツールが必須の場合の判定は、モデルの応答にツール呼び出しの構造が含まれるかどうかで機械的に判定できる。この判定をスキップして常にツール呼び出しを試行すると、不要なAPIコールコストが発生する可能性がある。特にトークン課金モデルでは、この分岐の最適化が直接的なコスト削減につながる場合がある。

flowchart TD
    A["ユーザー質問を受信"] --> B["ツール定義付きでモデルに送信"]
    B --> C{"応答にツール呼び出しがあるか?"}
    C -->|Yes| D{"最大ステップ数を超えていないか?"}
    D -->|No| E["ツールを実行し結果を取得"]
    E --> F["結果をコンテキストに追加"]
    F --> B
    D -->|Yes| G["タイムアウトエラーを返す"]
    C -->|No| H["最終回答をユーザーに返す"]

システムプロンプト vs Tool Calling:情報注入の使い分け

LLMアプリケーションでは、モデルに情報を渡す手段として「システムプロンプトへの事前注入」と「Tool Callingによる実行時取得」の2つがある。この2つは役割が根本的に異なる。システムプロンプトは会話の開始時に一度だけ設定される静的な文脈であり、Tool Callingは各ターンでモデルが動的に生成する行動の指示だ。

具体的な例として、ClaudeのWebインターフェースやモバイルアプリでは、会話の開始時にシステムプロンプトを通じて現在の日付などの最新情報をモデルに提供している。しかし、この仕組みはClaude APIには適用されず、API利用者は自前で日付やタイムスタンプをリクエストに含める必要がある。つまり、同じプロバイダでも配信チャネルによって情報注入の責任の所在が変わる。API利用者としては、自前でタイムスタンプを生成・注入するロジックをアプリケーション側に実装し、フォーマットの統一(ISO 8601など)を担保する責任がある。

使い分けの判断基準

判断の軸は「情報の更新頻度」と「取得コスト」の2点になる。更新頻度が低く(会話中に変わらない)、取得コストが低い情報(企業の方針、サポート対象のリスト、現在の時間帯)はシステムプロンプトに載せる。更新頻度が高く、取得に外部APIの呼び出しが必要な情報(現在の在庫数、リアルタイムの為替レート)はTool Callingで取得する。この使い分けを混同すると、システムプロンプトに動的データを埋め込むために毎回プロンプトを再生成する無駄、あるいはTool Callingで静的データを取得するための不要なAPIコールが発生する可能性がある。

観点システムプロンプトTool Calling
役割静的な文脈の提供(方針・日付等)動的な行動の指示(データ取得・処理実行)
更新タイミング会話開始時1回各ターンでモデルが動的に生成
管理責任開発者が事前定義・メンテナンス実行時にアプリケーションコードが制御
典型例企業の方針、現在日付、禁止事項在庫照会、天気API、データベース検索

低レイヤー実装:HTTP/JSONレベルでのリクエスト生成

フレームワークを介さずHTTPクライアントライブラリ(Pythonならrequests、Node.jsならfetch)で直接APIを叩く場合、リクエストのペイロード構造を自前で構築する必要がある。Amazon BedrockのConverse APIを例にとると、toolConfigパラメータに利用可能なツールを定義し、メッセージ履歴とともにPOSTする。ペイロードの骨格は以下の通りだ。

import requests
import json

def build_tool_calling_request(messages, tools):
    """Tool Callingリクエストのペイロードを構築する。"""
    payload = {
        "modelId": "anthropic.claude-3-5-sonnet-20241022-v2:0",
        "messages": messages,
        "toolConfig": {
            "tools": tools
        }
    }
    return payload

# ツール定義の例(Bedrock Converse API形式)
weather_tool = {
    "toolSpec": {
        "name": "get_weather",
        "description": "Get current weather for a specified city. Use when the user asks about weather conditions.",
        "inputSchema": {
            "json": {
                "type": "object",
                "properties": {
                    "city": {
                        "type": "string",
                        "description": "City name in English"
                    }
                },
                "required": ["city"]
            }
        }
    }
}

# リクエスト送信(例:us-east-1リージョン)
def call_model(payload):
    response = requests.post(
        "https://bedrock-runtime.us-east-1.amazonaws.com/model/anthropic.claude-3-5-sonnet-20241022-v2:0/converse",
        headers={
            "Content-Type": "application/json",
            # BedrockはIAM認証を使用するため、BearerトークンではなくAWS SigV4署名が必要
            # 実際の環境ではboto3やaws-sigv4ライブラリを使用して署名を行う
        },
        json=payload,
        timeout=30
    )
    response.raise_for_status()
    return response.json()

レスポンスからツール呼び出しを抽出するパーサーロジックでは、モデルの応答が「テキストのみの最終回答」か「ツール呼び出しのリクエスト」かを判定する。Bedrock Converse APIのレスポンスでは、output.content配列の要素にtoolUse型が含まれるかで区別できる。ここでの注意点として、モデルがtoolUsetextを同じターンに混在させる場合がある。両方含まれる場合は、toolUseを優先して実行し、text部分は次のターンにコンテキストとして保持するのが一般的だ。

エラーハンドリングの分岐

失敗モードは大きく3種類に分かれる。1つ目はネットワーク障害(タイムアウト、5xxエラー)で、指数バックオフによる再試行が有効な場合がある。2つ目はモデルがスキーマに違反したJSONを返すケースで、json.loadsが例外を投げる。この場合はスキーマ違反の内容をエラーメッセージとしてモデルにフィードバックし、修正を促す再試行を行う。3つ目はツール実行自体の失敗(外部APIが500を返す等)で、このエラーメッセージも同様にモデルに返す。重要なのは、どの失敗モードでもモデルに「何が起きたか」を構造化して伝えることで、モデルが同じ失敗を繰り返さないようにすることだ。生のスタックトレースをそのまま渡すとトークンを浪費し、モデルの判断を混乱させるため、エラー種別と要約された原因の2要素に圧縮して渡すのが一般的だ。

実行とフィードバック:外部コードとの連携

モデルが生成した構造化リクエストを受け取ったら、次は自前のコードが実際に外部システムを呼び出す段階に入る。ここでの設計判断は、モデルの出力を「信頼してそのまま実行するか」、それとも「検証してから実行するか」である。プロダクション環境では後者が推奨されるが、検証の粒度が問題になる。

最低限実施すべき検証は3層ある。1層目はスキーマバリデーションで、モデルが返したJSONがツール定義で宣言したJSON Schemaに合致するかを機械的にチェックする。2層目はビジネスルールによる制約チェックで、例えば「注文数量が負数でない」「ユーザーIDが認証済みセッションに紐づく」などをコード側で確認する。3層目はリソース制限で、外部APIへの呼び出し頻度やデータ量に上限を設ける。この3層をスキップしてモデルの出力をそのまま実行すると、モデルのハルシネーションが直接本番データに作用するリスクがある。

実行環境の分離も重要な設計判断だ。ツールがシェルコマンドやファイルI/Oを含む場合は、モデルの出力をそのまま eval 等で展開せず、権限を剥奪したサブプロセスやコンテナ内で実行する。実行結果をモデルにフィードバックする際、生データが巨大な場合(例えば大量のクエリ結果)は、そのままメッセージに埋め込むとコンテキストウィンドウを圧迫する。ここで有効なのは、結果の要約(件数・集計値)と、モデルが次の判断に必要な部分データだけを切り出す戦略だ。

sequenceDiagram
    participant M as LLMモデル
    participant C as コントローラー
    participant V as バリデーション層
    participant T as ツール実行器
    participant X as 外部API

    M->>C: 構造化リクエスト(ツール名+引数)
    C->>V: スキーマ検証
    V->>C: 検証結果(OK/NG+理由)
    C->>T: 実行指示(権限制限付き)
    T->>X: 外部API呼び出し
    X->>T: レスポンス
    T->>C: 実行結果(要約済み)
    C->>M: 結果をメッセージに追加

非同期処理との組み合わせでは、長時間かかるツール(例:バッチ処理、外部サービスへのポーリング)に対しては、コントローラー側でタイムアウトを設定し、期限超過時にモデルに「処理中」の状態を通知する。ユーザー体験の観点では、ループが複数ステップにわたる場合に進捗をストリーミングで返す設計が望ましいが、これは実装コストが高いため、ツール実行の平均所要時間が数秒を超える場合のみ採用する判断基準を持つとよい。

セキュリティとコンプライアンス:Guardrailsの活用

Tool Callingが導入されると、LLMの出力が直接外部システムに作用する経路が生まれる。これは従来の「テキスト生成のみ」のLLMアプリケーションと根本的に異なるセキュリティ特性を持つ。モデルがハルシネーションにより存在しないAPIエンドポイントを呼び出そうとしたり、悪意ある入力から誘導されて意図しないツールを連続実行したりするリスクがある。

クラウドサービスレベルの防御として、Amazon Bedrockは多くの組織で利用されており、ISO、SOC、GDPRなどのコンプライアンス認証に対応している(Amazon Bedrock)。これにより、ツール実行のインフラ層でデータ残存や暗号化の要件を満たすことができる。

さらに、Bedrock Guardrailsという機能層では、有害なコンテンツをブロックし、不正な入出力を識別できる(Amazon Bedrock)。ただし、これらの数値はサービス側のベンチマークであり、自社のツールチェーンにおける実際のブロック率や偽陽性率は、導入後に計測して閾値を調整する必要がある。Guardrailsは入力フィルタと出力フィルタの両方に適用でき、Tool Callingの文脈では「モデルが生成したツール引数が業務上不適切な値(例:削除対象が全レコード)になっていないか」を出力側で検証する用途が有効だ。

監査ログの設計は、Tool Callingの信頼性を証明する上で欠かせない。記録すべき最小限の情報は、タイムスタンプ、呼び出されたツール名、引数のハッシュ値、実行結果のステータス、実行者IDの5要素である。引数の完全な生値をログに残す場合、個人情報や機密データがログに漏れるリスクがあるため、ハッシュ化やマスキングを適用する設計が望ましい。ログの保持期間はコンプライアンス要件(例:金融業界の5年保持)に合わせて設定し、ログ自体のアクセス制御もRBACで管理する。

実装例とリポジトリ:学習サンプルの活用

低レイヤー実装の学習において、ゼロから書くのではなく既存のサンプルコードを起点にすることが効率的だ。GitHubリポジトリ「learning-ai-out-loud-samples-for-aws」の ep07-tool-calling フォルダに、ツール呼び出しの実装例が含まれている(learning-ai-out-loud-samples-for-aws)。このサンプルはBedrock Converse APIを直接叩く最小構成であり、フレームワークの抽象化が介在しないため、HTTPペイロードの構造やレスポンスの解析ロジックを素のコードで追跡できる。

このサンプルを自社の基盤に組み込む際のカスタマイズポイントは、主に3つある。1つ目はツールレジストリの実装で、サンプルがハードコードしたツール定義を、設定ファイルやデータベースから動的に読み込む構造に置き換えること。2つ目はコントローラーのループ制御で、サンプルが単一呼び出しのみの場合、先述の最大ステップ数制限やタイムアウトロジックを追加すること。3つ目はエラーハンドリングの分岐で、スキーマ違反時の再試行回数を設定可能にし、再試行上限超過時のフォールバック(例:ユーザーに「処理が複雑です」と伝える)を実装すること。

単体テストの実装では、モデルの出力をシミュレートするモックサーバーが有効だ。実際のLLM APIをテストで叩くとコストとレイテンシが発生し、テスト実行時間が不安定になる。代わりに、ローカルでHTTPサーバーを立てて、事前に用意したJSONレスポンス(正常系・スキーマ違反・タイムアウト)を返すモックを構築する。これにより、パーサーロジックやバリデーション層の堅牢性を、モデルの挙動に依存せずに検証できる。テストケースは最低限、正常なツール呼び出し、存在しないツール名の指定、引数型エラー、空の引数、巨大な引数の5パターンをカバーすると、実運用で遭遇する主要な失敗モードを網羅できる。

運用と監視:プロダクション環境での課題

Tool Callingの制御フローが設計段階で固まったとしても、プロダクション環境では3つの運用課題が常時発生する。それぞれに対して、設計時に埋め込むべき対策を整理する。

出力フォーマットの変動への耐性

LLMの出力は、モデルのバージョン更新やプロンプトの微修正により、スキーマに準拠しない形式に変動しうる。例えば、JSONのキー名がキャメルケースからスネークケースに変わる、必須フィールドが欠落する、期待しない追加フィールドが混入する、といったケースが報告されている。こうした変動に対してパーサーロジックが脆弱だと、本番環境で突然のエラーが連鎖する。

対策としてまず有効なのは、スキーマバリデーションを「厳格モード」と「寛容モード」の2段階で実装することだ。厳格モードではスキーマ違反を即エラーとするが、寛容モードでは既知のフィールドのみを抽出し、未知のフィールドは無視して処理を継続する。寛容モードで処理できた場合でも、構造化ログに警告レベルの記録を残し、ダッシュボードで異常率を監視する。この2段階方式により、モデルの軽微な出力変動でユーザー体験が壊れることを防ぎつつ、本質的なスキーマ変更には気づける。

さらに、モデルのバージョンを固定してデプロイし、バージョン変更時は段階的なトラフィックシフト(カナリアデプロイ)で出力品質を比較する運用も有効だ。モデルの挙動は入力プロンプトの微妙な違いにも敏感なため、バージョン変更ごとに主要なテストケースを回し、スキーマ違反率やツール選択の正確率に回帰がないことを確認してから全量切替を行うべきである。

コスト管理とトークン最適化

Tool Callingのループ処理では、1回のユーザーリクエストに対してモデルが複数回呼び出されることがある。各呼び出しでコンテキスト(システムプロンプト、ツール定義、会話履歴、前回のツール実行結果)がすべて送信されるため、トークン消費量はループ回数に比例して増大する。特にツール定義のJSONスキーマが複雑な場合、1回の呼び出しでも数千トークンを消費する。

コストを抑制する設計判断として、以下の3点が実務で重要になる。

  • ツール定義の最小化:1回のリクエストで必要なツールだけを動的に含める。全ツールを常時注入するのではなく、ユーザーの意図を事前分類して関連ツールのサブセットを渡すことで、コンテキストのトークン数を削減できる。
  • ツール実行結果の要約:外部APIが返したJSONの全量ではなく、モデルが次の判断に必要なフィールドのみを抽出してフィードバックする。例えば、100件レコードが返却された場合、件数とサマリー、そしてモデルが参照する可能性のある数件だけを含める。
  • ループ上限の経済的根拠:最大ステップ数は技術的な安全策であると同時に、コスト上限でもある。1ステップあたりの平均トークン数と単価から、1リクエストあたりの最大コストを算出し、それをビジネス的に許容できる範囲に収めるよう上限を設定する。

監視の観点では、1リクエストあたりの平均トークン数、ループ回数の分布、ツール呼び出しの成功率をメトリクスとして常時収集し、閾値超過時にアラートを出す仕組みを構築する。特にループ回数の分布に右裾の長い歪み(まれに最大ステップ数に到達するリクエストが混在する)が現れた場合、特定の入力パターンでモデルがループに陥っている可能性があり、プロンプトの改善が求められる。

レイテンシ許容範囲とユーザー体験

Tool Callingのループ処理は、モデルの推論時間と外部APIの応答時間の合計が累積する。1回のツール呼び出しでモデル推論が2〜3秒、外部APIが1秒程度かかる場合、3回のループで合計9〜10秒の応答遅延が発生する。この遅延をユーザーが「正常な処理時間」として許容できるかどうかは、アプリケーションの性質に依存する。

リアルタイム性を要求されるチャットインターフェースでは、5秒を超えるとユーザーの離脱率が急激に上昇する傾向がある。この場合、以下の設計が有効だ。

  • ストリーミング応答の活用:モデルがツール呼び出しを決定した時点で「現在データベースを検索しています」という中間メッセージをストリーミングで送信し、最終回答の生成を待つ。これにより、ユーザーはシステムが応答していることを認識できる。
  • 並列ツール呼び出し:モデルが同時に複数のツール呼び出しを要求する場合(例:在庫確認と物流状況の同時取得)、これらをシーケンシャルに実行するのではなく並列に発行し、すべての結果が揃った時点でモデルにフィードバックする。
  • キャッシュの導入:短時間内(例:5分)に同じ引数で呼び出されるツール結果はキャッシュし、モデルへのフィードバック時にキャッシュから返す。在庫数や為替レートのように頻繁に変化しないデータでは、この手法でレイテンシを大幅に短縮できる。

レイテンシの監視では、モデル推論時間と外部API応答時間を分離して計測することが重要だ。モデル側の遅延であればプロンプトの最適化やモデルの切り替えで改善できるが、外部API側の遅延であればそのAPIのSLA見直しやキャッシュ戦略の強化が必要になる。混同したまま「遅い」と判断すると、対策の方向性を誤る。

まとめ:黒箱を制御するエンジニアリングの重要性

Tool Callingは、LLMが外部システムと対話するための構造化されたブリッジである。しかし、その内部構造を「フレームワークが勝手に処理してくれる」と捉えている限り、エラー時のデバッグも性能の最適化もできない。

本記事で整理してきた設計判断を振り返ると、共通する原則は3点に集約できる。

第一に、モデルの出力生成と外部コードの実行を明確に分離することだ。モデルは構造化されたリクエストを「生成」するだけで、実行は必ず自前のコードが行う。この分離が、セキュリティ監査ログの記録、実行前のバリデーション、エラー時のフォールバックを可能にする基盤になる。

第二に、制御フローを自前で実装することだ。ループの上限、タイムアウト、再試行ポリシー、コンテキストの圧縮戦略は、すべてアプリケーション固有の要件に基づいて設計すべきものである。フレームワークのデフォルト値に依存すると、プロダクション環境で問題が発生した際に、原因の切り分けと修正が困難になる。

第三に、モデルの出力を信頼しないことだ。スキーマに準拠しないJSON、存在しないツール名の指定、意図しない引数の組み合わせ——これらは「稀な異常」ではなく、プロダクションでは必ず発生する事象である。パーサーロジックの堅牢性、バリデーションの2段階設計、監視メトリクスの整備が、これらの事象を「障害」ではなく「処理可能なケース」に変える。

低レイヤーで実装することは、フレームワークの利便性を放棄することではない。モデルの出力解釈、ループ制御、エラーハンドリングの各層で、自社のビジネス要件に合わせた判断を埋め込めるようになることだ。この制御力があることで、AI連携のアプリケーションは「動いている間は便利だが、何か起きると止まる」状態から、「予期しない事象にも耐えながら継続的に動作する」状態へと移行する。

関連記事

参考

本記事は海外の技術トレンド「How AI Actually Calls an API? Tool Calling Explained from Scratch」(DEV)で話題のテーマをもとに、両儀システムソリューションズが独自に解説したものです。