1
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?

AWS 生成AI サービス:Azure OpenAI / AI Foundry ユーザーが陥る罠と趣味開発での問題切り分けメモ

Posted at

はじめに:Azure OpenAI から Bedrock へ、想定外の「選択の自由」

個人の趣味開発で Azure から AWS に移行することになり、Azure OpenAI Service と AI Foundry で動いていた生成AI アプリケーションを AWS に移植することになりました。「OpenAI の GPT モデルなら同じ」「REST API でラップすれば移植性が高い」という楽観的な見立てで始めた結果、本番環境で次々と予期しない問題が発生。Azure の「統合プラットフォーム」と AWS の「柔軟なサービス選択」の根本的な違いを痛感しました。

最初のローカル環境でのテストは順調でした。Bedrock の Claude でも推論リクエストは返ってくるし、PartyRock でノーコードアプリも作れます。

# これは普通に動く
import boto3
import json

bedrock = boto3.client('bedrock-runtime', region_name='us-east-1')

response = bedrock.invoke_model(
    modelId='anthropic.claude-v2',
    body=json.dumps({
        "prompt": "\n\nHuman: Hello\n\nAssistant:",
        "max_tokens_to_sample": 300
    })
)
print(json.loads(response['body'].read()))

しかし実際に障害対応訓練で複雑な RAG パイプラインや高負荷のトラブルシューティングを始めた途端、問題が続出しました。

問題1:Bedrock と SageMaker と PartyRock のどれを選ぶべきか分からない

Azure では「Azure OpenAI Service(統合 API)」か「AI Foundry(開発環境)」の 2 択でシンプルでしたが、AWS は Bedrock(マネージド推論)、SageMaker(カスタムモデル)、PartyRock(ノーコード)と選択肢が多すぎて、初期設計で迷走しました。

問題2:Bedrock のモデル ID が「プロバイダー名.モデル名」形式で Azure と異なる

Azure OpenAI では gpt-4 とデプロイ名だけ指定すれば良かったのに、Bedrock は anthropic.claude-v2amazon.titan-text-express-v1 といったプロバイダー名込みの ID で、モデル切り替え時にコード変更が必要でした。

問題3:Bedrock のスロットリングが「モデルごと」で細かい制御が必要

Azure OpenAI では TPM(Tokens Per Minute)をデプロイ単位で設定できたのに、Bedrock はモデルごとにクォータがあり、複数モデルを使う場合の制御が複雑で、予期せぬスロットリングが発生しました。

問題4:PartyRock のログが「どこにあるか分からない」

AI Foundry では Azure Monitor に統合されているのに、PartyRock は「アプリ内の Activity タブ」と「CloudWatch Logs」の両方を確認する必要があり、障害時にログを探すのに 15 分かかりました。

問題5:Bedrock の Knowledge Base(RAG)が「Kendra や OpenSearch と別設定」

Azure OpenAI の「自分のデータで拡張」では Azure Cognitive Search との統合が自動だったのに、Bedrock Knowledge Base は S3 + ベクトルDB(OpenSearch/Kendra/Pinecone)を手動で連携する必要があり、初回構築で 2 時間かかりました。

問題6:Bedrock のモデル応答形式が「プロバイダーごとに異なる」

Azure OpenAI では統一された OpenAI API 形式だったのに、Bedrock は Claude(Anthropic)と Titan(Amazon)でリクエスト/レスポンスの JSON 構造が違い、マルチモデル対応のコードが複雑化しました。

これら全ての問題と向き合う中で、AWS の生成AI サービスは「柔軟だが、明示的な設定と理解が必要」という設計思想だと理解しました(気がします)。


Azure OpenAI / AI Foundry との設計の違い:統合 vs 選択の自由

Azure OpenAI Service / AI Foundry と AWS 生成AI サービスは、どちらも「生成AI の推論基盤」ですが、アーキテクチャと統合度が大きく異なります。

項目 Azure (OpenAI / AI Foundry) AWS (Bedrock / PartyRock / SageMaker) 影響(実経験)
選択肢の数 2 つ(OpenAI / AI Foundry) 3 つ以上(Bedrock / PartyRock / SageMaker) AWS は「どれを選ぶか」の判断が必要
モデル ID デプロイ名(gpt-4 など) プロバイダー名.モデル名(anthropic.claude-v2) モデル切り替え時にコード変更が必要
API 形式 統一(OpenAI API 互換) プロバイダーごとに異なる(Claude/Titan/Jurassic) マルチモデル対応が複雑
スロットリング制御 TPM(Tokens Per Minute)をデプロイ単位で設定 モデルごとにクォータ(Service Quotas で管理) 複数モデル使用時の制御が複雑
RAG 統合 Azure Cognitive Search との自動統合 S3 + ベクトルDB(OpenSearch/Kendra)を手動連携 初回構築に時間がかかる
ログ統合 Azure Monitor 標準統合 CloudWatch Logs(手動設定) PartyRock はアプリ内 Activity + CloudWatch の両方を確認
ノーコード開発 AI Foundry(統合開発環境) PartyRock(独立アプリビルダー) PartyRock は Bedrock と独立した UI
プロンプト管理 Prompt Flow(バージョン管理) 手動管理(または Parameter Store) プロンプトの履歴管理が手動
料金 トークン課金 + デプロイ時間課金 トークン課金のみ(オンデマンド) Bedrock はデプロイ維持コストなし

この表を見ると、Azure は「統合された開発体験」、AWS は「柔軟だが個別設定が必要」です。障害切り分けでは「どのサービスのどの設定が問題か」を理解する必要があります。


実際の障害シナリオ:Azure ユーザーがハマるポイント

シナリオA:Bedrock のスロットリングでリクエストが失敗する

背景

  • Bedrock で Claude を使った推論 API を本番デプロイ
  • Azure OpenAI では TPM 設定で問題なかったが、AWS では「429 Too Many Requests」が多発

問題検知

# アプリケーションログで 429 エラーを確認
aws logs tail /aws/lambda/genai-proxy --since 10m --filter-pattern "429"
# → "ThrottlingException: Rate exceeded for model anthropic.claude-v2"

# Azure OpenAI では TPM を 120K に設定していたが、Bedrock はどこで設定?

CloudWatch Metrics で確認

# Bedrock のスロットリングメトリクスを確認
aws cloudwatch get-metric-statistics \
  --namespace AWS/Bedrock \
  --metric-name ModelInvocationThrottles \
  --dimensions Name=ModelId,Value=anthropic.claude-v2 \
  --start-time $(Get-Date).ToUniversalTime().AddMinutes(-30).ToString("s") \
  --end-time $(Get-Date).ToUniversalTime().ToString("s") \
  --period 60 --statistics Sum
# → Sum: 45(30 分間で 45 回スロットリング)

# Invocations メトリクスを確認
aws cloudwatch get-metric-statistics \
  --namespace AWS/Bedrock \
  --metric-name Invocations \
  --dimensions Name=ModelId,Value=anthropic.claude-v2 \
  --period 60 --statistics Sum
# → Sum: 120(30 分間で 120 リクエスト = 4 リクエスト/分)

# 4 リクエスト/分でスロットリング?Azure では 120K TPM(約 2000 リクエスト/分)だったのに…

Service Quotas の確認

# Bedrock のクォータを確認
aws service-quotas list-service-quotas --service-code bedrock --query 'Quotas[?QuotaName==`Anthropic Claude V2 input tokens per minute`]'
# → {
#     "QuotaName": "Anthropic Claude V2 input tokens per minute",
#     "Value": 10000.0  ← 10K トークン/分(Azure の 120K TPM の 1/12!)
#   }

# 原因判明:
# - Azure OpenAI では「デプロイ作成時に TPM を指定」してスケーリング
# - Bedrock では「リージョン&モデルごとのデフォルトクォータ」があり、明示的に引き上げが必要

クォータ引き上げリクエスト

# Service Quotas でクォータ引き上げをリクエスト
aws service-quotas request-service-quota-increase \
  --service-code bedrock \
  --quota-code L-xxxxxxxx \
  --desired-value 100000
# → リクエスト ID: req-abc123(承認に 1~3 営業日かかる)

# 短期対応:リトライ+指数バックオフを実装

短期対処(コード修正)

# boto3 での指数バックオフ実装
import boto3
from botocore.config import Config
from botocore.exceptions import ClientError
import time

config = Config(
    retries={
        'max_attempts': 5,
        'mode': 'adaptive'  # 自動的に指数バックオフ
    }
)
bedrock = boto3.client('bedrock-runtime', config=config)

def invoke_with_retry(model_id, body, max_retries=3):
    for attempt in range(max_retries):
        try:
            response = bedrock.invoke_model(modelId=model_id, body=body)
            return response
        except ClientError as e:
            if e.response['Error']['Code'] == 'ThrottlingException':
                wait_time = (2 ** attempt) + (random.randint(0, 1000) / 1000)
                print(f"Throttled. Retrying in {wait_time}s...")
                time.sleep(wait_time)
            else:
                raise
    raise Exception("Max retries exceeded")

学び

  • Azure OpenAI では「デプロイ作成時に TPM を指定」してスケーリングするが、Bedrock は「リージョン&モデルごとのクォータ」を事前に引き上げる必要がある
  • Bedrock のクォータは Service Quotas で確認・変更(承認に時間がかかる)
  • 本番前に負荷テストでクォータを確認し、事前申請が必須

シナリオB:PartyRock のログが見つからない

背景

  • PartyRock でノーコード RAG アプリを構築
  • AI Foundry では Azure Monitor にログが統合されていたが、PartyRock では「どこにログがあるか分からない」

問題検知

# PartyRock アプリでエラーが発生しているが、ログが見つからない
# Azure AI Foundry では「Monitoring」タブでログが一元表示されていたのに…

# CloudWatch Logs で探してみる
aws logs describe-log-groups --log-group-name-prefix /aws/partyrock
# → []  ← Log Group が存在しない?

PartyRock コンソールで確認

# PartyRock アプリのコンソールを開く(ブラウザ)
# https://partyrock.aws/u/<user-id>/apps/<app-id>

# 「Activity」タブを開く
# → 最近の実行履歴が表示される
# → エラーが出ているセル:「Knowledge Base Search」が空返却

CloudWatch Logs の正しい場所

# PartyRock のログは /aws/partyrock ではなく、
# /aws/bedrock または /aws/lambda にある(アプリの構成による)

# Bedrock Knowledge Base のログを確認
aws logs describe-log-groups --log-group-name-prefix /aws/bedrock
# → /aws/bedrock/knowledge-bases/kb-abc123 が存在

# ログを確認
aws logs tail /aws/bedrock/knowledge-bases/kb-abc123 --since 10m
# → "S3 bucket not found: my-knowledge-base-bucket"  ← S3 バケットが見つからない!

S3 バケットの確認

# Knowledge Base で指定した S3 バケットを確認
aws s3 ls s3://my-knowledge-base-bucket/
# → "An error occurred (NoSuchBucket) when calling the ListObjectsV2 operation: The specified bucket does not exist"

# 原因判明:
# - PartyRock で Knowledge Base を作成時、S3 バケット名を手動入力したが、タイポしていた
# - Azure AI Foundry では Azure Cognitive Search が自動作成されるが、
#   PartyRock では S3 バケットを事前に作成して指定する必要がある

短期対処

# 正しい S3 バケットを作成
aws s3 mb s3://my-knowledge-base-bucket-correct

# ドキュメントをアップロード
aws s3 cp ./docs/ s3://my-knowledge-base-bucket-correct/ --recursive

# PartyRock の Knowledge Base 設定を更新(コンソールから手動)
# S3 URI: s3://my-knowledge-base-bucket-correct

検証

# PartyRock アプリで再度テスト
# 「Activity」タブで新しい実行を確認
# → Knowledge Base Search が結果を返すようになった

# CloudWatch Logs で確認
aws logs tail /aws/bedrock/knowledge-bases/kb-abc123 --since 5m
# → "Retrieved 5 documents from S3"  ← 正常に動作

学び

  • Azure AI Foundry では Azure Monitor にログが統合されているが、PartyRock は「アプリ内 Activity タブ」と「CloudWatch Logs」の両方を確認する必要がある
  • PartyRock のログは /aws/partyrock ではなく、/aws/bedrock/aws/lambda にある
  • Knowledge Base は S3 バケットを事前に作成して指定する必要がある(Azure Cognitive Search のような自動作成はない)

シナリオC:Bedrock の Knowledge Base(RAG)検索が遅い

背景

  • Bedrock Knowledge Base で RAG を構築
  • Azure OpenAI の「自分のデータで拡張」では数秒で返ってきたが、Bedrock では 20 秒以上かかる

問題検知

# Lambda でプロキシした RAG API のレスポンスタイムを確認
aws logs tail /aws/lambda/rag-proxy --since 10m | Select-String "Duration"
# → Duration: 23456.78 ms(23 秒!)

# Azure OpenAI + Cognitive Search では 2~5 秒だったのに…

X-Ray でトレース確認

# Lambda の X-Ray トレースを確認
aws xray get-trace-summaries \
  --start-time $(Get-Date).ToUniversalTime().AddMinutes(-15).ToString("s") \
  --end-time $(Get-Date).ToUniversalTime().ToString("s") \
  --filter-expression 'service("rag-proxy")'

# トレース詳細を取得
$traceId = "1-abc-def-ghi"
aws xray batch-get-traces --trace-ids $traceId
# → Lambda → Bedrock Knowledge Base: 18 秒
# → Bedrock Knowledge Base → OpenSearch: 17 秒  ← OpenSearch が遅い!

OpenSearch クラスターの確認

# OpenSearch のクラスター状態を確認
aws opensearch describe-domain --domain-name my-knowledge-base-domain
# → {
#     "DomainStatus": {
#       "ClusterConfig": {
#         "InstanceType": "t3.small.search",  ← 小さいインスタンス
#         "InstanceCount": 1
#       },
#       "SearchInstanceCount": 1
#     }
#   }

# Azure Cognitive Search では「Standard S1」($250/月)を使っていた
# AWS では「t3.small.search」($25/月)を選んでしまった

OpenSearch のメトリクスを確認

# SearchRate(検索リクエスト数)を確認
aws cloudwatch get-metric-statistics \
  --namespace AWS/ES \
  --metric-name SearchRate \
  --dimensions Name=DomainName,Value=my-knowledge-base-domain \
  --start-time $(Get-Date).ToUniversalTime().AddMinutes(-30).ToString("s") \
  --end-time $(Get-Date).ToUniversalTime().ToString("s") \
  --period 60 --statistics Average
# → Average: 5(5 検索/分)

# SearchLatency を確認
aws cloudwatch get-metric-statistics \
  --namespace AWS/ES \
  --metric-name SearchLatency \
  --dimensions Name=DomainName,Value=my-knowledge-base-domain \
  --period 60 --statistics Average,Maximum
# → Average: 15000ms, Maximum: 22000ms  ← 15~22 秒のレイテンシ!

短期対処(インスタンスタイプ変更)

# OpenSearch のインスタンスタイプを変更
aws opensearch update-domain-config \
  --domain-name my-knowledge-base-domain \
  --cluster-config InstanceType=r6g.large.search,InstanceCount=2
# → 変更には 15~30 分かかる

# 待機中に、検索クエリの最適化も検討

検証

# インスタンスタイプ変更後、再度テスト
aws logs tail /aws/lambda/rag-proxy --since 5m | Select-String "Duration"
# → Duration: 3456.78 ms(3.5 秒!)

# X-Ray で確認
# → Bedrock Knowledge Base → OpenSearch: 2 秒  ← 改善!

学び

  • Azure Cognitive Search は「Standard S1」がデフォルト推奨だが、OpenSearch は「t3.small」でも起動できてしまう
  • 本番環境では最低 r6g.large 以上を推奨(メモリ最適化インスタンス)
  • OpenSearch のメトリクス(SearchLatency, CPUUtilization)を事前に監視する必要がある

シナリオD:Bedrock のモデル応答形式が Claude と Titan で異なる

背景

  • マルチモデル対応のために Claude(Anthropic)と Titan(Amazon)を両方使う設計
  • Azure OpenAI では統一 API だったが、Bedrock ではレスポンス形式が違う

問題検知

# Claude で動いていたコード
response = bedrock.invoke_model(
    modelId='anthropic.claude-v2',
    body=json.dumps({
        "prompt": "\n\nHuman: Hello\n\nAssistant:",
        "max_tokens_to_sample": 300
    })
)
result = json.loads(response['body'].read())
print(result['completion'])  # → 正常に動作

# Titan に切り替えると…
response = bedrock.invoke_model(
    modelId='amazon.titan-text-express-v1',
    body=json.dumps({
        "prompt": "\n\nHuman: Hello\n\nAssistant:",
        "max_tokens_to_sample": 300
    })
)
result = json.loads(response['body'].read())
print(result['completion'])  # → KeyError: 'completion'  ← エラー!

レスポンス構造の確認

# Claude のレスポンス
# {
#   "completion": " Hello! How can I assist you today?",
#   "stop_reason": "stop_sequence"
# }

# Titan のレスポンス
# {
#   "results": [
#     {
#       "outputText": "Hello! How can I assist you today?",
#       "completionReason": "FINISH"
#     }
#   ]
# }

# 原因判明:
# - Claude: `completion` フィールド
# - Titan: `results[0].outputText` フィールド
# - Azure OpenAI では統一された `choices[0].text` だったのに…

抽象化レイヤーの実装

def invoke_bedrock_model(model_id, prompt, max_tokens=300):
    """Bedrock モデルの差異を吸収する抽象化レイヤー"""
    
    # リクエストボディの構築(モデルごとに異なる)
    if 'anthropic.claude' in model_id:
        body = {
            "prompt": f"\n\nHuman: {prompt}\n\nAssistant:",
            "max_tokens_to_sample": max_tokens
        }
    elif 'amazon.titan' in model_id:
        body = {
            "inputText": prompt,
            "textGenerationConfig": {
                "maxTokenCount": max_tokens,
                "temperature": 0.7
            }
        }
    elif 'ai21.j2' in model_id:
        body = {
            "prompt": prompt,
            "maxTokens": max_tokens
        }
    else:
        raise ValueError(f"Unsupported model: {model_id}")
    
    # 推論実行
    response = bedrock.invoke_model(
        modelId=model_id,
        body=json.dumps(body)
    )
    result = json.loads(response['body'].read())
    
    # レスポンスの抽出(モデルごとに異なる)
    if 'anthropic.claude' in model_id:
        return result['completion']
    elif 'amazon.titan' in model_id:
        return result['results'][0]['outputText']
    elif 'ai21.j2' in model_id:
        return result['completions'][0]['data']['text']
    else:
        raise ValueError(f"Unsupported model: {model_id}")

# 使用例
text = invoke_bedrock_model('anthropic.claude-v2', 'Hello')
print(text)  # → 正常に動作

text = invoke_bedrock_model('amazon.titan-text-express-v1', 'Hello')
print(text)  # → 正常に動作

長期対応(ライブラリ化)

# LangChain や LlamaIndex を使用して抽象化
from langchain.llms import Bedrock

# LangChain が内部でモデル差異を吸収
llm = Bedrock(model_id='anthropic.claude-v2')
response = llm('Hello')

llm = Bedrock(model_id='amazon.titan-text-express-v1')
response = llm('Hello')
# → 同じインターフェースで呼び出し可能

学び

  • Azure OpenAI では統一された OpenAI API 形式だが、Bedrock はプロバイダーごとにリクエスト/レスポンス形式が異なる
  • マルチモデル対応には抽象化レイヤーが必須(LangChain/LlamaIndex 推奨)
  • モデル切り替え時は必ず API ドキュメントで形式を確認

AWS 生成AI サービスの優先順位:障害発生時の実戦順序

最初の 3 分:どこで何が起きているか把握

# 1. CloudWatch Metrics で Bedrock のエラー/スロットリングを確認
# Invocations(成功)
aws cloudwatch get-metric-statistics \
  --namespace AWS/Bedrock \
  --metric-name Invocations \
  --dimensions Name=ModelId,Value=$MODEL_ID \
  --start-time $(Get-Date).ToUniversalTime().AddMinutes(-15).ToString("s") \
  --end-time $(Get-Date).ToUniversalTime().ToString("s") \
  --period 60 --statistics Sum

# InvocationErrors(エラー)
aws cloudwatch get-metric-statistics \
  --namespace AWS/Bedrock \
  --metric-name InvocationErrors \
  --dimensions Name=ModelId,Value=$MODEL_ID \
  --period 60 --statistics Sum

# ModelInvocationThrottles(スロットリング)
aws cloudwatch get-metric-statistics \
  --namespace AWS/Bedrock \
  --metric-name ModelInvocationThrottles \
  --dimensions Name=ModelId,Value=$MODEL_ID \
  --period 60 --statistics Sum

# 2. CloudWatch Logs でエラーメッセージを確認
aws logs tail /aws/lambda/$FUNCTION_NAME --since 10m --filter-pattern "ERROR"

# 3. PartyRock の場合は Activity タブを確認
# ブラウザで https://partyrock.aws/u/<user-id>/apps/<app-id> を開く

次の 10 分:原因カテゴリ別切り分け

1) スロットリング → Service Quotas の確認

Bedrock はモデルごとにクォータがある。

# Service Quotas を確認
aws service-quotas list-service-quotas --service-code bedrock \
  --query 'Quotas[?contains(QuotaName, `Claude`)]'

# クォータ引き上げリクエスト
aws service-quotas request-service-quota-increase \
  --service-code bedrock \
  --quota-code L-xxxxxxxx \
  --desired-value 100000

対応案

  • リトライ+指数バックオフを実装(boto3 の Config で設定可能)
  • 複数リージョンに分散
  • クォータ引き上げを事前申請

2) Knowledge Base 検索が遅い → OpenSearch/Kendra のパフォーマンス

ベクトルDB のインスタンスタイプやインデックスサイズを確認。

# OpenSearch のメトリクスを確認
aws cloudwatch get-metric-statistics \
  --namespace AWS/ES \
  --metric-name SearchLatency \
  --dimensions Name=DomainName,Value=$DOMAIN_NAME \
  --period 60 --statistics Average,Maximum

# CPUUtilization を確認
aws cloudwatch get-metric-statistics \
  --namespace AWS/ES \
  --metric-name CPUUtilization \
  --dimensions Name=DomainName,Value=$DOMAIN_NAME \
  --period 60 --statistics Average

対応案

  • インスタンスタイプを変更(r6g.large 以上推奨)
  • インデックスの最適化(不要なフィールドを削除)
  • 検索クエリの Top-K を減らす

3) PartyRock のログが見つからない → CloudWatch Logs の場所

PartyRock のログは /aws/partyrock ではない。

# Bedrock Knowledge Base のログ
aws logs describe-log-groups --log-group-name-prefix /aws/bedrock/knowledge-bases

# Lambda のログ(PartyRock が内部で使用)
aws logs describe-log-groups --log-group-name-prefix /aws/lambda

対応案

  • PartyRock の「Activity」タブでセル単位のエラーを確認
  • CloudWatch Logs で /aws/bedrock/aws/lambda を確認
  • S3 バケット名やデータソースの設定ミスを疑う

4) モデル応答形式の違い → 抽象化レイヤー

Claude と Titan でレスポンス形式が異なる。

# Claude: result['completion']
# Titan: result['results'][0]['outputText']
# AI21 Jurassic: result['completions'][0]['data']['text']

対応案

  • LangChain や LlamaIndex で抽象化
  • 自前の抽象化関数を実装(上記シナリオ参照)
  • モデル切り替え時は必ずテスト

5) IAM 権限不足 → Bedrock の実行ロール

Lambda や EC2 から Bedrock を呼び出す際の権限。

# IAM ロールのポリシーを確認
aws iam list-attached-role-policies --role-name bedrock-execution-role

# 必要な権限:
# - bedrock:InvokeModel
# - bedrock:InvokeModelWithResponseStream(ストリーミング使用時)
# - s3:GetObject(Knowledge Base 使用時)

対応案

  • マネージドポリシー AmazonBedrockFullAccess をアタッチ(開発環境)
  • 本番環境では最小権限の原則に従う

よくある落とし穴と対策

落とし穴 理由 AWS での対策
スロットリングが頻発 モデルごとにクォータがあり、デフォルト値が低い Service Quotas で事前にクォータ引き上げ
Knowledge Base 検索が遅い OpenSearch/Kendra のインスタンスタイプが小さい r6g.large 以上を使用、メトリクス監視
PartyRock のログが見つからない /aws/partyrock ではなく /aws/bedrock/aws/lambda Activity タブ + CloudWatch Logs 両方確認
モデル応答形式が異なる プロバイダーごとに JSON 構造が違う LangChain/LlamaIndex で抽象化
IAM 権限不足 Bedrock の実行ロールに権限がない AmazonBedrockFullAccess または最小権限ポリシー
Azure OpenAI との API 互換性なし Bedrock は OpenAI API 互換ではない コード移行時にリクエスト/レスポンス形式を変更
プロンプト管理が手動 Azure Prompt Flow のようなバージョン管理がない Parameter Store や S3 でプロンプトを管理

移行実装時のチェックリスト

□ Bedrock:Service Quotas でクォータを確認し、必要なら事前申請
□ Bedrock:リトライ+指数バックオフを実装(boto3 Config)
□ Bedrock:モデル ID を環境変数化(プロバイダー名.モデル名)
□ Bedrock:抽象化レイヤーを実装(LangChain/LlamaIndex 推奨)
□ Knowledge Base:S3 バケットを事前作成、ドキュメントをアップロード
□ Knowledge Base:OpenSearch/Kendra のインスタンスタイプを適切に設定(r6g.large 以上)
□ PartyRock:Activity タブと CloudWatch Logs の両方で監視
□ CloudWatch Logs:主要なログの保存期間を設定(コスト最適化)
□ CloudWatch Metrics:Invocations, InvocationErrors, ModelInvocationThrottles のアラート設定
□ IAM:Bedrock 実行ロールに必要な権限を付与(bedrock:InvokeModel など)

さいごに

AWS の生成AI サービスは Azure OpenAI Service のような「統合プラットフォーム」ではなく、「柔軟な選択肢と明示的な設定」が特徴です。Bedrock、PartyRock、SageMaker それぞれに特性があり、適材適所での使い分けが求められます。

Azure では「Azure OpenAI Service を使えば大体 OK」という快適さがありましたが、AWS では「どのサービスをどう組み合わせるか」を理解する必要があります。しかし、柔軟性が高い分、細かい制御やコスト最適化は AWS の方が有利な場面もあります。

本記事の優先度順に切り分ければ、落ち着いて障害対応できるのかなー、と思いました。


補足:AWS マネジメントコンソールでの基本操作

CLI に慣れていない場合、AWS マネジメントコンソール(ポータル)での操作が便利です。以下は障害対応で頻繁に使う画面の場所と確認方法です。

Bedrock の基本操作

1. モデルの確認とテスト実行

1. AWS マネジメントコンソールにログイン
2. 検索バーで「Bedrock」と入力 → Amazon Bedrock を選択
3. 左メニューから「Base models」をクリック
4. 利用したいモデル(例:Claude)の「Request model access」をクリック
   → 初回はモデルへのアクセス申請が必要(数分~数時間で承認)
5. 承認後、左メニューから「Playgrounds」→「Chat」を選択
6. モデルを選択(例:Anthropic Claude 3 Sonnet)
7. プロンプトを入力してテスト実行
   → レスポンスが返ってくることを確認

2. モデルのクォータ確認

1. AWS マネジメントコンソール右上のアカウント名をクリック
2. 「Service Quotas」を選択
3. 左メニューから「AWS services」をクリック
4. 検索バーで「Bedrock」と入力
5. 「Amazon Bedrock」を選択
6. クォータ一覧から確認したいモデルを選択
   例:「Anthropic Claude V2 input tokens per minute」
7. 「Request quota increase」をクリックして引き上げ申請

3. CloudWatch でメトリクス確認

1. AWS マネジメントコンソールで「CloudWatch」を検索
2. 左メニューから「Metrics」→「All metrics」を選択
3. 「Bedrock」を選択
4. 「By Model ID」を選択
5. 確認したいモデルの以下のメトリクスをチェック:
   - Invocations(成功したリクエスト数)
   - InvocationErrors(エラー数)
   - ModelInvocationThrottles(スロットリング数)
6. 「Graphed metrics」タブで時系列グラフを確認
7. 右上の期間を「Last 1 hour」などに変更して直近の状況を確認

PartyRock の基本操作

1. アプリの作成と実行

1. ブラウザで https://partyrock.aws にアクセス
2. 「Sign in」→ AWS アカウントでログイン
3. 「Build your own app」をクリック
4. アプリ名とプロンプトを入力(例:「Document QA Bot」)
5. 「Generate」をクリック → 自動的にセルが生成される
6. 各セルの設定を調整:
   - Input セル:ユーザー入力を受け取る
   - LLM セル:Bedrock モデルで推論
   - Output セル:結果を表示
7. 右上の「Publish」をクリックして公開

2. Knowledge Base(RAG)の設定

1. PartyRock アプリの編集画面で、セルを追加
2. 「Knowledge Base」セルを選択
3. 「Create new Knowledge Base」をクリック
4. Knowledge Base 名を入力(例:「my-docs-kb」)
5. Data source として「S3」を選択
6. S3 バケット名を入力(事前に作成が必要)
   → S3 コンソールで「Create bucket」して作成
7. ドキュメント(PDF, TXT, HTML など)を S3 にアップロード
8. 「Sync data source」をクリックしてインデックス作成
   → 数分~数十分かかる
9. PartyRock のセルで Knowledge Base を選択して使用

3. Activity(実行履歴)の確認

1. PartyRock アプリの画面で、下部の「Activity」タブをクリック
2. 最近の実行履歴が時系列で表示される
3. 各実行をクリックすると、セルごとの入出力が確認できる
4. エラーが発生しているセルは赤色で表示される
5. セルをクリックして詳細なエラーメッセージを確認

4. CloudWatch Logs での確認(より詳細なログ)

1. AWS マネジメントコンソールで「CloudWatch」を検索
2. 左メニューから「Logs」→「Log groups」を選択
3. 以下の Log Group を探す:
   - /aws/bedrock/knowledge-bases/kb-xxxxx
   - /aws/lambda/partyrock-xxxxx(内部で使われる Lambda)
4. Log stream を選択して最新のログを確認
5. フィルターバーで「ERROR」や「Exception」で検索

Bedrock Knowledge Base の構築(ポータル操作)

1. S3 バケットの作成とドキュメントアップロード

1. AWS マネジメントコンソールで「S3」を検索
2. 「Create bucket」をクリック
3. Bucket name を入力(例:my-knowledge-base-docs)
4. Region を選択(Bedrock と同じリージョン推奨)
5. デフォルト設定のまま「Create bucket」をクリック
6. 作成したバケットをクリック
7. 「Upload」をクリックしてドキュメント(PDF, TXT など)をアップロード

2. OpenSearch Serverless の作成(ベクトルDB)

1. AWS マネジメントコンソールで「OpenSearch Service」を検索
2. 左メニューから「Serverless」→「Collections」を選択
3. 「Create collection」をクリック
4. Collection name を入力(例:kb-vector-store)
5. Collection type で「Vector search」を選択
6. Network access で「Public」を選択(開発環境の場合)
7. Encryption は AWS managed key を選択
8. 「Create」をクリック → 作成に 5~10 分かかる

3. Bedrock Knowledge Base の作成

1. AWS マネジメントコンソールで「Bedrock」を検索
2. 左メニューから「Knowledge bases」を選択
3. 「Create knowledge base」をクリック
4. Knowledge base details:
   - Name: my-docs-kb
   - Description: ドキュメント検索用 KB
5. 「Next」をクリック
6. Data source configuration:
   - Data source name: s3-docs
   - S3 URI: s3://my-knowledge-base-docs/
7. 「Next」をクリック
8. Embeddings model:
   - Amazon Titan Embeddings G1 - Text を選択
9. Vector database:
   - 先ほど作成した OpenSearch Serverless collection を選択
10. 「Next」→「Create」をクリック
11. 作成後、「Sync」をクリックしてインデックス作成
    → ドキュメント数に応じて数分~数十分

4. Knowledge Base のテスト

1. 作成した Knowledge Base の詳細画面を開く
2. 右上の「Test」ボタンをクリック
3. クエリを入力(例:「製品の価格は?」)
4. 「Run」をクリック
5. 検索結果が表示されることを確認
   → 結果が空の場合は、ドキュメントの Sync 状態を確認

CloudWatch でのログ確認(障害時の定番操作)

1. Lambda のログ確認

1. AWS マネジメントコンソールで「CloudWatch」を検索
2. 左メニューから「Logs」→「Log groups」を選択
3. 検索バーで「/aws/lambda/」と入力
4. 対象の Lambda 関数の Log group をクリック
5. Log streams を時系列で確認(最新が上)
6. 最新の Log stream をクリック
7. エラーメッセージを検索(Ctrl+F で「ERROR」や「Exception」)

2. Logs Insights でクエリ検索

1. CloudWatch の左メニューから「Logs Insights」を選択
2. 「Select log group(s)」で対象の Log group を選択
3. クエリエディタに以下を入力:
   fields @timestamp, @message
   | filter @message like /ERROR/
   | sort @timestamp desc
   | limit 20
4. 右上の期間を選択(例:Last 1 hour)
5. 「Run query」をクリック
6. 結果が表形式で表示される

3. メトリクスアラームの設定

1. CloudWatch の左メニューから「Alarms」→「All alarms」を選択
2. 「Create alarm」をクリック
3. 「Select metric」をクリック
4. 「Bedrock」→「By Model ID」を選択
5. 「InvocationErrors」をチェック
6. 「Select metric」をクリック
7. Conditions で Threshold type を「Static」、条件を「Greater」、値を「5」に設定
8. 「Next」をクリック
9. SNS topic を作成または選択(メール通知用)
10. 「Next」→ Alarm name を入力 → 「Create alarm」

X-Ray でのトレース確認

1. X-Ray トレースマップの確認

1. AWS マネジメントコンソールで「X-Ray」を検索
2. 左メニューから「Service map」を選択
3. サービス間の依存関係がグラフ表示される
   例:API Gateway → Lambda → Bedrock
4. 各ノードをクリックすると、レスポンスタイムやエラー率が表示される
5. 遅延やエラーが発生しているノードを特定

2. トレースの詳細確認

1. X-Ray の左メニューから「Traces」を選択
2. フィルターで期間を設定(例:Last 1 hour)
3. レスポンスタイムが長いトレースをクリック
4. タイムラインで各サービスの処理時間を確認
   例:Lambda 内部で 15 秒、Bedrock 呼び出しで 12 秒など
5. 「Segments」タブで詳細なログやメタデータを確認

画面操作のチートシート

確認したいこと 開く画面 見るべき項目
Bedrock のエラー数 CloudWatch → Metrics → Bedrock InvocationErrors の Sum
Bedrock のスロットリング CloudWatch → Metrics → Bedrock ModelInvocationThrottles の Sum
Lambda のエラーログ CloudWatch → Logs → /aws/lambda/xxx Log stream の最新エントリ
PartyRock の実行履歴 PartyRock アプリ → Activity タブ 各セルの成功/失敗状態
Knowledge Base の検索結果 Bedrock → Knowledge bases → Test クエリを入力して Run
API のレスポンスタイム X-Ray → Traces Duration の長いトレース
クォータの確認 Service Quotas → AWS services → Bedrock 各モデルのクォータ値
S3 のドキュメント確認 S3 → Buckets → バケット名 Objects タブ

注釈:本記事で出現する主要な専門用語

Bedrock

  • AWS のマネージド生成AI 推論サービス。Anthropic Claude、Amazon Titan、AI21 Jurassic などのモデルを API 経由で利用できる。Azure OpenAI Service に相当するが、プロバイダーごとに API 形式が異なる。

PartyRock

  • AWS のノーコード生成AI アプリビルダー。複数の AI セルを組み合わせて RAG パイプラインを構築できる。Azure AI Foundry に近いが、独立したアプリとして動作。

Knowledge Base for Bedrock

  • Bedrock の RAG(Retrieval-Augmented Generation)機能。S3 + ベクトルDB(OpenSearch/Kendra/Pinecone)を連携して、独自データで拡張された推論を実行。Azure OpenAI の「自分のデータで拡張」に相当。

Service Quotas

  • AWS のリソース制限を管理するサービス。Bedrock はモデルごとにトークン数/分のクォータがあり、Service Quotas で確認・変更する。Azure OpenAI の TPM(Tokens Per Minute)設定に相当。

モデル ID(Model ID)

  • Bedrock でモデルを指定する際の識別子。プロバイダー名.モデル名 の形式(例:anthropic.claude-v2, amazon.titan-text-express-v1)。Azure OpenAI のデプロイ名とは異なる。

ThrottlingException

  • Bedrock でリクエストがクォータを超えた際に発生するエラー。HTTP 429 に相当。リトライ+指数バックオフで対応する。

OpenSearch Service

  • AWS のマネージド検索エンジン。Bedrock Knowledge Base のベクトルDB として使用される。Azure Cognitive Search に相当するが、インスタンスタイプの選択が必要。

Kendra

  • AWS のエンタープライズ検索サービス。自然言語クエリに対応。Bedrock Knowledge Base のデータソースとしても使用可能。Azure Cognitive Search に近い。

X-Ray

  • AWS の分散トレーシングサービス。Lambda → Bedrock → OpenSearch のレイテンシを可視化できる。Azure Application Insights の依存関係追跡に相当。

LangChain / LlamaIndex

  • 生成AI アプリケーションの開発フレームワーク。Bedrock のモデル差異を抽象化し、統一インターフェースで呼び出し可能にする。

Azure OpenAI Service

  • Azure のマネージド OpenAI API サービス。統一された OpenAI API 形式で GPT-4, GPT-3.5, DALL-E などを利用できる。Bedrock に相当するが、API 形式が統一されている。

AI Foundry (Azure)

  • Azure の統合生成AI 開発環境。Prompt Flow でプロンプトのバージョン管理、Azure Monitor でログ統合が標準。PartyRock に相当するが、統合度が高い。

TPM (Tokens Per Minute)

  • Azure OpenAI でデプロイごとに設定するトークン数/分の上限。Bedrock の Service Quotas に相当するが、デプロイ作成時に指定できる。

Prompt Flow (Azure)

  • Azure AI Foundry のプロンプト管理機能。プロンプトのバージョン管理、A/B テスト、デプロイができる。Bedrock には同等機能がなく、Parameter Store や S3 で手動管理が必要。

Azure Cognitive Search

  • Azure の検索サービス。Azure OpenAI の「自分のデータで拡張」機能で自動統合される。Bedrock Knowledge Base では OpenSearch/Kendra を手動連携する必要がある。

SageMaker

  • AWS のマネージド機械学習プラットフォーム。カスタムモデルの学習・デプロイに使用。Bedrock は事前学習済みモデルの推論専用。

boto3

  • AWS の Python SDK。Bedrock API を呼び出す際に使用。Config で指数バックオフを設定可能。
1
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
1
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?