4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Amazon Bedrockを使ったAPIを作ってみた件

Last updated at Posted at 2024-12-08

記事を書こうと思ったきっかけ

勉強会のネタとしてBedrockを使ったAPIを作ることを実施しようと考えている。実施するために事前にやってみようと思った次第。

システムの全体像

image.png

かなりシンプルな構成。1時間半いかないくらいでのボリュームで勉強会を実施したいので、なるべくシンプルに。

準備

今回はBedrockが東京リージョンでしか使えないので、API GatewayやLambdaも東京リージョンに作成。
Bedrockのモデルは「Claude 3.5 Sonnet v1」を利用

Lambdaの設定

「Lambda」>「関数の作成」を選択。
Pythonを指定し、IAMロールは名前を付けて新規作成。
まずは、基本設定などを編集。おそらくタイムアウトは3秒だと短いので30秒に設定。また、作成したIAMロールにBedrockを利用するためのIAMポリシー(AmazonBedrockFullAccess)を付与。

一旦動作確認のために以下のページを参考にコードを作成し、適当なプロンプトに対して正しく応答が得られるかを試してみた。

import json
import boto3

bedrock_runtime = boto3.client('bedrock-runtime')
model_id = 'anthropic.claude-3-5-sonnet-20240620-v1:0'

request_body = json.dumps({
    "anthropic_version": "bedrock-2023-05-31",
    "max_tokens": 1000,
    "messages":[
        {
            "role":"user",
            "content":"Amazon Bedrockについて日本語で教えて。"
        }
    ]
})

def lambda_handler(event, context):
    # TODO implement

    response = bedrock_runtime.invoke_model(
        body = request_body,
        modelId = model_id,
        contentType = 'application/json'
    )

    parsed_response = json.loads(response.get('body').read())
    output_text = parsed_response['content'][0]['text']
    return {
        'statusCode': 200,
        'body': output_text
    }

以下のようなリターンが返ってきた。いけてそう。

Response:
{
  "statusCode": 200,
  "body": "Amazon Bedrockは、AWSが提供する完全マネージド型のサービスで、大規模言語モデル(LLM)や生成AI用のAPIを簡単に利用できるプラットフォームです。以下にBedrockの主な特徴を挙げます:\n\n1. 多様なAIモデル:\n   Anthropic、AI21 Labs、Stability AI、Amazon等の様々なプロバイダーのAIモデルにアクセスできます。\n\n2. サーバーレス:\n   インフラストラクチャの管理が不要で、使用した分だけ料金を支払う方式です。\n\n3. プライバシーとセキュリティ:\n   データはAWS内で暗号化され、プライベートエンドポイントの使用も可能です。\n\n4. カスタマイズ機能:\n   ファインチューニングやプロンプトエンジニアリングにより、モデルをカスタマイズできます。\n\n5. 統合性:\n   他のAWSサービスとシームレスに統合できます。\n\n6. スケーラビリティ:\n   需要に応じて自動的にスケールします。\n\n7. コスト効率:\n   必要な時に必要なだけリソースを使用できます。\n\nBedrockを使用することで、企業は複雑なAI技術を簡単に自社のアプリケーションやサービスに組み込むことができます。これにより、チャットボット、コンテンツ生成、データ分析など、様々な用途にAIを活用することが可能になります。"
}

Bedrockでモデルを呼び出し実行したい場合はboto3.clientにはbedrock-runtimeを指定する必要がある。また、bedrock-runtimeでモデルを呼び出し実行したい場合、modelIdとモデルごとに決められたbodyを指定する必要がある。
今回ClaudeのMessages APIで必要なbodyにおいて、必須のパラメータは以下の通り。

{
    "anthropic_version": "bedrock-2023-05-31" //anthoropicのバージョン
    "max_tokens": 1000, //生成するトークンの最大数
    "messages":[ //プロンプトに入力するメッセージ
        {
            "role":"user", // 会話の順番の役割でuserもしくはassistantを指定
            "content":"Amazon Bedrockについて日本語で教えて。" // 会話内容。画像の指定も可能らしい。
        }
    ]
}

他にもオプションで回答のランダム性など指定可能。Anthoropic Claudeのバージョン2.1以降であれば、あらかじめsystemパラメータで特定の目標や役割をインプットできる。例えば「あなたは優秀な校閲者です」的な。

次にAPI Gatewayから受け取ったデータをBedrockに投げる形に変更。
systemパラメータで事前に役割を指定し、クエリパラメータで受け取った単語に対して応答を返すような形にしてみる。

import json
import boto3
import logging

logger = logging.getLogger()
logger.setLevel("INFO")

bedrock_runtime = boto3.client('bedrock-runtime')
model_id = 'anthropic.claude-3-5-sonnet-20240620-v1:0'

def lambda_handler(event, context):
    # TODO implement

    logger.info(event)

    input_text = event['queryStringParameters']['input_text']

    request_body = json.dumps({
    "anthropic_version": "bedrock-2023-05-31",
    "max_tokens": 100,
    "messages":[
        {
            "role":"user",
            "content":input_text
        }
    ],
    "system":"あなたは有名でとても面白い芸人です。以下の単語に基づいてギャグを生成し、ギャグのみを出力してください。"
})

    response = bedrock_runtime.invoke_model(
        body = request_body,
        modelId = model_id,
        contentType = 'application/json'
    )

    parsed_response = json.loads(response.get('body').read())
    output_text = parsed_response['content'][0]['text']
    return {
        'statusCode': 200,
        'body': json.dumps({
            'output_text': output_text
        }, ensure_ascii=False),
        'isBase64Encoded':False,
        'headers':{}
    }

API Gatewayの設定

AWSコンソールより「API Gateway」>「API」>「APIを作成」をクリックし、「REST API」で構築を選択。

image.png

API名は適当につけてAPIエンドポイントタイプは「リージョン」を選択。これでリソースが作成されるので、「メソッドを作成」をクリックし、メソッドの作成を進める。
メソッドタイプをPOSTとしLambda関数との統合を設定。Lambdaプロキシ統合もONにした。そして、作成したLambdaを指定し、URLクエリ文字列パラメータでAPI呼び出し時に必要な情報を設定した。

image.png
image.png

いざテスト・・・!

Postmanを使ってAPIを実行してみる。
image.png

「飴があめぇ」くらいな感じで返すのかと思いきや、意外と一捻りしてきた回答。。。

今回詰まったところ

Boto3のBedrockの使い方

Boto3にはBedrock ClientとBedrockRuntime Clientがあり、最初はBedrock Clientの方を参考にしていた。このBedrock ClientはFine-tuningなどモデルを調整したり評価したりするために使われる様子。

json.dumpsの扱い

ensure_ascii=Falseを指定しておらず、文字化けしてしまっていた。デフォルトがTrueであるため、ASCII文字を含む場合は自動的にエスケープしないようにFalseの設定が必要とのこと。

解決していない部分

連続でリクエストすると、Internal server errorが返ってくる。
ログを見てみると「ThrottlingException」というのが出ている。何度もリクエスト送っているため制限がかかっている模様。これの対処については追々考えようと思う。

まとめ

とりあえず勉強会用の簡単な構成は作れたので、これをもとに資料を作っていこうと思う。
逆に短すぎるような気もしてきた。。。
image.png

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?