1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

プロンプト管理、まだハードコードしていませんか? ― Bedrock Prompt Management入門

1
Posted at

はじめに

生成AIアプリケーションを開発していると、こんな課題にぶつかりませんか?

  • プロンプトがコードにハードコードされていて、修正のたびにデプロイが必要
  • チームメンバーごとに違うプロンプトを使っていて、品質がバラバラ
  • 「前のバージョンのプロンプトのほうが良かった」と言われても戻せない
  • モデルやパラメータを変えて比較したいが、検証環境を毎回用意するのが面倒

これらの課題を解決するのがAmazon Bedrock Prompt Managementです。

本記事では、カスタマーサポートBotのプロンプトを管理するという実務シナリオをベースに、Prompt Managementの主要機能をハンズオン形式で解説します。

Prompt Managementとは

Amazon Bedrock Prompt Managementは、プロンプトの作成・テスト・バージョン管理・デプロイを一元的に行うための機能です。

イメージとしてはSSM Parameter Store + モデル設定 + 実行がセットになったものです。SSM Parameter Storeはパラメータの値を管理しますが、Prompt Managementはプロンプト・モデル・推論パラメータをまとめて管理し、ARN一つで実行まで完了します。

# 従来: プロンプトをコードに埋め込み → 修正のたびにデプロイ
response = bedrock.converse(
    modelId="jp.anthropic.claude-sonnet-4-5-20250929-v1:0",
    system=[{"text": "あなたはカスタマーサポート担当です..."}],
    messages=[{"role": "user", "content": [{"text": prompt_text}]}],
    inferenceConfig={"temperature": 0.3, "maxTokens": 1024},
)

# Prompt Management: ARNを指定するだけ → プロンプト改善時にデプロイ不要
response = bedrock.converse(
    modelId=prompt_version_arn,
    promptVariables={"customer_name": {"text": "田中太郎"}, "issue": {"text": "..."}},
)

主要コンセプト

概念 説明
Prompt モデルへの入力テンプレート。変数を含めて再利用可能にできる
Variable {{variable_name}}の形式で定義するプレースホルダー。実行時に値を差し込める
Variant 同一プロンプトの異なる構成(モデル・パラメータ・プロンプト文面の組み合わせ)
Draft 編集中の作業バージョン。何度でも上書き保存できる
Version 特定時点のスナップショット。本番デプロイ用の不変なバージョン

全体ワークフロー

Step 1         Step 2           Step 3                   Step 4
プロンプト作成 → Variant追加&比較 → Version作成&API呼び出し → プロンプト改善&Version更新
                                        ↑                        |
                                        └────────────────────────┘
                                             改善サイクル

実務シナリオ:カスタマーサポートBot

今回は以下のシナリオで進めます。

ECサイトのカスタマーサポートBotを構築する。
顧客の名前と問い合わせ内容を受け取り、丁寧かつ的確に回答するプロンプトを、チームで管理・運用したい。

ハンズオン

前提条件

  • AWSアカウントとクレデンシャル設定済み
  • Bedrockモデルアクセスが有効(Claude Sonnet 4.5など)
  • Python 3.10以上
  • boto3インストール済み
pip install boto3

Bedrockの一部モデルはon-demandのモデルIDでの呼び出しがサポートされていません。その場合は推論プロファイルID(例: jp.anthropic.claude-sonnet-4-5-20250929-v1:0)を使用してください。利用可能な推論プロファイルはaws bedrock list-inference-profilesで確認できます。

Step 1: プロンプトを作成する

まず、カスタマーサポートBot用のプロンプトをAPIで作成します。

import boto3

# Bedrock Agentクライアントを作成
client = boto3.client("bedrock-agent", region_name="ap-northeast-1")

# カスタマーサポート用プロンプトを作成
response = client.create_prompt(
    name="CustomerSupportBot",
    description="ECサイトのカスタマーサポート用プロンプト",
    variants=[
        {
            "name": "Claude_Sonnet",
            "modelId": "jp.anthropic.claude-sonnet-4-5-20250929-v1:0",
            "templateType": "CHAT",
            "inferenceConfiguration": {
                "text": {
                    "temperature": 0.3,
                    "maxTokens": 1024,
                }
            },
            "templateConfiguration": {
                "chat": {
                    "system": [
                        {
                            "text": "あなたはECサイトのカスタマーサポート担当です。以下のルールに従って回答してください。\n1. 顧客の名前を使って丁寧に対応する\n2. 問題の解決策を具体的に提示する\n3. 解決できない場合はエスカレーション先を案内する\n4. 回答は簡潔に、3文以内にまとめる"
                        }
                    ],
                    "messages": [
                        {
                            "role": "user",
                            "content": [
                                {
                                    "text": "顧客名: {{customer_name}}\n問い合わせ内容: {{issue}}"
                                }
                            ]
                        }
                    ]
                }
            },
        }
    ],
)

prompt_id = response["id"]
prompt_arn = response["arn"]
print(f"プロンプトID: {prompt_id}")
print(f"プロンプトARN: {prompt_arn}")

ポイントは以下の通りです。

  • templateTypeCHATにすることで、システムプロンプトとユーザーメッセージを分離できる
  • {{customer_name}}{{issue}}を変数として定義し、実行時に値を差し込める
  • temperature: 0.3で安定した回答を生成するよう設定

Step 2: Variantを追加してモデルを比較する

同じプロンプトに対して、異なるモデルやパラメータの構成(Variant)を追加して比較できます。update_promptで既存のプロンプトにVariantを追加します。

# 既存のプロンプト情報を取得
prompt_info = client.get_prompt(promptIdentifier=prompt_id)

# 現在のVariantリストを取得
variants = prompt_info["variants"]

# 新しいVariantを追加(Haikuモデル + 高めのtemperature)
variants.append(
    {
        "name": "Claude_Haiku",
        "modelId": "apac.anthropic.claude-3-haiku-20240307-v1:0",
        "templateType": "CHAT",
        "inferenceConfiguration": {
            "text": {
                "temperature": 0.7,
                "maxTokens": 1024,
            }
        },
        "templateConfiguration": {
            "chat": {
                "system": [
                    {
                        "text": "あなたはECサイトのカスタマーサポート担当です。以下のルールに従って回答してください。\n1. 顧客の名前を使って丁寧に対応する\n2. 問題の解決策を具体的に提示する\n3. 解決できない場合はエスカレーション先を案内する\n4. 回答は簡潔に、3文以内にまとめる"
                    }
                ],
                "messages": [
                    {
                        "role": "user",
                        "content": [
                            {
                                "text": "顧客名: {{customer_name}}\n問い合わせ内容: {{issue}}"
                            }
                        ]
                    }
                ]
            }
        },
    }
)

# プロンプトを更新
client.update_prompt(
    promptIdentifier=prompt_id,
    name="CustomerSupportBot",
    description="ECサイトのカスタマーサポート用プロンプト",
    variants=variants,
)
print("Variant追加完了")

同じ入力(customer_name = 田中太郎issue = 3日前に注文した商品がまだ届きません。注文番号はORD-12345です。)で比較した結果は以下の通りです。

Claude Sonnet 4.5(temperature 0.3)の回答:

田中太郎様、お問い合わせいただきありがとうございます。

注文番号ORD-12345の配送状況を確認いたしましたところ、現在配送センターから発送済みで、
明日中にはお届けできる予定となっております。万が一明日中に届かない場合は、配送業者への
調査を開始いたしますので、再度ご連絡いただけますでしょうか。

Claude 3 Haiku(temperature 0.7)の回答:

田中様

大変申し訳ございません。ご注文のORD-12345は通常3-5営業日での配送となっておりますが、
配送が遅延しているようです。早急に配送状況を確認し、できるだけ早くお届けできるよう
手配させていただきます。
比較観点 Claude Sonnet 4.5 (temperature 0.3) Claude 3 Haiku (temperature 0.7)
回答の正確さ 高い(具体的な配送状況を提示) やや汎用的な回答
レスポンス速度 約3.8秒 約2.3秒
コスト 高め 低め
適したユースケース 正確性重視の問い合わせ対応 FAQ的な定型回答

Variantを比較し、ユースケースに最も適した構成を選んでDraftに保存します。

Step 3: Version作成&Converse APIで呼び出し

最適なVariantが決まったら、Versionを作成して本番アプリケーションから呼び出します。

Draftはあくまで作業用なので、Converse APIで呼び出すにはVersionの作成が必要です。

# Versionを作成(現在のDraftのスナップショット)
version_response = client.create_prompt_version(
    promptIdentifier=prompt_id,
    description="v1: 初回リリース - Sonnet 4.5 + temperature 0.3"
)

version_arn = version_response["arn"]
print(f"Version ARN: {version_arn}")
# 出力例: Version ARN: arn:aws:bedrock:ap-northeast-1:123456789012:prompt/XXXXXXXXXX:1

# Bedrock Runtimeクライアントを作成
runtime_client = boto3.client("bedrock-runtime", region_name="ap-northeast-1")

# プロンプトをConverse APIで呼び出し
response = runtime_client.converse(
    modelId=version_arn,  # VersionのARNを指定
    promptVariables={
        "customer_name": {"text": "田中太郎"},
        "issue": {"text": "3日前に注文した商品がまだ届きません。注文番号はORD-12345です。"},
    },
)

# 回答を表示
print(response["output"]["message"]["content"][0]["text"])
# 出力例
田中太郎様、お問い合わせいただきありがとうございます。

注文番号ORD-12345の配送状況を確認いたしましたところ、現在配送センターから発送済みで、
明日中にはお届けできる予定となっております。万が一明日中に届かない場合は、配送業者の
追跡番号をお送りいたしますので、再度ご連絡ください。

本番アプリケーションでは、このVersion ARNを環境変数等に設定し、modelIdに指定するだけです。プロンプトの内容はアプリケーションコードに一切含まれません。

Converse APIでPrompt ManagementのプロンプトARNを使用する場合、additionalModelRequestFieldsinferenceConfigsystemtoolConfigフィールドはリクエストに含めることができません。これらの設定はプロンプト側で定義されたものが使用されます。また、modelIdにはDraftのARNではなくVersionのARNを指定する必要があります。

Step 4: プロンプトを改善してVersion 2をリリースする

運用開始後、「もっと共感的な対応にしてほしい」というフィードバックがあったとします。

# Draftを更新(システムプロンプトを改善)
prompt_info = client.get_prompt(promptIdentifier=prompt_id)
variants = prompt_info["variants"]

# Sonnet Variantのシステムプロンプトを更新
for variant in variants:
    if variant["name"] == "Claude_Sonnet":
        variant["templateConfiguration"]["chat"]["system"] = [
            {
                "text": "あなたはECサイトのカスタマーサポート担当です。以下のルールに従って回答してください。\n1. まず顧客の状況に共感を示す\n2. 顧客の名前を使って丁寧に対応する\n3. 問題の解決策を具体的に提示する\n4. 解決できない場合はエスカレーション先を案内する\n5. 回答は簡潔に、3文以内にまとめる"
            }
        ]

client.update_prompt(
    promptIdentifier=prompt_id,
    name="CustomerSupportBot",
    description="ECサイトのカスタマーサポート用プロンプト",
    variants=variants,
)

# テスト後、新しいVersionを作成
response = client.create_prompt_version(
    promptIdentifier=prompt_id,
    description="v2: 共感表現を追加"
)

new_version_arn = response["arn"]
print(f"Version 2 ARN: {new_version_arn}")
# アプリケーションのPROMPT_VERSION_ARNを更新するだけで切り替え完了

この運用フローにより、アプリケーションコードを変更せずにプロンプトの改善・デプロイが可能になります。

問題が発生した場合は、アプリケーションが参照するARNをVersion 1に戻すだけでロールバックできます。

実務で活きるポイントまとめ

DraftとVersionの使い分け

Draft(開発用) Version(本番用)
役割 自由に編集・テスト可能 不変のスナップショット
用途 チーム内でプロンプトを検討 本番アプリから参照
流れ 最適な構成が決まったら → 新Version作成でリリース

Prompt Managementを導入するメリット

課題 従来の方法 Prompt Management
プロンプト修正 コード変更 + デプロイ プロンプト更新 + Version作成のみ
バージョン管理 Git管理 or ドキュメント 自動的にVersion管理される
A/Bテスト 独自実装が必要 Variantで即座に比較可能
チーム共有 ファイル共有 or Wiki コンソールで一元管理
ロールバック Gitリバート + デプロイ 旧VersionのARNに切り替え

まとめ

Amazon Bedrock Prompt Managementを使うことで、プロンプトをコードから分離し、作成→比較→デプロイ→改善のライフサイクルを一元管理できます。

特に実務では以下の点が効果的です。

  • Variableにより、1つのプロンプトを複数のユースケースで再利用
  • Variantにより、モデルやパラメータの違いを素早く比較
  • Versionにより、本番環境の安定性を保ちながらプロンプトを継続改善

プロンプトがアプリケーションの中核を担う生成AIシステムにおいて、Prompt Managementは「プロンプトのCI/CD」とも言える存在です。ぜひ実務のプロンプト運用に取り入れてみてください。

参考ドキュメント

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

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?