ankuro.dev
← ブログ一覧に戻る
【開発記録 #3】BedrockでWell-Architectedレビューを生成する——システムプロンプト設計
2026-03-21#AWS#Bedrock#Lambda#Claude Code#システムプロンプト#個人開発

【開発記録 #3】BedrockでWell-Architectedレビューを生成する——システムプロンプト設計

インフラができたら次はLambdaの中身。Claude Codeにどう依頼すれば、AIが使えるシステムプロンプトを設計してくれるのか。モデル選定の判断基準も含めて記録する。


まず使うクライアントを決める

BedrockをPythonから呼ぶとき、boto3のクライアントが2つある。

クライアント 用途
bedrock-runtime モデルを直接呼び出す
bedrock-agent-runtime Knowledge BaseやAgentを使う

今回はモデルに直接プロンプトを投げてレビューを生成するだけなので bedrock-runtime を選ぶ。

RAGを追加するPhase 5で bedrock-agent-runtime に移行する予定だが、今は最小構成で動かすことを優先する。後から変えられる部分は後回しにする判断が、開発を止めないコツ。


モデル選定の判断基準

Claude Codeに「どのモデルを使うべきか」を相談する前に、自分で判断軸を持っておく。

モデル 入力 (1Mトークン) 出力 (1Mトークン)
Claude Haiku 4.5 $0.80 $4.00
Claude Sonnet 4.5 $3.00 $15.00

Well-Architectedレビューの用途なら、Haikuで十分な品質が出ると判断した。理由は2つ。

  1. レビューの精度は「モデルの賢さ」より「システムプロンプトの設計」に依存する部分が大きい
  2. SaaSとして提供する場合、コストがそのまま収益性に直結する

Sonnetは3〜4倍のコストがかかる。精度が同程度ならHaikuを選ぶ。本当に精度が足りないと分かってから乗り換えれば十分。


Lambdaの生成依頼——出力形式まで指定する

Claude Codeへの依頼:

lambda/review.pyを作ってください。
- boto3でBedrock(Claude Haiku)を呼び出す
- 入力:アーキテクチャの説明文(JSON)
- 出力:Well-Architectedの5本柱に沿ったレビュー結果(JSON)
- システムプロンプト:AWSのSolutions Architectとして振る舞う

「出力:JSON」と明示したのが重要なポイント。

出力形式を指定しないと、Claude Codeは自由なフォーマットでレビューを返す実装を作る。フロントエンドで扱うためにはJSON形式である必要があるため、最初から仕様に含めた。

生成されたシステムプロンプトの骨格:

SYSTEM_PROMPT = """
あなたはAWSの認定ソリューションアーキテクトです。
AWS Well-Architectedフレームワークの5つの柱(運用上の優秀性・セキュリティ・信頼性・パフォーマンス効率・コスト最適化)に基づいて、
提供されたAWSアーキテクチャを評価してください。
以下のJSON形式で回答してください:
{
  "operational_excellence": {"score": 1-5, "issues": [], "recommendations": []},
  "security": {"score": 1-5, "issues": [], "recommendations": []},
  "reliability": {"score": 1-5, "issues": [], "recommendations": []},
  "performance_efficiency": {"score": 1-5, "issues": [], "recommendations": []},
  "cost_optimization": {"score": 1-5, "issues": [], "recommendations": []}
}
"""

5本柱それぞれにスコア(1〜5)・問題点・推奨事項を返す構造。Claude Codeはプロンプトの依頼に「JSON形式で」と書いていたのを受けて、具体的なJSONスキーマまで自動で設計してきた。このスキーマはほぼそのまま採用した。


東京リージョンのモデルIDは別物

ローカルテストを実行したら最初のエラー:

ValidationException: The provided model identifier is invalid

生成されたコードに含まれていたモデルIDは anthropic.claude-haiku-4-5-20251001。これは東京リージョンでは使えない。

東京リージョンでClaude Haikuを使う場合、クロスリージョン推論プロファイルのIDを使う必要がある。正しいIDの確認方法:

aws bedrock list-inference-profiles --region ap-northeast-1

正しいIDは:

jp.anthropic.claude-haiku-4-5-20251001-v1:0

jp. プレフィックスと末尾の -v1:0 が東京リージョンでは必要。Claude Codeはリージョン固有の仕様を必ずしも知っているわけではない。AWSのリージョン特有の制約は自分で確認する必要がある。

このエラーはClaude Codeにそのまま貼り付けると解決策を提案してくれるが、最終的に正しいモデルIDを特定するのはAWSコンソールかCLIで確認するしかない。


JSONが返ってこない——Claudeの出力の癖

モデルIDを修正して再実行したら次のエラー:

Bedrockの応答をパースできませんでした

原因はClaudeの出力の癖。「JSON形式で返して」と指示しているのに、実際の出力はこうなっていた:

```json
{
  "operational_excellence": ...
}
```

コードブロック(```json ```)で囲まれて返ってくる。json.loads() にそのまま渡せないのでパースエラーになる。

Claude Codeに「コードブロックを除去する処理を追加して」と依頼したら、strip処理を追加してきた:

def extract_json(text):
    text = re.sub(r'```json\s*', '', text)
    text = re.sub(r'```\s*', '', text)
    return json.loads(text.strip())

システムプロンプトに「JSONのみを返してください、コードブロックは不要です」と書いても、モデルによってはコードブロックを付けて返すことがある。strip処理は保険として必ず入れておくのが安全。


実際のレビュー結果

「EC2インスタンス1台にすべてを詰め込んだ構成」を入力して動作確認:

{
  "operational_excellence": {
    "score": 2,
    "issues": ["デプロイの自動化がない", "ログ収集の仕組みがない"],
    "recommendations": ["CodeDeployでデプロイ自動化", "CloudWatch Logsへのログ転送設定"]
  },
  "security": {
    "score": 2,
    "issues": ["すべてのポートが0.0.0.0/0で開放されている", "IAMロールが未設定"],
    "recommendations": ["セキュリティグループで必要なポートのみ開放", "EC2インスタンスにIAMロールを付与"]
  },
  "reliability": {
    "score": 1,
    "issues": ["単一障害点(SPOF)", "オートスケーリングなし"],
    "recommendations": ["マルチAZ構成への変更", "Auto Scalingグループの設定"]
  }
}

「単一障害点」「セキュリティグループの過剰な開放」など、実際のレビューで指摘されるような内容が出た。Haikuでも十分な品質と判断した。


システムプロンプト設計でつかんだ感覚

出力形式は最初の依頼に含める
JSONが必要なら「出力:JSON形式で」と明示。後から変えると生成コードの修正範囲が広くなる。

リージョン固有の仕様はClaude Codeに頼らない
東京リージョンのモデルIDのように、AWSのリージョン特有の制約は自分でドキュメントを確認する。

Claudeの出力の癖を知っておく
JSON指定でもコードブロックで返ってくることがある。strip処理は標準で入れる。

Phase 1完了。APIエンドポイントにアーキテクチャの説明を投げればWell-Architectedレビューが返ってくる状態になった。次回からはPhase 2——Cognito認証を追加していく。


前回:第2回——CDK × Claude CodeでLambda + API Gatewayを最速で作る | 次回:第4回——Amazon CognitoでユーザーIDと認証を実装する