RAG 채팅 어시스턴트를 처음부터 직접 구축해 보았습니다 — 프로덕션 RAG에 대해 아무도 말해주지 않는 것들
요약
실제 프로덕션 환경에서 작동하는 RAG 시스템 구축 시 직면하는 기술적 난제와 해결책을 다룹니다. 단순한 임베딩을 넘어 청킹 전략, 하이브리드 검색, 컨텍스트 최적화의 중요성을 강조합니다.
핵심 포인트
- 시맨틱 청킹과 중첩 전략을 통해 컨텍스트 손실 방지
- BM25와 벡터 유사도를 결합한 하이브리드 검색 활용
- 비용과 품질을 고려한 상위 5개 청크 제한 및 중복 제거
- 쿼리 재작성 및 재순위화(Reranking)를 포함한 아키텍처 설계
모두가 RAG (Retrieval-Augmented Generation, 검색 증강 생성) 채팅 어시스턴트를 구축하는 것이 얼마나 쉬운지에 대해 이야기합니다. 그냥 문서 몇 개를 임베딩(embedding)하고, 벡터 데이터베이스(vector database)에 넣은 다음, LLM을 연결하면 되는 것 아닌가요?
글쎄요, 저는 최근 몇 주 동안 거의 2,000개의 문서가 있는 실제 지식 베이스 플랫폼을 위한 프로덕션 RAG 시스템을 구축하는 데 시간을 보냈습니다. 그리고 말씀드리자면 — 주말 해커톤 데모와 실제 사용자를 위해 실제로 작동하는 것 사이에는 엄청난 격차가 있습니다.
RAG란 무엇인가?
올해 이 약어를 수천 번쯤 들어보지 않으셨을 수도 있으니 설명하자면: RAG는 자신의 지식 베이스에서 관련 문서를 검색하여 이를 LLM에 컨텍스트(context)로 제공하는 기술입니다. 이를 통해 AI는 학습 데이터의 차단 시점(training cut-off) 대신 여러분의 데이터를 기반으로 답변하게 됩니다.
이론은 간단합니다. 하지만 현실은 지뢰밭입니다.
아무도 경고해주지 않는 세 가지 지뢰
1. 청킹(Chunking)이 전부입니다 (그리고 아마 당신은 잘못하고 있을 것입니다)
저의 첫 번째 시도는 어땠을까요? 중첩(overlap) 없이 500개 토큰 단위로 청킹을 나누는 것이었습니다. 결과는 끔찍했습니다. 검색된 청크의 절반이 문장 중간에서 잘려 나가 중요한 컨텍스트를 잃어버렸습니다.
실제로 효과가 있었던 방법:
- 시맨틱 청킹 (Semantic chunking): 자연스러운 경계(제목, 문단 구분)에서 분할
- 중첩 전략 (Overlap strategy): 인접한 청크 사이에 15-20%의 중첩 적용
- 메타데이터 강화 (Metadata enrichment): 각 청크에 소스 문서의 제목, 카테고리, 위치 정보를 포함
이 단 한 번의 변화만으로 답변 품질이 약 40% 향상되었습니다.
2. 벡터 검색(Vector Search)만으로는 충분하지 않습니다
임베딩(embeddings)에 대한 순수 코사인 유사도(cosine similarity)는 주제적으로 유사한 결과를 반환하지만, 구체적인 기술 질문에 대해서는 빗나가는 경우가 많습니다.
승리하는 조합:
- 정확한 기술 용어 매칭을 위한 BM25 (키워드 검색)
- 의미론적 이해를 위한 벡터 유사도 (Vector similarity)
- 가중치 점수를 적용한 하이브리드 랭킹 (Hybrid ranking) (0.4 BM25 + 0.6 벡터)
이 하이브리드 접근 방식은 "PostgreSQL 커넥션 풀링을 구성하는 방법"(BM25 승리)과 "부하 상황에서 왜 데이터베이스가 느려지는가"(벡터 승리)를 모두 잡아냅니다.
3. 컨텍스트 윈도우(Context Window)는 공짜가 아니라 예산입니다
대부분의 튜토리얼은 검색된 청크(chunks)를 프롬프트에 가능한 한 많이 집어넣습니다. 하지만 모든 토큰은 비용을 발생시키며 응답 품질을 저하시킵니다.
저의 접근 방식:
- 가장 관련성이 높은 상위 5개 청크 (10개도, 20개도 아닙니다)
- 지능적 중복 제거 (Intelligent deduplication): 거의 동일한 청크를 제거합니다.
- 출처 표기 (Source attribution): 각 답변은 원문 기사로 연결됩니다.
실제로 작동했던 아키텍처 (The Architecture That Actually Worked)
사용자 질문 → 쿼리 재작성 (Query Rewriting) → 하이브리드 검색 (Hybrid Search) (BM25 + Vector)
→ 재순위화 (Reranking) → 상위 5개 선택 (Top-5 Selection) → 프롬프트 조립 (Prompt Assembly) → LLM 응답
주요 기술 선택:
- 벡터 데이터베이스 (Vector DB): Supabase (pgvector) — Postgres이며 이미 SQL을 알고 있기 때문입니다.
- 임베딩 (Embeddings): OpenAI text-embedding-3-small (빠르고, 저렴하며, 충분히 성능이 좋습니다)
- 재순위화 (Reranking): 커스텀 스코어링 함수 (BM25 + 벡터 + 최신성 가중치)
- LLM: 프로덕션 트래픽에서의 비용 효율성을 위해 GPT-4o-mini 사용
결과 (The Results)
- 지식 베이스 내 약 2,000개의 기술 기사
- 대부분의 질문에 대해 1초 미만의 쿼리 지연 시간 (latency)
- 출처가 연결된 답변 — 모든 응답은 어떤 기사에서 가져왔는지 인용합니다.
- 쿼리당 비용: 약 $0.005 (임베딩 + LLM 호출)
다르게 했을 것 같은 점 (What I'd Do Differently)
- 첫날부터 재순위화 모델 (reranker model)로 시작할 것 — 추가적인 연산 비용을 들일 가치가 있습니다.
- 피드백 루프 (feedback loop)를 조기에 구축할 것 — 사용자가 답변에 대해 좋아요/싫어요를 표시할 수 있게 합니다.
- 청킹 (chunking)을 과하게 설계하지 말 것 — 단순하게 시작하고, 실제 쿼리 패턴에 따라 반복 개선하세요.
결론 (The Bottom Line)
RAG는 마법이 아닙니다. 엔지니어링입니다. 그리고 모든 엔지니어링 문제와 마찬가지로, 악마는 디테일에 있습니다. "내 노트북에서는 작동한다"와 "새벽 3시에 이상한 질문을 던지는 수천 명의 사용자에게도 작동한다" 사이의 간극은 청킹 전략, 하이브리드 검색 튜닝, 그리고 끊임없는 반복 개선으로 채워집니다.
만약 지금 RAG 시스템을 구축하고 있다면: 단순하게 시작하고, 모든 것을 측정하며, 검색 파이프라인 (retrieval pipeline)을 최소 세 번은 다시 작성할 각오를 하세요.
개발자 도구 구축에 대해 더 깊이 알아보고 싶으신가요? codcompass.com에서 저의 기술 지식 베이스를 확인해 보세요. 소프트웨어 출시(shipping)에 관한 실무적인 통찰을 담아 매주 업데이트되고 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기