過去にQiitaに投稿した内容のアーカイブです。
こんなの作ってみました。
エージェント開発の試行錯誤っぷりをお楽しみください。
Agents for Amazon Bedrockの構築方法
前回の構成をもとにしました。
Agents for Amazon Bedrockの構築方法は他の方の投稿などを参照ください。 (皆さん、検証が早い!w)
https://qiita.com/nasuvitz/items/c34419150eaee78544cc
https://qiita.com/Naoki_Ishihara/items/769f373f01261aec285a
https://qiita.com/cyberBOSE/items/14cf7024ea42ec1fb4be
https://qiita.com/minorun365/items/86a3667290a8e5657f65
https://dev.classmethod.jp/articles/agents-for-amazon-bedrock-ga/
概要
概要図:
ホテルの予約は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のソースコードはこちら。
https://github.com/moritalous/hotel-booking-agents
試行錯誤
パターン①:ユーザー側が気を使って丁寧に入力する
まずは手始めに、ユーザーが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個までなので、それほど複雑なことはできなさそう
- このままだと人の予約も見れちゃったりするので、プロダクションにはまだ遠い印象