
RAG의 정밀도가 나오지 않을 때, top-k를 늘리기 전에 failure mode를 구분하라
요약
RAG 시스템의 정밀도가 낮을 때 무작정 파라미터를 수정하기보다 실패 모드(failure mode)를 단계별로 구분하여 원인을 파악해야 합니다. 데이터 부재, 검색 실패, LLM 해석 오류, 출력 오류를 구분함으로써 불필요한 리소스 낭비를 막고 정확한 해결책을 적용하는 프레임워크를 제시합니다.
핵심 포인트
- top-k 증가 등 해결책을 늘리기 전 실패 원인(failure mode)을 먼저 구분해야 함
- DB 데이터 부재, 검색 실패, LLM 해석 오류, 출력 오류는 각각 해결 방법이 다름
- 데이터 부재 문제는 파이프라인 전체를 재가동해야 하므로 비용과 신선도 관리가 중요함
- 단순 검색 방식에서 필요한 시점에 근거를 가져오는 방식으로의 전환 고려 필요
RAG의 정밀도가 나오지 않는다.
top-k를 늘린다.
Vector DB를 바꾼다.
rerank를 추가한다.
전형적인 패턴입니다.
하지만 그전에 반드시 확인해야 할 것이 있습니다.
지금 고장 난 것이 정말 retrieval(검색)일까요?
검색도 하고 있고, context(문맥)도 전달하고 있으며, LLM도 답변을 내놓고 있습니다.
그럼에도 답변이 어긋날 때, 해결 방법을 늘려갈수록 고쳐야 할 지점은 오히려 보이지 않게 됩니다.
이 글은 trend-to-rule이라는 작은 구현 과정에서 겪었던, "failure mode를 구분하지 않은 채 해결 방법만 늘려갔던" 오류에 대한 기록입니다. 코드는 공개하지 않겠습니다. 분류를 위한 프레임워크만 작성하겠습니다.
RAG가 어긋날 때, 처음에는 단순히 "검색 결과가 나쁘다"라고 치부하곤 했습니다.
Vector DB가 약한 것인지, 검색 query(질의)가 나쁜 것인지, retrieve(검색)는 되었으나 LLM이 해석을 잘못한 것인지, 아니면 해석은 맞는데 마지막 output(출력) 단계에서 무너진 것인지.
이 지점들이 뒤섞이면 갑자기 수정하기가 어려워집니다. 검색도 하고 있고, context도 전달하고 있으며, LLM도 답변을 내놓고 있습니다. 하지만 어디를 고쳐야 할지 알 수 없게 됩니다.
이 상황에서 top-k를 늘리면 운 좋게 맞을 수도 있습니다. 하지만 왜 맞았는지 알 수 없기 때문에, 다음에 틀렸을 때 다시 원점으로 돌아가게 됩니다.
해결 방법을 늘리기 전에, 실패의 원인을 위치에 따라 구분합니다.
1. DB에 들어있지 않음
2. 들어있지만 retrieve 되지 않음
3. retrieve 되었으나 LLM이 해석을 잘못함
...
이 4가지는 고쳐야 할 곳이 전부 다릅니다.
DB에 들어있지 않음 → 정보를 추가해야 합니다. 검색 조정으로는 해결되지 않습니다. -
retrieve 되지 않음 → query나 search strategy(검색 전략)를 살펴봐야 합니다. -
해석을 잘못함 → schema(스키마)나 중간 생성물을 살펴봐야 합니다. -
output에서 무너짐 → final answer(최종 답변)의 구성 방식을 살펴봐야 합니다. -
이 부분을 구분하지 않은 채 query expansion, top-k 증가, MMR, chunk size 변경, reranker 추가, agentic RAG를 추가해 나가면, 고치고 있다고 생각하면서 실제로는 다른 곳을 건드리게 됩니다. 이 방법들은 모두 "가져오는 방식"을 바꾸는 수단이며, 1번, 3번, 4번 문제에는 효과가 없습니다.
자체 Vector DB를 운영하며 힘들었던 점은, 1번(DB에 들어있지 않음)을 해결하는 것이 매우 무겁다는 것이었습니다.
DB에 내용이 부족하다는 것을 깨달아도, 이를 추가하려면 RSS를 다시 가져오고, ingest(수집)하고, chunk(청크 분할)하고, embedding(임베딩)하여 index(인덱스)를 업데이트해야 합니다. 한 번의 검증이 pipeline(파이프라인) 전체를 한 바퀴 도는 과정이 됩니다.
그러면 어떤 일이 벌어질까요? "DB에 들어있지 않은 것 아닌가"라고 생각하면서도, 추가하는 과정이 번거롭기 때문에 정밀도를 높이고 싶어도 그 직전 단계에서 멈추게 됩니다. failure mode의 1번이 비용 문제 때문에 고칠 수 없는 지점이 되어버리는 것입니다.
게다가 trend-to-rule이 다루었던 것은 fashion / trend였으며, evidence(근거)에 신선도(freshness)가 중요했습니다. DB를 키울수록 현재의 모습을 보고 싶은데 과거의 evidence까지 함께 떠안게 됩니다. DB의 내용이 조금씩 "현재"가 아니게 됩니다. 그저 검색을 하고 싶었을 뿐인데, DB의 신선도 관리까지 시작하게 됩니다.
그래서 쌓아두고 검색하는 것이 아니라, 그 시점에 필요한 evidence를 가져오는 방향(Web 검색에 가까운 방식)으로 전환했습니다.
여기서 중요한 점은 검색 서비스의 승패를 따지는 것이 아닙니다. 제가 한 일은, 4가지 분류 중 1번과 2번을 설계 단계에서 줄일 수 있는 형태로 만든 것입니다.
DB에 들어있지 않음 → 쌓아두지 않으므로 애초에 일어나기 어려움
DB에 들어있지만 오래됨 → 그 시점에 가져오므로 일어나기 어려움
추가·업데이트가 무거움 → pipeline을 유지하지 않으므로 사라짐
"검색이 나쁘다"라는 하나의 결론으로 뭉뚱그려 생각했다면, 여기까지 도달하지 못했을 것입니다. Web 검색이 효과적이었던 것이 아니라, Web 검색을 통해 배제할 수 있는 failure mode를 찾아낸 것입니다. 가져서는 안 될 책임을 설계 범위 밖으로 밀어낸 것뿐입니다.
물론 이것이 Vector DB 불필요론은 아닙니다. 사내 문서, 사양서, 계약서와 같이 자체 corpus(말뭉치)가 필요한 용도에서는 Vector DB가 당연히 필요합니다. trend-to-rule처럼 "공개 정보를 신선도와 함께 그 시점에 가져오고 싶은" 용도에서, 쌓아두는 책임이 무거웠다는 이야기입니다.
RAG가 어긋날 때 보아야 할 것은 "어떤 방법을 추가할 것인가"가 아니라, 어떤 failure mode에서 막혀 있는가였습니다.
수단(top-k, rerank, MMR, agentic RAG)은 특정 시점의 정답일 뿐입니다. 토대가 바뀌면 필요 여부도 바뀝니다. 하지만 4가지 분류를 통한 구분은 검색 기반을 바꾸더라도 유효했습니다.
수단은 사라집니다. 하지만 책임(responsibility)의 구분은 남습니다.
검색 결과(retrieval results)를 늘리기 전에 보았어야 했던 것은 검색 결과의 개수가 아니라, 어떤 책임이 어디에서 멈춰 있는가였습니다.
이 "failure mode를 구분하는 것"은 RAG의 책임을 순차적으로 나누어 가는 과정의 일부입니다.
검색 쿼리 설계(search query design), 검색된 근거(retrieved evidence), rerank가 정말로 효과가 있는지, 공통 규칙의 추출, 그리고 출력 경계(output boundary)에 이르기까지, 구현의 출처, 판단의 근거, 관측된 근거를 PDF에 정리했습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Qiita AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기