법률 AI 검색 실험기 (1) — 벡터 검색이 실패하는 이유
도입: 법률 QA를 만들면서 마주한 첫 번째 벽
법률 질의응답 시스템을 만드는 일은, 처음에는 RAG(Retrieval-Augmented Generation)의 교과서적 응용처럼 보였습니다. 법 조문을 임베딩해서 벡터 DB에 넣고, 사용자 질문과 유사한 조문을 검색한 뒤, LLM이 답변을 생성하면 되니까요.
실제로 단일 정답 질문 -- "주택임대차보호법상 대항력은 언제 취득하나요?" 같은 -- 에는 이 방식이 잘 작동했습니다. 해당 조문과 질문의 텍스트 유사도가 높기 때문입니다.
문제는 현실의 법률 질문이 그렇게 단순하지 않다는 데서 시작됩니다. "부당해고 당했는데 어떻게 하나요?"라는 질문에 정확히 답하려면 근로기준법 23조(해고제한), 26조(해고예고), 28조(구제신청) 세 조문이 모두 필요합니다. 그런데 벡터 검색은 보통 28조(구제신청)만 찾고, 나머지 두 조문은 Top-50에도 들어오지 않았습니다.
이 글은 저희가 법률 QA 시스템을 만들면서 벡터 검색의 구조적 한계를 발견하고, 그 원인을 분석한 과정을 다룹니다.
문제 정의: 복수 정답 질문이란
법률 상담에서 사용자가 던지는 질문은 대부분 하나의 조문으로 답할 수 없습니다. 하나의 상황에 여러 법률 조항이 얽혀 있기 때문입니다.
저희는 이런 질문을 "복수 정답 질문"이라고 정의하고, 정답이 2~4개 조문인 11개 평가 문항을 설계했습니다. 예를 들면 이런 것들입니다.
- "부당해고 당했는데 어떻게 하나요?" -- 정답: 해고제한(23조), 해고예고(26조), 구제신청(28조)
- "세금을 과다하게 부과한 것 같아요" -- 정답: 경정청구(45조의2), 불복(55조), 청구기간(61조)
- "양도차익이 4억인데 세금이 얼마나?" -- 정답: 양도소득 범위(94조), 장기보유공제(95조), 세율(104조)
이 질문들의 공통점은, 사용자가 명시적으로 언급하지 않은 조문이 정답에 포함되어 있다는 점입니다. "부당해고 어떻게 하나요"라는 질문에는 "해고예고"라는 단어가 없고, "세금이 과다하다"는 말에는 "심판청구"라는 단어가 없습니다.
실제 데이터: 복수 정답 11문항 평가 결과
저희는 여러 임베딩 모델을 비교 평가했습니다. 핵심 지표는 두 가지입니다.
- Article Recall@K: 전체 정답 조문 31개 중 Top-K 안에 들어온 수
- Question Full Recall@K: 11개 질문 중 모든 정답 조문이 Top-K 안에 들어온 질문 수
초기 평가에서 가장 성능이 좋았던 bge-m3 모델의 결과입니다.
| 지표 | @5 | @10 |
| Article Recall | - | 14/31 (45%) |
| Question Full Recall | 0/11 | 1/11 (9%) |
Top-10 기준으로 정답 조문의 절반도 찾지 못했고, 11개 질문 중 모든 정답을 다 찾은 문항은 단 1개뿐이었습니다.
이후 임베딩 모델을 교체하고 Top-K를 50까지 확대한 최고 baseline(pplx-embed-v1-4b)에서는 상황이 많이 개선되었습니다.
| 지표 | @50 |
| Article Recall | 30/31 (97%) |
| Question Full Recall | 10/11 (91%) |
참고: 이 수치는 초기 평가 기준 기준이다. 이후 multi-2 문항의 정답 정의를 재검토하면서(민법 766조 → 756조) benchmark를 수정했고, 최종적으로는 graph 검색과 결합하여 31/31, 11/11을 달성했다. 이 과정은 이후 "1차 아키텍처 확정: 실험에서 운영으로" 편에서 자세히 다룬다.
Top-50까지 확대하니 대부분의 조문을 회수할 수 있었습니다. 하지만 여전히 놓치는 조문이 있었고, 더 중요한 것은 Top-50이라는 범위 자체가 실용적이지 않다는 점입니다. 50개 조문을 LLM에 넘기는 것은 비용과 레이턴시 면에서 부담이 크고, 노이즈가 많아지면 LLM의 선별 정확도도 떨어집니다.
End-to-end 기준 최고 성능은 gpt-5.4 no-web all-in-one 조합으로, Selection Recall 29/31, Full Recall 9/11을 기록했습니다. 하지만 이 수치도 결국 retrieval 단계에서 후보군에 포함되지 않은 조문은 아무리 좋은 LLM을 써도 찾을 수 없다는 한계를 보여줍니다.
핵심 병목은 LLM 선별(selection)이 아니라 검색(retrieval) 자체였습니다.
벡터 검색은 왜 실패하는가
벡터 검색의 원리는 "텍스트가 의미적으로 비슷하면 벡터 공간에서 가까이 위치한다"는 전제에 기반합니다. 이 전제는 많은 경우에 유효하지만, 법률 도메인에서는 구조적으로 맞지 않는 상황이 자주 발생합니다.
의미적 유사도와 논리적 관계의 괴리
질문별로 벡터 검색이 놓친 조문을 분석하면 명확한 패턴이 보입니다.
| 질문 | 찾은 조문 | 놓친 조문 | 놓친 이유 |
| 계약해제 원상회복+손배 | 548조(해제효과) | 551조(해제와 손배) | 같은 제도의 다른 효과 |
| 불법행위+사용자배상 | 750조(불법행위) | 756조(사용자책임) | 같은 불법행위의 책임 귀속 |
| 대항력+소액임차인 | 8조(소액임차인) | 3조(대항력) | 전제조건 |
| 해고사유+예고+구제 | 28조(구제신청) | 23조, 26조 | 절차 체인 |
| 경정청구+이의+심판 | 45의2(경정청구) | 55조, 61조 | 불복 절차 체인 |
| 양도소득+공제+세율 | 95조(장기보유공제) | 94조, 104조 | 계산 체인 |
벡터 검색이 놓치는 조문들은 질문과 텍스트가 안 닮았지만 논리적으로는 반드시 필요한 조문들입니다. "부당해고 당했는데 어떻게 하나요"라는 질문과 "해고예고" 조문 사이에는 텍스트 유사도가 낮습니다. 하지만 해고 절차를 이해하는 사람이라면 이 둘이 연결되어 있다는 걸 압니다.
임베딩 모델은 아무리 좋아도 텍스트를 고차원 벡터로 압축하는 과정에서 이런 논리적 관계 정보를 잃어버립니다. 이것은 모델의 성능 문제가 아니라 bi-encoder 아키텍처의 구조적 한계입니다.
다섯 가지 miss 패턴
놓친 조문들을 관통하는 관계 유형을 정리하면 다섯 가지로 분류됩니다.
- 절차 체인(PROCEDURE_CHAIN): 같은 법적 절차의 단계들. 해고 제한 -> 해고 예고 -> 구제 신청처럼, 하나의 절차를 구성하는 조문들이 흩어져 있는 경우.
- 계산 체인(CALCULATION_CHAIN): 같은 세금이나 금액 계산의 구성요소. 소득 정의 -> 공제 -> 세율처럼, 하나의 계산 흐름에 속하지만 각각 별도의 조문인 경우.
- 전제조건(PREREQUISITE): A 권리가 성립하려면 B 조건이 필요한 경우. 갱신청구권을 행사하려면 먼저 대항력을 갖추어야 하는 것처럼.
- 같은 원인의 다른 효과(EFFECT_OF): 계약 해제라는 같은 원인에서 원상회복과 손해배상이라는 다른 효과가 나오는 경우.
- 기간/제한(LIMITATION): 권리에 딸린 기간 제한. 임차권의 존속기간이나 갱신청구 기한처럼.
이 다섯 패턴은 모두 "텍스트로는 안 닮았지만 논리적으로 연결된" 관계입니다. 벡터 검색이 원리적으로 포착하기 어려운 종류의 관계이며, 이것이 법률 도메인에서 벡터 검색만으로는 충분하지 않은 근본적인 이유입니다.
업계에서도 같은 문제를 겪고 있다
이 문제는 저희만 겪는 것이 아닙니다. 최근 RAG 연구에서 벡터 검색의 멀티홉 추론 한계는 핵심 연구 주제로 부상하고 있습니다.
2025년 ACM TKDD에 게재된 멀티홉 QA 연구에서는 기존의 반복적 검색(iterative retrieval) 방법이 검색 횟수가 늘어날수록 원래 추론 경로에서 벗어나는 "쿼리 드리프트" 문제를 보고했습니다. 저희가 쿼리 분해(query decomposition)를 시도했을 때 경험한 것과 정확히 같은 현상입니다 -- 분해된 서브쿼리가 원래 의미에서 드리프트하면서 단일 정답 문항의 성능이 20/20에서 16/20으로 급락했습니다.
2025년 발표된 HopRAG 논문(arXiv:2502.12442)은 벡터 유사도 기반 검색이 논리적 관계를 포착하지 못하는 한계를 지적하며, 그래프 기반 검색으로 멀티홉 추론을 지원하는 방법을 제안했습니다. 또한 인도의 법률 AI를 다룬 Domain-Partitioned Hybrid RAG 연구(arXiv:2602.23371)는 법률 코퍼스를 판례, 법령, 헌법으로 분리한 뒤 Neo4j 기반 법률 지식 그래프로 관계형 쿼리와 멀티홉 추론을 지원하는 아키텍처를 제안했는데, 이는 저희가 독립적으로 도달한 결론과 놀라울 정도로 유사합니다.
결국 업계 전반에서 "벡터 검색만으로는 부족하다"는 공감대가 형성되고 있으며, 특히 법률처럼 조문 간 논리적 관계가 핵심인 도메인에서는 그래프 기반 확장이 사실상 필수적인 보완재로 논의되고 있습니다.
시도했지만 부족했던 것들
벡터 검색의 한계를 우회하기 위해 몇 가지 방법을 시도했습니다.
쿼리 분해 (Query Decomposition)
질문을 여러 서브쿼리로 분해한 뒤 각각 검색하고 RRF(Reciprocal Rank Fusion)로 병합하는 방식입니다. 결과는 복수 정답에서 소폭 개선(+2~3 Q.Full)이 있었지만, 단일 정답 문항에서 심각한 성능 저하가 발생했습니다. pplx-embed-v1-4b 모델은 세법 문항에서 17/17이 0/17으로 완전히 무너졌습니다. 분해된 서브쿼리가 원래 맥락에서 벗어나는 쿼리 드리프트가 원인이었습니다.
Agentic RAG
LLM이 검색 결과를 보고, 부족하다고 판단하면 재검색하는 방식입니다. 이론적으로는 매력적이지만 근본적인 순환 논리가 있습니다. "결과가 충분한지" 판단하려면 이미 법률 지식이 있어야 합니다. 게다가 비용과 레이턴시가 3~10배 증가합니다.
Co-citation 기반 확장
판례에서 함께 인용된 조문을 확장하는 방식입니다. 저희 MongoDB에는 판례 73,032건에서 추출한 158,152건의 법조문 참조 데이터가 이미 있었습니다. 실제로 근로기준법 28조(구제신청)에서 출발하면, 관련 판례 177건을 거쳐 23조(해고제한)가 148회 공출현하는 것을 확인할 수 있었습니다.
하지만 데이터 폭발 문제가 심각했습니다. 민법 750조(불법행위)처럼 범용 조항 하나만 걸리면 관련 판례가 2,173건, 공출현 조문이 1,307개로 폭발합니다. 또한 co-citation은 통계적 상관관계이지 논리적 관계가 아닙니다. 28조와 26조(해고예고)는 판례에서 함께 인용되는 빈도가 낮지만, 논리적으로는 해고 절차의 핵심 구성요소입니다.
다음 글 예고
이 글에서 확인한 것은 명확합니다. 법률 QA에서 벡터 검색은 필요하지만 충분하지 않습니다. 텍스트 유사도로는 포착할 수 없는 논리적 관계 -- 절차 체인, 계산 체인, 전제조건, 기간 제한 -- 가 법률 질의응답의 정확도를 결정합니다.
이 법률 AI 검색 실험기 시리즈에서는 이 문제를 실제로 어떻게 풀어갔는지를 다룹니다. 임베딩 모델 벤치마크, LLM selector 비교, query rewriting, Graph RAG 도입, 멀티 컬렉션 라우팅까지 — 한국 법률 도메인에서 RAG를 운영 가능한 수준까지 끌어올리는 과정을 한 편씩 기록할 예정입니다.
다음 편에서는 법률 도메인에 맞는 임베딩 모델을 어떻게 골랐는지, 5종 모델을 직접 비교한 실험 결과를 다룹니다.
법률 QA를 만들면서 배운 것은, 검색 시스템의 정확도는 임베딩 모델의 성능이 아니라 "어떤 종류의 관계를 포착할 수 있느냐"에 달려 있다는 것입니다. 벡터 검색이 잘하는 것(텍스트 유사도)과 법률 도메인이 요구하는 것(논리적 관계) 사이의 간극을 메우는 것이 이 시리즈의 주제입니다.
참고 자료:
- HopRAG: Multi-Hop Reasoning for Logic-Aware Retrieval-Augmented Generation
- Domain-Partitioned Hybrid RAG for Legal Reasoning
- Retrieval-Augmented Generation for Multi-Hop Question Answering Based on Structured Planning (ACM TKDD)
- How to Solve 5 Common RAG Failures with Knowledge Graphs
- Vector Search Is Not All You Need (Towards Data Science)
- Advanced RAG Techniques (Neo4j)

