はじめに
OpenAI DevDayで発表されたJSONモードをAWS Lambdaを利用して試してみました。
OpenAIの開発者向けカンファレンスのDevDayで様々なアップデートがありました。
弊社ブログでも発表内容がまとめられています。
アップデートのうち、JSON形式でレスポンスを返すことが保証されたJSONモードがサポートされましたので、今回は、新機能をAWS Lambdaを利用して試してみます。
JSONモードに関するドキュメントは、以下のみでコードの例がなかったため、コードも含めて紹介します。
利用するにあたり注意点
- モデルのうち
gpt-4-1106-preview
とgpt-3.5-turbo-1106
のみでJSONモードが利用可能です。 response_format
に{ type:"json_object" }
を設定することで、JSONモードが有効になります。- プロンプトに
JSON
という言葉がない場合、エラーになります。 - レスポンス内容のうち、
finish_reason
がlength
の場合、メッセージが切れている可能性があります。 - JSONモードを使用すると、出力データが正しいJSON形式であることは保証されます。しかし、そのデータが特定のスキーマ(データの構造や形式)に一致するかどうかは保証されません
Lambda
Lambdaで利用するOpenAIアカウントAPIキーの発行方法やOpenAIが提供するPython向けのライブラリをLambdaにアップロードする方法は下記の記事を参考ください。
ランタイムPython 3.11
を選択し、Lambda関数を作成します。
作成後、下記の設定を行います
- 環境変数では、キーはAPI_Key、値はAPIキーの値を入力
- Lambdaのレイヤーを追加します
試してみた
下記のコードで実行してみます。
この例では、1月から12月までの月末の日付(31日、30日など)をグルーピングしてJSON形式で出力しています。
gpt-4-vision-preview
は1日100回までの制限があったため、gpt-3.5-turbo-1106
で検証しました。
from decimal import Decimal
import json, os, openai
def decimal_to_int(obj):
if isinstance(obj, Decimal):
return int(obj)
def lambda_handler(event, context):
openai.api_key = os.environ['API_Key']
input_text = """
1月から12月のうち、月末の日付(31日、30日など)からグルーピングしてJSON形式で出力してください
"""
response = openai.ChatCompletion.create(
model="gpt-3.5-turbo-1106",
messages=[
{"role": "user", "content": input_text}
],
response_format= { "type":"json_object" },
temperature=0,
)
response_content = response["choices"][0]["message"]["content"]
response_content = json.loads(response_content)
print("Received response:" + json.dumps(response, default=decimal_to_int, ensure_ascii=False))
return response_content
実行結果は以下の通り、JSONで返ってきました。また、内容も正しいです。
{
"31日": [
"1月",
"3月",
"5月",
"7月",
"8月",
"10月",
"12月"
],
"30日": [
"4月",
"6月",
"9月",
"11月"
],
"28日または29日": [
"2月"
]
}
レスポンス内容は、下記のとおりでした。
finish_reason
がlength
になっている場合は、メッセージが一部切れている可能性があります。
Received response:{
"id": "chatcmpl-8IA9bs4NAl0EVaRugRilyeCnPilSX",
"object": "chat.completion",
"created": 1699339627,
"model": "gpt-3.5-turbo-1106",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "{\n \"31日\": [\"1月\", \"3月\", \"5月\", \"7月\", \"8月\", \"10月\", \"12月\"],\n \"30日\": [\"4月\", \"6月\", \"9月\", \"11月\"],\n \"28日\": [\"2月\"]\n}"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 51,
"completion_tokens": 65,
"total_tokens": 116
},
"system_fingerprint": "fp_eeff13170a"
}
エラー
ちなみに、input_text
内にJSONという言葉を削除すると、以下の通り、JSONという言葉をいれましょうと、エラーメッセージが出力されました。
'messages' must contain the word 'json' in some form, to use 'response_format' of type 'json_object'.
他のプロンプト 1
input_text
を下記にしてみます。
input_text = """
2023年の日本の祝日とその日付を、月ごとにグルーピングしてJSON形式で出力してください。
会社の休みが1月4日と12月4日にあるので、追加してください。
日付を昇順にしてください。
"""
レスポンスは下記のとおりです。
天皇誕生日は、令和においては祝日ではないので、間違えていますね。
{
"1月": {
"元日": "2023-01-01",
"成人の日": "2023-01-09",
"会社の休み": "2023-01-04"
},
"2月": {
"建国記念の日": "2023-02-11"
},
"3月": {
"春分の日": "2023-03-21"
},
"4月": {
"昭和の日": "2023-04-29"
},
"5月": {
"憲法記念日": "2023-05-03",
"みどりの日": "2023-05-04",
"こどもの日": "2023-05-05"
},
"7月": {
"海の日": "2023-07-17"
},
"8月": {
"山の日": "2023-08-11"
},
"9月": {
"敬老の日": "2023-09-18",
"秋分の日": "2023-09-23"
},
"10月": {
"体育の日": "2023-10-09"
},
"11月": {
"文化の日": "2023-11-03",
"勤労感謝の日": "2023-11-23"
},
"12月": {
"天皇誕生日": "2023-12-23",
"会社の休み": "2023-12-04"
}
}
他のプロンプト 2
以前、OpenAI API のFunction Callingを利用し、プロンプトの中で、アーティスト名と曲名を抽出し、JSON形式で返すように試したことがあります。
同様のことをJSONモードでもできるか確認します。プロンプトは以下の通りです。
input_text = """
## 依頼
下記の文章から、アーティスト名と曲名を例を参考にJSON形式で出力して下さい。
アーティスト名や曲名が省略されている場合、正式名称に変換してください。
## 例
{
"artist": "Ado",
"song": "うっせいわ"
}
## 文章
オフィシャルひげだんディズムのプリテンダーをかけてほしいです。できますか?
"""
文章からアーティスト名と曲名を抽出することができました。アーティスト名は、正式名称への変換は難しいようですね。
{
"artist": "オフィシャルひげだんディズム",
"song": "プリテンダー"
}
ちなみに、gpt-3.5-turbo-1106
の場合、Lambdaの実行時間は、3秒程度でした。
終わりに
今回は、DevDayで発表されたJSONモードを試してみました。
JSON形式で返してくれるため、色々な用途で利用できそうですね。色々なプロンプトで試していきたいと思います。
参考になれば幸いです。