당신의 RAG 평가가 검색기(Retriever)가 아닌 청커(Chunker)를 채점하고 있는 이유
요약
대부분의 RAG 평가 프레임워크가 청킹(Chunking) 방식의 결함을 감지하지 못하는 구조적 문제를 지적합니다. 골드 세트가 이미 청킹된 데이터를 기준으로 생성되기 때문에, 청커의 성능 저하가 검색 성능 평가에 반영되지 않는 생존 편향 문제를 다룹니다.
핵심 포인트
- RAG 평가는 검색기가 청커와 일치하는지를 테스트할 뿐, 정보 보존력을 측정하지 못함
- 골드 세트 구축 과정에서 청킹 실패 사례가 배제되는 생존 편향 발생
- 청킹은 단순 배관 작업이 아닌 의미론적 독립성을 결정하는 모델링 과정임
- 해결책으로 정답 구간을 청크 경계와 분리하여 청커를 직접 테스트해야 함
요약(TL;DR) — 대부분의 RAG 평가 프레임워크는 '정확한 검색(correct retrieval)'을 정답(gold answer)을 생성한 청크(chunk)와 일치하는 것으로 정의합니다. 하지만 그 정답 청크는 당신이 테스트하려는 바로 그 청킹(chunking) 방식에 의해 나누어진 것입니다. 이로 인해 청킹 실패가 보이지 않게 됩니다. 평가는 잘못된 검색은 감지할 수 있지만, 깨진 청크를 올바르게 검색한 경우는 결코 감지할 수 없습니다. 해결책은 정답 답변 구간(gold answer spans)을 청크 경계(chunk boundaries)로부터 분리하고, 임베딩(embeddings)이나 리랭커(re-rankers)가 개입하기 전에 청커(chunker)를 직접 스트레스 테스트하는 것입니다.
모든 RAG 사후 분석(postmortem)은 결국 똑같은 세 가지 용의자를 비난합니다: 임베딩 모델(embedding model), 리랭커(re-ranker), 또는 프롬프트(prompt)입니다. 그중 청커(chunker)를 비난하는 경우는 거의 없습니다. 청킹이 괜찮아서가 아닙니다. 대부분의 평가 설정이 구조적으로 청킹 실패를 잡아낼 수 없기 때문입니다. 즉, 설계 단계부터 청킹이 보이지 않도록 만들어져 있습니다.
여기에 아무도 인지하지 못하는 루프(loop)가 있습니다. 당신은 문서를 가져와 청킹을 하고, 사람이나 모델에게 그 청크 중 하나에 답이 있는 질문을 작성하게 함으로써 골드 평가 세트(gold evaluation set)를 만듭니다. 그런 다음 검색기(retriever)가 동일한 청크를 표면화하는지 확인하여 검색(retrieval)을 평가합니다. 컨텍스트 정밀도(context precision), 컨텍스트 재현율(context recall), k에서의 히트 레이트(hit rate at k) — 이 모든 것은 골드 세트가 가져와야 한다고 말하는 그 청크를 가져왔는지 여부를 측정합니다. 하지만 골드 세트는 청킹이 이루어진 후에, 청크 경계를 진실의 단위(unit of truth)로 사용하여 정의되었습니다. 당신은 검색기가 당신의 청커와 일치하는지를 테스트하고 있는 것입니다. 당신은 청커가 검색기에 필요한 정보를 보존했는지를 테스트하고 있는 것이 아닙니다.
청킹은 전처리(Preprocessing)의 탈을 쓴 모델링 결정(Modeling Decision)이다
팀들은 청킹(Chunking)을 단순한 배관 작업(Plumbing)처럼 취급합니다. 즉, 크기를 정하고, 오버랩(Overlap)을 정하고, 그냥 배포해 버리는 것이죠. 하지만 청크 경계(Chunk boundary)는 의미론적 독립성(Semantic independence)에 대한 하나의 주장입니다. 텍스트를 분할할 때마다 여러분은 "이 구절에 대한 질문에 답하는 데 필요한 모든 것이 이 N개의 토큰 안에 포함되어 있다"라고 주장하는 셈입니다. 그 주장은 대개 틀렸습니다. 정의(Definitions)가 그 정의 대상이 되는 용어와 분리됩니다. 4번째 단락의 주의 사항(Caveat)이 1번째 단락에서 수식하던 주장으로부터 고립됩니다. 표(Table)의 헤더 행은 데이터 행과 다른 청크로 넘어가 버립니다.
이러한 문제들은 표준 평가(Standard eval)에서는 전혀 드러나지 않습니다. 왜냐하면 평가의 정답(Gold answer) 자체가 이미 정의상 정답을 포함하고 있는 청크에서 추출되었기 때문입니다. 여러분은 정답이 두 개의 청크에 걸쳐 나뉘어 있는 골드 질문(Gold question)을 생성한 적이 없습니다. 골드 세트(Gold sets)를 구축하는 워크플로우 자체가 자연스럽게 이미 "완전해" 보이는 청크들을 선택하도록 설계되어 있기 때문입니다. 즉, 평가 세트는 여러분의 청킹 방식이 성공한 사례들만 모아놓은 생존 편향(Survivorship-biased)된 샘플입니다.
더 나은 임베딩(Embeddings)과 리랭커(Re-Rankers)가 이를 해결할 수 없는 이유
이 부분은 시니어 엔지니어들도 실수하는 지점입니다. 왜냐하면 이것이 검색 품질(Retrieval-quality) 문제처럼 보이고, 실제로도 그렇게 다뤄지기 때문입니다. 문맥 정밀도(Context precision)가 낮으면, 본능적으로 임베딩 모델을 교체하거나, 리랭커(Re-ranker)를 추가하거나, 검색 결과 개수(Retrieval k)를 조정하려 합니다. 때로는 이것이 도움이 되기도 합니다. 리랭커는 미세하게 관련 있는 청크를 상단으로 올릴 수 있고, 더 나은 임베딩 모델은 키워드 검색이 놓칠 수 있는 의미론적으로 관련된 청크를 찾아낼 수 있습니다. 하지만 그 어떤 것도 청크 경계가 이미 삭제해 버린 정보를 다시 되살릴 수는 없습니다.
만약 "이 정책의 예외 사항은 무엇인가?"라는 질문에 대한 답을 얻기 위해 12번 청크의 정책 문구와 14번 청크의 예외 목록이 모두 필요하다면, 리랭커가 14번 청크의 순위를 높게 매긴다고 해서 문제가 해결되지 않습니다. 모델이 두 청크가 연결되어 있음을 이해할 수 있도록, 두 청크가 모두 검색되어 충분한 문맥과 함께 결합(Stitched)되어야 합니다. 리랭킹(Re-ranking)은 순서를 최적화할 뿐입니다. 완전성(Completeness)에 대해서는 아무것도 할 수 없습니다. 그리고 완전성이야말로 청킹이 스택의 다른 모든 구성 요소보다 앞선 단계(Upstream)에서 보존하거나 파괴하는 바로 그 속성입니다.
당신의 평가 스위트(Eval Suite)에 빠져 있는 진단 도구
만약 당신의 청커(Chunker)가 문제인지 알고 싶다면, 의도적으로 순환 구조를 깨뜨려야 합니다. 이는 청킹(Chunking)이 일어나기 전, 텍스트가 어떻게 분할될지 전혀 모르는 사람이 _원본 문서(Source document)_를 바탕으로 정답(Gold answers)을 작성한 작고 별도인 평가 세트를 구축하는 것을 의미합니다. 그런 다음 청커를 실행하고, 임베딩(Embed)하고, 검색(Retrieve)한 뒤, 단순히 "올바른 청크를 가져왔는가"보다 더 구체적인 것을 확인하십시오. 즉, 검색된 청크들의 합집합이 질문에 답하는 데 필요한 모든 사실을 포함하고 있는지, 그리고 각 사실이 원본 텍스트에서 서로 인접해 있다는 점과 무관하게 독립적으로 검색 가능한지를 확인해야 합니다.
이 과정은 표준 RAG 지표에는 이름조차 없는 실패 범주를 드러냅니다: 바로 부분적 답변 검색(Partial-answer retrieval)입니다. 검색기(Retriever)는 자신의 역할을 수행하여 관련 있는 무언가를 찾아냈지만, 찾아낸 것이 파편(Fragment)일 뿐입니다. 그러면 생성기(Generator)는 누락된 부분을 환각(Hallucinate)하거나, 더 나쁜 경우에는 무엇이 누락되었는지 인지하지 못한 채 절반의 진실만을 가지고 자신 있게 답변합니다. 청크 수준에서 작동하는 문맥 재현율(Context recall) 지표는 해당 파편이 정답 청크(Gold chunk)와 우연히 겹치기만 한다면 이를 기꺼이 성공(Hit)으로 점수화할 것입니다. 이러한 지표들은 그 파편이 충분했는지를 묻도록 설계된 적이 없습니다.
경계선을 신뢰하는 대신 스트레스 테스트하기
어떠한 종합적인 검색 점수보다 더 유용한 진단 도구는 경계선 스트레스 테스트(Boundary stress test)입니다. 실제 운영 중인 청킹 방식을 가져와 내부 의존성이 알려진 문서들을 대상으로 실행해 보십시오. 예를 들어 상호 참조가 포함된 번호 매겨진 목록, 헤더가 분리된 표, 몇 페이지 뒤에 사용되는 정의된 용어가 포함된 계약서, 호출 지점과 멀리 떨어진 함수 정의가 포함된 코드 등이 대상이 됩니다. 의존성 쌍(Dependency pair)이 공유된 검색 앵커(Retrieval anchor) 없이 청크 간에 분리되는 빈도를 기계적으로 측정하십시오. 이 수치는 대개 불편할 정도로 높게 나타날 것이며, 기존의 평가 점수와 깔끔하게 상관관계를 보이지 않을 것입니다. 왜냐하면 기존의 평가 점수는 애초에 이것을 측정하도록 설계되지 않았기 때문입니다.
그 수치를 얻고 나면, 해결책은 좁고 명확하게 정의되어 있습니다. 고정된 토큰 창(token windows) 대신 문서 계층 구조를 존중하는 의미론적 또는 구조 인식 청킹(semantic or structure-aware chunking), 각 청크가 부모 섹션의 요약을 포함하는 문맥적 청크 증강(contextual chunk augmentation), 또는 고립된 청크 대신 청크 주변 영역을 가져오는 검색 전략(retrieval strategies) 등이 그것입니다. 이 중 어느 것도 생소한 기술이 아닙니다. 대부분의 기술 스택에서 부족한 것은 기술 그 자체가 아니라, 당신에게 실제로 어떤 기술이 필요한지 알려주는 측정(measurement)입니다.
골드 세트(Gold Set)를 자산이 아닌 부채로 취급하라
불편한 결론은, 당신의 자체적인 청킹 방식(chunking scheme)을 기반으로 구축된 RAG 평가 세트(eval set)의 수명이 청커(chunker)의 변경 주기에 따라 결정된다는 것입니다. 청크 크기, 중첩(overlap), 또는 분할 로직을 조정할 때마다, 기존 청크에 "정렬(aligned)"되었던 골드 세트는 더 이상 새로운 청크의 실패 모드(failure modes)를 나타내지 못할 수 있습니다. 더 나쁜 점은, 애초에 청커와 독립적이지 않았기 때문에 여전히 건강한 점수를 보고할 것이라는 사실입니다. 평가 대상이 되는 산출물(artifact)과 얽혀 있는 평가는 점진적으로 퇴화하는 것이 아니라, 하단의 시스템이 형태를 바꾸는 동안에도 계속 '정상(green)'이라고 보고하며 조용히 퇴화합니다.
골드 답변(gold answers)을 청크 경계로부터 분리(decoupling)하는 것은 초기 비용이 더 많이 듭니다. 청크 단위의 주석(chunk-level annotation) 대신 소스 단위의 주석(source-level annotation)이 필요하며, 구축 속도도 더 느립니다. 하지만 이것만이 "검색기(retriever)가 약한 것"과 "청커(chunker)가 검색기에 필요한 정보를 이미 버려버린 것"을 실제로 구분할 수 있는 신호를 얻을 수 있는 유일한 방법입니다. 이 둘은 서로 다른 버그이며, 해결 방법도 다릅니다. 하지만 현재 대부분의 RAG 팀은 평가 도구가 이 둘을 구분하지 못하기 때문에 잘못된 버그를 디버깅하고 있습니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기