インターネットアクセス禁止環境下で Amazon Bedrock APIを実行

# はじめに

MEGAZONE 株式会社 のテック陣「MEGAZONEのゆかいな仲間たち」がおくる、Megazone Japan Advent Calendar 2023 の18日目のエントリーです。

阿河です。
お客様からAmazon Bedrock気になるとのお声を頂くようになりました。インターネットアクセス禁止環境でセキュアに実行する方法を検証したのでその記録です。

# 1. 指針

- Bedrock APIを呼び出す主体は、インターネットアクセス不可の環境に置く。今回はインターネットアクセス不可にしたSageMakerノートブックインスタンス(バージニア北部リージョンのプライベートサブネットに紐づけ)を使いました。
- Bedrock用のVPC エンドポイントを使用。
- 必要なデータがあれば、S3に置く。
- 細かい制御できるのかしら。。

# 2. 検証


https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/api-setup.html

実装というのはおこがましいですが、上記ドキュメントのセットアップ方法を参考にしながら、必要に応じて修正を加えていきます。

### モデルアクセスを有効化

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2697264/9f3daecc-856e-107b-d46a-49b5de0a5a12.png)

https://docs.aws.amazon.com/ja_jp/bedrock/latest/userguide/model-access.html

まずモデルを使用する前にそのモデルへのアクセスをリクエストします。
今回はClaude v2を使います。

### SageMakerノートブックインスタンスの準備

バージニア北部リージョンに、下記の設定を持つノートブックインスタンスを作成してください。

- プライベートサブネットに紐づける。NAT Gatewayは利用しない。
- Direct internet access: Disabled
- ロールはドキュメントに記載の権限範囲で設定します。

### VPCエンドポイント

- com.amazonaws.us-east-1.s3
- aws.sagemaker.us-east-1.notebook
- com.amazonaws.us-east-1.sagemaker.api
- com.amazonaws.us-east-1.bedrock
- com.amazonaws.us-east-1.bedrock-runtime

上記を有効化。

### Jupyerでのコード実装

ドキュメント通り、サンプルコードを使います。

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

```
指定された Amazon Bedrock モデルを起動し、リクエストボディで提供された入力を使って推論を実行します。
テキストモデル、画像モデル、埋め込みモデルの推論を実行するには InvokeModel を使用します。

ヘッダーに指定する modelId は、使用するモデルの種類によって異なります。
ベースモデルを使用する場合は、モデルIDまたはそのARNを指定します。

Provisionedモデルを使用する場合は、ProvisionedModelName、またはProvisioned Throughputの作成時に返されたprovisionedModelArnを指定します。

カスタムモデルを使用する場合は、まずそのモデルの Provisioned Throughput を購入します（詳細については、『Amazon Bedrock ユーザーガイド』の Provisioned Throughput を参照してください）。次に、ProvisionedModelNameまたはProvisionedModelArnを指定します。

リクエスト・ボディの中で、レスポンスに影響を与えるプロンプト・パラメータと推論パラメータを指定します。
```

「Invoke Model」APIの説明は上記の通りです。


```
import boto3
import json
bedrock = boto3.client(service_name='bedrock-runtime')

body = json.dumps({
    "prompt": "\n\nHuman:Please explain AWS in a way that even kindergarteners can understand\n\nAssistant:",
    "max_tokens_to_sample": 300,
    "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())
# text
print(response_body.get('completion'))
```

prompt部分は、質問変更しました。

### 実行結果

```
Here is an explanation of AWS for kindergarteners:

AWS is like a really big playground with lots of fun things to play with! There are swings, slides, sandboxes, and jungle gyms. Each thing you want to play with is called a "service."

If you want to go down the slide, you use the "EC2" slide service. If you want to swing, you use the "S3" swing service. There are services for all kinds of fun activities! 

The playground monitor is called AWS. AWS makes sure all the equipment is safe and lets you know how long you can play with each thing. AWS gives you a bracelet that tracks how much time you spend playing. 

At the end of recess, AWS tells your teacher how long you played on everything so your parents know how much to pay for the playground. The more things you play with, the more money it costs. But AWS lets you play with lots of fun stuff!

So AWS is like the biggest, funnest playground ever that lets you play with super cool toys and keeps everything working nicely! The end.

--------------------------------------------------------------------------------------

幼稚園児のためのAWSの説明です：

AWSは、楽しい遊び道具がたくさんある、本当に大きな遊び場のようなものです！ブランコ、滑り台、砂場、ジャングルジム。遊びたいものはそれぞれ「サービス」と呼ばれる。

滑り台を滑りたければ、「EC2」という滑り台のサービスを使う。ブランコなら「S3」。あらゆる種類の楽しいアクティビティのためのサービスがある！

遊び場の監視員はAWSと呼ばれる。AWSはすべての遊具の安全性を確認し、それぞれの遊具で遊べる時間を知らせてくれる。AWSは、遊んだ時間を記録するブレスレットをくれる。

休み時間が終わると、AWSは、遊具で遊んだ時間を先生に報告します。遊んだものが多ければ多いほど、それだけお金がかかる。でもAWSは、楽しいものでたくさん遊ばせてくれる！

だからAWSは、超クールなおもちゃで遊べて、すべてがうまく機能し続ける、これまでで一番大きくて楽しい遊び場のようなものなのだ！終わり。
```

AWSを幼稚園児でも分かるように説明すると、上記の通り。


### ついでに

InvokeModel APIって、IAMの条件キーで制限できるのかしら。

https://docs.aws.amazon.com/ja_jp/service-authorization/latest/reference/list_amazonbedrock.html

この記事を書いている2023/12/15時点のlatest版では、条件キーなどの制限はできないようですね。(VPC Configで厳密に制御など出来るのかなと思って調べました)

リソースタイプで、foundation-modelの制御などは出来るようです。


# さいごに

簡易的な誰かの参考になれば幸いです。

御覧いただき ありがとうございました。