Amazon Bedrock Intelligent Prompt Routing を試す

:::note info
2024/12 現在 プレビュー

2024/04/22 GA
https://aws.amazon.com/jp/about-aws/whats-new/2025/04/amazon-bedrock-intelligent-prompt-routing-generally-available/
:::


# 内容

AWS re:Invent 2024 で発表があった Amazon Bedrock Intelligent Prompt Routing をシンプルに纏めます。

https://aws.amazon.com/jp/blogs/news/reduce-costs-and-latency-with-amazon-bedrock-intelligent-prompt-routing-and-prompt-caching-preview/

https://aws.amazon.com/jp/about-aws/whats-new/2024/12/amazon-bedrock-intelligent-prompt-routing-preview/

- 単純な問いかけ → ⼩さいモデル
- 複雑な問いかけ → ⼤きなモデル

といったように自動で振り分け、必要な品質を保ちながらコストを最大 30 ％ 削減


# 利用可能なモデル

- Claude 3 Haiku, Claude 3.5 Sonnet

- Llama 3.1 8B Instruct, Llama 3.1 70B Instruct

のいずれかのセットで対応可能。


# 対応リージョン

- バージニア
- オレゴン


# コンソールから確認してみる

「基盤モデル」の「Prompt Routers」で今回は「Anthropic Prompt Router」をチェック
![スクリーンショット 2024-12-21 18.56.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/bfd6902f-9019-8fa9-c7fc-815aedd2ab65.png)

「Anthropic Prompt Router」の中を確認してみます。

- Models for routing : ルーティング基準はランタイムにルーター内部モデルによって予測された各プロンプトの最大モデルの応答と最小モデルの応答の品質差を定義してルーティング
- Fallback model : 選択したモデルのどれも望ましいパフォーマンス基準を満たさない場合に使用

![スクリーンショット 2024-12-21 19.04.18.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/04a0730d-be3d-11a8-0752-67973442c16e.png)

playground で単純な問いかけと複雑な問いかけをしてみます。

- Claude 3 Haiku となった場合

![スクリーンショット 2024-12-21 19.19.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/20e9f4b7-0450-39c2-b7cf-594d9060db03.png)

- Claude 3.5 Sonnet

![スクリーンショット 2024-12-21 19.21.54.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/c03ae4be-714d-e3d7-720c-c72ca823cea5.png)

おー回答があっているかは確認してませんが、いい感じに振り分けてくれてますね。


# SDK で確認してみる

実装は、AWS ブログのものを利用させていただいてます。

```py
import json
import boto3

bedrock_runtime = boto3.client(
    "bedrock-runtime",
    region_name="us-west-2",
)

MODEL_ID = "arn:aws:bedrock:us-west-2:1234567890:default-prompt-router/anthropic.claude:1"

user_message = "<XXXXXX>"
messages = [
    {
        "role": "user",
        "content": [{"text": user_message}],
    }
]

streaming_response = bedrock_runtime.converse_stream(
    modelId=MODEL_ID,
    messages=messages,
)

for chunk in streaming_response["stream"]:
    if "contentBlockDelta" in chunk:
        text = chunk["contentBlockDelta"]["delta"]["text"]
        print(text, end="")
    if "messageStop" in chunk:
        print()
    if "metadata" in chunk:
        if "trace" in chunk["metadata"]:
            print(json.dumps(chunk['metadata']['trace'], indent=2))
```

user_message を`日本の祝日を教えて下さい。`と質問してみます。

![スクリーンショット 2024-12-21 20.23.52.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/7cc68635-2ab4-9a68-54b5-571795340520.png)

user_message を`日本の祝日が土曜日となった場合は振替休日となります。2023年に振替休日となった日を教えて下さい。`と質問してみます。

![スクリーンショット 2024-12-21 20.26.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/280929/48af3b3d-15ee-8da8-bed2-e9cfa4c6090d.png)

但し、ちょとこのコードからは、どちらのモデルを利用しているかは確認できていません。promptRouter を出力させればいいようですが。。。
ちなみに、CloudWatch Logs には promptRouter は表示されていませんでした。

```json
{
  "promptRouter": {
    "invokedModelId": "arn:aws:bedrock:us-west-2:123456789012:inference-profile/us.anthropic.claude-3-haiku-20240307-v1:0"
  }
}
```

https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock-runtime/client/converse_stream.html

converse_stream ではなく、converse で試さている方がいたので下記を参考にすると良いでしょう。

https://www.cloudbuilders.jp/articles/5237/