Part 1에서 간단한 API 연결이나 Docs를 훑어보는 시간을 가졌다면,
Part 2에서는 실제 서비스에 적용하기 위해 꼭 필요한 구조화 작업들과 활용 예시를 설명하겠습니다.
필수 구조 잡기
사실 구조는 개발자의 성향, 그리고 상황에 따라 판단되어야 하고 그에 맞게 달라져야 합니다.
여기서는 필수적으로 해줘야 하는 작업만 살펴보겠습니다.
API Key 숨기기
local에서 혼자서만 개발하는 환경이라면 상관 없지만,
GitHub에 올릴 예정이라면, 그리고 Public Repository라면 꼭 해줘야 하는 작업입니다.
Part 1에서 우리는 configuration 안에 apiKey를 문자열 그대로 넣어줬었는데요,
이렇게 되면 깃헙에 올라갔을 때 우리 apiKey가 노출이 되게 됩니다.
폭탄 과금을 맞지 않으려면 gitHub에는 올리지 않고, local에서만 관리하는 방법이 필요합니다.
프로젝트 root에 .env 파일을 만들어 주고,
.env 파일 안에 OPENAI_API_KEY=sk-... 이렇게 자신의 키를 적어줍니다.
그 후에는 process.env.OPENAI_API_KEY를 통해 코드에서 접근해주면 됩니다.
바뀐 코드는 아래와 같습니다.
const configuration = new Configuration({
organization: 'org-hVb9jLGgEG18b8M3S4DskHc9',
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(configuration);
실제로 활용해보기
Part 1에서 API 옵션들에 대해 알아봤으니, 이제 실제로 적용시켜보겠습니다.
파트 1에서 썼던 것과 똑같은 예시 프로젝트를 사용합니다. https://github.com/mckaywrigley/chatbot-ui
system role로 빙의 시키기
우선, yes or no로만 답변하는 챗봇을 만들어보겠습니다.
system에
'모든 대답은 yes or no로만 답해줘. 그 외에는 아무 말도 하지 마.'
라고 입력해서 예/아니오만 할 수 있는 애로 빙의시켜 보겠습니다.
const testResponse = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{
role: 'system',
content:
'모든 대답은 yes or no로만 답해줘. 그 외에는 아무 말도 하지 마.',
},
{ role: 'user', content: message.content },
],
});
잘 하네요.
그럼 이번엔 좀 더 어려운 걸 시켜볼게요.
모든 답변을 '다나' 이행시로만 하는 친구로 빙의시켜 보겠습니다.
const testResponse = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{ role: 'system', content: "모든 대답을 '다나' 이행시로만 답해줘" },
{ role: 'user', content: message.content },
],
});
흠.. 아무래도 이행시가 뭔지 모르는 것 같죠?
이행시가 뭔지 알려줘야겠네요.
그 가이드는 assistant role에서 줄 수 있습니다.
assistant로 공부 시키기
파트1에서 assistant는 맥락을 기억하거나 언어모델에게 답변 가이드를 제시할 때 사용한다고 설명했습니다.
바로 이행시를 학습시켜볼게요.
const testResponse = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{ role: 'system', content: "모든 대답을 '다나' 이행시로만 답해줘" },
{
role: 'assistant',
content:
'이행시라는 건 2글자로 이루어진 단어가 있을 때 각각의 글자로 시작하는 글을 뜻해.\n' +
'예를 들면 이런 거야\n' +
'고: 고등어는\n' +
'등: 등푸른 생선이에요',
},
{ role: 'user', content: message.content },
],
});
이행시에 대한 간단한 설명과 '고등'이라는 단어로 이행시 예시를 하나 들어줬습니다.
이제 대답을 잘 하는지 볼까요?
이제 잘 하네요!
assistant, user로 맥락 기억 시키기
이렇게 assistant와 user를 잘 활용하면 답변 가이드 뿐 아니라 어떤 맥락에서 얘기하고 있는지 기억하게 시킬 수 있습니다.
단순히 사용자가 질문을 던질 때마다 그걸 user role로 추가하고, 모든 답변을 assistant로 추가해 맥락을 기억하게 할 수도 있습니다.
하지만 그렇게 하면 request에 너무 많은 token이 쓰이겠죠.
맥락을 기억하게 하는 방법에 user, assistant를 쓰지 않고 다른 좋은 방법들도 많이 있지만,
우선 user와 assistant를 쓴다고 가정하고 이 상황에서 token을 아끼는 좋은 전략들이 소개된 블로그 글이 있어 공유합니다.
maxToken 제어하기
다시 이행시로만 대답하는 챗봇으로 돌아가,
말이 너무 긴 것 같으니 간결하게 대답하는 녀석으로 만들어보겠습니다.
maxToken을 활용해줄게요.
극단적으로 답변하는 데에 10토큰만 줘보겠습니다.
const testResponse = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{ role: 'system', content: "모든 대답을 '다나' 이행시로만 답해줘" },
{
role: 'assistant',
content:
'이행시라는 건 2글자로 이루어진 단어가 있을 때 각각의 글자로 시작하는 글을 뜻해.\n' +
'예를 들면 이런 거야\n' +
'고: 고등어는\n' +
'등: 등푸른 생선이에요',
},
{ role: 'user', content: message.content },
],
max_tokens: 10, // 10토큰만 써
});
말이 끊겼네요.
아마 다나 이행시 중에서 '다' 부분만 쓰다가 끊긴 것 같아요.
Docs에서도 너무 적은 토큰은 말을 끝맺지 못할 수 있으니 적절한 양으로 조절하라고 권고하고 있어요.
만약 한 답변에 strict하게 토큰 수를 제한해야 하는 상황이 아니라고 하면 system에 '10자 내로 간결하게 대답해'와 같은 가이드를 줄 수 있습니다.
창의적인 답변 기대하기
이번에는 다양한 파라미터를 활용해 창의적인 이행시를 짓기 위한 최적의 모델로 만들어 볼게요.
값은 휴리스틱하게 변화를 지켜봐 가면서 주면 됩니다.
저는 이렇게 한 번 줘볼게요.
const testResponse = await openai.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: [
{ role: 'system', content: "모든 대답을 '다나' 이행시로만 답해줘" },
{
role: 'assistant',
content:
'이행시라는 건 2글자로 이루어진 단어가 있을 때 각각의 글자로 시작하는 글을 뜻해.\n' +
'예를 들면 이런 거야\n' +
'고: 고등어는\n' +
'등: 등푸른 생선이에요',
},
{ role: 'user', content: message.content },
],
temperature: 0.8,
top_p: 0.9,
frequency_penalty: 0.2,
presence_penalty: 0.3,
});
중복을 피하고, 최대한 많은 단어를 탐색해 선택할 수 있도록 값을 부여했습니다.
사실 이런 예시에서는 체감이 잘 안 되지만,
맞춤법/문법 검사기 같은 기존 내용이 정확히 반복되어야 하는 태스크들에서는 유의미한 결과가 있을 거예요.
이 파라미터들은 잘 이해하지 못하고 수정하면 생각하는 결과가 아예 나오지 않을 수 있습니다.
조금씩 변경해가며 변화를 관찰하며 맞춰나가는 게 좋습니다.
파라미터 예시
맞춤법, 문법 검사기
맞춤법, 문법은 paraphrase 없이 주어진 문장 내에서 고쳐야 합니다.
후보 단어를 까다롭게, 극단적으로 선택해야 하고, 중복된 단어에 대한 페널티는 없어도 됩니다.
Temperature: 0
Frequency penalty: 0.0
Presence penalty: 0.0
role/system: 'Correct this to standard English'
role/user: 'I’m looking forward to see you'
아이디어 생성기
아이디어 생성에서 가장 중요한 건 이미 나온 아이디어는 더 이상 아이디어가 아니라 '생각'에 불구하다는 것입니다.
중복에 대한 penalty를 줘서 단순한 생각이 아닌 새롭고 참신한 아이디어를 만들 수 있게 설정해줘야 합니다.
Temperature: 0.6
Frequency penalty: 1
Presence penalty: 1
세 줄 요약
세 줄 요약을 위해서는 우선 문장이 너무 길어서는 안 되겠죠. (Max tokens)
또 주어진 내용과 너무 동떨어지면 안 될 겁니다.
Max tokens: 60
Temperature: 0.7
Frequency penalty: 0.0
Presence penalty: 0.0
role/system: 'tl;dr'
더 많은 예시는 챗지피티한테 물어보세요
이렇게 챗지피티한테 물어보면 적절한 파라미터를 잘 추천해주니 적극 활용해보세요.
'개발 잡기술' 카테고리의 다른 글
Metabase(메타베이스)를 활용해 데이터 시각화하기 (1) | 2024.01.07 |
---|---|
사이드 프로젝트에 미친 사람이 서비스 20개 만들면서 느낀 것들 (8) | 2023.12.10 |
Wix에서 카카오 API 사용하기 (도메인 에러 해결) (3) | 2023.05.17 |
[Typescript] OpenAI의 ChatGPT API로 나만의 챗봇 만들어보기 Part. 1 (0) | 2023.04.09 |
개발 협업에서 Git & GitKraken 사용하기 (0) | 2023.04.08 |