じゃらんAIチャット的なものをChatGPT x microCMSで作ってみた
じゃらんさんのAIチャットが話題ですね。
AIチャットは「東京から車で1時間でいける温泉宿を教えて」などとチャットでリクエストすると、該当する宿やエリアを教えてくれるというものです。
AIチャットで宿を探せる
応答は「温泉」や「ご飯」などの最初に聞いた内容に準じた形で回答してくれるため、窓口で聞いているような体験ができます。
大変面白いと思ったので、同じような仕組みをChatGPT x microCMSで作ってみました。
作ったもの
AIチャットのデモ(ここで試せます)
ルームサービスのメニューについて教えてくれるAIチャットです。
質問内容を理解して、文脈に合ったメニューを回答します。
仕組み
ChatGPTとmicroCMSを組み合わせて実装しています。
入力を受け付けて応答するまでの処理は、以下のようなことをしています。
裏側でChatGPTのAPIを2回、microCMSのAPIを1回叩いています。
microCMSのデータ構造
ルームサービスのメニューはmicroCMSで管理しています。
今回は3つのメニューを登録しました。
microCMSは入稿したコンテンツをAPIベースで取得できます。
例えば以下のようにクエリパラメータを指定すると、「1,000円以内の和食のメニュー」 を取得できます。
https://room-service-him.microcms.io/api/v1/menus
?filters=price[less_than]1000[and]genre[contains]和食
レスポンスのイメージ
{
"contents": [
{
"id": "cupg071dpn",
"name": "肉じゃが",
"genre": [
"和食"
],
"price": 900,
"description": "シェフこだわりの牛肉を使った肉じゃがです。"
}
]
}
金額とジャンルで絞り込んだメニューのみが取得できています。
このメニューの絞り込みを、チャット経由で実現しようというのが今回の試みです。
実装
それでは実装の解説です。3つのステップを順に紹介していきます。
1. ユーザーの入力から条件を抽出する(ChatGPT)
ユーザーは自然言語でチャット欄に入力します。
ChatGPTを使って、入力された内容から「金額」「ジャンル」を抽出していきましょう。
次のようなプロンプトでChatGPTにリクエストします。
次のテキストから、「価格」と「ジャンル(和食・洋食・中華 のいずれか)」を抽出してください。
出力はJSONで。
======================
${inputString}
======================
# Example_1
-----
価格: 500円以上、1000円以下
ジャンル: 和食
{
"price_less_than": 1000,
"price_greater_than": 500,
"genre": "和食"
}
-----
# Example_2
-----
価格: 2000円以下
ジャンル: 和食
{
"price_less_than": 2000,
"genre": "和食"
}
-----
# Example_3
-----
価格: 指定なし
ジャンル: 和食
{
"genre": "和食"
}
-----
# Output
`;
${inputString}
にユーザーの入力文を渡すと、条件を抽出してJSON形式で出力してくれます。
次の画像を見ると、入力テキストから条件部分を抽出できていることがわかります。
抽出された条件が下に表示されている
2. 条件に合うメニューを取得する(microCMS)
抽出した条件を使って、microCMSからメニューを取得します。
filters
パラメータを使ってコンテンツを絞り込んでいます。
// microCMS JS SDKを使ってデータを取得する
const { createClient } = require("microcms-js-sdk");
const client = createClient({
serviceDomain: "room-service-him",
apiKey: process.env.MICROCMS_API_KEY,
});
// 金額、ジャンルでフィルタする
const data = await client.get({
endpoint: "menus",
queries: {
filters: "price[less_than]2000[and]genre[contains]洋食",
},
});
microCMSからのレスポンス(data
)は次のようになっています(見やすさのため一部省略)。
{
contents: [
{
id: 'r94ojnu_tt',
name: 'カルボナーラ',
genre: [ '洋食' ],
price: 1200,
description: 'チーズをふんだんに使ったカルボナーラ。スタッフのイチオシです。'
},
{
id: 'qrrz5n3ct8hx',
name: 'ピザ',
genre: [ '洋食' ],
price: 1600,
description: '厨房の釜で焼き上げたマルゲリータピザ。出来立てをお届けします。'
}
],
totalCount: 2,
offset: 0,
limit: 10
}
3. 絞り込んだメニュー情報を渡して応答文を生成する(ChatGPT)
取得したメニュー情報を参考情報としてChatGPTに渡し、応答文を生成します。
まずは、先ほど取得したメニュー情報を文字列に変換します。
const menuStrings = data.contents.map((menu: any) => {
return `メニュー名: ${menu.name}
ジャンル: ${menu.genre}
価格: ${menu.price}円
特徴: ${menu.description}
----------`;
このメニューのテキスト情報を使って、以下のようにプロンプトを組みます。
あなたはユーザーの質問に答えるアシスタントです。
ルームサービスのメニューについての質問に答えてください。メニューの特徴を添えると喜ばれます。
メニューの情報:
=============
${menuStrings.join("\n")}
=============
ユーザーからの質問:
=============
${input}
=============
アシスタントの回答:
`;
文脈に合うメニューをプロンプトに渡して、その上でユーザーの質問文に回答するように指示しています。
ChatGPTはコンテキストに合った回答をするため、ユーザーが温度について聞いていればその面を強調して答えるなど、自然な会話の流れでメニューを紹介します。
温かいものを聞いたので、そこに触れた応答文になっている
今回はデモなので簡単な例にしていますが、応答にメニューページへのURLを含めたり、自由なキーワードでメニューを調べたりなど拡張もできそうです。
作ったもの(再掲)
実装はこれで完了です。改めて動作を見てみましょう。
ChatGPT → microCMS → ChatGPT の順にAPIを叩いている(デモはこちら)
応答を生成する部分はChatGPTのStreamを利用して逐次出力するようにしています。
待ち時間も短縮され、内容が少しずつ表示されていて体験がよくなっているかと思います。
おわりに
ChatGPTとmicroCMSを組み合わせてAIチャットの機能を実装してみました。
今回は価格とジャンルの2つの条件でしたが、microCMSに保存するデータ構造を高度にすれば、より要望にマッチした結果を回答できます。
裏側でやっていることは検索なので、Webページで詳細検索のUIを提供するのと役割自体は同じです。
しかしユーザーにリテラシーを求めない点や、会話のなかで目当てのコンテンツを見つけていく体験は心地よく、チャットならではの良さを感じました。
今回はルームサービスを例に作りました。他にもいろいろな応用ができると思います。
末にソースコードを添付しているので、興味があれば色々試してみてください。最後までお読みいただきありがとうございました。
Appendix
今回紹介したものはこちらのサイトでお試しいただけます。
また、ソースコードはGitHubで公開しています。
どなたかのお役に立てれば幸いです。
Discussion