コンテンツにスキップ

9.3.4 ツール呼び出し戦略

ツール呼び出し戦略のルーティング図

  • ツール呼び出し戦略が、なぜ Agent 成功の鍵のひとつなのかを理解する
  • 「呼ばない / 1回だけ呼ぶ / 複数ステップで呼ぶ / フォールバックする」の代表的なパターンを区別する
  • 基本的なルーティング、リトライ、検証ロジックの設計方法を学ぶ
  • より完全なツール戦略の例を読めるようになる

なぜ「ツールがある」ことと「ツールを使える」ことは同じではないのか?

Section titled “なぜ「ツールがある」ことと「ツールを使える」ことは同じではないのか?”

Agent を作るとき、最初に多くの人がやることは:

  • 検索ツールをつなぐ
  • 計算ツールをつなぐ
  • データベースをつなぐ

そして、これでシステムが強くなると思いがちです。

でも実際には、よく次のような問題が起こります。

  • ツールを呼ばなくてよい場面で、むやみに呼んでしまう
  • 呼ぶべき場面で、逆に呼ばない
  • 違うツールを呼んでしまう
  • ひとつの処理で 5 回も連続で呼び、止まらなくなる

つまり、本当の問題は:

システムにツールがあるか

ではなく、

システムに「ツールを使う戦略」があるか

です。

家のキッチンに包丁、鍋、オーブン、電子レンジがあっても、それだけで料理ができるわけではありません。
大事なのは:

  • いつ切るか
  • いつ煮るか
  • いつ焼くか
  • どこで失敗したらどう直すか

Agent のツール呼び出し戦略も同じです。


まずは代表的な戦略を整理する

Section titled “まずは代表的な戦略を整理する”

次のような場合に向いています。

  • 一般的な説明
  • 簡単な言い換え
  • 文体の変換

たとえば:

「この文章をもっとフォーマルにして」

このようなタスクは、通常は外部ツールを必要としません。

次のような場合に向いています。

  • 天気を調べる
  • 数式を計算する
  • 1 件の知識ベース記録を調べる

これは最もシンプルで、最も安定しやすい呼び出し方法です。

次のような場合に向いています。

  • まず注文を調べて、次に返金ルールを調べて、最後に結論を出す
  • まず資料を検索し、次に要約し、最後に出力を生成する

このときの戦略は、単に「どのツールを呼ぶか」ではなく、「次のステップでもまだ呼ぶ必要があるか」です。

もし:

  • メインのツールが失敗した
  • 結果が信頼できない
  • パラメータ検証に通らない

場合は、システムは次のどれをするか決める必要があります。

  • リトライする
  • 別のツールに切り替える
  • ユーザーに追加情報を求める
  • その場で「できない」と伝える

これもツール戦略の大事な部分です。


ツールを呼ぶ前に何を判断するべきか?

Section titled “ツールを呼ぶ前に何を判断するべきか?”

すべての問題がツールチェーンを通るべきとは限りません。
ツールを呼ぶたびに、次のものが増えます。

  • 遅延
  • コスト
  • 失敗経路

そのため、最初のステップはしばしば:

まずツールが必要かどうかを判断すること。

必要なら、どのツールを選ぶか?

Section titled “必要なら、どのツールを選ぶか?”

たとえばユーザーがこう聞いたとします。

「この注文はまだ返金できますか?」

必要になる可能性があるのは:

  1. 注文状態を調べる
  2. 返金ポリシーを調べる

つまり、ツール選択は常に「1つ選べば終わり」ではなく、順番のある組み合わせ問題になることがあります。

どのツールを使うべきか分かっていても、パラメータが足りないことがあります。

たとえば:

「天気を調べて」

これでは都市名がありません。
この場合、最も自然な戦略は、適当に推測することではなく:

先にユーザーへ確認すること

です。


ツールを呼んだ後に何を判断するべきか?

Section titled “ツールを呼んだ後に何を判断するべきか?”

ツールから返答があっても、そのまま使ってよいとは限りません。

たとえば:

  • API タイムアウト後に空の値が返る
  • 検索結果の関連性が低い
  • データベースに記録が見つからない

タスクによっては、1 回の呼び出しでは最終答えまで行けません。

たとえば:

  • まず知識ベースを調べる
  • 次に計算する
  • 最後にユーザーが読みやすい形でまとめる

つまり、ツール戦略は本質的にはよく次の流れになります。

呼び出す -> 観察する -> 次の一手を決める


最小限だが学習価値のある戦略例

Section titled “最小限だが学習価値のある戦略例”

次の例では、3 つのケースを分けます。

  • ツールを呼ばない
  • 1 つのツールを呼ぶ
  • パラメータが足りないときは先に確認する
def route_query(query):
if "要約" in query or "書き換え" in query:
return {"action": "no_tool", "reason": "純テキストタスク"}
if "天気" in query:
if "北京" in query:
return {"action": "tool", "tool": "weather", "arguments": {"city": "北京"}}
return {"action": "ask_user", "question": "どの都市の天気を調べたいですか?"}
if "計算" in query:
expression = query.replace("計算", "").strip()
return {"action": "tool", "tool": "calculator", "arguments": {"expression": expression}}
return {"action": "fallback", "reason": "現在、適切な戦略がありません"}
queries = [
"この文章を要約して",
"北京の天気はどうですか",
"天気を調べて",
"計算 12 * 7"
]
for q in queries:
print(q, "->", route_query(q))

期待される出力:

Terminal window
この文章を要約して -> {'action': 'no_tool', 'reason': '純テキストタスク'}
北京の天気はどうですか -> {'action': 'tool', 'tool': 'weather', 'arguments': {'city': '北京'}}
天気を調べて -> {'action': 'ask_user', 'question': 'どの都市の天気を調べたいですか?'}
計算 12 * 7 -> {'action': 'tool', 'tool': 'calculator', 'arguments': {'expression': '12 * 7'}}

この例はシンプルですが、「戦略」という層をよく表しています。

  • すべての入力をツールに渡すわけではない
  • パラメータが足りないからといって、無理に推測しない
  • どうしても分からないときは fallback がある

import ast
import operator
OPS = {
ast.Add: operator.add,
ast.Sub: operator.sub,
ast.Mult: operator.mul,
ast.Div: operator.truediv,
}
def safe_calculate(expression):
def visit(node):
if isinstance(node, ast.Expression):
return visit(node.body)
if isinstance(node, ast.Constant) and isinstance(node.value, (int, float)):
return node.value
if isinstance(node, ast.BinOp) and type(node.op) in OPS:
return OPS[type(node.op)](visit(node.left), visit(node.right))
if isinstance(node, ast.UnaryOp) and isinstance(node.op, ast.USub):
return -visit(node.operand)
raise ValueError("unsupported_expression")
return visit(ast.parse(expression, mode="eval"))
def get_weather(city):
return {"city": city, "temperature": 22, "condition": "sunny"}
def calculate(expression):
return {"result": safe_calculate(expression)}
def execute_strategy(query):
decision = route_query(query)
if decision["action"] == "no_tool":
return {"type": "answer", "content": "この種のタスクは、モデルが直接テキストを生成するほうが向いています。"}
if decision["action"] == "ask_user":
return {"type": "question", "content": decision["question"]}
if decision["action"] == "tool":
if decision["tool"] == "weather":
result = get_weather(**decision["arguments"])
return {"type": "tool_result", "content": result}
if decision["tool"] == "calculator":
result = calculate(**decision["arguments"])
return {"type": "tool_result", "content": result}
return {"type": "fallback", "content": "このリクエストを安定して処理できません。"}
for q in ["北京の天気はどうですか", "天気を調べて", "計算 9 + 8"]:
print(q, "->", execute_strategy(q))

期待される出力:

Terminal window
北京の天気はどうですか -> {'type': 'tool_result', 'content': {'city': '北京', 'temperature': 22, 'condition': 'sunny'}}
天気を調べて -> {'type': 'question', 'content': 'どの都市の天気を調べたいですか?'}
計算 9 + 8 -> {'type': 'tool_result', 'content': {'result': 17}}

ツール戦略のルーティングと実行結果図

このコードが本当に教えているのは次のことです。

ツール呼び出し戦略は、1 行の if ではなく、「判断 + 分岐 + 実行 + フォールバック」の連なりとして設計するものです。


実際のシステムでよく使う戦略パターン

Section titled “実際のシステムでよく使う戦略パターン”

まず、問題がどのツール、またはどのサブシステムに属するかを判断します。

向いている場面:

  • ツールが多い
  • タスクの境界がはっきりしている

ツールを呼んだ後、すぐに結果を信じず、もう一度確認します。

向いている場面:

  • 外部データが不安定
  • ツールの失敗率が高い

再試行 / フォールバックパターン(Retry / Fallback)

Section titled “再試行 / フォールバックパターン(Retry / Fallback)”

まずリトライし、それでもだめなら段階的に性能を落とし、最後に兜底します。

向いている場面:

  • 外部 API が不安定
  • オンラインサービスが揺れやすい

計画してからツールを選ぶパターン(Plan-then-tool)

Section titled “計画してからツールを選ぶパターン(Plan-then-tool)”

先に計画を立て、それからツールの順番を決めます。

向いている場面:

  • 複数ステップのタスク
  • 複数ツールの依存関係がある場合

いつ「ツールを少なく使う」べきか?

Section titled “いつ「ツールを少なく使う」べきか?”

これも、とても重要な戦略能力です。

ツールを少なくしてよい典型例

Section titled “ツールを少なくしてよい典型例”
  • ただ要約する
  • ただ言い換える
  • 文体を変える
  • すでに十分な文脈がある

なぜ少ないほうがよいことがあるのか?

Section titled “なぜ少ないほうがよいことがあるのか?”

ツールを 1 回増やすたびに、次のコストも増えます。

  • レイテンシ
  • 失敗の可能性
  • 状態管理のコスト

だから成熟したシステムは、「呼べるなら何でも呼ぶ」のではなく、

省けるところは省く

という考え方を持っています。


ツール呼び出し戦略を「ルーティングルール」だと考える

Section titled “ツール呼び出し戦略を「ルーティングルール」だと考える”

ルーティングはその一部にすぎません。
本当の戦略には、次の判断も含まれます。

  • 呼ぶかどうか
  • 追い質問するかどうか
  • 次のステップに進むかどうか
  • フォールバックするかどうか

呼び出し失敗後の次の手がない

Section titled “呼び出し失敗後の次の手がない”

リトライもなく、fallback もなく、追加確認もない。こうしたシステムは本番ではとても脆いです。

実際の開発では、多くの戦略はプログラム側のフレームワークで明確に制御すべきです。モデルに完全に任せきりにするべきではありません。


このページを終えたら、この証拠カードを残します。

ツール契約
名前、説明、入力スキーマ、出力スキーマ
権限
ツールが読み取りまたは変更を許可されている範囲
呼び出しトレース
引数、結果、エラー、再試行、またはフォールバック
失敗確認
間違ったツール、不適切な引数、危険な操作、または観測不足
安全対策
検証、確認、サンドボックス化、レート制限、またはロールバック

この節で最も大事なのは、「どのツールを使えるか」を知ることではなく、次を理解することです。

ツール呼び出し戦略は、Agent が正しいタイミングで、正しい順序で、正しい方法でツールを呼べるかどうかを決めます。

これはしばしば、「ツールをたくさんつなげる」こと以上に、システム品質へ大きく影響します。


  1. この節の例に search_docs(keyword) ツールを追加し、ルーティングロジックを拡張してください。
  2. 「ツール実行でエラーが出たら、人間の確認に fallback する」分岐を追加してください。
  3. 考えてみましょう。ユーザーが「天気を調べて、着る服の指標も計算して」と聞いたら、戦略層ではこの処理をどう分割すべきでしょうか?
  4. 自分の言葉で説明してみましょう。なぜツール呼び出し戦略は、Agent の品質を分ける分岐点のひとつだと言えるのでしょうか?
参考実装と解説
  1. search_docs(keyword) は知識検索用の routing 分岐を追加し、自由文だけでなく evidence snippet を返すようにします。
  2. ツール実行エラーはまず分類します。安全な一時的エラーだけ再試行し、それ以外は人間確認または制御された失敗にします。
  3. 「天気を調べて服装指数を計算する」タスクは、天気検索、条件の解釈、小さな計算またはルールベース推薦に分けます。
  4. tool strategy は Agent 品質の境界です。ツール順序、状態の受け渡し、エラー復旧、停止条件を決めるからです。