[Agents for Amazon Bedrock] 「次の金曜日に飲み会を登録して」〜今日が何日か知らないLLMに、自然な日付指定でカレンダー登録してみました

2024.06.18

1 はじめに

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

Agents for Amazon Bedrockでは、アクションとしてLambdaが利用できるため、簡単に外部サービスにアクセスすることが出来ます。このため、外部のカレンダーサービス等への登録をエージェントへの依頼として実装することも可能です。

LLMで自然な言語でやり取りできるメリットを考えると、日付指定で、2024-07-01みたいな、定型を要求するよりも、「明日」とか「来週の水曜日」みたいな、指定ができると良いなと思い作ってみました。

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

「明日」とか、「来月の第1日曜日」のような、自然な日付指定で利用できていることが確認できます。

下記は、今月と来月のカレンダーです。本日は、2024-06-18なのですが、 エージェントが、判断した日付は、間違っていないことが確認できます。

なお、今回は、自然な日付指定の検証が目的だったため、「カレンダー登録」自体は、実装されていません。

適切なパラメータでLambdaが実行されていることを確認するまで、となっていることをご了承ください。

2 LLMは、「本日」が分からない

当然のことですが、LLMは、学習に使用したデータの期間に依存しており、それ以外には正確に対応できません。

次のように、「本日」が、分からないのです。

そして。このような問題に対応するためは、プロンプト内に、「本日」の情報を付加して利用することが一般的です。

今回は、この仕組みをアクション(Lambda)で実装してみました。

3 動作の概要

動作の概要は、以下のとおりです。


① ユーザーが、カレンダー登録を依頼
② 日付に関する部分をパラメータとして「日付変換Lambda」を呼び出す
③ 日付指定をYYYY-MM-DDに変換する
④ 日付(YYYY-MM-DD)及び、タイトルをパラメータにして「カレンダー登録Lambda」を呼び出す
⑤ カレンダー登録する(未実装)

4 日付変換

日付変換Lambdaは、「自然言語による日付表現」をパラメータ(DateStr)で受取り、Anthropicclaude-3-haikuを使用して、YYYY-MM-DDに変換しています。

Haikuに送っているプロンプトは、以下のようになっています。

`本日は、${today}です。${dateStr}の年月日を教えて下さい。レスポンスの形式は、
YYYY-MM-DDの形式で、年月日のみを返してください`

lambda/agent-calendar-function/index.ts

import { BedrockRuntimeClient, ConverseCommand } from "@aws-sdk/client-bedrock-runtime";

const modelId = "anthropic.claude-3-haiku-20240307-v1:0";
const region = "us-east-1";

async function convertDateStr(dateStr: string): Promise<string | undefined> {
  const client = new BedrockRuntimeClient({ region: region });
  try {
    const today = new Date().toLocaleDateString();
    const userMessage = `本日は、${today}です。${dateStr}の年月日を教えて下さい。レスポンスの形式は、YYYY-MM-DDの形式で、年月日のみを返してください`;
    console.log(`userMessage: ${userMessage}`);
    const command = new ConverseCommand({
      modelId,
      messages: [
        {
          role: "user",
          content: [{ text: userMessage }],
        },
      ],
      inferenceConfig: { maxTokens: 512, temperature: 0.5, topP: 0.9 },
    });
    const response = await client.send(command);

    return response.output!.message!.content![0].text;
  } catch (err) {
    console.log(`ERROR: Can't invoke '${modelId}'. Reason: ${err}`);
  }
  return undefined;
}

exports.handler = async function (event: any) {
  console.log(event);

  let body = "unknown";

  if (event["function"] === "createDatestr") {
    const params: { dateStr: string } = { dateStr: "" };
    setParams(params, event);

    // YYYY.MM.DD 形式の日付文字列に変換する
    const dateStr = await convertDateStr(params.dateStr);
    if (dateStr) {
      body = dateStr;
    }
・・・略・・・

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

エージェント向けの指示では、日付の扱いなどを細かく指定しています。

assets/instruction.txt

あなたは、 {日付}と{タイトル}を聞いて{カレンダー登録}するアシスタントです

以下は、処理の例です

ユーザー: 本日に「犬の散歩」を登録して
エージェント: (内部処理)「本日」を{日付変換}で、「2024/06/11」という形式に変換する
エージェント: (内部処理)タイトル:「犬の散歩」日付: 2024/06/11 で{カレンダー登録}を実行する
エージェント:  2024/06/11 犬の散歩 を登録しました。

ユーザー: 7月1日に「犬の散歩」を登録して
エージェント: (内部処理)「7月1日」を{日付変換}で、「2024/07/01」という形式に変換する
エージェント: (内部処理)タイトル:「犬の散歩」日付: 2024/07/01 で{カレンダー登録}を実行する
エージェント:  2024/07/01 犬の散歩 を登録しました。

ユーザー: 来週の水曜日に「犬の散歩」を登録して
エージェント: (内部処理)「来週の水曜日」を{日付変換}で、「2024/07/12」という形式に変換する
エージェント: (内部処理)タイトル:「犬の散歩」日付: 2024/07/12 で{カレンダー登録}を実行する
エージェント:  2024/07/01 犬の散歩 を登録しました。

## 日付変換

文字列をYYYY-MM-DD形式の日付文字列に変換する
YYYY-MM-DDの形式でレスポンスが返る

## カレンダー登録

日付及びタイトルでカレンダー登録を行う
タイトルは、100文字以内の自由なテキストです

6 Lambda

登録されたアクショングループ(Lambda)は、1つです。

lambda/agent-calendar-function/index.ts

アクショングループファンクションとしては、日付変換カレンダー登録の2つが設定されており、それぞれ、createDatestr及び、writteCalenderを名前でとLambdaが呼び出されます。

Lambdaの中では、パラメータfunctionで分岐して処理しています。

if (event["function"] === "createDatestr") {

    // 自然言語の日付指定をYYYY.MM.DD 形式の日付文字列に変換して返す

} else if (event["function"] === "writeCalender") {

    // 日付 params.dateStr と タイトル params.title を使ってカレンダー登録処理を行う
}

7 CDK

コードは、Githubに置かれており、CDKとしてデプロイ出来るようになっております。

  • セットアップ
% git clone https://github.com/furuya02/amazon-bedrock-agents-calendar-registration.git
% cd amazon-bedrock-agents-calendar-registration
% npm i
% cd lambda/agent-calendar-function; npm i; cd ../..
  • CDKデプロイ
% export AWS_DEFAULT_REGION=us-east-1
% npx cdk diff
% npx cdk deploy

8 最後に

今回は、自然な日付指定を処理できるエージェントを作成してみました。 LLMで出来ること、出来ないことを見極めて、適切な処理の流れ作る作業は、なかなか難しいなと感じました。

今回、LambdaからBedrockを使用して分かったのですが、2024/06/18現在、Node.js 20.xにバンドルされているAWS-SDKのバージョンでは、Bedrockランタイムのバージョンが古いようで、以下のようにエラーとなってしまいました。

INFO    ERROR: Can't invoke 'anthropic.claude-3-haiku-20240307-v1:0'. 
Reason: TypeError: client_bedrock_runtime_1.ConverseCommand is not a constructor

Lambdaに最新の @aws-sdk/client-bedrock-runtime を追加することで、エラーは回避できました。

package.json

{
  "name": "agent-calendar-function",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "author": "",
  "license": "ISC",
  "types": "./index.d.ts",
  "dependencies": {
    "@aws-sdk/client-bedrock-runtime": "^3.598.0"
  }
}