본문으로 건너뛰기

© 2026 Molayo

Dev.to헤드라인2026. 06. 15. 14:16

내가 왜 문서 Q&A 시스템을 처음부터 직접 만드는 것을 그만두었는가

요약

문서 Q&A 시스템 구축 시 미세 조정(Fine-tuning)과 키워드 검색의 한계를 경험하고, 이를 해결하기 위한 RAG(검색 증강 생성)의 필요성과 구현 방법을 다룹니다. Python과 OpenAI, ChromaDB를 활용한 기본적인 RAG 파이프라인 구축 단계를 소개합니다.

핵심 포인트

  • 미세 조정은 특정 사실 검색 능력이 부족하며 유지보수가 어려움
  • 키워드 검색은 자연어 질문의 맥락과 재현율을 잡기 어려움
  • RAG는 모델이 쿼리 시점에 외부 데이터를 참조하게 하는 방식임
  • 임베딩, 벡터 DB, LLM을 결합한 파이프라인 구축이 핵심임

두 달 전, 저는 간단해 보이는 프로젝트에 깊이 빠져 있었습니다. 바로 우리 회사의 내부 문서를 바탕으로 질문에 답할 수 있는 시스템을 구축하는 것이었습니다. 우리에게는 수백 개의 PDF, Confluence 페이지, 그리고 README 파일들이 있었습니다. 목표는 주니어 개발자들이 자연어 (Natural Language) 질문을 던지면 즉각적으로 정확한 답변을 얻을 수 있도록 하는 것이었습니다.

저는 "그게 얼마나 어렵겠어? 그냥 우리 문서들로 작은 LLM (Large Language Model)을 미세 조정 (Fine-tuning)하면 되겠지."라고 생각했습니다.

스포일러: 생각보다 훨씬 더 어려웠습니다.

막다른 길: 모델 미세 조정 (Fine-Tuning)

저는 2주 동안 우리 문서를 수집, 정제 및 청킹 (Chunking)하는 데 시간을 보냈습니다. Hugging Face 학습 스크립트를 작성하고, GPU를 대여하여 7B 파라미터 모델을 미세 조정했습니다. 결과는 어땠을까요? 우리 API 문서를 토씨 하나 안 틀리고 읊을 수는 있지만, "만료된 토큰에 대해 우리 인증 흐름(auth flow)이 실패하는 이유가 무엇인가요?"와 같은 질문에는 환각 (Hallucination) 현상 없이 답변하지 못하는 모델이 나왔습니다.

미세 조정은 모델에게 텍스트의 패턴을 가르쳐 주었지만, 특정 사실을 '검색 (Retrieve)'하는 능력은 주지 못했습니다. 게다가 문서가 변경될 때마다 매번 다시 학습시켜야 했습니다. 이는 지속 불가능했습니다.

두 번째 막다른 길: 순수 키워드 검색

다음으로, 저는 BM25 스코어러 (Scorer)를 사용하는 Elasticsearch를 시도했습니다. 문서를 청크로 나누고 사용자의 질문에서 키워드를 검색하는 방식이었습니다. 문제는 자연어 질문이 키워드와 잘 매칭되지 않는다는 것이었습니다. "비밀번호를 어떻게 재설정하나요?"라는 질문은 "재설정"과 "비밀번호"에 관한 청크와 매칭되겠지만, 다요소 인증 (Multi-factor auth)을 위한 중요한 단계들은 놓치게 됩니다. 재현율 (Recall)이 형편없었습니다.

깨달음: 검색 증강 생성 (RAG)

RAG (Retrieval-Augmented Generation)에 대해 읽고 나서, 저는 해결책이 내 데이터로 모델을 학습시키는 것이 아니라, 쿼리 시점에 모델이 올바른 데이터를 '찾아볼 수 있는' 방법을 제공하는 것이라는 점을 깨달았습니다. 핵심 아이디어는 다음과 같습니다:

  1. 문서를 더 작은 청크로 나눕니다.
  2. 임베딩 모델 (Embedding model)을 사용하여 각 청크에 대한 임베딩 (Embedding, 벡터)을 생성합니다.
  3. 임베딩을 벡터 데이터베이스 (Vector database)에 저장합니다.
  4. 질문이 들어오면, 질문을 임베딩하고 가장 유사한 청크를 찾습니다.
  5. 해당 청크들과 질문을 LLM에 전달하여 답변을 합성합니다.

Python, OpenAI 임베딩 (embeddings), 그리고 ChromaDB를 사용하여 작동하는 프로토타입을 단계별로 안내하겠습니다.

최소 기능 RAG 파이프라인 구축하기 (코드 포함)

1단계: 종속성 설치

pip install chromadb openai tiktoken langchain langchain-community

2단계: 문서 로드 및 분할

이 예제에서는 작은 텍스트 파일을 사용하겠습니다. 실제 상황에서는 LangChain의 문서 로더 (document loader)를 사용하면 됩니다.

from langchain_community.document_loaders import TextLoader
from langchain.text_splitter import RecursiveCharacterTextSplitter

...

중첩 (overlap)은 청크 (chunk) 경계에서 문맥이 손실되지 않도록 보장합니다.

3단계: 임베딩 및 ChromaDB에 저장

from langchain_community.embeddings import OpenAIEmbeddings
from langchain_community.vectorstores import Chroma

...

4단계: 질의 및 답변

from langchain.chains import RetrievalQA
from langchain_community.chat_models import ChatOpenAI

...

이것으로 끝입니다. 50줄 미만의 코드로 작동하는 Q&A 시스템을 만들었습니다.

교훈 및 트레이드오프 (Trade-offs)

RAG는 마법이 아닙니다. 그 나름의 고충이 있습니다:

  • 청크 크기 (Chunk size)가 중요합니다. 너무 작으면 문맥이 손실되고, 너무 크면 관련 없는 정보가 답변을 희석시킵니다. 저는 문서 유형에 따라 300~600 토큰 (tokens) 사이로 결정했습니다.
  • 임베딩 비용. 대규모 코퍼스 (corpus)의 경우, OpenAI API를 사용하여 수천 개의 청크를 임베딩하면 비용이 누적될 수 있습니다. Sentence Transformers의 all-MiniLM-L6-v2와 같은 무료 모델로 전환할 수 있지만, 정확도는 떨어집니다.
  • 지연 시간 (Latency). 모든 질의는 질문을 임베딩하고, 벡터 DB (vector DB)를 검색한 다음, LLM을 호출해야 합니다. 평균적으로 2~3초가 소요됩니다. 실시간 채팅을 위해서는 캐싱 (caching)이나 더 빠른 LLM이 필요할 수 있습니다.
  • 환각 (Hallucinations)은 여전히 발생합니다. 검색된 청크가 관련이 없다면, LLM은 여전히 답변을 지어낼 수 있습니다. 프로덕션 환경에서는 "신뢰도 확인 (confidence check)"이나 폴백 (fallback) 메커니즘을 추가하는 것이 필수적입니다.

다음에 다시 한다면 다르게 할 점

첫째, 임베딩 (embedding) 및 검색 (retrieval) 인프라를 처리해 주는 관리형 서비스 (managed service)로 시작할 것입니다. 예를 들어, Interwest Info AI (https://ai.interwestinfo.com/)와 같은 플랫폼은 벡터 DB (vector DB)와 청킹 (chunking) 전략을 추상화하여 제공하므로, 문서를 업로드하기만 하면 API를 얻을 수 있습니다. 그랬다면 ChromaDB의 특이한 동작 방식이나 확장성 (scaling) 문제로 씨름하며 보낸 2주를 아낄 수 있었을 것입니다.

둘째, RAG 파이프라인 (pipeline)을 구축하기 _전"에" 검색 품질을 평가하는 데 더 많은 시간을 투자할 것입니다. 20개의 질문으로 구성된 작은 테스트 세트를 만들고, 어떤 청크 (chunk)가 검색되어야 하는지 수동으로 검증하십시오. 이를 통해 청킹 (chunking) 및 임베딩 (embedding) 모델이 기준에 부합하는지 알 수 있습니다.

이 접근 방식을 사용하지 말아야 할 때

  • 문서가 50개 미만이고 수동으로 큐레이션할 수 있다면, 약간의 NLP (자연어 처리)를 결합한 간단한 키워드 검색만으로도 충분할 수 있습니다.
  • 질문이 모두 구조화된 데이터 (structured data)에 관한 것이라면 (예: "X의 값은 무엇인가요?"), 전통적인 SQL 쿼리 (query)가 더 빠르고 신뢰할 수 있습니다.
  • 500ms 이내에 답변이 필요하다면, 최적화된 추론 (inference)을 제공하는 호스팅 솔루션을 고려하십시오.

여러분의 차례

문서 Q&A 시스템을 처음부터 직접 구축해 본 경험은 그 어떤 블로그 포스트보다 검색 (retrieval) 과정의 트레이드오프 (trade-offs)에 대해 더 많은 것을 가르쳐 주었습니다. 하지만 이제 궁금합니다. 지식 베이스 (knowledge base) 챗봇을 구축할 때 여러분이 선호하는 방식은 무엇인가요? LangChain을 사용하여 직접 구축(DIY)하시나요, 아니면 SaaS 플랫폼을 사용하시나요? 댓글로 논의해 봅시다.

AI 자동 생성 콘텐츠

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

원문 바로가기
0

댓글

0