OpenAI API로 챗봇 만들기

ChatGPT 같은 AI 챗봇을 직접 만들어보고 싶나요? OpenAI API를 사용하면 30분 안에 나만의 챗봇을 만들 수 있습니다. 오늘은 Node.js로 기본 챗봇을 구현하고 스트리밍 응답까지 다뤄보겠습니다.

AI Chatbot
AI 챗봇 개발

목표

  • OpenAI API 키 발급받기
  • Node.js로 기본 챗봇 만들기
  • 스트리밍 응답 구현하기
  • 컨텍스트 유지하기 (대화 이력 관리)

1. OpenAI API 키 발급

  1. OpenAI 플랫폼 접속
  2. 회원가입 및 로그인
  3. API KeysCreate new secret key
  4. 생성된 키를 안전한 곳에 저장! (다시 안 보여줌)

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. 비용 최적화 팁

  1. 모델 선택: 간단한 작업은 gpt-4o-mini 사용 (더 저렴)
  2. 컨텍스트 제한: 불필요한 대화 이력 제거
  3. 프롬프트 최적화: 긴 프롬프트보다는 명확한 프롬프트
  4. 캐싱: 동일한 질문 응답 캐싱

9. 추가로 해볼 수 있는 것들

  1. Next.js + OpenAI – 웹 인터페이스 챗봇
  2. Function Calling – API 호출과 연동
  3. 벡터 DB – RAG (검색 증강 생성)
  4. 멀티모달 – 이미지 분석 기능
  5. 스트리밍 UI – 실시간 응답 웹 인터페이스

결론

이 예제로 OpenAI API의 기본을 익혔습니다:

  • API 연동
  • 대화 컨텍스트 관리
  • 스트리밍 응답

다음으로는 Vercel AI SDK로 웹 챗봇을 만들어보세요! 🚀

질문이 있거나 막히는 부분이 있다면 댓글로 남겨주세요! 😊