aws amplify의 서버리스로 GPT를 활용해야하는 작업이 있는데, 그 전에 nodejs로 GPT가 잘 돌아가는지 테스트 할 겸 써 봄
v3 에서 v4로 변하면서 메소드명이 조금 달라졌음
위 사이트 보고 좀 구글링하면서 테스트 해 보았다.
openAI의 playground을 통해 테스트하고 코드도 받을 수 있음
async function callChatGPT(prompt) {
try {
const openai = new OpenAIApi({
apiKey: process.env.OPEN_AI_KEY,
});
const response = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: [
{
role: "system",
content:
"너는 모든 내용들을 객관식 문제로 만들어주는 문제집이야, 앞으로 사용자가 긴 내용들을 입력하면 너는 객관식으로 문제를 내줘야해",
},
],
max_tokens: 100,
temperature: 0,
});
return response.choices[0].message;
} catch (error) {
console.error("Error calling ChatGPT API:", error);
return null;
}
}
};
openai.chat.completions.create() 메소드에는 여러개가 있는데
많은 블로그들을 찾아본게 아니라서 필요한 경우 적절히 사용하면 좋을 듯하다.
기술 면접 내용들을 예시로 문제를 만들어 달라고 요청해 보았다.
이 정도면 만족한다. 이제 응답 값을 문제와 답 2가지로 나눠서 관리하는 법을 찾아 봄
그 중 Function calling이라고 지원하는게 있었다.
https://platform.openai.com/docs/guides/function-calling
Function calling
API 호출에서 함수를 설명하고 모델이 하나 이상의 함수를 호출하기 위한 인수가 포함된 JSON 개체를 출력하도록 지능적으로 선택하도록 할 수 있습니다. Chat Completions API는 함수를 호출하지 않습니다. 대신 모델은 코드에서 함수를 호출하는 데 사용할 수 있는 JSON을 생성합니다.
open ai 공식 docs
간단하게 요약하자면,
required을 설정할 경우 그 함수에 대해 결과값을 필수로 받을 수 있다.
import "dotenv/config";
import OpenAIApi from "openai";
export const getTest = async (req, res) => {
const prompt =
"2.브라우저 저장소에 대해서 차이점을 설명해주세요.\n브라우저 저장소에는 Local Storage, Session Storage, Cookie 세 가지가 있습니다.\n\n먼저 데이터를 보관하는 기간에 차이가 있습니다.\n로컬 스토리지는 데이터를 영구적으로 저장하는 데 사용되고, 세션 스토리지는 브라우저의 세션이 유지되는 동안만 데이터가 유지되기 때문에, 사용자가 브라우저 창을 닫거나 탭을 종료하면 데이터가 삭제됩니다. 쿠키는 만료 기간을 설정하여 유효 기간을 설정할 수 있으며, 유효기간을 설정하지 않으면 영구적으로 저장될 수 있습니다.\n저장 용량에도 차이가 있습니다.\n로컬 스토리지와 세션 스토리지는 최소 5MB 이상의 저장 용량을 제공하는 반면 쿠키는 4KB 이하의 작은 데이터만 저장할 수 있습니다.";
const response = await callChatGPT(prompt);
const data = JSON.parse(response);
if (response) {
res.json(data);
} else {
res.status(500).json({ error: "Failed to get response from ChatGPT API" });
}
async function callChatGPT(prompt) {
try {
const openai = new OpenAIApi({
apiKey: process.env.OPEN_AI_KEY,
});
const response = await openai.chat.completions.create({
model: "gpt-3.5-turbo",
messages: [
{
role: "system",
content:
"너는 모든 내용들을 객관식 문제로 만들어주는 문제집이야, 앞으로 사용자가 긴 내용들을 입력하면 너는 객관식으로 문제를 내줘야해",
},
{
role: "user",
content: prompt,
},
],
tools: [
{
type: "function",
function: {
name: "quiz",
description:
"공부한 내용으로 객관식 문제를 알려줌 (예: 대한민국의 수도는 어디인가요?\n1. 서울\n2. 부산\n3. 대구\n4. 인천.)",
parameters: {
type: "object",
properties: {
question: {
type: "string",
description:
"객관식 문제로 알려줘야하며, 한국어로 출력해야한다 (예: 대한민국의 수도는 어디인가요?)",
},
options: {
type: "string",
description:
"문제의 보기를 보여줘야한다, 한국어로 출력해야한다 (예: \n1. 서울\n2. 부산\n3. 대구\n4. 인천.)",
},
answer: {
type: "number",
description: "각 문제의 정답 번호를 알려주세요. (예: 1, 2, 3)",
},
},
required: ["quiz", "options", "answer"],
},
},
},
],
temperature: 1,
max_tokens: 256,
});
return response.choices[0].message.tool_calls[0].function.arguments;
} catch (error) {
console.error("Error calling ChatGPT API:", error);
return null;
}
}
};
질문, 정답보기, 정답 3가지를 따로 받아 온 것을 확인할 수 있다.
공식 페이지는 조금 복잡하게 되어있는데 나는 내 방식대로 그냥 받아와서 파싱하여서 보니 잘 받아와져 있었음