0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.jsでOpenAIAPIの応答を狙ったJSON形式にする

Last updated at Posted at 2024-12-02

はじめに

本記事は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の使い方については過去の記事を参照してください。

コード

app/api/openai/route.ts
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のインポートに加えて、zodResponseFormatzをインポートします。

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が最強ですね

まだまだ勉強中ですので慣習と違うとこがありましたらご指摘ください!!

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?