はじめに

本記事は長すぎて分割された以下シリーズの最後の記事になります。主にモデルに指示するためのインストラクションのチューニングと、実際の動作確認を行います。

インストラクション

指示文はこちらで定義していますが、モデルに出力形式を伝えるために多少チューニングする必要がありました。具体的には、要約と詳細 (JSON) をテンプレートにそれぞれ埋め込んだ形で回答を返すように制御しました。

Slack API の文字数制限

公式な記述は見つけられませんでしたが、Slack API のメッセージは 3000 文字程度が上限のようです。マークダウン記法や絵文字 (:thumbsup: のような文字列表現) も文字列としてカウントされます。このため結果を 2500 文字以内にまとめるように指示しています (超えないとは限りませんが)

あなたはAWSに精通したソリューションアーキテクトです。いくつかの機能を使い分け、ユーザーの要求に2500文字以内の日本語で回答してください。

また、出力が2500文字を超える場合のみ、出力結果の一部を省略してください。出力が2500文字を超えない場合は省略しないでください。

テンプレートに沿った回答

以下のようなテンプレートを用意し、

#テンプレート:
*要約*

```
ここに[要約]を配置
```

*詳細*

```
ここに[詳細]を配置
```

以上

こんな感じで指示することでテンプレートに回答を埋め込むようにしました。

タスク1からタスク3の場合は、テンプレートに関数の結果を埋め込む形で回答してください。[要約]には、結果をリージョンごとに要約したものを配置してください。[詳細]には、関数の結果をフォーマット例を参考にJSONとして整形し、配置してください。なお”json”という言語識別子は不要です。

「整形」や「フォーマット」などの文言で指示しても JSON をきちんと整形してくれるわけではなかったため、以下のようなフォーマット例を参照させています。

[
  {
    "region": "us-east-1",
    "totalInstances": 0,
    "runningInstances": 0
  },
  {
    "region": "us-east-2",
    "totalInstances": 1,
    "runningInstances": 0
  }
]

余計な文言の抑制

LLM の回答では、テンプレートに沿った回答を指示してもその前後に関係のない文言を付け加えてしまうことがよくあります。この現象は以下のような指示で抑制することができました。このあたりの精度はモデルによるかもしれません。

応答はテンプレートの形式を満たし、「要約」で開始して「以上」で終了してください。

XML タグ

テンプレートへの埋め込みは XML タグで指示すると精度が上がりますが、タグごと回答に含めてしまう傾向がありました。このため今回は XML タグによる指示は行いませんでした。後処理でプログラム的に中身だけ取得するようなケースでは XML タグを使ったほうが確実かと思います。

動作確認

スタックのデプロイをすませ、動作確認します。

初期応答は問題ありません。

108472_1

エージェントのアクションを使わない応答は問題なさそうです。

108472_2

会話履歴も保持しています。

108472_3

Task 1: 全リージョンのインスタンス数の取得

108472_4

Task 2: 全リージョンの Owner タグのないインスタンスの取得

108472_5

Task 3: 全リージョンのインバウンドが解放されたインスタンスの取得 (長いので展開していませんが、問題なく取得できています)

108472_6

おわりに

Agents for Amazon Bedrock を呼び出す Slackbot を Go 言語で実装してみました。正直、オペレーションの結果を投稿するだけなら Bedrock である必然性はないのですが、今回のケースだと以下のような実益があります。

  • まず要約を提示してから詳細を提供することで受け取る側の認知負荷を下げることができる
  • 文脈を保持したまま追加の質問を被せたり、見解を述べさせたり、まとめさせたりできる

今後、付随する機能として以下も試してみたいと思います。

  • Amazon EventBridge を使って定期投稿する (レポート生成)
  • JSON が大きい場合は 3000 文字を超えることもありうるので、S3 にアップロードして署名付き URL を返す