🛒
OpenAIのAPIとFunction Callingを活用したAI販売員のサンプル実装
Function Callingを利用し、以下のような会話ができるコードを書いてみた。
- Function Callingで以下の関数を定義
- 商品ランキングのカテゴリ一覧を返す
- 商品カテゴリIDを引数で受け取り、そのカテゴリの人気商品を返す
- GPT-3.5には家電量販店の販売員をしてもらう
- 在庫がある商品を優先して案内する
- ユーザーが欲しい商品のカテゴリを入力すると、人気の商品を勧める
- ユーザーがexitと入力すると処理を終了する
実際の動作
どんな商品をお探しですか?
('exit'で終了):USBメモリ
GPT-3の回答: USBメモリのおすすめ商品は以下の通りです。
1. USBメモリA 512GB
- 在庫あり
2. USBメモリB 256GB
- 在庫なし
3. USBメモリ 1TB 令和最新型
- 在庫あり
在庫がある商品を優先していますので、USBメモリA 512GBかUSBメモリ 1TB 令和最新型がおすすめです。どちらになさいますか?
('exit'で終了):ハードディスクはある?
GPT-3の回答: 申し訳ありませんが、現在ハードディスクの在庫はございません。他の商品をお探しすることはできますので、どうぞお気軽にお申し付けください。
('exit'で終了):exit
「 ('exit'で終了):」の後ろはユーザーからの入力です。
- USBメモリ
- get_product_ranking_categoriesでカテゴリIDを取得(例の場合、USBメモリはid=1)
- get_product_rankingでUSBメモリの人気商品を取得
- ハードディスクはある?
- USBメモリと同様に処理
- こちらは在庫がないため、その旨を伝えている。素晴らしい
コード
import json
import openai
openai.organization = "org-xxx" # TODO 実際の組織IDを設定する
openai.api_key = "xxxx" # TODO APIキーを設定する
def get_product_ranking_categories(params):
# TODO APIリクエストを実装する。サンプルは固定値としている
categories = [
{"id":"1","name":"USBメモリ"},
{"id":"2","name":"ハードディスク"},
]
return json.dumps(categories, ensure_ascii=False)
def get_product_ranking(params):
# TODO APIリクエストを実装する。サンプルは固定値としている
if params.get("categoryId") == "1":
return json.dumps([
{"id": 1001, "name":"USBメモリA 512GB","isInStock":True},
{"id": 1002, "name":"USBメモリB 256GB","isInStock":False},
{"id": 1003, "name":"USBメモリ 1TB 令和最新型","isInStock":True},
], ensure_ascii=False)
return json.dumps([
{"id": 2001, "name":"HDD A","isInStock":False},
{"id": 2002, "name":"HDD B","isInStock":False},
{"id": 2003, "name":"HDD C","isInStock":False},
], ensure_ascii=False)
functions = [
{
"name": "get_product_ranking_categories",
"description": "商品ランキングのカテゴリ一覧を取得する",
"parameters": {
"type": "object",
"properties": {
"name": {
"type": "string",
"description": "カテゴリ名",
},
},
"required": [],
},
},
{
"name": "get_product_ranking",
"description": "商品カテゴリIDを受け取り、そのカテゴリの人気商品ランキングを返す。レスポンスには、商品IDと商品名、店舗在庫有無の情報を持ったdictを返す。",
"parameters": {
"type": "object",
"properties": {
"categoryId": {
"type": "string",
"description": "商品カテゴリID",
},
},
"required": ["categoryId"],
},
}
]
def ask_gpt3(conversation):
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo-0613",
messages=conversation,
functions=functions,
function_call="auto",
)
# print(response)
return response
def main():
print("どんな商品をお探しですか?")
conversation = [{"role": "system", "content": "あなたは家電量販店の販売員です。ユーザーが欲しい商品のカテゴリを聞いて、おすすめの商品を教えてあげてください。ユーザーは正確にカテゴリ名を入力しないため、カテゴリ名が一番近いであろうカテゴリを勧めてください。ただし、店舗に在庫がある商品を優先して勧めてください。"}]
while True:
# ユーザーからの入力を受け取る
user_input = input(" ('exit'で終了):")
if user_input.lower() == 'exit':
break
conversation.append({"role": "user", "content": user_input})
while True:
# GPT-3.5に質問する
response = ask_gpt3(conversation)
# レスポンスを確認
message = response.choices[0]["message"]
if message.get("function_call"):
# 関数呼び出しの場合
f_call = message.get("function_call")
function_name = f_call["name"]
args = json.loads(f_call["arguments"])
function_response = globals()[function_name](args)
# print(function_response)
conversation.append({
"role": "function",
"name": function_name,
"content": function_response,
})
else:
# GPT-3.5の回答を出力する
resMessage = message["content"].strip()
conversation.append({"role": "assistant", "content": resMessage})
print("GPT-3の回答:", resMessage)
break
if __name__ == "__main__":
main()
Discussion