당신의 RAG 시스템이 계속 환각을 일으키는 이유: 기본기를 건너뛴 것에 대한 숨겨진 비용
요약
RAG 시스템의 환각 현상은 도구의 문제가 아닌 기본기 부족과 계층적 추상화 부채에서 비롯됩니다. 청킹 전략, 하이브리드 검색의 가중치 조절 등 하위 계층의 원리를 이해해야 신뢰할 수 있는 시스템을 구축할 수 있습니다.
핵심 포인트
- 라이브러리에 의존한 추상화는 디버깅을 어렵게 만드는 '추상화 부채'를 발생시킴
- 청크 크기 선택은 단순 파라미터 조절이 아닌 시맨틱한 결정 과정임
- 하이브리드 검색은 단순 결합이 아닌 도메인에 따른 정교한 가중치 조합의 문제임
- 성공적인 RAG를 위해서는 라이브러리 이면의 작동 원리에 대한 정신적 모델이 필요함
청크 크기(chunk size)에 관한 포럼 스레드에는 47개의 답글이 달려 있습니다. 모두가 512 토큰 대 1024 토큰, 하이브리드 검색(hybrid search) 대 순수 벡터 검색(pure vector search), 리랭킹(reranking)이 실제로 도움이 되는지 여부를 두고 논쟁하고 있습니다. 당신은 튜토리얼에 따라 "운영 준비가 완료된(production-ready)" LangChain 파이프라인을 가지고 앉아 있지만, 검색 정확도(retrieval accuracy)는 34%에 불과합니다. 당신은 그 이유를 모릅니다. 당신은 어떤 블로그 포스트에서 말했기 때문에 청크 크기를 선택했을 뿐입니다. 당신은 의미론적 청킹(semantic chunking)이 임베딩(embeddings)에 어떤 영향을 미치는지 실제로 알지 못합니다.
이것은 도구의 문제가 아닙니다. 그것은 기본기(fundamentals)의 문제입니다.
저는 지난 분기에 RAG 파이프라인을 처음부터 다시 구축하는 데 3주를 보냈습니다. 새로운 RAG 파이프라인이 필요해서가 아니라, 운영 환경에서 조용히 실패하고 있는 파이프라인을 물려받았기 때문입니다. 이전 팀은 문서에 있는 모든 "모범 사례(best practice)"를 따랐습니다. 벡터 DB(vector DB)는 적절하게 인덱싱되었습니다. LLM 호출은 캐싱되었습니다. 검색(retrieval)은... 블랙박스였습니다. 그리고 비즈니스 사용자들이 특정 유형의 쿼리에 대해 환각(hallucinations)이 발생한다고 불평하기 시작했을 때, 아무도 그 이유를 설명할 수 없었습니다.
이것이 아무도 경고하지 않는 RAG 세금, 즉 **계층적 추상화 부채(Layered Abstraction Debt)**입니다. 하위 계층을 이해하지 못한 채 라이브러리를 쌓아 올리면, 단순히 편의성을 빌려오는 것이 아니라 눈먼 상태를 빌려오는 것입니다. 시스템은 작동하다가 어느 순간 작동하지 않게 되며, 그때 당신은 정신적 모델(mental model)을 구축한 적이 없기 때문에 디버깅을 할 수 없습니다.
연구가 실제로 보여주는 것
이 조사의 계기가 된 atsushi11o7의 Qiita 포스트는 신선할 정도로 일본답지 않은 접근 방식을 취합니다: 모든 것을 처음부터 구현하는 것입니다. 저자는 하이브리드 검색(dense vector embeddings와 희소 BM25 키워드 매칭을 결합)을 살펴본 다음, 검색 시스템이 무엇을 쿼리할지 결정할 수 있는 에이전틱 RAG(Agentic RAG) 패턴으로 확장합니다. 이것이 바로 일본 개발 커뮤니티가 탁월한 능력을 발휘하는 심층 분석 콘텐츠입니다. 즉, 막연한 설명보다는 구체적인 구현을 중시하는 것입니다.
구현을 통해 얻은 핵심 통찰: 하이브리드 검색 (Hybrid Search)은 단순히 "벡터 검색 + 키워드 검색"을 더하는 것이 아닙니다. 이는 각 극단적인 방식에서 발생하는 특정 실패 모드(failure modes)를 고려해야 하는 가중치 조합(weighted combination)의 문제입니다. 순수 시맨틱 검색 (Pure semantic search)은 정확한 일치 항목을 놓칩니다 (예: "error code 403"이 관련 없는 결과만 반환함). 순수 키워드 검색 (Pure keyword search)은 개념적 유사성을 놓칩니다 (예: "authentication failure"가 "unauthorized access"와 매칭되지 않음). 하이브리드 검색을 한다는 것은 두 방식 모두를 충분히 이해하여 올바르게 가중치를 부여해야 함을 의미하며, 그 가중치는 도메인에 따라 달라집니다.
당신이 추상화하여 간과하고 있는 세 가지 계층
여기서부터 불편한 진실이 드러납니다. 모든 RAG 라이브러리는 출력 품질을 직접적으로 제어하는 세 가지 계층을 추상화하여 숨기고 있습니다.
1. 청킹 전략 (Chunking Strategy)
청크 크기 (Chunk size)는 단순한 성능 파라미터가 아니라 시맨틱 (semantic) 결정입니다. 청크당 512 토큰은 각 임베딩 (embedding)이 대략 한 단락을 캡처한다는 것을 의미합니다. 따라서 검색 결과는 단락 단위로 반환됩니다. 하지만 질문이 여러 단락에 걸친 종합적인 정보를 요구한다면, 당신은 잘못된 단위의 정보를 검색하고 있는 것입니다.
Qiita의 구현은 오버랩 (overlap)을 포함한 시맨틱 청킹 (semantic chunking)을 사용하는데, 이는 또 다른 차원을 추가합니다. 즉, 청크 간에 얼마나 많은 문맥 (context)이 흘러 들어가는가 하는 문제입니다. 오버랩이 너무 많으면 중복된 검색 결과가 발생하고, 너무 적으면 교차 참조 체인 (cross-reference chains)이 끊어지게 됩니다.
2. 임베딩 모델 선택 (Embedding Model Selection)
밀집 임베딩 (Dense embeddings, OpenAI, Cohere 또는 오픈 소스 모델로부터 생성)은 의미론적 의미를 포착하지만 구문 (syntax)을 놓칩니다. "Error: connection refused"와 "Error: connection timeout"은 완전히 다른 디버깅 단계를 요구함에도 불구하고 동일하게 임베딩될 수 있습니다. BM25는 키워드 중복은 포착하지만 의미는 완전히 놓칩니다.
진정한 질문은 이것입니다: 당신의 특정 도메인에서 "관련성 (relevance)"이란 무엇을 의미합니까? 법률 계약서인가요? 코드 문서인가요? 고객 지원 티켓인가요? 각 도메인마다 답이 다르며, 당신의 임베딩이 실제로 무엇을 포착하는지 이해하지 못한다면 그 답을 내릴 수 없습니다.
3. 정밀도(Precision) 대 재현율(Recall)의 트레이드오프 (Retrieval vs. Recall Trade-off)
벡터 유사성 검색(Vector similarity search)은 잠재적으로 관련 있는 모든 것을 찾는 재현율(Recall)에 최적화되어 있습니다. 하지만 실제 운영 환경의 RAG는 질문에 답하는 내용만을 반환해야 하는 정밀도(Precision)가 필요합니다. 이 두 목표 사이의 간극이 바로 하이브리드 검색(hybrid search)이 존재하며, 실제로 'RAG가 제대로 작동하지 않는다'고 불평하는 대부분의 사례가 여기에 해당합니다.
# Qiita 구현에서 가져온 단순화된 하이브리드 스코어링 (Simplified hybrid scoring)
def hybrid_score(dense_result, sparse_result, alpha=0.5):
# Alpha는 dense와 sparse 가중치를 제어함
...
'올바른' 알파 값은 문서에 나와 있지 않습니다. 이는 도메인 의존적이며, 실제 쿼리를 실험해봐야만 알 수 있습니다. 이 과정에는 스코어가 실제로 무엇을 측정하는지 이해하는 것이 필요합니다.
에이전트형 RAG (Agentic RAG): 검색이 복잡해질 때
Qiita 게시물에서 다루는 더 진보된 패턴은 에이전트형 RAG(Agentic RAG)입니다. 여기서 검색 시스템 자체가 결정을 내릴 수 있습니다. '내가 이것을 검색해야 할까?', '쿼리를 개선해야 할까?', '여러 소스에서 가져와야 할까?' 등이 해당됩니다.
여기서 추상화는 진정으로 위험해집니다. 에이전트형 RAG란 검색 시스템에 분기 논리(branching logic)가 있다는 의미입니다. 만약 기본적인 검색 작동 방식을 이해하지 못한다면, 에이전트가 어떻게 실패할지 예측할 수 없습니다. 실제 문제는 쿼리 분류 임계값(query classification thresholds)인데도 불구하고 '왜 에이전트가 내 문서를 무시하는가'를 디버깅하는 데 몇 주를 보낼 수도 있습니다.
솔직한 경고: 만약 임베딩 생성, 벡터 저장소, 유사성 검색, 결과 재순위 지정(result reranking)을 통해 기본적인 RAG 파이프라인을 처음부터 구현할 수 없다면, 에이전트형 RAG를 할 준비가 된 것이 아닙니다. 복잡성이 누적되고 실패 모드도 기하급수적으로 늘어납니다.
회의적인 관점 (The Skeptical Take)
여기서 저는 '처음부터 구축하라'는 설교에 반론을 제기하겠습니다. 항상 옳은 결정은 아닙니다. 깨끗한 데이터와 명확한 쿼리 패턴을 가진 안정적이고 잘 이해된 도메인의 경우, 라이브러리를 사용하는 것으로 충분합니다. 시스템이 예상치 못한 방식으로 실패할 때만 부채(technical debt)가 누적됩니다.
진정한 기술은 언제 라이브러리를 사용하고, 언제 직접 구축해야 하는지를 아는 것입니다. 저의 경험적인 규칙은 다음과 같습니다. 인프라(벡터 DB (vector DB) 작업, 캐싱 (caching), API 처리)에는 라이브러리를 사용하되, 검색 로직 (retrieval logic)은 직접 구축하십시오. 그렇게 하면 결과가 잘못 나왔을 때 실제로 어떤 일이 일어나고 있는지 이해할 수 있으면서도, 분산 시스템 관리 (distributed systems management)를 처음부터 다시 만들 필요는 없습니다.
생존 체크리스트
다음 RAG 프로젝트를 시작하기 전에:
-
청킹 전략 (chunking strategy)을 벤치마크하십시오 — 3가지 서로 다른 청크 크기에 대해 동일한 쿼리를 실행하십시오. Top-1 및 Top-5에서의 정밀도 (precision)를 측정하십시오. "올바른" 정답은 블로그 포스트가 아니라 당신의 데이터에 달려 있습니다.
-
실제 데이터로 임베딩 모델 (embedding model) 선택을 테스트하십시오 — 당신의 도메인에서는 OpenAI의 ada-002가 GPT-4 임베딩보다 성능이 더 좋을 수 있습니다. 합성 테스트 케이스 (synthetic test cases)가 아닌 실제 쿼리로 비교를 수행하십시오.
-
2주 동안 검색 실패 (retrieval failures)를 기록하십시오 — 사용자가 "이것은 내 질문에 답이 되지 않는다"라고 말할 때마다, 쿼리, 검색된 청크 (retrieved chunks), 그리고 기대되는 답변을 기록하십시오. 2주가 지나면 당신의 하이브리드 검색 (hybrid search)이 처리하지 못하는 패턴을 파악하게 될 것입니다.
-
나중에 라이브러리를 사용하더라도 BM25를 한 번은 직접 구현해 보십시오 — 키워드 매칭 (keyword matching)의 기준점 (baseline)을 이해하면 벡터 검색 (vector search) 성능을 더 잘 평가할 수 있는 능력이 생깁니다. 그러면 단순히 "의미적 유사성 (semantic similarity)"에 감탄하는 것을 멈추고, "무엇과 비교했을 때인가?"라고 묻기 시작할 것입니다.
디버깅할 수 없는 RAG 파이프라인은 프로덕션 준비가 된 것이 아닙니다. 그것은 프로덕션이 연기된 것뿐입니다. 라이브러리는 시장 출시 시간을 벌어주지만, 이해력을 벌어다 주지는 않습니다. 그리고 그 이해력이 바로 데모에서 작동하는 시스템과 실제 세상에서 작동하는 시스템의 차이를 만듭니다.
당신의 의견은 어떠신가요?
가장 많은 디버깅 시간을 소모하게 만든 RAG 검색 실패 사례는 무엇이었나요? 그것은 청킹 문제였나요, 임베딩 불일치였나요, 아니면 완전히 다른 무엇이었나요? 당신이 첫 파이프라인을 구축하기 전에 아무도 경고해주지 않았던 것에 대해 듣고 싶습니다.
일본 개발자 커뮤니티(Qiita)의 구현 연구를 바탕으로 합니다. "바닥부터 구현하기 (implement from scratch)" 방식은 추상화하기 전에 각 계층을 이해하려는 일본의 깊은 엔지니어링 전통을 반영합니다.
토론: 당신에게 가장 많은 디버깅 시간을 소모하게 만든 RAG 검색 실패 사례는 무엇이었나요? 그리고 그것이 청킹 (chunking) 문제였나요, 임베딩 불일치 (embedding mismatch)였나요, 아니면 완전히 다른 무엇이었나요?
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기