メインコンテンツへスキップ

9.3.4 ツール呼び出し戦略

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

この節の位置づけ

前の節で、ツールを安全にモデルの後ろへつなぐ方法はすでに学びました。
この節では、さらに一歩先へ進みます。

ツールはつなげばよいわけではなく、大事なのはどう使うかです。

システムの品質差を大きく左右するのは、「ツールがあるか」よりも「いつ呼ぶか、最初にどれを呼ぶか、失敗したらどうするか」です。

学習目標

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

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

よくある誤解

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

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

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

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

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

つまり、本当の問題は:

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

ではなく、

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

です。

生活のたとえ

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

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

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


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

ツールを呼ばない

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

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

たとえば:

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

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

1 回だけ呼ぶ

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

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

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

複数ステップで呼ぶ

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

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

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

フォールバックと代替処理

もし:

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

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

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

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


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

本当にツールが必要か?

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

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

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

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

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

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

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

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

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

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

パラメータは十分か?

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

たとえば:

「天気を調べて」

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

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

です。


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

結果は信頼できるか?

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

たとえば:

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

次のステップが必要か?

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

たとえば:

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

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

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


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

次の例では、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))

期待される出力:

この文章を要約して -> {'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))

期待される出力:

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

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

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

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


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

Router パターン

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

向いている場面:

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

Verify パターン

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

向いている場面:

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

Retry / Fallback パターン

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

向いている場面:

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

Plan-then-tool パターン

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

向いている場面:

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

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

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

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

  • ただ要約する
  • ただ言い換える
  • 文体を変える
  • すでに十分な文脈がある

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

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

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

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

省けるところは省く

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


初心者がよくはまる落とし穴

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

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

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

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

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

毎回モデルに全部決めさせる

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


まとめ

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

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

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


練習

  1. この節の例に search_docs(keyword) ツールを追加し、ルーティングロジックを拡張してください。
  2. 「ツール実行でエラーが出たら、人間の確認に fallback する」分岐を追加してください。
  3. 考えてみましょう。ユーザーが「天気を調べて、着る服の指標も計算して」と聞いたら、戦略層ではこの処理をどう分割すべきでしょうか?
  4. 自分の言葉で説明してみましょう。なぜツール呼び出し戦略は、Agent の品質を分ける分岐点のひとつだと言えるのでしょうか?