はじめに
本記事はNext.jsでのOpenaiAPIを使った開発の際、進化版JSONモードであるStructured Outputを使ったときのことをまとめます。
あくまでも使い方を備忘録的にまとめたものになりますので、より細かい情報が欲しい場合は公式ドキュメントにアクセスしてください
環境
- Next.js 13.4.5
- React 18.2
- openai 10.9.0
JSON形式について
JavaScript Object Notationの略称で、可視性と処理の速さを両立したデータ形式。
JavaScriptにおけるオブジェクトのような構造を持つ
実装
公式ドキュメントの通りに実装していきます。
Next.jsにおけるOpenAIAPIの使い方については過去の記事を参照してください。
コード
import { NextResponse, NextRequest } from 'next/server';
import { OpenAI } from 'openai';
import { zodResponseFormat } from 'openai/helpers/zod.mjs';
import { z } from 'zod';
import type { OpenaiTypes } from '@/types';
export async function POST(req: NextRequest) {
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY });
const Human = z.object({
name: z.string(),
age: z.number(),
});
const completion = await openai.beta.chat.completions.parse({
model: "gpt-4o-2024-08-06",
messages: [
{ role: "system", content: "入力される文章から名前と年齢を抜き出して" },
{ role: "user", content: "こんにちは、私は太郎です。20歳です。" },
],
response_format: zodResponseFormat(Human, "human"),
});
const response = completion.choices[0].message.parsed;
console.log(response);//{ name: '太郎', age: 20 }
return NextResponse.json(response);
}
解説
1. Zodのインストール
typescriptにおけるデータ構造を管理するライブラリであるZodを使用します。
npm install zod
2. インポート
OpenAI
のインポートに加えて、zodResponseFormat
とz
をインポートします。
import {OpenAI} from 'openai';
import { zodResponseFormat } from 'openai/helpers/zod.mjs';
import { z } from 'zod';
3. 出力形式の定義
下の様に、出力形式を定義します。配列や、ネストされたオブジェクト構造での宣言も可能です。
const Human = z.object({
name: z.string(),
age: z.number(),
});
出力は以下の形式をサポートしています(公式ドキュメントより引用)
- String
- Number
- Boolean
- Integer
- Object
- Array
- Enum
- anyOf
4.モデルの選択
公式ドキュメントには次のように書かれています。すべてのgpt-4o系のモデルで動作が確認できました。
Supported models
Structured Outputs are available in our latest large language models, starting with GPT-4o:
gpt-4o-mini-2024-07-18 and later
gpt-4o-2024-08-06 and later
Older models like gpt-4-turbo and earlier may use JSON mode instead.
5.API呼び出し
追加のプロパティ、response_format
を指定し、出力を調節します。
zodResponseFormat
の引数はそれぞれ(作成したスキーマ,スキーマの識別子)
となります
const completion = await openai.beta.chat.completions.parse({
model: "gpt-4o-2024-08-06",
messages: [
{ role: "system", content: "入力される文章から名前と年齢を抜き出して" },
{ role: "user", content: "こんにちは、私は太郎です。20歳です。" },
],
response_format: zodResponseFormat(Human, "human"),
});
6.応答を取り出す
↓のようにして応答をJSON形式で取り出します
const response = completion.choices[0].message.parsed;
console.log(response);//{ name: '太郎', age: 20 }
ちなみに、completion.choices[0].message
は次のようになっていることから、
.content
で文字列、.parsed
でJSON形式のオブジェクトを取り出せることが分かります
{
role: 'assistant',
content: '{"name":"太郎","age":20}',
refusal: null,
tool_calls: [],
parsed: { name: '太郎', age: 20 }
}
また、得られた出力は通常のオブジェクトの様にドットでプロパティの値を取り出せます。
console.log(response.name);//=>太郎
console.log(response.age);//=>20
まとめ
以上になります。生成AI関連のトレンドな技術は半年前のブログがもう古かったりするので公式docが最強ですね
まだまだ勉強中ですので慣習と違うとこがありましたらご指摘ください!!
参考