Python/NLP Code

OpenAI GPT API에서 structured output 구조로 대답을 받도록 설정하는 방법 정리(pydantic 기능 활용)

jimmy_AI 2024. 11. 5. 23:08
반응형

안녕하세요.

때로는 ChatGPT API를 사용하는 과정에서 원하는 response를

포맷이 고정된 json 구조(structured output)로 받고 싶은 경우가 있습니다.

 

이런 경우를 위하여 pydantic의 type 지정 기능을 활용하여

응답의 포맷을 고정하도록 주문하는 방법들이 있는데요.

 

이를 활용하는 예시 코드들을 간략하게 살펴보면서

기능 사용법에 대한 이해를 해보도록 하겠습니다.

 

 

코드 예시

방법 1

먼저, OpenAI Client를 선언합니다.

from openai import OpenAI

OPENAI_API_KEY = "sk-xxxx" # 사용할 OpenAI API Key
client = OpenAI(api_key=OPENAI_API_KEY)

 

이후, 원하는 포맷의 json 양식을 pydantic 모델로 선언하고,

openai 모듈의 pydantic_function_tool 메소드를 활용하여

tools 객체를 아래와 같이 선언합니다.

from pydantic import BaseModel
import openai

class GetUserInfo(BaseModel):
    user_name: str
    age: int
    gender: str

tools = [openai.pydantic_function_tool(GetUserInfo)]

 

이후, client 호출을 다음과 같은 양식으로 진행하면

선언한 pydantic 양식에 맞는 structured output이 생성된 결과를

살펴보실 수 있습니다.

messages = []
messages.append({"role": "system", "content": "당신은 유저의 정보를 추출하는 assistant입니다. 주어진 말을 듣고 필요한 유저의 정보들을 추출해주세요."})
messages.append({"role": "user", "content": "안녕하세요. 제 이름은 jimmy이고요, 나이는 28세 입니다. 성별은 남성이에요."})

response = client.chat.completions.create(
model='gpt-4o-2024-08-06',
messages=messages,
tools=tools
)

print(response.choices[0].message.tool_calls[0].function)
# Function(arguments='{"user_name":"jimmy","age":28,"gender":"남성"}', name='GetUserInfo')

 

실제 결과로 추출한 정보는 다음과 같이 파싱이 가능합니다.

# result 객체는 딕셔너리 구조
result = eval(response.choices[0].message.tool_calls[0].function.arguments)

# 정보 파싱 예시
print(result.get("user_name")) # 'jimmy'
print(result.get("age")) # 28
print(result.get("gender")) # '남성'

 

방법 2

또는, 다음과 같이 client.beta의 기능을 활용하는 방법도 있습니다.

(OpenAI 클라이언트 및 pydantic 모델 선언 과정은 앞서 다룬 방법 1과 동일합니다.)

completion = client.beta.chat.completions.parse(
    model="gpt-4o-2024-08-06",
    messages=[
        {"role": "system", "content": "당신은 유저의 정보를 추출하는 assistant입니다. 주어진 말을 듣고 필요한 유저의 정보들을 추출해주세요."},
        {"role": "user", "content": "안녕하세요. 제 이름은 jimmy이고요, 나이는 28세 입니다. 성별은 남성이에요."},
    ],
    response_format=GetUserInfo,
)

event = completion.choices[0].message.parsed

print(event.user_name) # 'jimmy'
print(event.age) # 28
print(event.gender) # '남성'

 

이 글이 structured output을 가져오는 과정에 도움이 되셨기를 기원하겠습니다.

잘 봐주셔서 감사드립니다.