# 법률 AI 검색 실험기 (2) — 임베딩 모델 5종 벤치마크: 법률 도메인 실전 비교

법률 RAG 시스템에서 가장 먼저 결정해야 하는 것은 "어떤 임베딩 모델을 쓸 것인가"다. MTEB 리더보드 점수가 높다고 해서 우리 도메인에서도 잘 동작하리라는 보장은 없다. 한국 법률 조문이라는 특수한 코퍼스 위에서, 실제 질문셋으로 직접 비교하는 것이 유일한 방법이다.

이 글에서는 임베딩 모델 5종을 동일 조건에서 평가한 과정과 결과를 공유한다. 모델 선택 하나가 retrieval 성능의 천장을 결정한다.

---

## 평가 대상: 임베딩 모델 5종

평가에 사용한 모델은 다음 5종이다.

| 모델 | 파라미터 | 벡터 차원 | 개발사 | 특징 |
|---|---:|---:|---|---|
| BGE-M3 | 568M | 1024 | BAAI | 다국어, dense/sparse/multi-vector 지원 |
| pplx-embed-v1-0.6b | 0.6B | 1024 | Perplexity | 경량 임베딩, INT8 네이티브 |
| pplx-embed-v1-4b | 4B | 2560 | Perplexity | 대형 임베딩, MTEB 최상위권 |
| pplx-embed-context-v1-0.6b | 0.6B | 1024 | Perplexity | 문서 문맥 인식 경량 모델 |
| pplx-embed-context-v1-4b | 4B | 2560 | Perplexity | 문서 문맥 인식 대형 모델 |

BGE-M3는 BAAI에서 공개한 다국어 임베딩 모델로, XLM-RoBERTa 기반이며 8192 토큰까지 처리할 수 있다. dense, sparse, multi-vector 세 가지 retrieval 방식을 동시에 지원하는 것이 특징이다.

Perplexity의 pplx-embed 시리즈는 2종 x 2사이즈, 총 4개 모델로 구성된다. `pplx-embed-v1`은 표준 dense retrieval용이고, `pplx-embed-context-v1`은 문서 수준 문맥을 반영하여 청크를 임베딩하는 contextual embedding 모델이다. context 모델은 인덱싱 시에만 사용하고, 쿼리 임베딩에는 표준 v1을 사용하는 비대칭 구조를 갖는다. Qwen3 기반으로 학습되었으며, quantization-aware training을 통해 INT8 임베딩을 네이티브로 생성한다.

---

## 평가 환경

### 코퍼스

한국 주요 기본법(민법, 형법, 상법, 민사소송법, 형사소송법, 헌법, 행정소송법 등)에서 추출한 **약 2,300여 개 조문**을 코퍼스로 사용했다. 5개 모델 모두 정확히 동일한 문서 세트로 벡터 DB 컬렉션을 구성했다. 데이터 정합화 작업을 거쳐, 모든 컬렉션의 문서 수와 구조가 일치하는 것을 사전 검증했다.

### 질문셋

총 84개 질문을 다섯 유형으로 나누어 평가했다.

| 질문 유형 | 문항 수 | 설명 |
|---|---:|---|
| 단일정답 직접 질문 | 20 | 특정 조문을 직접 묻는 질문 |
| 단일정답 시나리오 질문 | 20 | 실생활 시나리오로 우회하여 묻는 질문 |
| 단일정답 세법 질문 | 17 | 세법 도메인 특화 질문 |
| 복수정답 질문 | 11 | 여러 조문이 정답인 질문 (정답 조문 31개) |
| Holdout 질문 | 16 | 도메인 커버리지 확인용 |

복수정답 질문이 가장 중요한 평가 축이다. 단일정답은 대부분의 모델이 쉽게 맞추지만, 여러 조문을 빠짐없이 찾아와야 하는 복수정답에서 모델 간 차이가 극명하게 드러났다.

### 비교 조건

두 가지 모드로 비교했다.

- **raw**: 사용자 질문 원문 그대로 검색. vector hybrid (dense + BM42 sparse) 사용.
- **prerewrite**: LLM 프리라이터로 질문을 변환한 뒤 검색. vector + graph 검색을 RRF로 병합.

추가로, graph 검색을 완전히 제외한 **vector-only** 조건도 별도 실험했다.

### 메트릭

- **@K recall**: K개 결과 안에 정답 조문이 몇 개 포함되었는가
- **Full match**: 복수정답 질문에서, 한 질문의 정답 조문을 모두 찾았는가 (11문항 중 몇 문항 완전 적중)
- K = 10, 20, 50으로 측정

---

## 결과 1: Hybrid 검색 (dense + BM42 + graph)

복수정답 @50 기준이 모델 선택의 핵심 지표였다.

### 복수정답 @50 비교

| 모델 | Raw Recall | Raw Full | Raw 속도 | Pre Recall | Pre Full | Pre 속도 |
|---|---:|---:|---:|---:|---:|---:|
| BGE-M3 | 28/31 | 8/11 | 103ms | 29/31 | 9/11 | 1,536ms |
| pplx-embed-v1-0.6b | 28/31 | 8/11 | 322ms | 29/31 | 9/11 | 1,700ms |
| **pplx-embed-v1-4b** | **30/31** | **10/11** | 319ms | **30/31** | **10/11** | 1,708ms |
| pplx-embed-context-v1-0.6b | 26/31 | 6/11 | 323ms | 29/31 | 9/11 | 1,712ms |
| pplx-embed-context-v1-4b | 28/31 | 8/11 | 332ms | **30/31** | **10/11** | 1,714ms |

`pplx-embed-v1-4b`가 raw 모드에서 이미 30/31 recall, 10/11 full match를 달성했다. 프리라이터를 붙여도 결과가 동일했다. 즉 이 모델은 질문 원문만으로도 충분히 강력한 retrieval을 보여준 것이다.

반면 BGE-M3와 0.6b 모델들은 @50에서 28/31에 머물렀고, 프리라이터를 적용해야 29/31까지 올라갔다.

### 단일정답 요약

| 질문 유형 | 핵심 결과 |
|---|---|
| 직접 질문 20 | 전 모델 raw @10 = 20/20. 프리라이터 적용 시 오히려 @10이 19/20으로 하락하는 경우 발생 |
| 시나리오 질문 20 | 4b 모델 2종은 raw @10 = 20/20. BGE-M3 raw @10 = 18/20 |
| 세법 질문 17 | BGE-M3만 raw @10 = 16/17, 나머지 4종은 17/17 |

단일정답에서는 대부분의 모델이 높은 성능을 보였지만, 시나리오 질문과 세법 질문에서 4b 모델의 우위가 확인되었다.

---

## 결과 2: Vector-Only 검색 (graph 제외)

graph 검색 없이 순수 벡터 검색만으로 평가한 결과도 동일한 결론을 가리켰다.

### 복수정답 Vector-Only 비교 (주요 K 값)

| 모델 | Mode | @20 | F@20 | @30 | F@30 | @50 | F@50 | 속도 |
|---|---|---:|---:|---:|---:|---:|---:|---:|
| BGE-M3 | raw | 21/31 | 4/11 | 23/31 | 5/11 | 28/31 | 8/11 | 113ms |
| BGE-M3 | pre | 21/31 | 5/11 | 22/31 | 6/11 | 27/31 | 8/11 | 1,291ms |
| pplx-v1-0.6b | raw | 24/31 | 5/11 | 26/31 | 7/11 | 28/31 | 8/11 | 336ms |
| **pplx-v1-4b** | **raw** | **25/31** | **7/11** | **26/31** | **7/11** | **30/31** | **10/11** | **323ms** |
| pplx-v1-4b | pre | 24/31 | 5/11 | 27/31 | 7/11 | 29/31 | 9/11 | 1,501ms |
| pplx-ctx-v1-0.6b | raw | 23/31 | 6/11 | 24/31 | 6/11 | 26/31 | 6/11 | 319ms |
| pplx-ctx-v1-4b | raw | 26/31 | 7/11 | 27/31 | 7/11 | 28/31 | 8/11 | 326ms |

여기서 주목할 점이 두 가지 있다.

첫째, **vector-only에서도 `pplx-embed-v1-4b raw`가 @50 = 30/31로 최고 성능**이었다. graph 검색 없이도 이 모델의 벡터 품질 자체가 우수하다는 뜻이다.

둘째, **프리라이터가 vector-only에서는 오히려 성능을 깎는 경우가 있었다**. `pplx-embed-v1-4b`는 프리라이터 적용 시 30/31에서 29/31로 하락했고, BGE-M3도 28/31에서 27/31로 떨어졌다. 프리라이터가 graph 검색과 결합될 때는 도움이 되지만, 벡터 단독 검색에서는 오히려 원래 질문의 의미를 왜곡할 수 있다는 신호였다.

### K값에 따른 성능 변화

`pplx-embed-v1-4b raw`의 복수정답 recall 변화를 K값별로 보면:

| K | Recall | Full Match |
|---:|---:|---:|
| 10 | 19/31 | 2/11 |
| 20 | 25/31 | 7/11 |
| 30 | 26/31 | 7/11 |
| 40 | 28/31 | 8/11 |
| 50 | 30/31 | 10/11 |

K20과 K50 사이에 정보 손실이 상당히 크다. K20에서 25/31이던 recall이 K50에서 30/31까지 올라간다. "프리라이터로 K를 줄일 수 있다"는 가설은 이번 실험에서 지지되지 않았고, 복수정답 시나리오에서는 충분한 K가 확보되어야 한다는 결론에 이르렀다.

---

## 속도 비교

| 모델 | Raw 평균 | Prerewrite 평균 |
|---|---:|---:|
| BGE-M3 | ~103ms | ~1,536ms |
| Perplexity 계열 4종 | ~309-342ms | ~1,400-1,714ms |

BGE-M3가 raw 기준 약 3배 빠르다. 다만 prerewrite를 적용하면 LLM 호출 비용이 지배적이 되면서 모델 간 속도 차이가 줄어든다. raw 모드에서 Perplexity 계열은 약 320ms 수준으로, 실서비스에서 충분히 사용 가능한 범위다.

---

## 최종 선택: pplx-embed-v1-4b

종합적으로 `pplx-embed-v1-4b`를 retrieval 기본 모델로 선택했다. 이유는 다음과 같다.

**1. 복수정답 retrieval 최고 성능**

가장 까다로운 복수정답 @50에서 30/31 recall, 10/11 full match. hybrid든 vector-only든 동일하게 최상위였다.

**2. 프리라이터 없이도 강력한 성능**

다른 모델들은 프리라이터를 붙여야 성능이 올라갔지만, 이 모델은 raw 질문만으로 이미 최고 수준에 도달했다. 이는 파이프라인을 단순하게 유지할 수 있다는 실질적인 장점이다.

**3. 단일정답에서도 회귀 없음**

직접 질문, 시나리오 질문, 세법 질문 모두에서 최상위 또는 동률. 복수정답에서 강하다고 해서 단일정답이 약해지는 트레이드오프가 없었다.

**4. 허용 가능한 지연 시간**

raw 기준 약 320ms. BGE-M3보다는 느리지만, 법률 QA 서비스의 응답 시간 예산 안에 충분히 들어온다.

---

## 이 실험에서 확인한 것

- **벤치마크 점수와 도메인 성능은 다르다.** MTEB 리더보드에서의 순위가 한국 법률 도메인에서의 순위를 보장하지 않는다. 직접 평가 외에 지름길은 없다.
- **데이터 정합화가 공정한 비교의 전제 조건이다.** 5개 컬렉션의 문서 수가 불일치하는 상태에서는 비교 자체가 무의미하다. 2,336개로 맞추는 작업이 평가보다 먼저 수행되어야 한다.
- **프리라이터는 만능이 아니다.** "질문을 다듬으면 무조건 좋아진다"는 직관과 달리, 특정 모델/조건에서는 오히려 성능이 하락했다. 특히 vector-only 검색에서 이 현상이 두드러졌다.
- **복수정답이 진짜 변별력이다.** 단일정답은 대부분의 모델이 쉽게 맞추므로 모델을 구분하기 어렵다. 여러 조문을 동시에 찾아야 하는 복수정답 시나리오가 실질적인 벤치마크다.
- **K값은 넉넉하게.** 복수정답에서 K20과 K50 사이의 정보 손실이 크다. K50을 유지한다.

법률 RAG의 핵심 파이프라인에서, 임베딩 모델 선택은 모든 후속 단계의 성능 상한을 결정하는 첫 번째 관문이다. 이 단계에서의 비교 실험은 생략할 수 없다.

