[Agents for Amazon Bedrock] 居酒屋の案内と予約ができるエージェントをCDKでデプロイしてみました

2024.06.16

1 はじめに

CX事業本部製造ビジネステクノロジー部の平内(SIN)です。

Agents for Amazon Bedrockを使用すると、Knowledge bases for Amazon BedrockやLambdaを呼び出して複雑な処理ができるエージェントを作成することができますが、今回は、これを手軽にデプロイ出来るようにとCDK化してみました。

最初に、作成したエージェントが動作している様子をご確認ください。

居酒屋に関する質問は、ナレッジベースの情報を使ってレスポンスし、予約を希望すると、日時や人数など必要な情報を聞き取って、「予約」を行っているのがわかります。

ナレッジベースとして使用したのは、前回作成した「架空の居酒屋案内」です。

予約は、「予約API」として作成したLambdaを呼び出しますが、実装としては、渡されたパラメータをログに残すだけのものになっています。

実際に「居酒屋の予約」となると、空席の確認や、キャンセル対応など、色々複雑な作業が必要だと思いますが、今回は、エージェントからLambdaが実行されることの確認のみとなっていることをご了承ください。

2 Knowledge bases for Amazon Bedrock

Knowledge bases for Amazon Bedrockで使用されている、データや、データベース(Pinecone)についての説明は、前回のブログをご参照ください。

[Knowledge bases for Amazon Bedrock] 居酒屋の案内をするナレッジベースをCDKでデプロイしてみました

なお、今回作成したCDKでは、このナレッジベースも併せてデプロイされます。

3 エージェント向けの指示

「エージェント向けの指示」は、以下のようになっています。

ユーザが、「お店に関する質問」を行った場合、ナレッジベースが使用され、「予約」の場合、「予約API」(Lambda)を呼び出すようになっています。

あなたは、居酒屋の店員です
あなたは、{予約の受付}と{お店に関する質問}ができます

## 予約の受付

予約の受付は、以下のとおり作業します
  {予約日}が、不明の場合は、ユーザーに聞いて下さい
  {予約時間}が、不明の場合は、ユーザーに聞いて下さい
  {予約人数}が、不明の場合は、ユーザーに聞いて下さい
  {予約日}、{予約時間}、{予約人数}の全部が揃ったら {予約API}を呼び出してください

以下は、会話の例です

ユーザー: 3月1日に予約したいです
エージェント: 3月1日の何時からですか
ユーザー: 18時です
エージェント: 何人で予約しますか
ユーザー: 3人です


## お店に関する質問

予約以外の質問は、{居酒屋案内のナレッジベース}を使用して答えます

4 Lambda

Lambdaは、予約日、予約時間、及び、予約人数の3つのパラメータをとります。

「エージェント向けの指示」で指示された通り、必要なパラメータが不足しているときは、ユーザーへの確認が行われます。

例えば、次のように、必要なパラメータが全部揃っている時は、直ちにLambdaが起動されます。

そして、不足している場合は、それをエージェントが聞き取っているのがわかります。

Lambdaのコードは、以下です。最初に書いた通り、単純に受け取ったパラメータをログに残しているだけです。

パラメータとレスポンスの形式については、下記にドキュメントがあります。

Amazon Bedrock のアクショングループを満たすために Amazon Bedrock エージェントがユーザーから引き出す情報を送信するように Lambda 関数を設定する

exports.handler = async function (event: any) {
  // パラメータ表示
  const params: { date: string; hour: string; numberOfPeople: string } = { date: "", hour: "", numberOfPeople: "" };
  event["parameters"].forEach((param: any) => {
    const key = param["name"] as keyof typeof params;
    if (params.hasOwnProperty(key)) {
      params[key] = param["value"];
    }
  });
  console.log(`date(予約日):${params.date} hour(時間):${params.hour} numberOfPeople(人数):${params.numberOfPeople}`);

  // レスポンス
  return {
    messageVersion: "1.0",
    response: {
      actionGroup: event["actionGroup"],
      function: event["function"],
      functionResponse: {
        responseBody: {
          TEXT: {
            body: "OK",
          },
        },
      },
    },
    sessionAttributes: event["sessionAttributes"],
    promptSessionAttributes: event["promptSessionAttributes"],
  };
};

4 CDK

(1) コード

CDKの主なコードは、以下です。

Pineconeをストレージとするナレッジベースとデータソースに併せて、Lambdaが定義されています。 また、「エージェント向けの指示」は、assetsにテキストとして格納しました。

lib/agent-izakaya-stack.ts

(2) デプロイ

CDKのコードは、Githubにあり、以下の手順でデプロイできます。

https://github.com/furuya02/amazon-bedrock-agents-izakaya/

% git clone https://github.com/furuya02/amazon-bedrock-agents-izakaya.git
% cd amazon-bedrock-agents-izakaya
% npm i

cdk.jsonにPineconeに関する設定がありますので、エンドポイント及びシークレットのARNを編集します。

"context": {
    "pineconeEndpoint": "https://xxxxxxx.pinecone.io",
    "pineconeSecretArn": "arn:aws:secretsmanager:us-east-1:xxxxxxxx",

CDKデプロイは、以下のとおりです。

% export AWS_DEFAULT_REGION=us-east-1
% npx cdk deploy

Githubリポジトリの、assetsフォルダにナレッジベース用のデータがありますので、作成されたバケットにアップロード してください。

% aws s3 cp assets/izakaya_guidance.pdf s3://kb-izakaya-xxxxxxxx/izakaya_guidance.pdf
% aws s3 cp assets/izakaya_menu.txt s3://kb-izakaya-xxxxxxxx/izakaya_menu.txt

5 動作確認

更新の後は、「準備」をクリックしてら「テスト」で、動作確認が可能です。

6 最後に

今回は、Knowledge bases for Amazon Bedrock及び、Lambdaを使用したAgentsをCDKで作成してみました。

ちょっと難しかったのは、Lambdaのパラメータを適切に渡すあたりでした。最終的には、時間、人数などを分解し、可能な限りinteger型を使用することで、やや安定して受け渡しができるようになった感じです。

ちなみに、date「予約日」は、String型であり、X月X日みたいな標準化はされません。「明日の18時から」とからだと、「予約日」には、「tomorrow」が入っていました。

この辺は、LLMで頑張るのか、プログラムで頑張るのか、ちょっと検討が必要そうです。

細かいところ、難しい問題は色々ありそうですが、この強力な Agents for Amazon BedrockをCDK化しておくことで、手返し良く試せるのでは?と妄想しています。