Amazon BedrockにUse Tools（Function calling）が来た

急ぎご連絡まで。


```shell
pip install "boto3>=1.34.116"
```

```python
import json

import boto3

bedrock_client = boto3.client("bedrock-runtime")


model_id = "anthropic.claude-3-haiku-20240307-v1:0"

toolConfig = {
    "tools": [
        {
            "toolSpec": {
                "name": "get_weather",
                "description": "Get the current weather in a given location",
                "inputSchema": {
                    "json": {
                        "type": "object",
                        "properties": {
                            "location": {
                                "type": "string",
                                "description": "The city and state, e.g. San Francisco, CA",
                            }
                        },
                        "required": ["location"],
                    }
                },
            }
        }
    ]
}


messages = [
    {
        "role": "user",
        "content": [{"text": "What is the weather like in San Francisco?"}],
    }
]

response = bedrock_client.converse(
    modelId=model_id, messages=messages, toolConfig=toolConfig
)

print(json.dumps(response, indent=2, ensure_ascii=False))
```

```json:レスポンス
{
  "ResponseMetadata": {
    "RequestId": "8174d361-3f38-4afc-af3f-c00c3f9464ad",
    "HTTPStatusCode": 200,
    "HTTPHeaders": {
      "date": "Thu, 30 May 2024 23:47:24 GMT",
      "content-type": "application/json",
      "content-length": "346",
      "connection": "keep-alive",
      "x-amzn-requestid": "8174d361-3f38-4afc-af3f-c00c3f9464ad"
    },
    "RetryAttempts": 0
  },
  "output": {
    "message": {
      "role": "assistant",
      "content": [
        {
          "text": "Here is the weather for San Francisco, CA:"
        },
        {
          "toolUse": {
            "toolUseId": "tooluse_VwMxYFWoTKSKIKQ6I_m8iQ",
            "name": "get_weather",
            "input": {
              "location": "San Francisco, CA"
            }
          }
        }
      ]
    }
  },
  "stopReason": "tool_use",
  "usage": {
    "inputTokens": 354,
    "outputTokens": 67,
    "totalTokens": 421
  },
  "metrics": {
    "latencyMs": 952
  }
}
```

* bodyを`json.dumps`しなくて良くなった
* レスポンスを謎の書式でパースしなくて良くなった
* モデル名を`cohere.command-r-v1:0`にかえる **だけ** で、Command RのToolが使える

Anthropicのドキュメントは一読したほうが良さそう

* `chain of thought`したほうがいいよ。SonnetとHaikuはプロンプトで指示しようね　[ここ](https://docs.anthropic.com/en/docs/tool-use#chain-of-thought-tool-use)
* 複雑なTool使うときは`Opus`がいいよ [ここ](https://docs.anthropic.com/en/docs/tool-use#tool-use-best-practices-and-limitations)

---

ツールを実行したあとのリクエストはこんな感じになります。
ちゃんとmessageを作らないとエラーになりました。

```python
contents = response["output"]["message"]["content"]
messages.append(response["output"]["message"])

tool_use_id = ""
for content in contents:

    if "toolUse" in content:
        tool_use_id = content["toolUse"]["toolUseId"]
        break

messages.append(
    {
        "role": "user",
        "content": [
            {
                "toolResult": {
                    "toolUseId": tool_use_id,
                    "content": [{"text": "15 degrees"}],
                },
            }
        ],
    }
)

response2 = bedrock_client.converse(
    modelId=model_id, messages=messages, toolConfig=toolConfig
)

print(json.dumps(response2, indent=2, ensure_ascii=False))
```

```json:レスポンス
{
  "ResponseMetadata": {
    "RequestId": "9747e53a-4cb4-4228-8617-86591cc6b448",
    "HTTPStatusCode": 200,
    "HTTPHeaders": {
      "date": "Fri, 31 May 2024 03:35:19 GMT",
      "content-type": "application/json",
      "content-length": "393",
      "connection": "keep-alive",
      "x-amzn-requestid": "9747e53a-4cb4-4228-8617-86591cc6b448"
    },
    "RetryAttempts": 0
  },
  "output": {
    "message": {
      "role": "assistant",
      "content": [
        {
          "text": "Based on the weather information, the current temperature in San Francisco, CA is 15 degrees. I don't have any additional details about the weather conditions, but the temperature is reported to be 15 degrees."
        }
      ]
    }
  },
  "stopReason": "end_turn",
  "usage": {
    "inputTokens": 441,
    "outputTokens": 47,
    "totalTokens": 488
  },
  "metrics": {
    "latencyMs": 1120
  }
}
```