こんなの作ってみました。
エージェント開発の試行錯誤っぷりをお楽しみください。
Agents for Amazon Bedrockの構築方法
前回の構成をもとにしました。
Agents for Amazon Bedrockの構築方法は他の方の投稿などを参照ください。
(皆さん、検証が早い!w)
概要
-
概要図:
ホテルの予約はGoogleカレンダーに登録するようにしました。APIが用意されていて簡単に使用できました。
-
API:
はじめは予約を行うAPIと客室が空いているかをチェックするAPIの2つを用意しました。
お試しなので、誰かが予約済みの場合は予約できないような感じで作りました。パス Description リクエストボディ(例) /reserve 予約を行うAPI {
"reservation_holder": "string",
"checkin": "2023-12-28",
"checkout": "2023-12-28"
}/is_vacancy 予約可能かどうかを判定するAPI {
"checkin": "2023-12-28",
"checkout": "2023-12-28"
} -
Model:
ケチなので
anthropic.claude-instant-v1
を選択しました。 -
Instructions for the Agent:
あなたはホテルの予約管理を行うAIアシスタントです。 高級ホテルのフロントマンのように振る舞ってください。
Lambdaのソースコードはこちら。
試行錯誤
パターン①:ユーザー側が気を使って丁寧に入力する
まずは手始めに、ユーザーがAPI側に合わせた入力をしてくれるパターンです。
APIに必要なパラメーターは以下の3つです。
- 予約者名
- チェックイン日
- チェックアウト日
一つの入力中にわかりやすく入れてみました。
期待通り動作しました。Googleカレンダーにも上手に登録されています。
パターン②:情報を小出しにしてみる
チャットでのやり取りっぽく、情報を小出しにしてみました。
情報が不足していると何が知りたいかを聞いてくれました。
ただ、予約に不要な連絡先をしつこく聞いてくる。。
こちらのパターンも、ちゃんと予約されました。
パターン③:もっと雑に依頼する
日付だけを雑に入力してみました。フォーマットが違うよと怒られます。
諦めずに挑戦してみますが、頑なに断ってきます。
実装を確認します。
class is_vacancy_req(BaseModel):
checkin: datetime.date = Field(description="チェックイン日")
checkout: datetime.date = Field(description="チェックアウト日")
FastAPIのドキュメント(Extra Data Types)で確認したところ、datetime.date
で定義した値はISO 8601フォーマットである必要があるようです。
datetime.date
In requests and responses will be represented as a str in ISO 8601 format, like: 2008-09-15.
入力チェックが厳しく、API内でエラーになってました。
-
解決方法
-
型定義を
datetime.date | str
に変更class is_vacancy_req(BaseModel): checkin: datetime.date | str = Field(description="チェックイン日") checkout: datetime.date | str = Field(description="チェックアウト日")
-
受け取った
checkin
とcheckout
を関数内で文字列型変換する。
dateutil.parser
のparse
を使うことで、ある程度表記ゆれにも対応できるようです。(ドキュメント)now = datetime.datetime.now(timezone) checkin = parse(request.checkin) checkout = parse(request.checkout) # 2023/12/28に1/1をパースすると、2023/1/1になるので、2024/1/1になるように調整 if checkin.astimezone(timezone) < now: checkin = checkin + relativedelta.relativedelta(years=1) if checkout.astimezone(timezone) < now: checkout = checkout + relativedelta.relativedelta(years=1)
-
こうすることで、日付が適当なフォーマットでも予約できました。
しかーし!
John Doeって誰やねん。。
出典:Wikipedia
英語で「名無しの権兵衛」に相当するのは、ジョン・ドウ (John Doe) である。Doe 自体に架空の姓の意味がある。ジョンは、ありふれた男性の名前であり、女性が対象となる場合は同様の理由でジェーンが用いられ、ジェーン・ドウ (Jane Doe) となる。複数の「名無しの権兵衛たち」を表す場合はそれぞれジョン・ドウズ (John Does)、ジェーン・ドウズ (Jane Does) となる。
予約名は必ずユーザーに問い合わせるようにしたいです。
Instructions for the Agentに一行追加してみます。
あなたはホテルの予約管理を行うAIアシスタントです。
高級ホテルのフロントマンのように振る舞ってください。
+ お客様名を間違えることは許されません。まずはお客様名を訪ねてください。
これで再挑戦したけど、改善しない。。。
さて、どうしたものか。。もうプロンプトで改善するアイディアは限界です。
モデルをClaude V2.1
(anthropic.claude-v2:1)にしてみると、、、
お!改善!!
さすがClaude V2.1!!!
東京リージョンに来てくれてありがとうございます!!!
(当分、来ないんじゃないっすかぁ。。とか言いふらしてごめんなさい!!!)
パターン④:「来週末」みたいな言い方で予約したい
どんどん欲が出てきます。「来週の土日」で挑戦します。
わかってたことですが、日付が違います。(来週末は1/6です)
Claudeが日付を知ってる訳はないので、日付情報を取得できるよう、APIを追加しました。
パス | Description | リクエストボディ(例) |
---|---|---|
/get_today | 処理当日の日付が取得できます |
リクエストボディはありません。レスポンスは"2023/12/28"
のように日付情報だけを返却します。
このAPIを足して再度挑戦です。
今週末を聞いてみると、、
いいね!
どことなくClaude 2.1にしたことでやり取りも丁寧になった気がします。
今週末がだめなので来週末で予約しました。
ホテルっぽいね!
パターン⑤:空いてる日を雑に聞く
どんどんイジワル質問がしたくなりますね。来週の月曜から水曜日で空いてるところありますか?と聞いてみました。
予約状況としては、火曜日から水曜日は予約が入ってますが、月曜日から火曜日は予約が入ってない状態でした。
一泊ではなく月曜日から水曜日の2泊の間が確保できるかチェックして、空いてないという判断になりました。
他の聞き方として、「1/8の週の水曜日」はどうでしょうか
残念ながら1/3になりました。水曜日はあってるのですごいですね。
日付の計算は間違うこともまだありますね。
パターン⑥:予約の変更がしたい
予約の変更機能を追加します。
3つのAPIを足すイメージです。
- 予約取得API
- 予約変更API
- 予約削除API
ですが、Agents for Amazon Bedrockのクオータ制限で、1つのAgentに5つのAPIまでしか含めることができません。
すでに3つAPIを使っているので、予約変更と予約削除を一つのAPIにして、フラグ制御をするようにしました。
パス | Description | リクエストボディ(例) |
---|---|---|
/get_my_reservation | 自分の予約を取得するAPI | { "reservation_holder": "string" } |
/update_reservation | 予約を更新するAPI | { "update_type": "update", "reserve_id": "string", "reserve_info": { "reservation_holder": "string", "checkin": "2023-12-28", "checkout": "2023-12-28" } } |
フラグでの制御とか、上手にできるか心配。。
予約の日付変更を実験
試行錯誤の結果、なんとか動きました!
色々やってる途中で、予約をキャンセルして別の日で取りますか?と、親切に言ってくれたので従ってみました。
いいですね!
ちゃんと1/6の予約が消えて、1/10に予約が入ってました。
つまずいたところ
-
リクエストパラメーターは必須だけで構成する
API定義で必須でなくしたり、条件付きで必須にすると、自動生成されるプロンプトには含まれないことがわかった。
-
リクエストに深いネストはやめた方がいい
パラメーターはフラットな形式にしないと正しく受け取れないように思う(FastAPIとの組み合わせのせいかもしれない)
まとめ
- デバッグがつらい。どこまでうまく動いているのか、何がだめなのかが、生成されたプロンプトを追わないといけない
- まだ上手く使いこなせていないのか、思ったように振る舞わせるのはまだまだ調整が必要
- 1つのエージェントでAPIが5個までなので、それほど複雑なことはできなさそう
- このままだと人の予約も見れちゃったりするので、プロダクションにはまだ遠い印象