LoginSignup
0
0

OpenAIのfunction callingを使って構造化されたダミーデータを生成する

Posted at

はじめに

OpenAI APIのfunction callingを使って、構造化されたダミーデータを生成してみました。

function callingによる構造化のよくある事例は、元になるテキストとデータ仕様を与えて、データ仕様に沿った情報を抽出する操作ですが、今回は、元になるテキストは与えず、データ仕様だけ与えて、そのデータ仕様に合致した構造化データをfunction callingで生成する、ということをやってみます。

以下のコードを実行してみたところ、指定した個数のダミーデータを得ることができました。

import openai
from openai_function_call import OpenAISchema
from typing import List
from pydantic import Field
import os
import dotenv

dotenv.load_dotenv()
openai.api_key = os.getenv("OPENAI_API_KEY")

class UserDetails(OpenAISchema):
    """User Details"""
    name: str = Field(..., description="User's name")
    age: int = Field(..., description="User's age")

class Users(OpenAISchema):
    """Users"""
    users: List[UserDetails] = Field(..., description="List of users")

completion = openai.ChatCompletion.create(
    model="gpt-3.5-turbo-0613",
    functions=[Users.openai_schema],
    messages=[
        {"role": "system", "content": "与えられたスキーマに沿って架空の人物を5名、生成してください"}
    ],
    function_call={"name": "Users"}
)

user_details = Users.from_response(completion)
print(user_details)
users=[UserDetails(name='John', age=25), UserDetails(name='Emily', age=30), UserDetails(name='Michael', age=35), UserDetails(name='Sophia', age=28), UserDetails(name='William', age=32)]

コード解説

ダミーのユーザーデータをChatGPTに生成させるタスクを想定します。
ユーザは名前と年齢の情報を持つとします。

function callingに渡すためのデータ構造の定義のために、openai_function_callを使います。データ構造の定義がpythonライクに直感的に書けるので便利です。

ライブラリをインストールします。

pip install openai-function-call python-dotenv

データ構造を定義します。

class UserDetails(OpenAISchema):
    """User Details"""
    name: str = Field(..., description="User's name")
    age: int = Field(..., description="User's age")

function callingを実行してみます。

completion = openai.ChatCompletion.create(
    model="gpt-3.5-turbo-0613",
    functions=[UserDetails.openai_schema],
    messages=[
        {"role": "system", "content": "与えられたスキーマに沿って架空の人物を5名、生成してください"}
    ],
    function_call={"name":"UserDetails"},
)

user_details = UserDetails.from_response(completion)
print(user_details)
name='Alice' age=25

25歳のAliceというユーザデータを構造化済みの状態で得ることができました。
しかし、1回のコールで1データしか得られないため、効率が悪いです。

そこで、UserDetailsのリストが得られるように、データ構造を修正します。修正というか、UserDetailsのリストを要素にもつ新たなクラスUsersを定義します。

class Users(OpenAISchema):
    """Users"""
    users: List[UserDetails] = Field(..., description="List of users")

これをfunction callingに渡して、実行します。

completion = openai.ChatCompletion.create(
    model="gpt-3.5-turbo-0613",
    functions=[Users.openai_schema],
    messages=[
        {"role": "system", "content": "与えられたスキーマに沿って架空の人物を5名、生成してください"}
    ],
    function_call={"name": "Users"}
)

user_details = Users.from_response(completion)
print(user_details)
users=[UserDetails(name='John', age=25), UserDetails(name='Emily', age=30), UserDetails(name='Michael', age=35), UserDetails(name='Sophia', age=28), UserDetails(name='William', age=32)]

messagesで指定した個数(5個)のuser情報を1回のコールで得ることができました。

おわりに

function callingを使って、構造化されたダミーデータを直接生成することを試してみました。
function callingが情報抽出に使えること自体はよく知られています(参考1参考2)が、元になるテキスト無しで構造化されたダミーデータを直接生成できるかどうかは、軽く調査した範囲では事例がなく、やってみる前はよくわかりませんでした。ちゃんと調べれば誰かは試していると思うのですが、自分で試したほうが早いので、やってみたところ、すんなり生成できることがわかりました。

ダミーデータ生成自体はChatGPTの有用な使い方の1つ(参考1参考2)ですが、構造化のためのプロンプト工夫や後処理が面倒なことが多いため、今回の方法が有用なシーンはそこそこあるような気がします。

本記事がどなたかのお役に立てば嬉しいです。

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