OpenAI API 함수 호출(Function Calling) 도입기
배경
챗봇 서비스에서 사용자 의도를 파악해 특정 API를 호출하는 로직을 구현 중이었다. 기존에는 프롬프트로 "JSON 형식으로 답변해줘"라고 요청했지만, 파싱 실패가 잦았고 예외 처리가 복잡했다.
OpenAI가 6월에 공개한 Function Calling 기능을 뒤늦게 알게 되어 적용해봤다.
기존 방식의 문제
const prompt = `사용자 메시지: "${userMessage}"
위 메시지에서 예약 정보를 추출해서 JSON으로 반환해줘.
{ "date": "YYYY-MM-DD", "time": "HH:MM", "people": number }`;
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [{ role: 'user', content: prompt }]
});
const json = JSON.parse(response.data.choices[0].message.content);
GPT가 "네, 알겠습니다. 추출된 정보는..." 같은 불필요한 텍스트를 포함하거나, 따옴표를 잘못 사용해서 JSON.parse가 자주 실패했다.
Function Calling 적용
const response = await openai.createChatCompletion({
model: 'gpt-3.5-turbo-0613',
messages: [{ role: 'user', content: userMessage }],
functions: [{
name: 'create_reservation',
description: '예약 정보를 생성한다',
parameters: {
type: 'object',
properties: {
date: { type: 'string', description: 'YYYY-MM-DD 형식' },
time: { type: 'string', description: 'HH:MM 형식' },
people: { type: 'number', description: '인원 수' }
},
required: ['date', 'time', 'people']
}
}],
function_call: 'auto'
});
const message = response.data.choices[0].message;
if (message.function_call) {
const args = JSON.parse(message.function_call.arguments);
// args는 항상 유효한 JSON
}
결과
- 파싱 에러가 거의 사라졌다
- 타입 검증이 명확해져서 후처리 로직이 간결해졌다
- 여러 함수를 정의하고 GPT가 적절한 것을 선택하게 할 수 있어 확장성이 좋다
다만 gpt-3.5-turbo-0613 이상 모델만 지원하고, 토큰 소비가 약간 늘어나는 점은 감안해야 한다.