들어가기 전에
RAG의 답변 품질이 기대보다 낮아서 여러 설정을 바꿨다고 가정해보겠습니다.
벡터 검색에 BM25를 추가하고, 검색된 문서의 순서를 다시 정하는 Reranker도 붙였습니다.
질문을 검색하기 좋은 형태로 바꾸는 Query Expansion을 적용하고, 청크 크기도 500자에서 300자로 줄였습니다.
수정이 끝난 뒤 다시 평가해보니 답변 정확도가 높아졌습니다.
수정 전 답변 정확도: 68%
수정 후 답변 정확도: 79%
분명 좋은 결과입니다. 그런데 여기서 한 가지 문제가 생깁니다.
과연 정확도가 높아진 이유는 무엇일까요? BM25를 추가한 것이 효과가 있었을까요? Reranker가 정답 문서를 위로 올려준 것일까요? Query Expansion이 사용자의 질문을 더 잘 이해하게 만든 것일까요? 청크 크기를 줄인 것이 도움이 된 걸까요?
아니면 네 가지 변경 중 일부는 오히려 성능을 떨어뜨렸지만 다른 변경의 효과가 더 커서 최종 점수만 높아진 것일까요?
여러 설정을 한꺼번에 바꾸면 결과가 좋아졌다는 사실은 알 수 있습니다. 하지만 무엇이 실제로 효과가 있었는지는 알기 어렵습니다.
이럴 때 사용하는 방법이 Ablation Study입니다. 이번 글에서는 Ablation Study가 무엇인지, RAG의 여러 설정을 어떤 순서로 비교해야 하는지, 검색 점수뿐만 아니라 응답 시간과 비용까지 어떻게 함께 확인해야 하는지 살펴보겠습니다.
여러 설정을 함께 바꾸면 결과만 남습니다
다음과 같은 RAG가 있다고 가정해보겠습니다.
질문
→ 벡터 검색
→ 상위 5개 청크 선택
→ LLM에 전달
→ 답변 생성
이 RAG의 Recall@5가 낮아서 다음과 같이 수정했습니다.
질문
→ Query Expansion
→ 벡터 검색 + BM25
→ 상위 20개 후보 검색
→ Reranker로 순서 조정
→ 상위 5개 청크 선택
→ LLM에 전달
→ 답변 생성
기존 시스템과 비교하면 많은 부분이 달라졌습니다.
질문 변환 기능 추가
BM25 검색 추가
검색 후보 수 변경
Reranker 추가
최종 문서 선택 방식 변경
수정 후 Recall@5와 답변 정확도가 높아졌다고 하겠습니다.
그렇다고 해서 새로 추가한 모든 기능이 효과가 있었다고 말할 수는 없습니다. 예를 들어 BM25를 추가한 것만으로 정답 문서가 검색 후보에 들어왔을 수도 있습니다. 이 경우 Query Expansion과 Reranker는 점수 향상에 거의 영향을 주지 않았을 수 있습니다.
반대로 BM25는 도움이 되지 않았지만 Reranker가 정답 문서를 위로 올려서 최종 답변이 좋아졌을 수도 있습니다.
Query Expansion이 일부 질문에는 도움이 되었지만, 다른 질문에서는 불필요한 단어를 추가해 검색 결과를 나쁘게 만들었을 가능성도 있습니다. 여러 변경을 한 번에 적용하면 이런 차이가 모두 최종 점수 안에 섞입니다.
점수가 높아졌습니다.
→ 무엇이 효과가 있었는지는 알 수 없습니다.
점수가 낮아졌습니다.
→ 무엇을 되돌려야 하는지 알 수 없습니다.
RAG를 계속 개선하려면 단순히 점수가 올랐다는 결과보다, 어떤 변경이 어느 단계에 영향을 주었는지 알아야 합니다.
Ablation Study는 하나를 빼고 비교하는 실험입니다
Ablation은 원래 어떤 시스템에서 특정 부분을 제거한다는 의미입니다.
머신러닝에서는 완성된 모델이나 시스템에서 한 요소를 빼본 뒤, 성능이 어떻게 달라지는지 확인하는 실험을 Ablation Study라고 부릅니다.
예를 들어 다음과 같은 RAG가 있다고 해보겠습니다.
하이브리드 검색
+ Reranker
+ Query Expansion
각 요소의 역할을 확인하려면 다음과 같이 비교할 수 있습니다.
전체 구성
→ 하이브리드 검색 + Reranker + Query Expansion
Reranker 제거
→ 하이브리드 검색 + Query Expansion
Query Expansion 제거
→ 하이브리드 검색 + Reranker
BM25 제거
→ 벡터 검색 + Reranker + Query Expansion
Reranker를 제거했을 때 NDCG와 답변 정확도가 크게 떨어진다면, Reranker가 검색 결과의 순서를 개선하는 데 실제로 기여했다고 볼 수 있습니다.
반대로 Query Expansion을 제거했는데도 점수가 거의 같다면, 현재 평가 질문에서는 Query Expansion의 효과가 크지 않았을 가능성이 있습니다.
엄밀히 말하면 Ablation Study는 시스템의 구성 요소를 제거하는 실험을 의미합니다.
다만 실무에서는 다음과 같은 비교도 비슷한 원칙으로 진행합니다.
BM25를 벡터 검색으로 교체하기
청크 크기를 300자에서 500자로 바꾸기
검색 후보 수를 10개에서 20개로 바꾸기
임베딩 모델만 교체하기
이런 실험은 구성 요소를 완전히 제거하는 것은 아니므로 엄밀한 의미의 Ablation Study와는 조금 다릅니다.
하지만 다른 조건은 그대로 두고 하나의 조건만 바꾼다는 핵심 원칙은 같습니다.
먼저 비교의 기준을 정해야 합니다
설정을 하나씩 바꾸기 전에 기준이 되는 RAG 구성을 정해야 합니다.
이 기준을 Baseline이라고 합니다. Baseline은 이후 실험 결과를 비교할 출발점입니다.
예를 들어 다음과 같이 정할 수 있습니다.
baseline = {
"retrieval": "dense",
"embedding_model": "embedding-model-a",
"chunk_size": 500,
"chunk_overlap": 50,
"candidate_k": 20,
"reranker": None,
"context_k": 5,
"query_expansion": False,
"llm": "llm-a",
"temperature": 0,
}
이 구성에서는 벡터 검색으로 20개의 후보를 찾고, 별도의 Reranker 없이 상위 5개를 LLM에 전달합니다.
Baseline을 정하지 않으면 실험 결과를 해석하기 어렵습니다.
하이브리드 검색의 Recall@20이 0.81입니다.
이 점수만 보고는 하이브리드 검색이 좋은지 판단할 수 없습니다. 기존 벡터 검색의 Recall@20이 0.72였다면 개선된 것입니다. 반대로 기존 점수가 0.85였다면 오히려 나빠진 것입니다.
그래서 실험 결과에는 항상 비교 대상이 있어야 합니다.
기준 구성: 벡터 검색
변경 구성: 하이브리드 검색
달라진 조건: 검색 방식 하나
무엇을 바꾸고 무엇을 그대로 둘지 정해야 합니다
Ablation Study에서 가장 중요한 것은 비교하려는 항목을 제외한 나머지 조건을 같게 유지하는 것입니다.
벡터 검색과 하이브리드 검색을 비교하면서 청크 크기와 검색 후보 수까지 바꾸면 어떤 설정이 점수 차이를 만들었는지 알 수 없습니다.
검색 방식을 비교할 때는 다음 조건을 동일하게 유지해야 합니다.
| 항목 적용 | 방법 |
| 평가 질문 | 같은 질문 사용 |
| 정답 데이터 | 같은 기대 답변과 정답 문서 사용 |
| 지식 베이스 | 같은 문서 버전 사용 |
| 청킹 | 같은 크기와 겹치는 범위 사용 |
| 검색 후보 수 | 같은 K 사용 |
| LLM | 같은 모델 사용 |
| 프롬프트 | 같은 내용 사용 |
| 생성 설정 | 같은 Temperature 사용 |
| 평가 지표 | 같은 계산 방법 사용 |
예를 들어 다음 두 구성을 비교하면 검색 방식의 차이를 확인할 수 있습니다.
실험 A
벡터 검색
청크 크기 500
후보 문서 20개
최종 문서 5개
Reranker 사용 안 함
Query Expansion 사용 안 함
실험 B
하이브리드 검색
청크 크기 500
후보 문서 20개
최종 문서 5개
Reranker 사용 안 함
Query Expansion 사용 안 함
두 구성에서 달라진 것은 검색 방식뿐입니다. 반면 다음 비교는 결과를 해석하기 어렵습니다.
실험 A
벡터 검색
청크 크기 500
후보 문서 10개
실험 B
하이브리드 검색
청크 크기 300
후보 문서 30개
검색 방식, 청크 크기, 후보 문서 수가 동시에 달라졌기 때문입니다.
어디를 바꿨는지에 따라 봐야 할 점수도 달라집니다
RAG의 최종 답변 정확도만 비교하면 변경된 설정이 어느 단계에 영향을 주었는지 알기 어렵습니다.
검색 방식을 바꿨다면 먼저 검색 점수를 봐야 합니다. Reranker를 추가했다면 정답 문서의 순위가 좋아졌는지 확인해야 합니다.
변경한 위치에 맞는 지표를 봐야 원인을 찾을 수 있습니다.
| 바꾼 부분 | 먼저 확인할 지표 |
| 검색 방식 | Recall@K |
| 검색 후보 수 | Recall@K, 응답 시간 |
| Reranker | MRR, NDCG@K, Precision@K |
| Query Expansion | Recall@K, 질문 유형별 성능 |
| 청크 크기 | Recall@K, 문맥 포함 여부, 중복 비율 |
| 최종 문서 수 | Context Precision, Context Recall |
| 프롬프트 | Faithfulness, 답변 정확도 |
| LLM | 답변 정확도, Faithfulness, 비용, 응답 시간 |
예를 들어 Reranker를 추가했는데 Recall@20만 비교하면 효과가 없는 것처럼 보일 수 있습니다. Reranker는 일반적으로 이미 검색된 후보 문서를 다시 정렬합니다.
따라서 후보 문서 20개 안에 정답이 들어 있는지를 나타내는 Recall@20은 달라지지 않을 수 있습니다.
Reranker 적용 전 Recall@20: 0.81
Reranker 적용 후 Recall@20: 0.81
하지만 정답 문서가 8위에서 2위로 올라왔다면 MRR이나 NDCG@5는 높아질 수 있습니다.
Reranker 적용 전 정답 문서 순위: 8위
Reranker 적용 후 정답 문서 순위: 2위
LLM에 상위 5개 문서만 전달하는 구조라면 이 순위 변화가 최종 답변에도 영향을 줄 수 있습니다.
그래서 Reranker의 효과는 Recall만으로 판단하기보다 문서 순서를 반영하는 지표와 함께 봐야 합니다.
검색 방식부터 하나씩 비교해보겠습니다
다음과 같은 Baseline을 기준으로 실험한다고 가정해보겠습니다.
벡터 검색
청크 크기: 500
검색 후보: 20개
LLM 전달 문서: 5개
Reranker: 사용 안 함
Query Expansion: 사용 안 함
여기서 검색 방식과 추가 기능을 하나씩 비교할 수 있습니다.
BM25만 사용해보기
첫 번째 실험에서는 벡터 검색을 BM25로 교체합니다.
Baseline
→ 벡터 검색
실험 1
→ BM25 검색
나머지 조건은 모두 동일하게 유지합니다. 이 실험을 통해 현재 평가 질문에서 정확한 단어가 포함된 키워드 검색과 의미가 비슷한 문서를 찾는 벡터 검색 중 어느 방식이 더 잘 맞는지 확인할 수 있습니다.
예를 들어 제품 번호, 약어, 사람 이름, 날짜가 포함된 질문에서는 BM25가 더 좋은 결과를 낼 수 있습니다. 반대로 사용자 질문과 문서가 서로 다른 표현을 사용한다면 벡터 검색이 더 유리할 수 있습니다.
중요한 것은 어느 방식이 항상 좋다고 미리 결론 내리지 않는 것입니다. 실제 문서와 질문을 기준으로 비교해야 합니다.
하이브리드 검색을 추가해보기
두 번째 실험에서는 벡터 검색과 BM25 결과를 함께 사용합니다.
Baseline
→ 벡터 검색
실험 2
→ 벡터 검색 + BM25
이때도 청크 크기, 후보 문서 수, 평가 질문은 그대로 유지합니다. 하이브리드 검색을 적용한 뒤 Recall@20이 높아졌다면, 두 검색 방식이 서로 놓친 문서를 보완했을 가능성이 있습니다. 다만 Recall만 높아지고 상위 결과에 관련 없는 문서가 많아질 수도 있습니다.
따라서 Precision과 NDCG도 함께 확인하는 것이 좋습니다.
Reranker를 추가해보기
이번에는 하이브리드 검색 결과에 Reranker만 추가합니다.
실험 2
→ 하이브리드 검색
실험 3
→ 하이브리드 검색 + Reranker
검색 후보는 두 실험 모두 20개로 유지합니다. Reranker의 목적은 후보 문서를 새로 찾는 것이 아니라 이미 검색된 문서를 질문과 더 관련 있는 순서로 다시 배치하는 것입니다.
따라서 다음 항목을 비교할 수 있습니다.
정답 문서의 평균 순위
1. MRR
2. NDCG@5
3. Precision@5
4. Recall@5 또는 Hit@5
5. 최종 답변 정확도
6. Reranking으로 추가된 응답 시간과 비용
검색 순위는 좋아졌지만 최종 답변은 그대로일 수도 있습니다. 이미 Reranker 적용 전에도 정답 문서가 LLM에 전달되고 있었다면 순위가 조금 올라가더라도 답변에는 큰 변화가 없을 수 있기 때문입니다.
Query Expansion을 추가해보기
다음으로 Query Expansion만 추가합니다.
실험 3
→ 하이브리드 검색 + Reranker
실험 4
→ Query Expansion + 하이브리드 검색 + Reranker
예를 들어 사용자가 다음처럼 질문했다고 가정해보겠습니다.
계정 없애면 예전 주문 기록도 지워지나요?
Query Expansion을 통해 다음과 같은 표현을 추가할 수 있습니다.
- 회원 탈퇴
- 거래 기록
- 개인정보 파기
- 주문 내역 보관 기간
이런 변환이 문서의 표현과 질문을 연결해 검색 누락을 줄일 수 있습니다.
하지만 질문과 관계없는 단어가 추가되면 검색 결과가 오히려 나빠질 수도 있습니다.
그래서 전체 평균뿐만 아니라 질문 유형별 결과를 함께 보는 것이 좋습니다.
- 구어체 질문에서는 좋아졌는가?
- 약어가 포함된 질문에서는 좋아졌는가?
- 숫자와 날짜 질문에는 어떤 영향을 주었는가?
- 원래 검색이 잘되던 질문이 나빠지지는 않았는가?
청크 크기만 바꿔보기
청크 크기를 비교할 때도 다른 조건을 그대로 유지해야 합니다.
실험 3
청크 크기: 500
하이브리드 검색
Reranker 사용
실험 5
청크 크기: 300
하이브리드 검색
Reranker 사용
청크 크기를 줄이면 하나의 청크가 더 구체적인 내용을 담게 될 수 있습니다.
반면 답변에 필요한 조건과 결론이 서로 다른 청크로 나뉠 수도 있습니다.
청크 크기가 커지면 문맥을 더 많이 보존할 수 있지만, 질문과 관계없는 내용도 함께 포함될 수 있습니다.
따라서 청크 크기는 Recall 하나만 보고 결정하기 어렵습니다.
- 정답 문장이 청크 안에 포함되어 있는가?
- 답변에 필요한 조건과 결론이 함께 들어 있는가?
- 비슷한 청크가 반복해서 검색되지는 않는가?
- LLM에 전달되는 토큰은 얼마나 늘어나는가?
- 최종 답변의 정확도는 어떻게 달라지는가?
가상의 실험 결과를 살펴보겠습니다
다음 표는 설명을 위해 만든 가상의 결과입니다.
| 구성 | Recall@20 | NDCG@5 | 답변 정확도 | 평균 응답 시간 |
| 벡터 검색 | 0.72 | 0.58 | 0.64 | 0.8초 |
| BM25 | 0.66 | 0.55 | 0.60 | 0.4초 |
| 하이브리드 검색 | 0.81 | 0.63 | 0.71 | 1.0초 |
| 하이브리드 + Reranker | 0.81 | 0.74 | 0.78 | 1.5초 |
| 하이브리드 + Reranker + Query Expansion | 0.84 | 0.75 | 0.79 | 2.3초 |
| 하이브리드 + Reranker, 청크 크기 300 | 0.76 | 0.70 | 0.73 | 1.4초 |
이 결과를 최종 답변 정확도만 보고 해석하면 다음과 같습니다.
기능을 많이 추가할수록 성능이 좋아졌습니다.
하지만 단계별 지표를 함께 보면 더 많은 내용을 알 수 있습니다.
하이브리드 검색은 검색 누락을 줄였습니다
벡터 검색에서 하이브리드 검색으로 바꾸자 Recall@20이 0.72에서 0.81로 높아졌습니다.
벡터 검색 Recall@20: 0.72
하이브리드 검색 Recall@20: 0.81
정답 문서가 검색 후보에 들어오는 비율이 높아졌다는 뜻입니다.
따라서 이 실험에서는 BM25 결과를 함께 사용하는 것이 검색 누락을 줄이는 데 도움이 되었다고 볼 수 있습니다.
Reranker는 정답 문서를 위로 올렸습니다
Reranker를 추가해도 Recall@20은 0.81로 그대로입니다. 하지만 NDCG@5는 0.63에서 0.74로 높아졌습니다.
Reranker 적용 전 NDCG@5: 0.63
Reranker 적용 후 NDCG@5: 0.74
새로운 정답 문서를 찾은 것은 아니지만, 이미 검색된 정답 문서를 더 높은 순위로 올렸다고 해석할 수 있습니다.
답변 정확도도 0.71에서 0.78로 높아졌으므로 검색 순서의 개선이 최종 답변에도 영향을 주었을 가능성이 있습니다.
Query Expansion의 효과는 크지 않았습니다
Query Expansion을 추가하자 답변 정확도가 0.78에서 0.79로 높아졌습니다.
점수는 좋아졌지만 차이는 크지 않습니다. 반면 평균 응답 시간은 1.5초에서 2.3초로 늘어났습니다.
답변 정확도: 0.01 상승
응답 시간: 0.8초 증가
이 정도의 개선이 추가 비용과 응답 시간을 감수할 만큼 의미 있는지는 별도로 판단해야 합니다.
모든 질문에 Query Expansion을 적용하기보다, 검색이 어려운 질문에만 선택적으로 적용하는 방법도 생각해볼 수 있습니다.
작은 청크가 항상 좋은 것은 아니었습니다
청크 크기를 500에서 300으로 줄이자 Recall과 답변 정확도가 모두 낮아졌습니다.
청크가 작아지면서 답변에 필요한 조건과 근거가 서로 나뉘었을 가능성을 확인해볼 수 있습니다.
물론 이 결과만으로 모든 RAG에서 500이 300보다 좋다고 결론 내릴 수는 없습니다.
현재 평가 문서와 질문에서는 500 크기가 더 적합했다는 뜻에 가깝습니다.
점수가 높아져도 무조건 좋은 변경은 아닙니다
RAG의 성능은 정확도 하나로만 결정되지 않습니다. Reranker와 Query Expansion을 추가하면 검색 품질이 좋아질 수 있지만, 처리 시간과 비용도 늘어납니다.
예를 들어 다음 두 구성이 있다고 가정해보겠습니다.
| 구성 | 답변 정확도 | 응답 시간 | 질문당 비용 |
| 하이브리드 + Reranker | 0.78 | 1.5초 | 8원 |
| Query Expansion 추가 | 0.79 | 2.3초 | 14원 |
정확도는 0.01 높아졌지만 응답 시간과 비용은 크게 증가했습니다. 사용자가 즉시 답변을 기대하는 서비스라면 이 변경은 적절하지 않을 수 있습니다.
반대로 법률이나 재무처럼 정확도가 특히 중요한 서비스라면 작은 개선이라도 의미가 있을 수 있습니다.
따라서 실험에서는 다음 내용을 함께 기록해야 합니다.
- 검색 성능
- 답변 정확도
- 근거와 답변의 일치 여부
- 평균 응답 시간
- LLM 입력 토큰 수
- 질문 한 건당 비용
- 오류 발생률
점수가 가장 높은 구성이 항상 운영하기 가장 좋은 구성은 아닙니다. 서비스에서 필요한 정확도를 만족하면서 응답 시간과 비용이 적절한 구성을 선택해야 합니다.
작은 점수 차이는 우연일 수도 있습니다
LLM의 답변은 같은 질문과 문서를 입력해도 조금씩 달라질 수 있습니다. Temperature가 0보다 크다면 이런 차이가 더 커질 수 있습니다. 평가 질문이 적을 때는 한두 개의 질문 결과만 바뀌어도 전체 점수가 크게 움직입니다.
예를 들어 평가 질문이 20개일 때 한 문제를 더 맞히면 정확도가 0.05 올라갑니다.
13개 정답 / 20개 질문
= 0.65
14개 정답 / 20개 질문
= 0.70
점수가 0.05 높아졌지만 특정 질문 하나의 결과가 달라진 것일 수 있습니다. 그래서 작은 차이를 바로 개선 효과라고 단정하면 안 됩니다.
다음 방법을 사용할 수 있습니다.
- 같은 평가 데이터로 반복 실행합니다.
- LLM의 Temperature를 0으로 고정합니다.
- 반복 실행한 평균 점수를 확인합니다.
- 평균뿐 아니라 점수가 흔들리는 범위도 기록합니다.
- 개선된 질문과 나빠진 질문을 직접 확인합니다.
- 질문 유형별로 결과를 나눠봅니다.
예를 들어 세 번 실행한 결과가 다음과 같다고 해보겠습니다.
Baseline
0.74
0.76
0.75
평균: 0.75
변경 구성
0.75
0.76
0.74
평균: 0.75
한 번의 실행에서는 변경 구성이 더 좋아 보일 수 있지만 반복 결과의 평균은 같습니다. 반면 다음과 같이 일관된 차이가 나타난다면 변경의 효과를 조금 더 신뢰할 수 있습니다.
Baseline 평균: 0.75
변경 구성 평균: 0.82
평가 데이터가 충분히 크고 중요도가 높은 실험이라면 점수 차이에 대한 통계적인 검증도 고려할 수 있습니다.
다만 처음부터 복잡한 통계 기법을 적용하기보다, 같은 조건으로 반복했을 때 비슷한 결과가 나오는지부터 확인하는 것이 좋습니다.
평균 점수만 보면 중요한 차이를 놓칠 수 있습니다
전체 평균이 높아졌다고 해서 모든 질문이 좋아진 것은 아닙니다.
예를 들어 하이브리드 검색을 적용한 뒤 전체 Recall이 높아졌다고 가정해보겠습니다.
질문 유형별로 나누면 다음과 같은 결과가 나올 수 있습니다.
| 질문 유형 | 벡터 검색 | 하이브리드 검색 |
| 의미가 비슷한 질문 | 0.82 | 0.83 |
| 약어·고유명사 질문 | 0.55 | 0.78 |
| 숫자·날짜 질문 | 0.61 | 0.80 |
| 비교 질문 | 0.70 | 0.69 |
| 여러 문서가 필요한 질문 | 0.65 | 0.66 |
전체 성능이 높아진 주된 이유는 약어, 고유명사 질문과 숫자·날짜 질문이 개선되었기 때문입니다.
반면 비교 질문은 조금 나빠졌습니다. 이렇게 분석하면 하이브리드 검색을 왜 사용하는지도 분명해집니다.
전체적으로 좋아졌기 때문
보다는 다음과 같이 설명할 수 있습니다.
벡터 검색이 놓치던 고유명사와 숫자 중심 질문을
BM25가 보완했기 때문
Ablation Study의 목적은 단순히 가장 높은 점수를 찾는 것이 아닙니다. 어떤 변경이 어떤 질문에 효과가 있었는지 이해하는 것입니다.
한 요소씩 본 뒤에는 조합도 확인해야 합니다
하나씩 비교하는 실험은 각 설정의 영향을 이해하는 데 도움이 됩니다. 하지만 RAG의 구성 요소는 서로 영향을 주기도 합니다.
예를 들어 Reranker는 정답 문서가 검색 후보 안에 있을 때만 효과를 낼 수 있습니다.
정답 문서가 후보에 없음
→ Reranker가 순위를 올릴 수 없음
후보 문서 수가 5개일 때는 정답 문서가 자주 빠지지만, 후보 수를 30개로 늘리면 Reranker가 정답 문서를 위로 올릴 기회가 생길 수 있습니다.
후보 5개 + Reranker
→ Recall이 낮아서 효과가 작음
후보 30개 + Reranker
→ 정답 후보가 포함되어 효과가 커짐
Query Expansion도 검색 방식에 따라 결과가 다를 수 있습니다.
문서에 등장하는 정확한 표현을 추가하면 BM25에는 도움이 될 수 있습니다. 반대로 불필요한 설명이 많이 붙으면 벡터 검색의 의미가 흐려질 수도 있습니다.
따라서 하나씩 비교한 뒤에는 효과가 있었던 요소들의 주요 조합도 확인해야 합니다. 다만 처음부터 가능한 모든 조합을 실험할 필요는 없습니다.
1. 각 요소를 하나씩 비교합니다.
2. 효과가 거의 없는 요소를 제외합니다.
3. 효과가 있었던 요소의 조합을 실험합니다.
4. 정확도, 시간, 비용을 함께 비교합니다.
이 순서로 진행하면 불필요한 실험 수를 줄이면서 구성 요소 간의 관계도 확인할 수 있습니다.
Python으로 실험 설정 관리하기
실험이 많아지면 어떤 설정을 바꿨는지 헷갈릴 수 있습니다. Python의 dataclass를 사용하면 기준 설정을 복사한 뒤 필요한 값만 바꿀 수 있습니다.
from dataclasses import dataclass, fields, replace
@dataclass(frozen=True)
class RAGConfig:
retrieval: str = "dense"
chunk_size: int = 500
chunk_overlap: int = 50
candidate_k: int = 20
context_k: int = 5
use_reranker: bool = False
use_query_expansion: bool = False
temperature: float = 0.0
baseline = RAGConfig()
hybrid = replace(
baseline,
retrieval="hybrid",
)
hybrid_with_reranker = replace(
hybrid,
use_reranker=True,
)
hybrid_with_query_expansion = replace(
hybrid_with_reranker,
use_query_expansion=True,
)
smaller_chunks = replace(
hybrid_with_reranker,
chunk_size=300,
)
두 설정 사이에서 무엇이 달라졌는지 확인하는 함수도 만들 수 있습니다.
def changed_fields(
before: RAGConfig,
after: RAGConfig,
) -> list[str]:
changed = []
for field in fields(RAGConfig):
before_value = getattr(before, field.name)
after_value = getattr(after, field.name)
if before_value != after_value:
changed.append(field.name)
return changed
실제로 확인해보겠습니다.
print(changed_fields(baseline, hybrid))
# ["retrieval"]
print(changed_fields(hybrid, hybrid_with_reranker))
# ["use_reranker"]
print(
changed_fields(
hybrid_with_reranker,
hybrid_with_query_expansion,
)
)
# ["use_query_expansion"]
비교하려는 설정이 하나보다 많으면 경고하도록 만들 수도 있습니다.
def validate_single_change(
before: RAGConfig,
after: RAGConfig,
) -> None:
changes = changed_fields(before, after)
if len(changes) != 1:
raise ValueError(
"한 번의 실험에서는 하나의 설정만 변경해야 합니다. "
f"현재 변경된 설정: {changes}"
)
이 검사를 사용하면 실수로 여러 설정을 바꾼 상태에서 결과를 비교하는 일을 줄일 수 있습니다.
다만 모든 실험이 반드시 하나의 설정만 바꿔야 하는 것은 아닙니다.
효과가 확인된 기능들의 조합을 비교하는 단계에서는 여러 설정이 달라질 수 있습니다. 이 경우에는 조합 실험임을 결과에 명확하게 기록해야 합니다.
실험 결과는 설정과 함께 남겨야 합니다
실험 점수만 기록하면 나중에 같은 결과를 다시 만들기 어렵습니다. 다음과 같은 정보를 함께 저장하는 것이 좋습니다.
experiment_result = {
"experiment_id": "rag-exp-014",
"parent_experiment_id": "rag-exp-011",
"hypothesis": (
"Reranker를 추가하면 정답 청크의 상위 5개 진입률이 "
"높아질 것이다."
),
"changed_setting": {
"use_reranker": {
"before": False,
"after": True,
}
},
"dataset_version": "eval-2026-07-01",
"document_version": "knowledge-base-2026-07-15",
"metrics": {
"recall_at_20": 0.81,
"ndcg_at_5": 0.74,
"answer_accuracy": 0.78,
"average_latency_ms": 1450,
},
"notes": (
"Recall@20은 변하지 않았지만 NDCG@5와 "
"답변 정확도가 높아졌습니다."
),
}
특히 다음 정보가 중요합니다.
- 무엇을 확인하려는 실험이었는가?
- 어떤 실험을 기준으로 비교했는가?
- 실제로 바뀐 설정은 무엇인가?
- 어떤 평가 데이터와 문서 버전을 사용했는가?
- 검색과 답변 점수는 어떻게 달라졌는가?
- 응답 시간과 비용은 얼마나 달라졌는가?
- 어떤 질문에서 좋아지고 나빠졌는가?
코드를 수정한 뒤 평가 데이터나 문서도 함께 바뀌었다면 이전 결과와 공정하게 비교하기 어렵습니다.
그래서 실험 설정뿐 아니라 데이터와 문서의 버전도 함께 기록해야 합니다.
실험 결과를 잘못 해석하기 쉬운 경우
평가 질문까지 함께 바꾸는 경우
기존 평가 질문과 새로운 평가 질문의 난이도가 다르면 점수 차이가 설정 때문인지 질문 때문인지 알 수 없습니다.
설정을 비교할 때는 같은 평가 데이터를 사용해야 합니다.
검색 방식과 K를 동시에 바꾸는 경우
벡터 검색에서는 상위 5개를 보고, 하이브리드 검색에서는 상위 20개를 보면 하이브리드 검색의 Recall이 높게 나올 가능성이 커집니다.
같은 K를 기준으로 비교한 뒤 K의 영향은 별도 실험으로 확인하는 것이 좋습니다.
최종 답변 점수만 보는 경우
답변 정확도가 높아져도 검색 자체는 나빠졌을 수 있습니다.
LLM이 이미 알고 있던 내용으로 우연히 정답을 만들었거나, 정답 문서 없이 그럴듯한 답을 생성했을 가능성이 있기 때문입니다.
검색 점수와 답변의 근거 일치 여부를 함께 확인해야 합니다.
가장 잘 나온 한 번의 결과만 선택하는 경우
같은 설정으로 여러 번 실행했다면 가장 높은 점수만 보고하면 실제보다 좋아 보일 수 있습니다.
반복 실행한 평균과 결과가 흔들리는 범위를 함께 봐야 합니다.
Test 데이터를 보면서 계속 수정하는 경우
최종 평가용 질문을 반복해서 확인하며 설정을 조정하면 해당 질문에만 잘 맞는 RAG가 될 수 있습니다.
설정 비교에는 Validation 데이터를 사용하고, Test 데이터는 최종 구성을 선택한 뒤 확인하는 편이 좋습니다.
비용과 응답 시간을 기록하지 않는 경우
정확도가 조금 높아졌더라도 처리 비용이 두 배가 되거나 사용자가 느끼는 응답 시간이 크게 늘었다면 운영에는 적합하지 않을 수 있습니다.
성능과 운영 비용을 함께 비교해야 합니다.
중간 정리
| 항목 | 의미 | 확인할 점 |
| Baseline | 비교의 기준이 되는 구성 | 설정과 데이터 버전을 명확하게 기록 |
| Ablation Study | 특정 요소를 제거해 역할 확인 | 나머지 조건은 동일하게 유지 |
| 교체 실험 | 한 구성 요소를 다른 방식으로 교체 | 벡터 검색과 BM25 비교 등 |
| 설정값 실험 | 하나의 값을 바꿔 영향 확인 | 청크 크기와 K 비교 등 |
| 검색 지표 | 문서를 얼마나 잘 찾고 정렬했는지 확인 | Recall, MRR, NDCG, Precision |
| 답변 지표 | 최종 답변이 정확하고 근거와 맞는지 확인 | 정확도, Faithfulness |
| 운영 지표 | 실제 서비스에 적용 가능한지 확인 | 응답 시간, 토큰, 비용 |
| 반복 실행 | 우연한 점수 변화를 줄임 | 평균과 변화 범위 확인 |
| 질문 유형 분석 | 어떤 질문에서 효과가 있었는지 확인 | 평균 점수만 보지 않기 |
| 조합 실험 | 구성 요소 간의 영향을 확인 | 개별 효과 확인 후 진행 |
Ablation Study의 핵심은 복잡하지 않습니다.
- 기준이 되는 구성을 정합니다.
- 한 번에 하나의 설정만 바꿉니다.
- 변경한 위치에 맞는 지표를 확인합니다.
- 정확도뿐 아니라 시간과 비용도 비교합니다.
- 좋아진 질문과 나빠진 질문을 직접 살펴봅니다.
이 과정을 거쳐야 점수가 오른 이유를 설명할 수 있습니다.
마치며
RAG의 성능이 좋아졌다고 해서 방금 추가한 모든 설정이 효과가 있었다고 말할 수는 없습니다.
벡터 검색에 BM25를 추가하고, Reranker와 Query Expansion을 붙이고, 청크 크기까지 바꾼 뒤 점수가 올랐다면 결과는 좋아졌지만 원인은 알 수 없습니다.
어떤 기능은 검색 누락을 줄였을 수 있습니다. 어떤 기능은 정답 문서의 순위만 높였을 수 있습니다. 또 다른 기능은 점수에는 거의 영향을 주지 않으면서 응답 시간과 비용만 늘렸을 수도 있습니다.
Ablation Study는 이런 차이를 확인하기 위해 구성 요소를 하나씩 빼거나 바꾸어 보는 실험입니다.
검색 방식을 바꿨다면 Recall을 확인하고, Reranker를 추가했다면 MRR과 NDCG를 살펴봐야 합니다.
최종 문서 수를 바꿨다면 Context Precision과 Context Recall을 확인하고, 프롬프트나 LLM을 바꿨다면 답변 정확도와 근거 일치 여부를 비교해야 합니다. 중요한 것은 가장 높은 점수를 만드는 설정을 무작정 찾는 것이 아닙니다.
- 무엇을 바꿨는가?
- 어느 단계의 점수가 달라졌는가?
- 어떤 질문이 좋아졌는가?
- 대신 나빠진 질문은 없는가?
- 추가된 시간과 비용은 감당할 수 있는가?
이 질문에 답할 수 있어야 개선 결과를 믿을 수 있습니다.
RAG는 여러 단계가 이어진 시스템입니다. 여러 설정을 한꺼번에 바꾸면 각 단계의 역할이 최종 점수 안에 가려집니다.
반대로 하나씩 비교하면 현재 RAG에서 실제로 필요한 기능과 그렇지 않은 기능을 구분할 수 있습니다.
점수가 높아진 것보다 더 중요한 것은, 왜 높아졌는지 설명할 수 있는 것입니다.
참고 자료
- Ablation Studies in Artificial Neural Networks
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks
- Dense Passage Retrieval for Open-Domain Question Answering
- Passage Re-ranking with BERT
- BEIR: A Heterogeneous Benchmark for Zero-shot Evaluation of Information Retrieval Models
- Precise Zero-Shot Dense Retrieval without Relevance Labels
- RAGChecker: A Fine-grained Framework for Diagnosing Retrieval-Augmented Generation
- Enhancing Retrieval-Augmented Generation: A Study of Best Practices
'AI' 카테고리의 다른 글
| [바미] 문서를 잘게 쪼갰더니 오히려 답을 못 찾았습니다 (0) | 2026.07.29 |
|---|---|
| [바미] 검색 결과 순서만 바꿨는데 답변이 좋아질까? (2) | 2026.07.28 |
| [바미] RAG는 왜 틀린 답을 할까? (0) | 2026.07.26 |
| [바미] 검색 결과는 몇 개까지 봐야 할까? - 상위 K개 평가 이해하기 (0) | 2026.07.25 |
| [바미] 좋은 RAG 평가는 좋은 문제에서 시작됩니다. (2) | 2026.07.24 |