정적인 이력서 전송을 그만: ‘내 이력서와 채팅’ 봇을 만든 방법 (Next.js + RAG)

발행: (2025년 12월 29일 오후 02:05 GMT+9)
7 min read
원문: Dev.to

Source: Dev.to

솔직히 말하자면: 채용 담당자는 당신의 포트폴리오를 보는 데 약 6초 정도밖에 쓰지 않습니다.
당신은 멋진 사이트를 만들고, CSS를 다듬고, Lighthouse 점수를 최적화하는 데 몇 주를 투자하지만, 대부분의 방문자는 히어로 섹션을 한 번 보고 바로 떠납니다.

저는 수동적인 포트폴리오가 아니라, 다음과 같은 질문에 답할 수 있는 능동적인 사이트를 원했습니다:

  • “그는 TypeScript 경험이 있나요?”
  • “그가 AWS와 작업한 적이 있나요?”
  • “우리가 그를 채용해야 하는 이유는 무엇인가요?”

그래서 저는 이력서를 “읽고” 실시간으로 질문에 답변해 주는 RAG 기반 AI 챗봇을 만들었습니다. 제가 어떻게 만들었는지 (그리고 여러분도 어떻게 만들 수 있는지) 아래에서 확인하세요.

Demo GIF

아키텍처: 순수함 유지

시작할 때 LangChain 같은 라이브러리를 살펴보았습니다. 강력하지만, 단순한 포트폴리오 봇에는 과도하게 느껴졌습니다. API 호출만 하려고 500 MB의 종속성을 추가하고 싶지 않았습니다.

Stack

  • Frontend: UI를 위한 Next.js 15 (App Router).
  • Backend: API 키를 안전하게 처리하기 위한 Node.js (Express).
  • AI: 인텔리전스를 위한 OpenAI API (gpt‑4o‑mini).
  • Logic: 맞춤형 RAG (Retrieval‑Augmented Generation) 파이프라인.

Source:

챌린지: 컨텍스트 & 스트리밍

챗봇을 만드는 것은 쉽습니다. 여러분을 아는 챗봇을 만드는 것은 더 어렵습니다.

1. “두뇌”(RAG)

전체 이력서를 매번 프롬프트에 붙여넣을 수는 없습니다—토큰과 비용이 낭비됩니다. 대신 간단한 벡터 검색 로직을 구현했습니다:

  • 앱이 시작될 때 내 포트폴리오 데이터(경력, 스킬, 소개)를 로드합니다.
  • 사용자가 질문을 하면 시스템이 가장 관련성 높은 “청크” 텍스트를 찾습니다.
  • 그 청크만을 시스템 프롬프트와 함께 OpenAI에 전달합니다:

“당신은 [Name]을 위한 AI 어시스턴트입니다. 아래 제공된 컨텍스트만 사용하여 채용 담당자의 질문에 답하십시오.”

2. “타자기” 효과 (스트리밍)

5초 동안 응답을 기다리는 것만큼 분위기를 깨는 건 없습니다. 텍스트가 단어 단위로 타이핑되는 “ChatGPT 느낌”을 원했습니다. 이를 위해 표준 REST 응답 대신 Server‑Sent Events (SSE) 를 사용했습니다.

// Example SSE endpoint (Node.js + Express)
app.get('/api/chat', (req, res) => {
  res.setHeader('Content-Type', 'text/event-stream');
  res.setHeader('Cache-Control', 'no-cache');
  res.flushHeaders();

  // Stream chunks from OpenAI
  openai.chat.completions.create({
    model: 'gpt-4o-mini',
    messages: [{ role: 'system', content: systemPrompt }, ...userMessages],
    stream: true,
  }).then(stream => {
    for await (const part of stream) {
      const content = part.choices[0]?.delta?.content;
      if (content) {
        res.write(`data: ${JSON.stringify({ content })}\n\n`);
      }
    }
    res.write('event: done\n\n');
    res.end();
  }).catch(err => {
    console.error(err);
    res.write('event: error\n\n');
    res.end();
  });
});

이렇게 하면 사용자는 즉시 활동을 확인할 수 있어 참여도가 유지됩니다.

Gotchas (왜 이 작업에 몇 주가 걸렸는가)

코드는 간단해 보이지만, 실제 운영 환경에 맞추는 것은 까다롭습니다:

  • Security: OpenAI 키는 클라이언트‑사이드 코드에 절대 노출돼서는 안 되며, 프록시 서버가 필요합니다.
  • Mobile Responsiveness: 플로팅 채팅 위젯은 iPhone 키보드가 나타날 때 레이아웃이 깨지지 않도록 처리해야 합니다.
  • Context Windows: 토큰 한도에 걸리지 않도록 채팅 기록을 신중하게 정리해야 합니다.

결과

이제 리크루터가 내 사이트를 방문하면, 단순히 스크롤만 하는 것이 아니라 참여하게 됩니다. 그들은 내 요금, 가용성, 그리고 기술 스택에 대해 물어볼 수 있어, 정적인 독백을 동적인 인터뷰로 바꿉니다.

포트폴리오에 추가하고 싶으신가요?

직접 만들고 싶다면 OpenAI Node SDK와 Server‑Sent Events를 살펴보는 것을 강력히 추천합니다. 훌륭한 학습 경험이 될 것입니다.

완전 타입이 지정된, 프로덕션 준비가 된 스타터 키트입니다:

  • Pure RAG 설정 (복잡한 라이브러리 없음)
  • 미리 구축된 스트리밍 UI (Next.js 15)
  • 간편한 “Resume” 구성

Template Screenshot

템플릿을 받아 이번 주말에 커스터마이징을 시작할 수 있습니다:

🚀 Lemon Squeezy 에서 받아보세요 – 결제 시 코드 HOLIDAY2026 을 사용하면 할인을 받을 수 있습니다!

코딩 즐겁게 하세요!

Back to Blog

관련 글

더 보기 »