본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 23. 05:04

주말 동안 비용 0원으로 중소기업(PME)을 위한 문서 어시스턴트를 구축했습니다

요약

Ollama, Supabase, Groq 등 무료 스택을 활용하여 중소기업용 RAG(검색 증강 생성) 문서 어시스턴트를 구축하는 방법을 소개합니다. 문서 추출부터 벡터 저장, 유사도 검색 및 출처 인용까지의 전체 파이프라인을 다룹니다.

핵심 포인트

  • Ollama와 Supabase를 활용한 100% 무료 RAG 스택 구성
  • 데이터 손실 방지를 위한 청크 분할 시 오버랩(Overlap) 적용의 중요성
  • 신뢰성을 위한 메타데이터 기반의 출처 인용 시스템 구축
  • 인제스션(Ingestion)과 질의(Query)의 두 단계 아키텍처 설계

월요일 오후 2시에 한 직원이 질문을 던진다고 상상해 보세요: "휴가는 며칠 전에 신청해야 하나요?" 그는 이메일, 3년 전에 보내온 PDF 안내서, 아무도 관리하지 않는 공유 폴더를 뒤지기 시작합니다. 5분 후, 그는 포기하고 이미 업무가 과중한 인사(RH) 담당자에게 가서 물어봅니다.

이 문제는 모든 중소기업(PME)에 존재합니다. 그리고 이를 해결할 수 있는 깔끔한 기술적 솔루션이 있습니다. 작동하며, 출처를 인용하고, 운영 비용이 0€입니다.

저는 이것을 주말 동안 구축했습니다. 정확히 어떻게 했는지 소개합니다.

우리가 구축할 것

RAG (Retrieval-Augmented Generation, 검색 증강 생성) 유형의 어시스턴트입니다. 내부 문서(PDF, Word)를 제공하면 시스템이 이를 인덱싱하고, 직원이 질문을 하면 관련 구절을 찾아 출처를 인용하며 답변을 생성합니다.

100% 무료 스택:

  • Ollama — 로컬 AI 모델 (embeddings + LLM)
  • Supabase — 벡터 확장 기능인 pgvector를 사용하는 PostgreSQL 데이터베이스
  • Groq — 초고속 추론 API (무료 티어)
  • Transformers.js — 온라인 데모를 위한 브라우저 내 embeddings
  • React + Vite + Tailwind — 인터페이스
  • Vercel — 배포

결과물은 온라인에서 확인할 수 있습니다: rag-pme.vercel.app

두 개의 체인으로 구성된 아키텍처

RAG는 종종 혼동되곤 하지만, 실제로는 두 개의 별개 파이프라인으로 구성됩니다.

체인 A — 인제스션 (문서당 1회 수행)

시스템에 문서를 제공할 때:

  1. 추출 (Extraction) — 페이지별로 원문 텍스트를 가져옵니다 (PDF의 경우 unpdf, Word의 경우 mammoth 사용)
  2. 분할 (Découpage) — 인접한 청크(chunk) 사이에 150자의 중첩(overlap)을 두어 약 900자 단위의 청크로 자릅니다. 중첩은 매우 중요한데, 아이디어가 중간에 잘려 손실되는 것을 방지하기 때문입니다. 무엇보다도, 각 청크에는 파일 이름, 페이지 번호와 같은 메타데이터 (metadata)가 포함됩니다.
  3. 임베딩 (Embedding) — 각 청크는 nomic-embed-text를 통해 768차원의 벡터 (vector)로 변환됩니다.
  4. 저장 (Stockage) — 벡터는 메타데이터와 함께 pgvector를 통해 Supabase에 저장됩니다.

체인 B — 질의 (질문할 때마다 수행)

  1. 질문 임베딩 (Embedding de la question) — 인제스션 (ingestion) 단계와 동일한 모델을 사용합니다.
  2. 유사도 검색 (Recherche par similarité)pgvector가 벡터를 비교하여 의미론적으로 가장 유사한 상위 3개의 청크를 찾아냅니다.
  3. 프롬프트 구성 (Construction du prompt) — 질문 + 청크 + 출처 + 엄격한 환각 방지 (anti-hallucination) 지침을 결합합니다.
  4. 생성 (Génération) — LLM이 출처를 인용하며 답변합니다.
  5. 표시 (Affichage) — 클릭 가능한 칩 (chips) 형태로 출처와 유사도 점수를 보여줍니다.

모든 것의 핵심은 메타데이터가 처음부터 끝까지 텍스트와 함께 이동한다는 점입니다. 이것 없이는 인용이 불가능합니다. 인용이 없으면 신뢰할 수 없습니다. 신뢰가 없으면 고객도 없습니다.

코드 — 주요 부분

메타데이터를 포함한 추출 및 분할

export interface Chunk {
  text: string;
  metadata: {
...

Supabase에서의 검색 함수

create or replace function match_documents (
  query_embedding vector(768),
  match_count int default 3
...

<=> 연산자는 벡터 간의 코사인 유사도 (cosine distance)입니다. 두 텍스트가 동일한 내용을 다룰수록 벡터는 더 가까워지며, 유사도 점수는 더 높아집니다.

환각 방지 프롬프트 (Le prompt anti-hallucination)

const prompt = `당신은 기업 내부 어시스턴트입니다. 제공된 발췌문(extraits)에만 기반하여 질문에 프랑스어로 답변하세요.
각 주장마다 괄호 안에 출처(파일명 및 페이지)를 명시하세요.
...

"만약 정보가 발췌문에 없다면, 그렇다고 말하라"는 지침은 타협 불가능한 사항입니다. 이 지침이 없으면 LLM (Large Language Model)은 빈틈을 메우기 위해 내용을 지어냅니다(hallucination). 인사(HR) 절차를 조회하는 중소기업(PME)에게 있어, 지어낸 답변은 법적 리스크가 될 수 있습니다.

프로덕션 환경에서의 임베딩 (embeddings) 문제

처음 마주한 함정은 다음과 같습니다: Ollama는 로컬에서 실행되지만, Vercel에는 로컬 서버가 없습니다. 저는 여러 솔루션을 테스트했습니다:

  • Hugging Face Inference API — 프로덕션 환경에서 CORS 문제로 차단됨
  • OpenAI embeddings API — 저렴하긴 하지만 유료임
  • Transformers.js — ✅ 최종 선택된 솔루션

Transformers.js는 임베딩 모델을 브라우저에서 직접 실행합니다. 외부 API도, 키(key)도, 비용도 전혀 들지 않습니다. 첫 번째 질문은 모델 로딩(약 30MB)으로 인해 5~10초 정도 걸리지만, 그 이후에는 즉각적으로 응답합니다.

const IS_PROD = import.meta.env.PROD;
let _pipeline: any = null;

...

실제 작동 모습

가상의 코퍼스(corpus)인 "Martin & Dubois SARL"를 대상으로 시스템과 주고받은 실제 대화 예시입니다:

질문: 휴가는 며칠 전에 신청해야 하나요?
답변: 모든 유급 휴가 신청은 희망 출발일로부터 최소 4주 전에 제출되어야 합니다. (livret_accueil.pdf, 2페이지)

질문: 업무 식비 한도는 얼마인가요?
답변: 식비 환급 한도는 25유로로 정해져 있습니다. (livret_accueil.pdf, 3페이지)

질문: 일주일 내내 재택근무를 할 수 있나요?
답변: 아니요, 재택근무는 주 2일로 제한됩니다. (livret_accueil.pdf, 4페이지)

가장 적절한 페이지가 매번 상단에 올라오며, 유사도 점수 (similarity score)는 62%에서 75% 사이를 기록합니다. 답변은 정확하고 출처가 명시되어 있으며, 시스템은 모르는 내용에 대해 명확하게 모른다고 답변합니다.

내가 다르게 했을 수도 있는 부분

모델보다 청킹 (chunking)이 더 중요합니다. 저는 다양한 LLM (Large Language Models) 사이에서 고민하는 것보다 청크 크기 (chunk size)를 테스트하는 데 더 많은 시간을 보냈습니다. 150의 오버랩 (overlap)을 가진 900자의 길이는 프랑스어 산문에서 잘 작동하지만, 이는 문서 유형에 따라 경험적으로 조정해야 합니다.

스캔된 PDF는 실제적인 문제입니다. 실제로는 스캔된 이미지인 PDF는 0개의 청크를 생성합니다. 실제 사례를 위해서는 OCR (Tesseract 또는 LLM의 Vision API)을 추가해야 합니다. 이것이 다음 기능 (feature)이 될 것입니다.

보안은 여전히 해결해야 할 과제입니다. 실제 중소기업 (PME)을 위해서는 인증 (authentication)을 추가하고, Supabase의 RLS (Row Level Security)를 활성화하며, 클라이언트 측에 Groq 키를 노출하지 않아야 합니다. 이는 다음 글의 주제가 될 것입니다.

이것이 왜 판매 가치가 있는가

이 시스템은 10명에서 200명 규모의 모든 중소기업 (PME)이 겪는 실제 문제를 해결합니다. 정보는 어딘가에 존재하지만, 아무도 그것을 어디서 찾아야 하는지 모릅니다. 인사팀 (RH)은 매주 똑같은 기본적인 질문에 20번씩 답변합니다.

기술 전문가가 아닌 사람도 데모를 이해하는 데 30초밖에 걸리지 않습니다. 질문을 던지면, 답변이 보이고, 출처가 보입니다. 검증 가능하며 구체적입니다.

배포 후 운영 비용은요? Supabase + Groq + Vercel의 무료 티어 (free tier)를 사용하면 **월 0€**입니다.

더 알아보기

소스 코드는 GitHub에서 확인할 수 있습니다: github.com/sharklandy/rag-pme

데모는 다음 주소에서 실행됩니다: rag-pme.vercel.app

다음 글에서는: 인증 추가, OCR을 통한 스캔된 PDF 지원, 그리고 Vercel에 인제스션 서버 (ingestion server)를 서버리스 (serverless)로 배포하는 내용을 다룹니다.

Landry Lhomme — 중소기업 (PME)용 AI 통합 전문 주니어 개발자. 프리랜서 미션 가능.
GitHub : sharklandy

AI 자동 생성 콘텐츠

본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.

원문 바로가기
0

댓글

0