티스토리 뷰

현재 온디바이스(On-Device) 환경에서 사용할 RAG 검색 시스템을 개선하고 있다.
처음에는 임베딩 모델을 바꾸거나, 검색어를 확장하거나, 리랭커를 붙이는 식으로 검색 성능을 올리는 데 집중했다. 그런데 실험을 하다 보니 생각보다 먼저 정리해야 할 문제가 있었다.
바로 "이 검색 시스템이 좋아졌다는 걸 무엇으로 판단할 것인가?" 였다.
RAG 검색 성능을 테스트하다 보면 자연스럽게 Recall@k, MRR 같은 평가 지표를 보게 된다. 검색 결과 상위 k개 안에 정답 문서가 들어왔는지, 정답이 몇 번째에 나왔는지를 보는 방식이다.
지표 자체는 명확했다. 문제는 테스트 데이터셋이었다.
좋은 점수가 나왔다고 해서 실제 서비스 검색이 좋아졌다고 말할 수 있을까? 반대로 점수가 낮게 나왔다고 해서 지금 시스템에 맞지 않는 방향으로 고쳐야 할까?
이번 글에서는 RAG 검색을 개선하기 전에 테스트 데이터셋부터 다시 봐야 했던 이유를 정리해보려고 한다.
1. 테스트 목적은 하나가 아니었다
처음에는 공개 벤치마크를 기준으로 검색 성능을 테스트하려고 했다.
대표적으로 MIRACL, Mr.TyDi, Ko-mrtydi 같은 다국어 검색 데이터셋을 검토했다. 이런 데이터셋은 구조가 잘 잡혀 있고, 다른 모델이나 검색 시스템과 비교하기에도 좋다.
하지만 실제로 살펴보니 내가 필요한 테스트는 하나가 아니었다.
첫 번째로는 검색기 자체가 정말 나아졌는지 확인할 데이터가 필요했다.임베딩 모델을 바꾸거나, corpus를 늘리거나, 검색 로직을 수정했을 때 정답 문서가 더 잘 올라오는지 봐야 했다.
두 번째로는 지금 사용하고 있는 검색 방식이 정말 맞는지 확인할 데이터가 필요했다. 현재 검색 파이프라인은 사용자의 입력을 그대로 검색에 넣지 않는다. 먼저 질의처리기에서 형태소 분석과 키워드 추출을 수행하고, 그 결과를 검색기에 넘기는 방식에 가깝다.
예를 들어 사용자가 "최근 서울에서 진행하는 AI 바우처 지원사업 찾아줘"라고 입력하면, 이 문장을 그대로 검색하는 것이 아니라 "최근", "서울", "AI 바우처", "지원사업"처럼 검색에 필요한 표현을 분리해서 사용하는 방식이다.
이 방식이 정말 검색 품질을 올려주는지 확인하고 싶었다.
즉, 테스트 데이터셋은 하나의 목적만 가지면 안 됐다. 검색기 자체가 좋아졌는지 볼 수 있어야 했고, 문장을 그대로 검색했을 때와 키워드로 분리해서 검색했을 때를 비교할 수도 있어야 했다.
2. 문장형 데이터 셋만으로는 부족했다
MIRACL이나 Mr.TyDi 같은 데이터셋은 대체로 자연어 질문에 가깝다.
# query
철학적 자연주의의 이론이 처음으로 등장한 것은 언제인가요?
# corpus
수학(數學)은 양, 구조, 공간, 변화 등의 개념을 다루는 학문이다. 현대 수학은 형식 논리를 이용해서 공리로 구성된 추상적 구조를 연구하는 학문으로 여겨지기도 한다. 수학은 그 구조와 발전 과정에서는 자연과학에 속하는 물리학을 비롯한 다른 학문들과 깊은 연관을 맺고 있다. 하지만, 어느 과학의 분야들과는 달리, 자연계에서 관측되지 않는 개념들에 대해서까지 이론을 일반화 및 추상화시킬 수 있다는 차이가 있다고 한다. 수학자들은 그러한 개념들에 대해서 추측을 하고, 적절하게 선택된 정의와 공리로부터의 엄밀한 연역을 통해서 추측들의 진위를 파악한다.
사용자가 궁금한 내용을 문장 형태로 질문하고, 그 질문에 맞는 문서를 찾는 구조다. 이런 데이터셋은 문장 그대로 임베딩해서 검색하는 방식의 성능을 보기에 좋다.
하지만 실제 서비스 검색창에 들어오는 입력은 꼭 그렇게 친절하지 않다.
사용자는 완성된 질문을 입력하지 않는다. 짧은 키워드를 던지거나, 날짜와 기관명만 넣거나, 문서 제목의 일부만 입력하는 경우가 많다.
"최근 공고", "서울 지원사업", "AI 바우처", "작년 3월 보고서"처럼 검색어에 가까운 입력이 더 많다.
이런 입력에서는 문장 전체의 의미를 잘 이해하는 것만큼이나, 어떤 단어를 검색어로 남기고 어떤 표현을 조건으로 처리할지가 중요해진다.
그래서 테스트 데이터셋도 문장형 질의만으로는 부족했다.
문장 그대로 검색하는 방식도 봐야 했고, 형태소 분석이나 키워드 추출을 거친 뒤 검색하는 방식도 같이 비교해야 했다.
결국 테스트 데이터셋은 좋은 검색 모델을 고르기 위한 데이터셋이면서, 동시에 현재 검색 방식이 맞는지 확인할 수 있는 데이터셋이어야 했다.
3. 검색기 테스트와 E2E 테스트는 분리해야 했다
테스트 범위를 정하는 것도 애매했다.
검색 시스템은 하나의 함수처럼 보이지만, 실제로는 여러 단계로 나뉜다.
사용자 입력을 정리하는 질의처리기가 있고, 검색어를 만들어내는 로직이 있고, 실제 문서를 찾는 검색기가 있다. 경우에 따라 리랭커나 후처리도 들어간다.
여기서 전체 결과만 보면 무엇이 좋아졌고 무엇이 나빠졌는지 알기 어렵다.
예를 들어 검색 결과가 좋아졌다고 하자. 그게 임베딩 모델이 좋아져서인지, 질의처리기가 더 좋은 키워드를 만들어서인지, 아니면 테스트 데이터셋이 쉬워서인지 분리하기 어렵다.
반대로 결과가 나빠졌을 때도 마찬가지다. 검색기 자체가 나쁜 건지, 앞단에서 검색어를 잘못 만든 건지, 테스트 질의가 현재 방식과 맞지 않는 건지 알기 어렵다.
그래서 이번에는 테스트 범위를 검색기 자체에 한정하려고 했다.
질의처리기와 E2E 파이프라인을 모두 포함하면 실제 서비스 품질에 더 가까워지지만, 원인을 분리하기는 어려워진다. 반대로 검색기만 보면 실서비스와는 조금 멀어지지만, 검색 방식의 차이를 더 명확하게 볼 수 있다.
이번 실험에서는 우선 검색 방식 자체를 비교하는 것이 목적이었기 때문에, query parser와 E2E 파이프라인은 별도 테스트 대상으로 분리하기로 했다.
4. 정답을 찾는 것만으로는 부족했다
처음에는 정답 문서가 검색 결과 안에 들어오는지만 보면 충분하지 않을까 생각했다.
Recall@k가 대표적이다. top 5나 top 10 안에 정답 문서가 들어오면 성공으로 보는 방식이다.
하지만 검색에서는 이것만으로 부족했다.
정답을 찾는 것도 중요하지만, 엉뚱한 문서를 위로 올리지 않는 것도 중요하다. 특히 RAG에서는 검색 결과가 그대로 LLM의 입력으로 들어갈 수 있기 때문에, 잘못된 문서가 섞이면 답변 품질까지 흔들릴 수 있다.
정답 문서가 top 5 안에 있더라도, 그 위에 비슷하지만 틀린 문서가 여러 개 있으면 좋은 검색이라고 보기 어렵다.
그래서 hard negative를 별도 축으로 유지해야 한다고 판단했다.
hard negative는 정답은 아니지만 정답과 헷갈리기 쉬운 문서다. 키워드가 비슷하거나, 기관명이 같거나, 날짜만 다른 문서들이 여기에 해당한다.
이런 문서를 잘 밀어내지 못하면 Recall 점수는 좋아 보여도 실제 검색 품질은 불안정할 수 있다.
결국 검색 테스트는 정답을 회수하는 능력과 오답을 밀어내는 능력을 같이 봐야 했다.
5. 테스트 데이터셋은 실패를 드러내야 한다
이번에 테스트 데이터셋을 다시 보면서 가장 크게 느낀 것은, 테스트 데이터셋은 시스템의 실패를 잘 드러내야 한다는 점이었다.
유명한 데이터셋이라고 해서 항상 현재 시스템에 좋은 테스트 데이터셋은 아니었다.
표준 벤치마크는 모델을 비교하거나 외부 기준을 확인하는 데 유용하다. 하지만 지금처럼 특정 검색 방식이 맞는지 검증하려면, 실제로 그 방식이 흔들리는 지점을 보여줄 수 있어야 한다.
문장 그대로 검색했을 때 유리한 질의가 있고, 키워드로 분리했을 때 유리한 질의가 있다. 날짜나 지역 조건이 중요한 질의도 있고, 단순 키워드 매칭만으로 충분한 질의도 있다.
이런 차이를 볼 수 있어야 검색 방식에 대한 판단을 할 수 있다.
그래서 테스트 데이터셋을 하나의 점수로만 보지 않기로 했다.
문장형 질의, 키워드형 질의, harder query, hard negative를 나눠서 봐야 했다. 그래야 검색 시스템이 어디서 잘 동작하고, 어디서 무너지는지 볼 수 있다.
마치며
검색기를 개발을 시작할 당시에는 막연히 좋은 기술을 결합해 검색기 성능을 올리면 되는 문제라고 생각했다.
하지만 막상 프로젝트를 시작과 끝을 경험해보니 그 전에 먼저 정해야 할 것이 있었다.
무엇을 기준으로 좋아졌다고 말할 것인가.
테스트 기준이 정리되지 않으면 실험 결과를 보고도 판단이 흔들린다. 어떤 방식은 문장형 질의에서 좋아 보이고, 어떤 방식은 키워드형 질의에서 좋아 보일 수 있다. Recall은 올랐지만 hard negative 구분은 나빠질 수도 있다.
그래서 RAG 검색을 개선하려면 먼저 테스트 데이터셋부터 다시 봐야 했다.
이번 글에서는 테스트 기준을 정리하는 과정까지 적었다. 다음 글에서는 실제로 사용자의 문장을 그대로 검색하는 방식과, 형태소 분석을 거쳐 키워드로 분리한 뒤 검색하는 방식을 비교했던 내용을 정리해보려고 한다.
오랜만에 글을 쓰는데 GPT의 도움을 받아 글을 쓰니 글 쓰는 허들이 많이 낮아진 느낌이 든다.
비슷한 내용들로 3~4부작으로 쓸 거 같다.
'개발 > AI' 카테고리의 다른 글
| RAG 검색 개선기: 질의처리 테스트셋을 만들며 고민한 것들 (0) | 2026.04.28 |
|---|---|
| RAG 검색 개선기: 검색기보다 먼저 봐야 했던 질의처리 (0) | 2026.04.28 |
| RAG 구축 시 고려해야 할 것들 (1) | 2026.01.31 |
| 벡터데이터베이스 pgvector 사용해보기 (with. 랭체인) (0) | 2025.11.04 |
| RAG와 임베딩 (1) — Embedding 모델 이해하기 (0) | 2025.10.27 |
- Total
- Today
- Yesterday
- CORS
- Kotlin
- ecs
- java
- 스프링부트
- Spring
- 티스토리챌린지
- docker
- serverless
- CloudFront
- EKS
- springboot
- AWS
- lambda
- ChatGPT
- JWT
- GIT
- cache
- Log
- AWS EC2
- OpenAI
- terraform
- 후쿠오카
- 오블완
- 인프런
- elasticsearch
- rag
- S3
- Redis
- 람다
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | |||||
| 3 | 4 | 5 | 6 | 7 | 8 | 9 |
| 10 | 11 | 12 | 13 | 14 | 15 | 16 |
| 17 | 18 | 19 | 20 | 21 | 22 | 23 |
| 24 | 25 | 26 | 27 | 28 | 29 | 30 |
| 31 |
