boto3 で Amazon Bedrock を叩く on Docker

## 何の記事？
- 2023/09/28にGAになったAmazon Bedrockに遅れて、boto3(python のAWS SDK)が対応した
  ので、boto3経由で叩く
- あまりまとまった情報がなかったぽい、IAM ポリシーについて記載する
  (モデルのARNがパッとわからなかった)

## 前提
- Amazon bedrockのサービスで利用するモデルのアクセス申請を行い、利用可能状態にしておく
　やりたかは[こちら](https://qiita.com/hamanuman/items/771ad6e3a205be1896f8)を参照
- 手元のPyhon/boto3を気軽にバージョンアップできないため、コンテナを作成して環境を作る
- コンテナにCoredntialファイルを渡すため、念の為新しいbedrock用のポリシーをもったCredentialを用意する

## Amazon Bedrock利用可能なPolicyの作成
- 2023/10/1 時点で、AWS Managedのいい感じのPolicyがなかったため、自身で作成する
- 今回利用するのはとりあえず、invokeだけなので、下記のみにする
- Recouceはモデル単位にすべきだと思うがARNが出てこない

``` policy.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "bedrock:InvokeModel"
            ],
            "Resource": "arn:aws:bedrock:us-east-1::foundation-model/anthropic.claude-v2"
        }
    ]
}
```
- よろしくないが、今回は新しくIAMユーザを作った
- みんなはちゃんとSwitchRoleしようね
- Amazon Bedrcokは東京リージョン未対応のため、有効化したリージョンをconfigに設定しておくこと
- 下記2ファイルを実行環境の`./awscofnig/` においておく
``` config .
[bedrock]
region=us-east-1
output=json
```
``` credentials .
[bedrock]
aws_access_key_id=########
aws_secret_access_key=#######
```

## Dockerでの環境構築

- Dcokerfielは[こちらの記事](https://qiita.com/m-oka-system/items/aa55fb21540711807bd3)をまるパクる
``` Dockerfile ## @m-oka-system様より引用 ## .
FROM python:3
USER root

RUN apt-get update && apt-get install -y --no-install-recommends \
    curl \
    unzip \
    jq \
    less \
    vim \
    && apt-get clean \
    && rm -rf /var/lib/apt/lists/*

RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN unzip awscliv2.zip
RUN ./aws/install

RUN pip install --upgrade pip
RUN pip install --upgrade setuptools
RUN pip install boto3
```

- ただし、credentialについては、新しくファイルを作ってコピーするためcompose.yamlは下記
``` compose.yaml
version: '3'
services:
  boto3_for_bedrock:
    build: .
    container_name: 'boto3_for_bedrock'
    working_dir: '/root/'
    tty: true
    volumes:
      - ./:/root
      - ./awsconfig/:/root/.aws/
```
- 以下２コマンドを実行
```
% docker compose up -d 
% docker compose exec boto3_for_bedrock bash
```
- コンテナに入って、boto3のバージョンを確認
```
root@7ba385cff42b:~# pip list | grep boto
boto3           1.28.57
botocore        1.31.57
```

- 下記ドキュメントを参考に対話用のpythonファイルを作成する
https://docs.aws.amazon.com/bedrock/latest/userguide/api-methods-run-inference.html
- 今回はパラメータで問いかけを渡すことにする

``` invoke_claude2.py
import boto3
import json
import sys

prompt = sys.argv[1] if len(sys.argv) > 0 else 'hello!!'　# 引数でpromptを渡す

session = boto3.Session(profile_name='bedrock', region_name="us-east-1") # reagion,profileを設定
bedrock = session.client(service_name='bedrock-runtime')

body = json.dumps({
    'prompt': '\n\nHuman:{0}\n\nAssistant:'.format(prompt),
    'max_tokens_to_sample': 500,
    'temperature': 0.1,
    'top_p': 0.9
})
                   
modelId = 'anthropic.claude-v2'
accept = 'application/json'
contentType = 'application/json'

response = bedrock.invoke_model(body=body, modelId=modelId, accept=accept, contentType=contentType)

response_body = json.loads(response.get('body').read())
print(response_body.get('completion'))
```

# 実行結果
```
root@7ba385cff42b:~# python invoke_claude2.py hello
 Hello! My name is Claude.
root@7ba385cff42b:~# python invoke_claude2.py "こんにちは！日本語は分かりますか？"
 はい、少しだけ日本語が分かります。まだ勉強中ですが、できる限り日本語で対応させていただきます。ご質問などあればお気軽に日本語でお聞きください。できる範囲で回答させていただきます!
root@7ba385cff42b:~# python invoke_claude2.py '你好，你会说话吗'
 是的,我会说话。我是 Claude,一个由 Anthropic 公司开发的 AI 助手。很高兴认识你。
```

引数でパラメタだけ渡して会話できる。便利
ターミナルに常駐させとこう