Amazon Nova が Converse API の ToolChoice のオプションを拡充（Auto・Any・Tool）

# 内容

https://aws.amazon.com/jp/about-aws/whats-new/2025/03/amazon-nova-expands-tool-converse-api/


# ToolChoice とは？

従来、Converse API では「Auto」モードのみが利用可能で、AI がツールを使うかどうかを自動で判断していました。​
今回のアップデートで、以下の 2 つのモードが追加され、合計 3 つのモードから選択できるようになったとのこと。

|モード|説明|
|---|---|
|Auto（自動）モード|AI がツールを使うかどうかを自動で判断します。​ユーザーとの自然な対話が求められるチャットボットなどに適しています。​|
|Any（任意）モード|指定したツールの中から、AI が少なくとも 1 つのツールを選んで使用します。​ツールの選択は AI に任せますが、必ずツールを使用する点が特徴です。​機械同士のやり取りなど、自然言語を解釈しないシステムとの連携に適しています。​|
|Tool（指定）モード|開発者が特定のツールを指定し、AI がそのツールを使用するように指示します。​出力形式が決まっている場合や、特定の処理を行いたい場合に有効です。​|


# どんな場面で役立つの？

- チャットボット開発：​ユーザーの質問に応じて、AI が適切なツールを使い分けることができます
- 業務自動化：​特定のツールを使って定型業務を処理する際に、AI が自動でツールを選択・実行します
- システム連携：​他のシステムと連携し、AI が必要なツールを使ってデータをやり取りします


# 動作確認

## Auto

### 実装

```python
import json
import boto3

# AWS設定
REGION_NAME = "us-west-2"
MODEL_ID = "us.amazon.nova-lite-v1:0"

# ツール定義
SEARCH_BOOKS_TOOL = {
    "toolSpec": {
        "name": "search_books",
        "description": "API to search books by title, author or genre",
        "inputSchema": {
            "json": {
                "type": "object",
                "properties": {
                    "query": {
                        "type": "string",
                        "description": "Search query for books"
                    },
                    "genre": {
                        "type": "string",
                        "description": "Genre to filter by",
                        "default": "all"
                    }
                },
                "required": []
            }
        }
    }
}

BOOK_DETAILS_TOOL = {
    "toolSpec": {
        "name": "get_book_details",
        "description": "API to get detailed information about a specific book",
        "inputSchema": {
            "json": {
                "type": "object",
                "properties": {
                    "book_id": {
                        "type": "string",
                        "description": "Unique identifier of the book"
                    }
                },
                "required": ["book_id"]
            }
        }
    }
}

# ツール設定全体
tool_config = {
    "toolChoice": {
        "auto": {}
    },
    "tools": [
        SEARCH_BOOKS_TOOL,
        BOOK_DETAILS_TOOL
    ]
}

# ユーザー入力
user_query = "I need a good science fiction book"

# メッセージ構造
messages = [{
    "role": "user",
    "content": [{"text": user_query}]
}]

# 推論パラメータ
inference_params = {
    "maxTokens": 1000,
    "temperature": 0.7
}

def call_bedrock_api(messages, tool_config, inference_params):
    client = boto3.client("bedrock-runtime", region_name=REGION_NAME)
    
    response = client.converse(
        modelId=MODEL_ID,
        messages=messages,
        toolConfig=tool_config,
        inferenceConfig=inference_params
    )
    return response

# APIを呼び出し
response = call_bedrock_api(messages, tool_config, inference_params)

# 結果の表示
print("[Full Response]")
print(json.dumps(response, indent=2))
```

### 出力

science fiction というキーワードを元に、SEARCH_BOOKS_TOOL が呼び出されたことがわかります。

```json
{
  "ResponseMetadata": {
    "RequestId": "9e4e0ef1-4972-45df-bfa5-b8dab2844ffe",
    "HTTPStatusCode": 200,
    "HTTPHeaders": {
      "date": "Sun, 20 Apr 2025 09:11:58 GMT",
      "content-type": "application/json",
      "content-length": "499",
      "connection": "keep-alive",
      "x-amzn-requestid": "9e4e0ef1-4972-45df-bfa5-b8dab2844ffe"
    },
    "RetryAttempts": 0
  },
  "output": {
    "message": {
      "role": "assistant",
      "content": [
        {
          "text": "<thinking>The User is looking for a science fiction book. I can use the 'search_books' tool to find books in the science fiction genre. I will need to specify the genre in the tool call.</thinking>\n"
        },
        {
          "toolUse": {
            "toolUseId": "tooluse_DCOzszRIRoaPxuO0So5PUg",
            "name": "search_books",
            "input": {
              "genre": "science fiction"
            }
          }
        }
      ]
    }
  },
  "stopReason": "tool_use",
  "usage": {
    "inputTokens": 483,
    "outputTokens": 80,
    "totalTokens": 563
  },
  "metrics": {
    "latencyMs": 763
  }
}
```

## Any

### 実装

先程の Auto の実装で、auto を any に変更するだけで後は同じです。

```python
tool_config = {
    "toolChoice": {
        "any": {}
    },
    "tools": [
        SEARCH_BOOKS_TOOL,
        BOOK_DETAILS_TOOL
    ]
}
```

Any モードは AI が少なくとも 1 つのツールを選んで使用されるため、user_query は次の通り、SEARCH_BOOKS_TOOL にも、BOOK_DETAILS_TOOL にも該当しない質問に置き換えてみます。

```json
user_query = "I need a good science fiction movie"
```

### 出力

search_books が使われましたが、content.text が存在しない状態となりました。

```json
  "output": {
    "message": {
      "role": "assistant",
      "content": [
        {
          "toolUse": {
            "toolUseId": "tooluse_SletMS7aQEiY_rYscjz7Pg",
            "name": "search_books",
            "input": {
              "genre": "science fiction"
            }
          }
        }
      ]
    }
  },
```

## Tool

### 実装

先程の Auto の実装で、auto を tool に変更し、BOOK_DETAILS_TOOL を強制するようにしてみます。

```python
tool_config = {
    "toolChoice": {
        "tool": { "name" : "get_book_details"}
    },
    "tools": [
        SEARCH_BOOKS_TOOL,
        BOOK_DETAILS_TOOL
    ]
}
```

user_query は先程の Any モードと同じです。

```json
user_query = "I need a good science fiction movie"
```

### 出力

get_book_details が使われ、content.text が存在しない状態となりました。

```
  "output": {
    "message": {
      "role": "assistant",
      "content": [
        {
          "toolUse": {
            "toolUseId": "tooluse_QW1AvHLDS5K62ViO8YlHUA",
            "name": "get_book_details",
            "input": {
              "query": "science fiction"
            }
          }
        }
      ]
    }
  },
```