13
3

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 Prompt ManagementがGAしましたよ!

Posted at

Amazon BedrockのPrompt ManagementがGAしました🎉🎉🎉

プレビュー時との違いなどはこちらに情報がありました!(ありがとうございます!)

Prompt Managementとは?

プロンプトをテンプレート化して登録しておく機能です。(超ざっくり!)

テンプレート化?

以下のプロンプトを例にします。

プロンプト
<text>の内容を英語に翻訳してください。

<text>こんにちは</text>

このプロンプトの一部分を変数(Variables)にして、再利用しやすい形にします。
変数は{{ }}で囲って表現します。

プロンプトテンプレート
<text>の内容を{{language}}に翻訳してください。

<text>{{message}}</text>
変数(Variables)
language
message

Prompt Managementやってみた

では、Prompt Managementを使ってみましょう

まずは、Boto3を「1.35.56」以降にアップデートします。

ライブラリーのインストール
pip install -U boto3

「create_prompt」APIを使用するので、作成するものは「プロンプト」となるのですが、一般用語としての「プロンプト」と見分けがつかないので、本記事では「"プロンプト"」とダブルクオートで囲って表現することにします。

"プロンプト"の作成は「bedrock-agent」を使います。
"プロンプト"の利用は従来通り「bedrock-runtime」を使います。

クライアントの定義
import boto3

bedrock_agent = boto3.Session().client("bedrock-agent")
bedrock_runtime = boto3.Session().client("bedrock-runtime")

プロンプトテンプレートのタイプとして、2024/11/09時点では「TEXT」と「CHAT」の2種類あります。

シンプルなテキスト(templateType: TEXT)

"プロンプト"の作成はAPIで一発です。

"プロンプト"の作成
response = bedrock_agent.create_prompt(
    name="prompt1",
    variants=[
        {
            "name": "variant-1",
            "modelId": "anthropic.claude-3-haiku-20240307-v1:0",
            "templateType": "TEXT",
            "templateConfiguration": {
                "text": {
                    "text": "<text>の内容を{{language}}に翻訳してください。<text>{{message}}</text>",
                    "inputVariables": [{"name": "language"}, {"name": "message"}],
                }
            },
        }
    ],
)

prompt1_arn = response["arn"]

他に推論のパラメーター(inferenceConfiguration)やメタデータ(metadata)の指定も可能です。

作成した"プロンプト"を使用するにはInvokeModel APIやConverse APIを使用します。

通常の呼び出しと異なる部分は以下のとおりです。

  • modelIdに"プロンプト"のARNを指定する
  • promptVariablesパラメーターで、変数を指定する
  • messagesパラメーターがない
"プロンプト"の呼び出し
respnose = bedrock_runtime.converse(
    modelId=prompt1_arn,
    promptVariables={"language": {"text": "英語"}, "message": {"text": "こんにちは"}},
)

呼び出し結果のフォーマットは通常のConverse APIと同様です。

呼び出し結果
{'ResponseMetadata': {'RequestId': 'd204bb30-a46c-4319-ae47-824858fe12fc',
  'HTTPStatusCode': 200,
  'HTTPHeaders': {'date': 'Sat, 09 Nov 2024 01:31:43 GMT',
   'content-type': 'application/json',
   'content-length': '251',
   'connection': 'keep-alive',
   'x-amzn-requestid': 'd204bb30-a46c-4319-ae47-824858fe12fc'},
  'RetryAttempts': 0},
 'output': {'message': {'role': 'assistant',
   'content': [{'text': 'Here is the translation of the text in English:\n\n<text>Hello</text>'}]}},
 'stopReason': 'end_turn',
 'usage': {'inputTokens': 35, 'outputTokens': 21, 'totalTokens': 56},
 'metrics': {'latencyMs': 1010}}

呼び出し部分がとてもシンプルになりますね!

複雑なこともできるチャット(templateType: CHAT)

templateTypeがTEXTの場合は、シンプルな一つのテキストのみでしたが、CHATを使うと複雑なことができるようになります。

具体的には以下のような違いがあります。

  • システムプロンプトの指定ができる
  • messagesとして、ユーザーとアシスタントのやり取りを複数指定できる(5つまで?)
  • ツールの指定ができる(後述)
"プロンプト"の作成
response = bedrock_agent.create_prompt(
    name="prompt2",
    variants=[
        {
            "name": "variant-1",
            "modelId": "anthropic.claude-3-haiku-20240307-v1:0",
            "templateType": "CHAT",
            "templateConfiguration": {
                "chat": {
                    "system": [{"text": "あなたは優秀なAIアシスタントです"}],
                    "messages": [
                        {
                            "role": "user",
                            "content": [
                                {
                                    "text": "<text>の内容を{{language}}に翻訳してください。<text>{{message}}</text>"
                                }
                            ],
                        }
                    ],
                    "inputVariables": [{"name": "language"}, {"name": "message"}],
                }
            },
        }
    ],
)

prompt2_arn = response["arn"]

contentで指定できるタイプはtextのみのようです。(Imageなどはできなさそう)

呼び出し部分は変わりません。

"プロンプト"の呼び出し
respnose = bedrock_runtime.converse(
    modelId=prompt2_arn,
    promptVariables={"language": {"text": "英語"}, "message": {"text": "こんにちは"}},
)

せっかくチャットなので、複数回のやり取りをしたい場合はどうするのでしょう?

ドキュメント上明確な記載は見つけられませんでしたが、初回のレスポンス以降をmessasgesにセットするとうまくいきました。

"プロンプト"の呼び出し(会話継続)
messages = []
messages.append(respnose["output"]["message"])
messages.append(
    {
        "role": "user",
        "content": [{"text": "ありがとう。私が依頼した内容を復唱してください。"}],
    }
)

respnose = bedrock_runtime.converse(
    modelId=prompt2_arn,
    promptVariables={"language": {"text": "英語"}, "message": {"text": "こんにちは"}},
    messages=messages,
)
呼び出し結果
{'ResponseMetadata': {'RequestId': '166daa25-6feb-4da4-a53a-3778e7a60734',
  'HTTPStatusCode': 200,
  'HTTPHeaders': {'date': 'Sat, 09 Nov 2024 01:49:55 GMT',
   'content-type': 'application/json',
   'content-length': '331',
   'connection': 'keep-alive',
   'x-amzn-requestid': '166daa25-6feb-4da4-a53a-3778e7a60734'},
  'RetryAttempts': 0},
 'output': {'message': {'role': 'assistant',
   'content': [{'text': '依頼された内容は以下の通りです:\n\n<text>こんにちは</text>\n\nを英語に翻訳してください、というものでした。'}]}},
 'stopReason': 'end_turn',
 'usage': {'inputTokens': 93, 'outputTokens': 47, 'totalTokens': 140},
 'metrics': {'latencyMs': 1060}}

Tool呼び出し(templateType: CHAT)

templateTypeがCHATの場合はツール呼び出しも"プロンプト"に含めることができます。
toolConfigurationブロックでツールを定義します。

"プロンプト"の作成
response = bedrock_agent.create_prompt(
   name="prompt3",
   variants=[
       {
           "name": "variant-1",
           "modelId": "anthropic.claude-3-haiku-20240307-v1:0",
           "templateType": "CHAT",
           "templateConfiguration": {
               "chat": {
                   "messages": [
                       {
                           "role": "user",
                           "content": [
                               {"text": "{{location}}の天気は?"},
                           ],
                       }
                   ],
                   "inputVariables": [{"name": "location"}],
                   "toolConfiguration": {
                       "toolChoice": {"auto": {}},
                       "tools": [
                           {
                               "toolSpec": {
                                   "name": "get_weather",
                                   "description": "Get the current weather in a given location",
                                   "inputSchema": {
                                       "json": {
                                           "type": "object",
                                           "properties": {
                                               "location": {
                                                   "type": "string",
                                                   "description": "The city and state, e.g. San Francisco, CA",
                                               }
                                           },
                                           "required": ["location"],
                                       }
                                   },
                               }
                           }
                       ],
                   },
               }
           },
       }
   ],
)

prompt3_arn = response["arn"]
"プロンプト"の呼び出し(会話継続)
respnose = bedrock_runtime.converse(
    modelId=prompt3_arn,
    promptVariables={"location": {"text": "東京"}},
)
呼び出し結果
{'ResponseMetadata': {'RequestId': '3f61250f-f524-4ad3-bbcc-4f329095915b',
  'HTTPStatusCode': 200,
  'HTTPHeaders': {'date': 'Sat, 09 Nov 2024 01:56:04 GMT',
   'content-type': 'application/json',
   'content-length': '281',
   'connection': 'keep-alive',
   'x-amzn-requestid': '3f61250f-f524-4ad3-bbcc-4f329095915b'},
  'RetryAttempts': 0},
 'output': {'message': {'role': 'assistant',
   'content': [{'toolUse': {'toolUseId': 'tooluse_RXZdMEfySyGT5ZZIS9RpnQ',
      'name': 'get_weather',
      'input': {'location': '東京'}}}]}},
 'stopReason': 'tool_use',
 'usage': {'inputTokens': 353, 'outputTokens': 54, 'totalTokens': 407},
 'metrics': {'latencyMs': 724}}

期待通り、呼び出し結果にtoolUseが含まれます。
ツール実行結果をtoolResultとしてセットし、再度呼び出します。

"プロンプト"の呼び出し(ツール実行結果)
messages = []
messages.append(respnose["output"]["message"])
messages.append(
    {
        "role": "user",
        "content": [
            {
                "toolResult": {
                    "toolUseId": respnose["output"]["message"]["content"][0]["toolUse"][
                        "toolUseId"
                    ],
                    "content": [{"text": "晴れ"}],
                }
            }
        ],
    }
)

respnose = bedrock_runtime.converse(
    modelId=prompt3_arn,
    promptVariables={"location": {"text": "東京"}},
    messages=messages,
)
呼び出し結果
{'ResponseMetadata': {'RequestId': '5de772cd-f4cb-4b6a-8bff-0c1de97316ee',
  'HTTPStatusCode': 200,
  'HTTPHeaders': {'date': 'Sat, 09 Nov 2024 01:56:08 GMT',
   'content-type': 'application/json',
   'content-length': '217',
   'connection': 'keep-alive',
   'x-amzn-requestid': '5de772cd-f4cb-4b6a-8bff-0c1de97316ee'},
  'RetryAttempts': 0},
 'output': {'message': {'role': 'assistant',
   'content': [{'text': '東京の天気は晴れです。'}]}},
 'stopReason': 'end_turn',
 'usage': {'inputTokens': 423, 'outputTokens': 15, 'totalTokens': 438},
 'metrics': {'latencyMs': 1035}}

エージェント呼び出し

GAのタイミングでBedrockエージェントにも対応したようです。

"プロンプト"の作成まではできるものの、呼び出し方がわからないです。。
Converse APIではエラーになり、Invoke Agentだと"プロンプト"を指定する方法がわからないです。

TBD.

13
3
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
13
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?