Amazon Bedrock の GA による API 周りの変更点をまとめておく

## この記事の目的
2023/9/28 についに Amazon Bedrock が一般提供開始されました。自分の観測範囲で、Preview → GA のタイミングで API 周りでいくつか大きな変更が入っている様子です。

プレビュー期間中も LangChain などの周辺ライブラリでは Bedrock のサポート対応が進んでいました。GA 時の変更でメンテナー、コントリビューターの皆さんがすごい勢いで対応されています。

逆にいうと、現時点でサンプルコード等をググると Preview 時の古い情報がヒットする可能性も大いにあります。そのため賞味期限は短いと思いますが、変更点をまとめておくことで、自分や他のどなたかの参考になればと思います。

:::note warn
以降、2023/9/29 に確認した内容をもとに記載をしています。前述のとおり順次対応が進んでいるため、この記事を読んでいただいたタイミングによっては記載内容が陳腐化している可能性があります。
:::

## エンドポイントの分割と変更
モデルへの推論リクエストを行うための API アクションである `InvokeModel` および `InvokeModelWithResponseStream` が Amazon Bedrock から Amazon Bedrock Runtime として分離されました。コントロールプレーンとデータプレーンに分かれたというイメージでしょうか。

https://docs.aws.amazon.com/bedrock/latest/APIReference/API_Operations.html

https://docs.aws.amazon.com/bedrock/latest/userguide/endpointsTable.html

例えば Bedrock の API に対応した boto3 の 1.28.57 以降では、サービス名もそれぞれ、`bedrock` と `bedrock-runtime` として区別されており、使用するアクションによって意識して使い分ける必要があります。

```py
import boto3

# モデルの Invoke は service_name が bedrock-runtime
bedrock-runtime = boto3.client(service_name='bedrock-runtime')

body = json.dumps({
    "prompt": "\n\nHuman:explain black holes to 8th graders\n\nAssistant:",
    "max_tokens_to_sample": 300,
    "temperature": 0.1,
    "top_p": 0.9,
})

response = bedrock-runtime.invoke_model(
    body=body,
    modelId="anthropic.claude-v2"
    accept="application/json"
    contentType="application/json"
)

# その他のアクションは bedrock 
bedrock = boto3.client(service_name='bedrock')
bedrock.list_foundation_models()
```

### 参考
Langchain での修正:

https://github.com/langchain-ai/langchain/pull/11161

Amazon Bedrock Workshop での修正

https://github.com/aws-samples/amazon-bedrock-workshop/pull/56

## Anthropic Claude モデルに関する変更
詳細は完全に理解できていませんが、Anthropic 社のサービスと Bedrock との互換性のため、プロンプトのラッピング要件が変更されたようです。より具体的にはプロンプトに誰が話しているのかを示す信号として `Human:` と `Assistant:` が含まれている必要があります。

LangChain 側でプロンプトのチェックとフォーマットをおこなうための修正が以下です。

https://github.com/langchain-ai/langchain/pull/11090

問題が顕在化する例として、LangChain の ConversationBufferMemory で会話の履歴を保持している場合があります。デフォルトでは `Human:` と `AI:` として履歴が保持するため、以下のように AI のプレフィックスを Assistant に変更することで Claude モデル利用時のエラーを回避することができます。

```py
from langchain.prompts import PromptTemplate
from langchain.chains import ConversationChain
from langchain.memory import ConversationBufferMemory
from langchain.llms.bedrock import Bedrock

llm = Bedrock(
    region_name="us-east-1",
    model_id="anthropic.claude-v2",
)

template = """\n
{history}
Human: {input}
Assistant:"""

prompt = PromptTemplate(
    template=template,
    input_variables=["history", "input"],
)

conversation = ConversationChain(
    prompt=prompt, 
    llm=llm, 
    memory=ConversationBufferMemory(
        # Anthropic requires the prefix to be "Assistant":
        ai_prefix="Assistant"
    )
)
```

## Titan モデルの名称変更
Titan は Embedding モデルと Text モデルが提供されていますが、それぞれのモデル名称と ID に変更がありました。

| Modality | 旧モデル名 | 旧モデル ID | 新モデル名 | 新モデル ID |
| --- | --- | --- | --- | --- |
| Embedding | Titan Text Embeddings v2 | amazon.titan-embed-g1-text-02 | Titan Embeddings G1 - Text | amazon.titan-embed-text-v1 |
| Text | Titan Text Large | amazon.titan-tg1-large | Titan Text G1 - Express | amazon.titan-text-express-v1 |

2023/9/29 時点で Amazon Bedrock Workshop などには古いモデル ID での記載が残っているようです。

https://github.com/aws-samples/amazon-bedrock-workshop/blob/main/04_Chatbot/00_Chatbot_Titan.ipynb

また Titan Text G1 - Express は 2023/9/29 時点では Preview であり、アクセス許可はロールアウトベースで行われるとあります。そのため変更後のモデル ID を使用したとしても現時点では多くのアカウントでは利用ができない点に注意してください。(Preview に参加していたアカウントは除く)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/125105/86c3a380-4683-c793-b8b7-88b9dbeb698f.png)

boto3 でのエラー例:
> AccessDeniedException: An error occurred (AccessDeniedException) when calling the InvokeModel operation: Your account is not authorized to invoke this API operation.

以上です。
参考になれば幸いです。