안녕하세요. 오늘은 OpenAI의 ChatGPT API를 사용해서 AI 챗봇을 만들어 볼 거예요. 개발자도구 콘솔에서 직접 실행 가능한 자바스크립트 코드를 구현하려고 했지만 HTML로 채팅창 디자인을 만들어서 대화하는 게 더 보기 편할 거 같아서 HTML 파일도 같이 만들겠습니다.
이번에 만들어볼 AI 챗봇은 OpenAI의 GPT-3 TURBO 모델을 활용할 거예요. 이 모델을 사용하기 위해선 API를 발급받아야 합니다. 이 모델은 API 요청 시 사용되는 토큰 수에 따라 비용이 발생하는데, 1000 토큰당 0.002$(약 2~3원)의 비용이 발생해요.
1000 토큰으로 생성 가능한 대략적인 문자 수는 600~700자 정도 되니 텍스트 길이를 적절하게 조절해서 사용한다면 큰 부담은 안될 거 같네요. 참고로 처음 API 발급 시 18$를 받을 수 있으니 테스트 또는 연습용으로 충분히 사용 가능하답니다.
자! 이제 먼저 Api 발급하는 방법부터 알아볼게요. 기존에 OpenAI 계정이 있다면 1분이면 발급이 가능해요.
1. 위 API 발급 페이지 접속 후 오른쪽 상단 메뉴에서 View Api Keys 접속
2. API Keys 화면의 Create New secret Key 클릭
3. 발급받은 API key 다른 곳에 복사해 놓기
발급이 다 됐으면 먼저 간단하게 화면을 만들게요. 화면은 단순한 채팅창 디자인을 적용해서 최소한의 CSS 코드만 사용하겠습니다. 파일명은 index.html로 생성합니다.
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>OpenAI를 이용한 챗봇</title>
<style>
body {
display: flex;
justify-content: center;
align-items: center;
height: 100vh;
margin: 0;
}
.message {
border-top: 1px solid #ccc;
padding: 10px;
margin-top: 5px;
background-color: #e6e6e6;
}
#chat-container {
width: 400px;
height: 600px;
display: flex;
flex-direction: column;
border: 1px solid #ccc;
}
#chat-messages {
flex: 1;
overflow-y: auto;
padding: 10px;
display: flex;
flex-direction: column-reverse;
}
#user-input {
display: flex;
padding: 10px;
}
#user-input input {
flex: 1;
padding: 10px;
outline: none;
}
#user-input button {
border: none;
background-color: #1e88e5;
color: white;
padding: 10px 15px;
cursor: pointer;
}
</style>
</head>
<body>
<div id="chat-container">
<div id="chat-messages"></div>
<div id="user-input">
<input type="text" placeholder="메시지를 입력하세요..." />
<button>전송</button>
</div>
</div>
<script src="chatbot.js"></script>
</body>
</html>
이렇게 기본적인 대화창 화면이 완성이 됐어요. 엔터를 치거나 전송 버튼 클릭 시 Api를 호출하도록 만들고 대화 사이에 간격을 줘서 구분하기 쉽게 했습니다. 실행 화면 ▼
아직 기능이 구현되지 않아 답변을 받을 수 없어요. 이제 자바스크립트 파일을 만들어서 질문에 답변을 받아오도록 할게요. 파일명은 html에서 참조하고 있는 chatbot.js로 만들면 됩니다.
// 채팅 메시지를 표시할 DOM
const chatMessages = document.querySelector('#chat-messages');
// 사용자 입력 필드
const userInput = document.querySelector('#user-input input');
// 전송 버튼
const sendButton = document.querySelector('#user-input button');
// 발급받은 OpenAI API 키를 변수로 저장
const apiKey = '발급받은 API키 입력';
// OpenAI API 엔드포인트 주소를 변수로 저장
const apiEndpoint = 'https://api.openai.com/v1/chat/completions'
function addMessage(sender, message) {
// 새로운 div 생성
const messageElement = document.createElement('div');
// 생성된 요소에 클래스 추가
messageElement.className = 'message';
// 채팅 메시지 목록에 새로운 메시지 추가
messageElement.textContent = `${sender}: ${message}`;
chatMessages.prepend(messageElement);
}
// ChatGPT API 요청
async function fetchAIResponse(prompt) {
// API 요청에 사용할 옵션을 정의
const requestOptions = {
method: 'POST',
// API 요청의 헤더를 설정
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${apiKey}`
},
body: JSON.stringify({
model: "gpt-3.5-turbo", // 사용할 AI 모델
messages: [{
role: "user", // 메시지 역할을 user로 설정
content: prompt // 사용자가 입력한 메시지
}, ],
temperature: 0.8, // 모델의 출력 다양성
max_tokens: 1024, // 응답받을 메시지 최대 토큰(단어) 수 설정
top_p: 1, // 토큰 샘플링 확률을 설정
frequency_penalty: 0.5, // 일반적으로 나오지 않는 단어를 억제하는 정도
presence_penalty: 0.5, // 동일한 단어나 구문이 반복되는 것을 억제하는 정도
stop: ["Human"], // 생성된 텍스트에서 종료 구문을 설정
}),
};
// API 요청후 응답 처리
try {
const response = await fetch(apiEndpoint, requestOptions);
const data = await response.json();
const aiResponse = data.choices[0].message.content;
return aiResponse;
} catch (error) {
console.error('OpenAI API 호출 중 오류 발생:', error);
return 'OpenAI API 호출 중 오류 발생';
}
}
// 전송 버튼 클릭 이벤트 처리
sendButton.addEventListener('click', async () => {
// 사용자가 입력한 메시지
const message = userInput.value.trim();
// 메시지가 비어있으면 리턴
if (message.length === 0) return;
// 사용자 메시지 화면에 추가
addMessage('나', message);
userInput.value = '';
//ChatGPT API 요청후 답변을 화면에 추가
const aiResponse = await fetchAIResponse(message);
addMessage('챗봇', aiResponse);
});
// 사용자 입력 필드에서 Enter 키 이벤트를 처리
userInput.addEventListener('keydown', (event) => {
if (event.key === 'Enter') {
sendButton.click();
}
});
API 요청 파라미터 설정값에 대해 설명할게요. 각각 설정한 값에 따라 다양한 답변을 받을 수 있으니 아래 내용을 참고해서 설정해 주세요. 위 예제에서는 기본적인 대화에서 사용되는 값으로 설정을 했습니다.
temperature: 0.8
답변의 다양성을 조절하는 값으로 높을수록 창의적인 답변이 나옵니다. 예를 들어 값이 1.0이면, 모델은 가능한 모든 단어 및 구문을 사용하여 답변을 생성하려고 시도합니다. 이 경우, 모델이 더 창의적이고 다양한 답변을 제공할 수 있습니다. 그러나 값이 0.2와 같이 낮으면, 모델은 상대적으로 보수적인 답변을 생성하려고 하므로 더 일반적인 응답이 생성될 가능성이 높습니다. 따라서 temperature 값은 모델의 출력 다양성을 제어하는 중요한 요소 중 하나입니다.
max_tokens: 1024
AI가 생성할 수 있는 단어의 최대 수를 제한하는 것을 의미합니다. 이를 이용하여 생성된 텍스트가 너무 길거나 너무 짧지 않도록 제어할 수 있습니다. 예를 들어, 만약 이 값을 50으로 설정하면, AI는 답변에 최대 50개의 단어만 사용할 수 있습니다. 만약 이 값이 너무 작으면, AI가 목적에 부합하는 적절한 답변을 생성하지 못할 수 있습니다. 반면, 너무 큰 값으로 설정하면, AI가 너무 긴 답변을 생성할 수 있습니다. 1024는 일반적으로 충분히 큰 값이며, 대부분의 경우에 적합한 값입니다.
top_p: 1
샘플링할 때 고려할 가능성이 높은 토큰들의 총합을 제한하는 값입니다. 예를 들어, top_p가 0.9이면 AI는 가능성 상위 90%의 토큰들만을 고려하여 답변을 생성합니다. 이는 모델이 생성할 수 있는 답변의 다양성을 유지하면서도 일관성을 유지할 수 있도록 도와줍니다. 이 값이 높을수록 생성된 답변의 다양성이 높아집니다.
frequency_penalty: 0.5
일반적으로 나오지 않는 단어를 억제하는 정도를 설정합니다. 예를 들어 값이 높으면(예: 1.0) AI는 "컴퓨터"와 같은 일반적인 단어를 선호하게 되고, 값이 낮으면(예: 0.0) AI는 "바이오매트릭스"와 같은 희귀한 단어도 사용할 수 있습니다.
presence_penalty: 0.5
AI가 생성한 텍스트에서 반복되는 단어나 구문을 억제하는 정도를 설정하는 매개변수입니다. 이 값이 높을수록 AI는 반복되는 구문을 피하려고 노력하며, 값이 낮을수록 반복되는 구문이 더 자주 나타날 수 있습니다. 예를 들어, 이 매개변수가 0.5로 설정되어 있으면, AI는 같은 단어나 구문이 반복되는 것을 어느 정도 피하도록 생성된 텍스트를 조정합니다. 이는 생성된 텍스트의 다양성을 높이는 데 도움을 줄 수 있습니다.
stop: ["Human"]
생성된 텍스트에서 특정 구문이 나오면 텍스트 생성을 중지하게끔 설정하는 것입니다. "Human"이라는 구문이 나타나면 AI는 그 이후에 오는 단어들을 생성하지 않고 생성을 중단합니다. 예를 들어, "안녕하세요. 오늘 날씨가 참 좋네요 Human, 그렇죠?"라는 대화에서 stop 구문으로 " Human"을 설정했다면, AI는 "오늘 날씨가 참 좋네요. "까지만 생성하고 그 이후에 오는 "그렇죠?"라는 생성하지 않게 됩니다. 이를 통해 생성된 텍스트를 조금 더 제어할 수 있습니다.
이제 직접 챗봇과 대화하도록 할게요. 처음에 만든 html 파일을 실행하면 됩니다. 실행 화면 ▼
간단한 질문을 해봤는데요. 응답속도가 생각만큼 빠르진 않네요. 그래도 대화를 못할 정도는 아니니 유용하게 사용할 수 있을 거 같습니다! GPT-3 Turbo의 다양한 기능들을 조절하면, 더욱 똑똑하고 자연스러운 챗봇을 만들어 볼 수 있답니다.
API 호출 제한이 초과되거나, 서버가 불안정한 경우 응답 오류가 발생할 수 있어요. 그럴 땐 콘솔 창에서 원인을 확인하면 됩니다.
아래 페이지에서 실시간으로 Api 사용량을 확인할 수 있으니 요청 제한을 초과하지 않도록 주의해서 사용하시면 돼요.
오늘은 이렇게 OpenAI의 GPT-3 TURBO를 이용해 자바스크립트로 챗봇을 만드는 방법을 알아보았어요. 챗봇은 개인화된 추천이나 콘텐츠 제공에도 활용될 수 있어요. 사용자의 관심사나 취향에 맞춰 정보를 제공하거나, 필요한 도움을 주는 것이 가능하다는 것이겠죠! - 끝 -