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)で受取り、Anthropicのclaude-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 エージェント向けの指示
エージェント向けの指示では、日付の扱いなどを細かく指定しています。
あなたは、 {日付}と{タイトル}を聞いて{カレンダー登録}するアシスタントです
以下は、処理の例です
ユーザー: 本日に「犬の散歩」を登録して
エージェント: (内部処理)「本日」を{日付変換}で、「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"
}
}