How are tools passed to llm? — final prompt sent to OpenAI Chat Model:LLMアプリ実装で見る設計論点
description: LangChainでツールをLLMに渡す際、実際にOpenAI APIへ送信されるプロンプトの中身はどうなっているのか。Stack Overflowの議論を起点に、tool calling実装の設計論点と運用上の注意点を整理します。
meta description: LangChainのtool callingでOpenAIに送られる最終プロンプトの構造を解説。functions/toolsパラメータの仕様、ログ取得方法、RAGとの組み合わせ時の設計判断をまとめます。
何が出たのか
2026年6月18日時点でStack Overflowに投稿された「How are tools passed to llm? (final prompt sent to OpenAI Chat Model)」というスレッドが、LLMアプリ開発者の間で静かに注目を集めています。スコアは2、回答1件、閲覧数453件と数字だけ見れば小さな議論ですが、内容はLangChainを使ったエージェント実装において多くの開発者が一度はぶつかる疑問を正面から扱っています。
問いの核心は「LangChainのAgentやToolを使ったとき、OpenAIのAPIに対して最終的にどんなリクエストが飛んでいるのか」です。LangChainはツール定義・プロンプト組み立て・API呼び出しを抽象化してくれる一方で、その抽象化の内側が見えにくくなります。デバッグや品質改善をしようとしたとき、「何が送られているか分からない」という状況は実装上の大きな障壁になります。
このスレッドが議論しているのは主に2点です。ひとつは、LangChainがツール情報をどのようにOpenAI APIのリクエストボディに変換しているか。もうひとつは、その最終リクエストをどうやって開発者が確認できるか、という観測手段の問題です。
同時期のHacker NewsやRedditのLangChain関連スレッドでも、「フレームワークの抽象化が深すぎてデバッグしにくい」「tool callingの挙動が想定と違ったときの原因特定が難しい」という声が複数上がっており、この問いは個別の疑問というより、LLMアプリ開発全体に共通する設計上の論点として捉えるべきものです。
技術的に面白い点
OpenAI Chat Completions APIにおけるtool callingの仕組みを整理しておきます。ツール(関数)をLLMに認識させるには、APIリクエストのtoolsパラメータ(旧来はfunctionsパラメータ)にJSON Schema形式でツールの定義を渡します。LLMはこの定義を読み取り、ユーザーの入力に応じてどのツールをどの引数で呼ぶかを判断し、レスポンスのtool_callsフィールドに返してきます。
LangChainはこの仕組みをラップしており、@toolデコレータやToolクラスで定義したPython関数を、内部で自動的にJSON Schema形式に変換してAPIリクエストに組み込みます。開発者はPythonの関数定義とdocstringを書くだけでよく、スキーマ変換の手間が省けます。
ここで技術的に面白いのは、「プロンプト」という概念の境界線です。従来のテキスト補完モデルでは、プロンプトはシンプルな文字列でした。Chat Completions APIではシステムメッセージ・ユーザーメッセージ・アシスタントメッセージという構造化されたメッセージ列になり、さらにtool callingではそこにtoolsパラメータが加わります。つまり「最終的にLLMに渡されるもの」はメッセージ列とツール定義の組み合わせであり、単一のプロンプト文字列ではありません。
LangChainでこの最終リクエストを確認する方法はいくつかあります。最も直接的なのはset_verbose(True)またはset_debug(True)を使う方法です。verboseモードではチェーンの各ステップの入出力が表示され、debugモードではさらに詳細なAPIリクエストの内容が出力されます。また、LangSmith(LangChainの公式トレーシングサービス)を使うと、各ステップで送受信されたペイロードをUIで確認できます。
```python
from langchain.globals import set_debug
set_debug(True)
```
このたった1行を追加するだけで、OpenAIへ送信されるリクエストボディの全体像がコンソールに出力されます。ツール定義がどのようなJSON Schemaに変換されているか、メッセージ履歴がどう構成されているかを実際に目で確認できます。
既存の流れとの違い
tool callingが登場する以前、LangChainのエージェントはReAct(Reasoning + Acting)パターンを採用していました。このパターンでは、ツール名・ツールの説明・使い方をすべてシステムプロンプトのテキストとして埋め込み、LLMに「どのツールを使うか」をテキスト形式で出力させていました。出力をパースして次のアクションを決定するという流れです。
この方式の問題は、ツール定義がプロンプトのトークンを消費すること、LLMの出力フォーマットが不安定でパースエラーが起きやすいこと、そしてツールの数が増えるほどプロンプトが肥大化することでした。
OpenAIのfunction calling(現在はtool calling)が導入されたことで、ツール定義はプロンプト本文から切り離され、専用のAPIパラメータとして渡せるようになりました。LLMはツール定義を構造化データとして受け取り、呼び出し判断を構造化JSONで返します。これによりパースの安定性が上がり、プロンプト本文のトークン消費も抑えられます。
LangChainはこの変化に対応し、create_openai_tools_agentやAgentExecutorといったコンポーネントを提供しています。ただし、LangChain自体のバージョンアップが頻繁であり、LLMChainからLCEL(LangChain Expression Language)への移行、initialize_agentの非推奨化など、APIの変化が激しい時期が続いています。Stack Overflowの投稿でも「古いドキュメントのコードが動かない」という文脈が背景にあることが多く、今回の議論もその延長線上にあります。
Hugging Faceのモデルハブでも、tool calling対応を明示したモデルが増えており、OpenAI互換のtool callingインターフェースを持つオープンソースモデルの選択肢が広がっています。この流れを踏まえると、tool callingの仕組みを正確に理解しておくことは、OpenAI以外のモデルへの切り替えを検討する際にも直接役立ちます。
実装・運用で気になる点
ログとトレーサビリティ: 本番環境でtool callingを使う場合、どのツールが何回呼ばれたか、引数は何だったかを記録する仕組みが必要です。LangSmithはこの目的に使えますが、外部サービスへのデータ送信が発生するため、機密情報を扱うシステムでは利用可否を事前に確認する必要があります。自前でログを取る場合は、callbacks機構を使ってon_tool_start/on_tool_endイベントをフックするのが標準的なアプローチです。
トークン消費の見積もり: ツール定義はAPIリクエストのトークンとしてカウントされます。ツールの数や説明文の長さによってはコンテキストウィンドウを圧迫し、コストにも影響します。ツールが10個を超えるような設計では、動的にツールセットを絞り込む(ユーザーの意図に応じて関連ツールだけを渡す)アーキテクチャを検討する価値があります。
RAGとの組み合わせ: RAG(Retrieval-Augmented Generation)と組み合わせる場合、検索ツールをtool callingで定義するパターンがあります。この場合、検索クエリの生成・検索実行・結果のコンテキスト組み込みという流れがすべてtool callingのループ内で起きるため、各ステップのレイテンシが積み重なります。応答時間の要件が厳しいシステムでは、ツール呼び出しの並列化や、検索を事前に実行してコンテキストとして渡すシンプルなパターンとの使い分けが必要です。
fallbackとエラーハンドリング: LLMがツールを呼び出す際、引数のスキーマに合わない値を返すことがあります。tool_choiceパラメータで特定のツールを強制呼び出しさせる設定や、Pydanticによる引数バリデーションをツール定義に組み込むことで、エラーの発生を抑えられます。それでも失敗した場合のfallback処理(リトライ、デフォルト値の使用、ユーザーへのエラー通知)を実装レベルで設計しておくことが重要です。
セキュリティと権限: ツールが外部APIや社内システムを呼び出す場合、LLMが生成した引数をそのまま実行することになります。SQLインジェクションに相当するプロンプトインジェクション攻撃(悪意ある入力でツールの引数を操作しようとする攻撃)への対策として、ツール側での入力バリデーションと、実行権限の最小化は必須の設計要件です。
Spectralの見解
1. 技術的な読み
tool callingはLLMアプリの信頼性を上げる重要な仕組みですが、フレームワークの抽象化が深い分、「何が起きているか分からない」状態に陥りやすい構造になっています。今回のStack Overflowの議論は、その不透明さへの素直な疑問であり、同じ疑問を持っている開発者は相当数いると考えられます。set_debug(True)やLangSmithによる可視化は、開発フェーズでは必ず有効にしておくべきです。LangChainのバージョン変化も速いため、使用しているバージョンのリリースノートを定期的に確認する運用が現実的な対策になります。
2. PoCで確認すべき点
PoC段階では、実際にOpenAIへ送信されるリクエストボディをログに出力し、ツール定義のJSON Schemaが意図通りに生成されているかを確認することを最初のステップにすることを推奨します。特に、Pythonの型ヒントやdocstringの書き方によってスキーマの内容が変わるため、LLMがツールを正しく認識できているかをプロンプトレベルで検証する工程が必要です。また、ツール呼び出しが発生しないケース(LLMが直接回答を返すケース)の挙動も合わせて確認しておくと、本番移行後のトラブルを減らせます。
3. 業務・プロダクト実装に移す時のリスク
本番環境での主なリスクは3点です。ひとつ目はコスト管理で、ツール定義のトークン消費が想定より大きくなるケースがあります。ふたつ目はレイテンシで、複数ツールの連鎖呼び出しが発生するとユーザー体験に影響します。みっつ目はセキュリティで、LLMが生成した引数で外部システムを操作する設計では、入力バリデーションと権限設計を実装レベルで組み込む必要があります。これらは設計段階で対処方針を決めておくことで、後工程での手戻りを防げます。
まとめ
LangChainでツールをLLMに渡す際の実態は、OpenAI APIのtoolsパラメータにJSON Schema形式のツール定義を含めたリクエストを送ることです。この仕組みは従来のReActパターンと比べてパースの安定性とトークン効率の面で優れていますが、フレームワークの抽象化によって内部が見えにくくなっています。
set_debug(True)やLangSmithを使った可視化、callbacksを使ったログ取得、Pydanticによる引数バリデーションといった実装上の工夫を組み合わせることで、tool callingの挙動を制御可能な状態に保てます。RAGとの組み合わせやセキュリティ要件がある場合は、設計段階からこれらの観点を組み込むことが、安定した本番運用につながります。
tool callingの仕組みを正確に把握しておくことは、OpenAI以外のモデルへの移行や、より複雑なマルチエージェント構成を検討する際の基盤にもなります。まず手元の実装で最終リクエストの中身を確認することが、次のステップへの最短経路です。
Spectralでは、LLMアプリのアーキテクチャ設計からPoC実装まで、技術的な観点を軸にした支援を行っています。tool callingの設計方針や既存システムへの組み込みについて相談したい場合は、お気軽にご連絡ください。
関連論点として How reliable are LLMs when it comes to playing: LLMアプリ実装で見る設計論点 もあわせて読むと、この技術動向の背景を追いやすくなります。
Spectralでは、技術調査からPoC設計、プロダクト実装まで支援しています。実現性の確認や事業活用の相談は サービス詳細 と お問い合わせ をご覧ください。

Author
森島拓生
Spectral 代表 / AI導入・エージェント設計
Spectral代表。AI Development & Consultingを軸に、非エンジニアとの対話から要件定義を構造化する「上流工程AI」や、AIエージェントによる業務自動化の設計・検証に取り組む。技術を導入して終わらせず、現場で継続して使える運用設計までを重視している。
AI導入について、もっと詳しく知りたい方へ
お問い合わせ