ChatGPT 같은 AI 챗봇을 직접 만들어보고 싶나요? OpenAI API를 사용하면 30분 안에 나만의 챗봇을 만들 수 있습니다. 오늘은 Node.js로 기본 챗봇을 구현하고 스트리밍 응답까지 다뤄보겠습니다.
목표
- OpenAI API 키 발급받기
- Node.js로 기본 챗봇 만들기
- 스트리밍 응답 구현하기
- 컨텍스트 유지하기 (대화 이력 관리)
1. OpenAI API 키 발급
- OpenAI 플랫폼 접속
- 회원가입 및 로그인
- API Keys → Create new secret key
- 생성된 키를 안전한 곳에 저장! (다시 안 보여줌)
2. 프로젝트 설정
mkdir openai-chatbot
cd openai-chatbot
npm init -y
npm install openai dotenv
.env 파일 생성:
OPENAI_API_KEY=sk-xxxxxxxxxxxxxxxx
3. 기본 챗봇 구현
index.js:
require('dotenv').config();
const OpenAI = require('openai');
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
async function chat(message, history = []) {
try {
const response = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
...history,
{ role: 'user', content: message }
],
temperature: 0.7,
});
return response.choices[0].message.content;
} catch (error) {
console.error('Error:', error.message);
throw error;
}
}
// 예제 실행
(async () => {
const history = [];
const userMessage = '안녕! 자기소개 좀 해줘';
const aiResponse = await chat(userMessage, history);
// 대화 이력 저장
history.push({ role: 'user', content: userMessage });
history.push({ role: 'assistant', content: aiResponse });
console.log('User:', userMessage);
console.log('AI:', aiResponse);
})();
4. 스트리밍 응답 구현
챗봇이 답변을 생성할 때 한 글자씩 실시간으로 보이게 만들어볼까요?
streaming.js:
require('dotenv').config();
const OpenAI = require('openai');
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
async function streamChat(message) {
try {
const stream = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
{ role: 'system', content: '친절한 도우미야.' },
{ role: 'user', content: message }
],
stream: true,
});
console.log('AI: ');
for await (const chunk of stream) {
const content = chunk.choices[0]?.delta?.content || '';
process.stdout.write(content);
}
console.log('
');
} catch (error) {
console.error('Error:', error.message);
throw error;
}
}
// 실행
streamChat('리액트로 간단한 TODO 앱 만드는 법 알려줘');
5. 컨텍스트 유지하기 (대화 이력)
context-aware.js:
require('dotenv').config();
const OpenAI = require('openai');
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
class ChatBot {
constructor(systemPrompt = '친절한 개발 도우미야.') {
this.systemPrompt = systemPrompt;
this.history = [];
this.maxHistory = 10; // 최근 10개의 대화만 유지
}
async chat(message) {
this.history.push({ role: 'user', content: message });
const response = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
{ role: 'system', content: this.systemPrompt },
...this.history.slice(-this.maxHistory)
],
temperature: 0.7,
});
const aiMessage = response.choices[0].message.content;
this.history.push({ role: 'assistant', content: aiMessage });
return aiMessage;
}
getHistory() {
return this.history;
}
clearHistory() {
this.history = [];
}
}
// 사용 예제
(async () => {
const bot = new ChatBot('리액트 전문가야.');
console.log('AI:', await bot.chat('리액트 Hooks는 뭐야?'));
console.log('---');
console.log('AI:', await bot.chat('useState랑 useEffect 차이는?'));
console.log('---');
console.log('AI:', await bot.chat('그럼 예제 코드 좀 줘'));
})();
6. 간단한 CLI 챗봇
cli-chat.js:
require('dotenv').config();
const OpenAI = require('openai');
const readline = require('readline');
const openai = new OpenAI({
apiKey: process.env.OPENAI_API_KEY
});
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout
});
const history = [];
function ask(question) {
return new Promise(resolve => {
rl.question(question, resolve);
});
}
async function main() {
console.log('🤖 OpenAI 챗봇 (종료하려면: exit)\n');
while (true) {
const message = await ask('You: ');
if (message.toLowerCase() === 'exit') {
console.log('👋 안녕히 가세요!');
rl.close();
break;
}
try {
const response = await openai.chat.completions.create({
model: 'gpt-4o-mini',
messages: [
{ role: 'system', content: '친절한 도우미야.' },
...history,
{ role: 'user', content: message }
],
temperature: 0.7,
});
const aiMessage = response.choices[0].message.content;
history.push({ role: 'user', content: message });
history.push({ role: 'assistant', content: aiMessage });
console.log('AI:', aiMessage);
console.log('');
} catch (error) {
console.error('Error:', error.message);
}
}
}
main();
실행:
node cli-chat.js
7. 핵심 개념 설명
Model 파라미터
| 파라미터 | 설명 | 범위 |
|---|---|---|
temperature |
응답의 무작위성 (0=결정적, 1=창의적) | 0 ~ 2 |
max_tokens |
최대 응답 길이 | 1 ~ 4096 |
top_p |
핵심 토큰 집합 크기 (nucleus sampling) | 0 ~ 1 |
presence_penalty |
새로운 주제 장려 | -2 ~ 2 |
frequency_penalty |
반복 감소 | -2 ~ 2 |
Role 타입
system: AI의 페르소나 설정user: 사용자 메시지assistant: AI 응답
8. 비용 최적화 팁
- 모델 선택: 간단한 작업은
gpt-4o-mini사용 (더 저렴) - 컨텍스트 제한: 불필요한 대화 이력 제거
- 프롬프트 최적화: 긴 프롬프트보다는 명확한 프롬프트
- 캐싱: 동일한 질문 응답 캐싱
9. 추가로 해볼 수 있는 것들
- Next.js + OpenAI – 웹 인터페이스 챗봇
- Function Calling – API 호출과 연동
- 벡터 DB – RAG (검색 증강 생성)
- 멀티모달 – 이미지 분석 기능
- 스트리밍 UI – 실시간 응답 웹 인터페이스
결론
이 예제로 OpenAI API의 기본을 익혔습니다:
- API 연동
- 대화 컨텍스트 관리
- 스트리밍 응답
다음으로는 Vercel AI SDK로 웹 챗봇을 만들어보세요! 🚀
질문이 있거나 막히는 부분이 있다면 댓글로 남겨주세요! 😊