Amazon BedrockをAWS Lambda上で呼び出してみた（API化）

# はじめに
こんにちは、はやぴー（@HayaP）です。

[前回の記事](https://qiita.com/HayaP/items/3395a0d6e1007448fca8)ではPythonスクリプトからAmazon Bedrockを利用してみましたが、今回はAWS LambdaからAmazon Bedrockを動かしてみたいと思います。

# 前提
前提として、Amazon BedrockでJurassic-2 Midが使用可能になっていることが必要です。
実施手順は、過去の記事[Amazon BedrockをPythonスクリプトから利用してみた
](https://qiita.com/HayaP/items/3395a0d6e1007448fca8)にありますので、ご参照ください。

# TL;DR (忙しい人用)
- Amazon BedrockのJurassic-2 MidモデルをAWS Lambdaから利用する手順を解説。
- Lambda関数はPython 3.11ランタイムとarm64アーキテクチャで作成。
- IAMロールを作成し、LambdaにアタッチしてBedrockへのアクセス権限を設定。
- 2023/10/14現在、Python3.11デフォルトのBoto3バージョンは古いため、新しいバージョンをLambda Layerにアップロード。
- Bedrock APIを呼び出し、指定したプロンプトに基づくモデルの応答を取得。

## 構成図
構成図は下記です。
非常にシンプルです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/5ba540ba-0553-5f85-b5d4-2fdbfd6b9c9f.png)

# 詳細
## Lambdaの作成
- 関数名
    - amazon-bedrock-test
- ランタイム
    - Python 3.11
- アーキテクチャ
    - arm64
- 実行ロール
    - 基本的な Lambda アクセス権限で新しいロールを作成

以下のパラメーターを指定してLambda関数を作成します。
あくまで一例なので、状況に応じて変更してください。
![Screenshot 2023-10-14 160436.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/b8b87091-a21a-8dab-288a-67f4172fe275.png)

## Boto3のダウンロード
Boto3は、Amazon Web Services (AWS)をPythonプログラムから利用するための公式SDK（Software Development Kit）です。Boto3を使用することで、PythonコードからAWSの各種サービスにアクセスし、操作することが可能になります。
[AWS SDK for Python (Boto3)](https://aws.amazon.com/jp/sdk-for-python/)

注意として、Boto3を介して、Bedrockを操作する場合
バージョンが1.28.63以上である必要があります。

[Boto3#Bedrock](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/bedrock.html)

:::note warn
2023/10/14現在、LambdaのランタイムとしてPython3.11を選択した場合、デフォルトでLambdaにラップされているBoto3は1.27.1であるため、最新の資源をLambdaのアップロードする必要があります。
:::

コマンド例（Linux）:
```bash
# ディレクトリの作成
$ mkdir -p bedrock_demo/python
# boto3のインストール
$ pip install -t bedrock_demo/python boto3
# bedrock_demoディレクトリに移動
$ cd bedrock_demo
# ZIPファイルの作成
$ zip -r boto3-1.28.57.zip python
```

コマンド例（Windows PowerShell）:
```powershell
# ディレクトリの作成
New-Item -ItemType Directory -Path bedrock_demo\python
# boto3のインストール
pip install -t bedrock_demo\python boto3
# bedrock_demoディレクトリに移動
cd bedrock_demo
# ZIPファイルの作成
Compress-Archive -Path python\* -DestinationPath boto3-1.28.57.zip
```

## Lambda Layerの作成
最新のBoto3資源を、Lambdaが利用できる状態にしたいです。
直でアップロードすることも可能ですが、Lambda Layerの使用が一般的です。
Lambda Layerの詳細は、下記をご覧ください。
[Lambda レイヤーでの作業](https://docs.aws.amazon.com/ja_jp/lambda/latest/dg/chapter-layers.html)

- 名前
    - boto3_12863
- .zipファイルをアップロード
- ファイル選択
    - 先ほど圧縮した、boto3-1.28.57.zipを選択してください
- 互換性のあるアーキテクチャ
    - arm64(Lambda作成時に指定したアーキテクチャを設定)
- ランタイム
    - Python3.11(Lambda作成時に指定したランタイムを設定)
![Screenshot 2023-10-14 171203.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/a8d62c31-203c-3884-a84d-832070524141.png)


## IAMロールの作成
次に、IAMロールを新規作成します。
現状、Amazon Bedrockにアクセスする権限を保持していないからです。

1. Lambdaコンソールの、アクセス権限メニューを選択します
1. ロール名を押下します
![Screenshot 2023-10-14 170607.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/9bb3d24e-18b3-66bb-c730-d3cbd62c0322.png)

3. インラインポリシーを押下します
![Screenshot 2023-10-14 170709.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/72ddedcf-d4e9-654d-b9d3-f3b4ee49d1d5.png)

5. JSONを選択し、下記を記述します。
```json
{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": "bedrock:*",
      "Resource": "*"
    }
  ]
}
```

![Screenshot 2023-10-14 170754.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/664e8b58-c523-f5ea-91af-d6691cf03402.png)

5.ポリシー名を入力（例は、bedrock_demo）し、作成を押下します。
 
 ![Screenshot 2023-10-14 170814.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/4ed986fa-8796-fdeb-7edc-c53339bf7d27.png)

無事、作成できました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/272038d7-1c52-7530-b194-cf1c0b3a5994.png)


## Pythonコードの記述
Lambda関数のコードは以下のように記述します。
基本的には、[前回の記事](https://qiita.com/HayaP/items/3395a0d6e1007448fca8)と同じなため
説明は省略します。

```python
import boto3
import json

bedrock_runtime = boto3.client('bedrock-runtime')

def lambda_handler(event, context):
    # プロンプトに設定する内容を取得
    prompt = event.get('prompt')

    # 各種パラメーターの指定
    modelId = 'ai21.j2-mid-v1' 
    accept = 'application/json'
    contentType = 'application/json'

    # リクエストBODYの指定
    body = json.dumps({
        "prompt": prompt,
        "maxTokens": 100,
        "temperature": 0.7,
        "topP": 1,
    })

    # Bedrock APIの呼び出し
    response = bedrock_runtime.invoke_model(
    	modelId=modelId,
    	accept=accept,
    	contentType=contentType,
        body=body
    )

    # APIレスポンスからBODYを取り出す
    response_body = json.loads(response.get('body').read())

    # レスポンスBODYから応答テキストを取り出す
    outputText = response_body.get('completions')[0].get('data').get('text')

    print(outputText)
```

## テスト
では、実行してみましょう。
1. Lambdaコンソールから、Testを押下します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/baebe50e-21b2-e811-b497-25cd30a9fdbc.png)

2. イベント名を入力（今回は、demoとします）し、その他はデフォルトのまま保存を押下します。 
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/d7f10fd2-2c92-6b4e-67f9-665f85f80de8.png)

イベントJsonを下記に書き換えてください。
そしたら、保存を押下し実行します。
```json
{
  "prompt": "what is aws"
}
```

成功しました。
```text
AWS stands for Amazon Web Services. It is a collection of cloud computing services provided by Amazon, which includes various tools for building, deploying, and managing applications and services in the cloud. AWS offers over 200 different services, including compute power, database storage, networking, analytics, machine learning, and artificial intelligence, which can be used by developers, businesses, and governments to build and deploy a wide range of applications and services. Some of the most popular AWS services include Amazon S3 (object storage), Amazon EC2 (virtual servers), Amazon RDS (relational database service), and Amazon DynamoDB (non-relational database service
```
と返ってきましたね。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/478323/7255f93a-f4f7-e5bc-3f6b-204c6f80e0ab.png)

# おわりに
今回はAWS LambdaからAmazon Bedrockを利用してみました。

Lambdaはスケーラブルで管理が簡単なので、実際のプロダクション環境でも利用しやすいでしょう。また、最新のBoto3を利用することで、Amazon Bedrockを簡単に操作することができます。
是非、皆さんもLambdaを使ってAmazon Bedrockを試してみてください。