GPT-3.5-Turbo Model을 활용한 채팅 프로젝트
처음 세상에 공개된 후 챗 GPT는 압도적인 성능으로 하나의 트렌드가 되었습니다. 검색 엔진을 대체할 만큼 정보 수집은 물론 대화, 코딩 등에서 큰 기량을 뽐내는 GPT 모델은 이미 인간의 일상 곳곳에 접목되어 다양한 업무를 대체하고, 보조하기 위한 수단으로 사용되고 있습니다.
이런 고성능 모델을 프로젝트에 활용하면 얼마나 재미있는 서비스를 만들어 볼 수 있을까요? (두근두근)
챗 GPT의 세 번째 버전의 인공 지능 중 하나인 GPT-3.5-Turbo 모델을 기반으로 진행한 저의 Open AI 프로젝트를 공유합니다.
특정 인물과 가상의 직업군을 가진 멘토와 커뮤니케이션을 체험하는 채팅 서비스를 만들고자 했는데요, 대화를 위한 언어 모델 선정 과정에서 GPT-3.5-Turbo을 선택하게 되었습니다.
GPT-3 과 비교했을 때 모든 측면에서 더 나은 성능을 제공하는 우수한 옵션들을 가졌고,
단일 텍스트 프롬프트만 허용했던 이전 버전과 달리 일련의 메시지를 입력으로 받아들일 수 있었기 때문에 대화형 프로젝트에서 사용했을 때 더 많은 컨텍스트와 사용자의 이전 응답을 통합해 유연한 대화가 가능하도록 업그레이드된 GPT-3.5-Turbo 모델이 최적일 것 같아 선택하게 되었습니다.
이번 프로젝트에서는 저명한 법률 전문가, 귀여운 고양이 비서 Milk, 유명인을 비롯해 조언을 구할 수 있는 다양한 직업군을 대화 멘토의 대상으로 설정해 보았는데요,
유저가 질문을 어떻게 던지냐에 따라 훨씬 퀄리티 놓은 대화로 이어지는 커뮤니케이션이 참 흥미로웠습니다.
| Open AI key 생성
- Open AI 홈페이지에 접속하여 계정을 생성합니다.
- Create new secret key 를 클릭해 생성된 API keys 🔑 값을 복사합니다.
- 생성된 API 키는 프로젝트의 환경 변수 파일에 저장합니다 :)
// .env
OPENAI_KEY=개인 API 키값
| Open AI API 호출
yarn add openai
import { Configuration, OpenAIApi } from 'openai';
const openAIConfig = new Configuration({
apiKey: process.env.OPENAI_KEY,
});
const openAIApi = new OpenAIApi(openAIConfig);
export const chatCompletion = async (req, res) => {
try {
const { prompt } = req.body;
const modelResponse = await openAIApi.createChatCompletion({
model: 'gpt-3.5-turbo',
messages: prompt,
});
const chatContent = modelResponse.data.choices[0].message.content;
res.status(200).json({ chatContent });
} catch (err) {
res.status(500).json({
message: err.message,
});
}
};
- OpenAI가 제공하는 API를 호출하기 위해 생성자에 발급 받은 apiKey 값을 전달합니다.
- gtp-3.5-tubo 모델을 불러오기 위해 openAIApi로부터 `createChatCompletion({ })` 함수를 호출합니다.
- 이때 함수로 전달하는 객체에 호출할 모델 이름과 유저와 주고받은 전체 prompt 정보를 전달해주면 됩니다.
- request가 정상적으로 수행될 경우 전달받은 data.choices[0].message.content 데이터로 접근해 모델로부터 전달된 전체 대화 content를 저장할 수 있으며, 에러가 발생할 경우 처리할 수 있도록 catch문을 작성해두었습니다.
{
"prompt": [
{
"role": "system",
"content": "너를 ${speaker}라고 생각하고 친근하게 대화해줘."
},
{
"role": "assistant",
"content": "${speaker}예요. 만나서 반갑습니다."
},
{
"role": "user",
"content": "반갑습니다!"
},
{
"role": "assistant",
"content": "안녕하세요! 발레를 얼마나 오랫동안 하셨나요?"
},
{
"role": "user",
"content": "별로 오래하진 않았어요 1년 반정도?"
},
{
"role": "assistant",
"content": "그래도 발레를 몇 년동안 하셨으니, 그 동안 많은 노력과 열정을 쏟으셨을 거예요. 발레를 처음 시작하게 된 계기와 즐거운 추억이 있으신가요?"
},
]
}
- 모델에 prompt를 전달할 때, system에 특정 role을 부여해줄 수 있는데요, 이를 통해 유저가 선택한 멘토와 멘토의 성향을 조정할 수 있습니다.
- 또한 유저가 채팅방에 입장했을 때, 일반적인 GPT 모델에서는 먼저 대화 호출하는 자연스러움이 없기 때문에, 프로젝트에서는 대화상대에게 초기 멘트를 설정해 유저가 대화를 이어갈 수 있도록 설정했어요.
| 프로젝트 화면
프로젝트 구성은 간단합니다 메인 화면에서 유저가 채팅할 대상을 선택하면, 채팅방으로 연결됩니다.
이때, 코드 단에서는 system 설정을 통해 채팅 전 선택된 멘토와 관련된 설정을 넣어줄 수 있으며 유저에게 먼저 대화를 걸게됩니다.
{
"prompt": [
{
"role": "system",
"content": "너를 ${speaker}라고 생각하고 친근하게 대화해줘."
},
{
"role": "assistant",
"content": "안녕하세요, ${speaker}예요. 만나서 반갑습니다."
},
]
}
유저가 대화를 입력하는 순간 위에서 작성한 chatCompletion API를 호출하게 되고,
const messageType = {
answer: 'assistant',
question: 'user',
};
const { response, err } = await chatCompletion({ prompt: newMessages });
정상적으로 모델 응답이 들어오면, 화면에 표시할 채팅 content를 업데이트해 줍니다.
if (response && response.text) {
setMessages([
...newMessages,
{
role: messageType.answer,
content: response.text,
},
]);
}
프로젝트에서는 유저가입력으로 모델측에 requset 요청이 가는 동안 상대방이 자연스럽게 타이핑 중인 느낌을 줄 수 있도록 로딩 애니메이션이 적용했고, 스크롤 영역을 감지해 채팅 대화가 어느정도 차는 순간부터는 상단 nav의 영역을 조절하는 효과를 추가했습니다.
| 일론 머스크와의 대화 내용
| 발레리나 & 10년차 시니어 프론트 엔지니어와의 대화 결과
결과는 생각보다 대화의 문맥이 너무 자연스럽게 이어져서 놀랬어요! ㅎㅎ
처음에는 인사이트를 넓힐 수 있는 대화 상대가 있으면 좋겠다 생각으로 시작하게 되었는데, 하다보니 너무 흥미로웠고,system 설정을 보다 구체적으로 작성하면, 더욱 의도에 맞는 대화를 이어갈 수 있겠다 생각했습니다 :)
초반에 3.5 turbo모델을 활용한 사례가 많지 않아 애를 먹었지만, Open AI 공식 문서가 너무 잘 정리되어 있어 많은 도움이 되었습니다.
온라인이기때문에 편하게 물어볼 수 있는 내용, 혼자만의 고민이나 개발적 궁금증을 털어놓기도 좋을 것 같습니다.
(어느 정도 추상화된 저의 멘토에게..!)
참조
- Open AI API 문서
OpenAI API
An API for accessing new AI models developed by OpenAI
platform.openai.com
- Open AI API 문서
Beginner’s Guide to OpenAI’s GPT-3.5-Turbo Model
From GPT-3 to GPT-3.5-Turbo: Understanding the Latest Upgrades in OpenAI’s Language Model API.
plainenglish.io
Posted by Ang