@shinyaz

Bedrock Converse API の tool use はモデルが1ターンで複数ツールを並列呼び出しする

約1分

Bedrock Converse API の tool use で A/B テストのバリアント選択を検証したときの発見。3 種類のツール(get_user_profileget_similar_usersget_variant_performance)を定義し、バリアント A/B 両方のパフォーマンスを取得するため計 4 回のツール呼び出しが必要なシナリオだった。

最初は「モデルが 1 つずつツールを呼び、結果を見て次のツールを呼ぶ」逐次パターンを想定していた。しかし実際には、モデルは 1 回のレスポンスで 4 つのツール呼び出しを同時に要求した。

Output
Turn 1: get_user_profile({"user_id": "user_001"})
Turn 1: get_similar_users({"user_id": "user_001", "limit": 10})
Turn 1: get_variant_performance({"experiment_id": "cta_test_2024", "variant_id": "A"})
Turn 1: get_variant_performance({"experiment_id": "cta_test_2024", "variant_id": "B"})

すべて Turn 1 で並列に要求され、結果を返すと Turn 2 で最終判断が返る。全検証で 2 ターンだった。

実装上のポイントは、output_message["content"] に複数の toolUse ブロックが含まれうるため、ループで全件処理して toolResult をまとめて返す必要がある点だ。

Python
if response["stopReason"] == "tool_use":
    tool_results = []
    for block in output_message["content"]:
        if "toolUse" in block:
            tool = block["toolUse"]
            result = execute_tool(tool["name"], tool["input"])
            tool_results.append({"toolResult": {
                "toolUseId": tool["toolUseId"],
                "content": [{"json": json.loads(result)}],
            }})
    messages.append({"role": "user", "content": tool_results})

ドキュメントの tool use のサンプルコードは単一ツールの例が中心だが、for ループで複数の toolUse ブロックを処理する構造にはなっている。ツール間に依存関係がなければ、モデルは並列呼び出しを選択する可能性が高い。

共有する

田原 慎也

田原 慎也

ソリューションアーキテクト @ AWS

AWS ソリューションアーキテクトとして金融業界のお客様を中心に技術支援をしており、クラウドアーキテクチャや AI/ML に関する学びをこのサイトで発信しています。このサイトの内容は個人の見解であり、所属企業の公式な意見や見解を代表するものではありません。