日別アーカイブ: 2026年2月3日

【AWS SAM×Bedrock】社内用セキュア生成AIチャットAPIの構築

はじめに

業務で生成AI(Amazon Bedrock)を活用したいけれど、「APIキーを直接開発者に配りたくない」「利用状況をログに残して管理したい」「特定のモデルだけを使わせたい」といった悩みはありませんか?
Bedrockを直接クライアントから叩くのではなく、API GatewayとLambdaを経由させる「プロキシAPI」を構築することで、これらのガバナンスやセキュリティの課題を解決できます。

今回は、AWS SAM (Serverless Application Model) を使って、この構成を最速・最小構成で構築する方法を紹介します。

以前の記事「AWS SAMを使って最もシンプルにLambda × APIGatewayのWebAPIを構築する」の応用編になりますので、SAMの基礎を知りたい方はそちらも合わせてご覧ください。

アーキテクチャ構成

作るものは非常にシンプルです。

User/App -> API Gateway -> Lambda -> Amazon Bedrock (Claude 3)

  • API Gateway: エンドポイントの公開、認証(将来的な拡張)
  • Lambda: リクエストの整形、Bedrockへのアクセス、ログ出力
  • Bedrock: 生成AIモデル (今回は Claude 3 Sonnet を使用)

IAMロールの権限管理により、LambdaだけがBedrockにアクセスできるようにするため、非常にセキュアです。

事前準備

  • AWS CLI と SAM CLI がインストールされていること
  • Amazon Bedrock のコンソールで、Claude 3 Sonnet のモデルアクセス許可が有効になっていること(これ重要です!有効化していないとエラーになります)

参考書籍

本記事の執筆にあたり、またはBedrock/SAMを深く学ぶために、2026年時点で最新の以下の書籍がおすすめです。特に『深掘りガイド』シリーズは実務で非常に役立ちます。

  • Amazon Bedrock 生成AIアプリ開発入門 [AWS深掘りガイド]
    • Bedrockの基本からRAG、エージェントまで網羅された決定版。
  • AIエージェント開発/運用入門 [生成AI深掘りガイド]
    • LangGraphやBedrockを使った自律型エージェントの開発・運用(LLMOps)に特化した一冊。2025年の「AIエージェント元年」を象徴する良書。
  • TECHNICAL MASTER はじめてのAWSモダンアプリ開発入門
    • AWS Amplify Gen2とBedrockを組み合わせた最先端のモダンアプリ開発手法が学べます。

ディレクトリ構成

今回は既存のテンプレートを使わず、ゼロから作ります。最終的に以下の構成になります。

bedrock-sam-chat
│  template.yaml
└─hello_world
      app.py

実装ステップ

1. SAMテンプレート (template.yaml)

まずはインフラ定義です。
たったこれだけの記述で、API Gateway、Lambda関数、IAMロール(Bedrockへのフルアクセス権限付き)が作成されます。

AWSTemplateFormatVersion: '2010-09-09'
Transform: AWS::Serverless-2016-10-31
Description: >
  Secure GenAI Chat API with Bedrock & SAM

Resources:
  ChatFunction:
    Type: AWS::Serverless::Function
    Properties:
      CodeUri: hello_world/
      Handler: app.lambda_handler
      Runtime: python3.9
      Architectures:
        - x86_64
      Timeout: 120 # 生成AIはレスポンスに時間がかかる場合があるため長めに設定
      Policies:
        - AmazonBedrockFullAccess # 最小権限にする場合は絞ってください
      Events:
        ChatApi:
          Type: Api
          Properties:
            Path: /chat
            Method: post

Outputs:
  ChatApi:
    Description: "API Gateway endpoint URL for Prod stage for Chat function"
    Value: !Sub "https://${ServerlessRestApi}.execute-api.${AWS::Region}.amazonaws.com/Prod/chat/"

ポイント:

  • Timeout: 120: デフォルトの3秒だと、生成AIの回答待ちでタイムアウトする可能性が高いため、長めに設定しています。
  • Policies: - AmazonBedrockFullAccess: LambdaにBedrockへのアクセス権限を付与しています。

2. Lambdaコード (hello_world/app.py)

次にアプリケーションロジックです。Pythonの boto3 を使ってBedrockを呼び出します。

import json
import boto3
import os

# クライアントの初期化はハンドラの外で行う(再利用のため)
bedrock = boto3.client('bedrock-runtime')

def lambda_handler(event, context):
    try:
        # リクエストボディからプロンプトを取得
        body = json.loads(event.get('body', '{}'))
        prompt = body.get('prompt', 'Hello')

        # 使用するモデルID (Claude 3 Sonnet)
        model_id = "anthropic.claude-3-sonnet-20240229-v1:0"

        # Bedrockへのリクエストペイロード作成
        # Claude 3向けのフォーマット (Messages API)
        request_body = json.dumps({
            "anthropic_version": "bedrock-2023-05-31",
            "max_tokens": 1000,
            "messages": [
                {
                    "role": "user",
                    "content": [{"type": "text", "text": prompt}]
                }
            ]
        })

        # Bedrock呼び出し
        response = bedrock.invoke_model(
            modelId=model_id,
            body=request_body
        )

        # レスポンスの解析
        response_body = json.loads(response.get('body').read())
        content = response_body.get('content')[0].get('text')

        return {
            "statusCode": 200,
            "body": json.dumps({
                "message": content
            }),
            "headers": {
                "Content-Type": "application/json"
            }
        }
    except Exception as e:
        print(f"Error: {str(e)}")
        return {
            "statusCode": 500,
            "body": json.dumps({
                "error": str(e)
            })
        }

デプロイと動作確認

デプロイ

プロジェクトのルートディレクトリで以下のコマンドを実行します。

sam build
sam deploy --guided

対話形式でスタック名などを聞かれますが、基本はデフォルト(Enter連打)でOKです。
デプロイが完了すると、Outputs セクションにAPIのURLが表示されます。

動作確認

curl コマンドでAPIを叩いてみましょう。

curl -X POST https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/chat/ \
     -H "Content-Type: application/json" \
     -d '{"prompt": "AWS SAMについて3行で教えて"}'

実行結果(例)

{"message": "AWS SAMは、サーバーレスアプリケーション構築のためのオープンソースフレームワークです。\nCloudFormationを拡張したシンプルな構文でリソースを定義できます。\nLambda、API Gateway、DynamoDBなどを簡単にデプロイ・管理できます。"}

無事、Claude 3からの回答が返ってくれば成功です!

さらなる拡張アイデア

この構成をベースに、以下のような機能を付け足していくと、立派な社内AIプラットフォームになります。

  1. VPCエンドポイント (PrivateLink): 以前の記事「AWS BedrockでVPCエンドポイント...」と組み合わせることで、社内ネットワークから閉域網でアクセス可能にできます。
  2. ログ保存: Lambda内でプロンプトと回答をDynamoDBやS3に保存すれば、誰がどんな使い方をしているか監査できます。
  3. ストリーミングレスポンス: 今回は簡易化のため待ち受け型(一括返信)にしましたが、LambdaのResponse Streamingを使えば、ChatGPTのように文字が少しずつ表示されるUIも実現可能です。

まとめ

AWS SAMを使えば、Bedrockを利用したチャットAPIがあっという間に構築できます。
まずはこの最小構成から始めて、プロジェクトの要件に合わせて育てていってみてください。
Happy Serverless Life!