
RAG의 정밀도 향상: 모든 법률을 넣었더니 기본 문제를 틀린 사례와 チャンキング(Chunking)을 통한 재정비
요약
일본의 모든 법률 데이터를 RAG 시스템에 투입했을 때 발생하는 정밀도 저하 문제를 분석하고, 이를 해결하기 위한 실험 과정을 다룹니다. 데이터 양이 늘어남에 따라 발생하는 검색 방해 요인을 파악하고, 구조 기반 チャンキング(Chunking)을 통한 개선 방안을 제시합니다.
핵심 포인트
- 데이터 양 증가 시 유사 조문(distractor)으로 인해 검색 정밀도가 하락할 수 있음
- 자동 평가 도구는 방향성을 측정할 뿐, 수작업 스팟 체크가 반드시 병행되어야 함
- top-k 상향 시 입력 토큰 상한(max_input_tokens) 설정과의 연동이 필수적임
- 단순 문맥 확장이 아닌, 구조 기반 チャンキング(Chunking)을 통한 검색 질 개선이 핵심임
이전 기사
이 기사에서 알 수 있는 것
- "데이터를 전부 넣으면 똑똑해진다"가 성립하지 않는 실례 (총 2,154개의 법률 RAG)
- 자동 평가(Evaluation Harness)가 기계적 판정에 그쳐, 수작업 확인이 필요한 이유
- 실패를 실험으로 분리하는 절차 (top-k → 입력 토큰 상한 → チャンキング(Chunking) A/B)
- チャンキング(Chunking)은 직접 제어할 수 있다 (Bedrock은 임베딩(Embedding)과 생성(Generation)만 담당)는 점
- 구조 기반(조(條) 단위) チャンキング(Chunking)으로 기본 문제를 재정비한 과정과, 그럼에도 남는 한계
전제: Amazon S3 Vectors + Bedrock으로 만든 저빈도 RAG에, 일본의 모든 법률(약 2,154개·6,400만 자·약 22만 チャン크(Chunk))을 투입한 상태에서의 "정밀도 개선" 실전 기록입니다.
(구축과 스케일에 관한 이야기는 별도 기사에 작성했습니다.)
1. 사건: 전부 넣었더니, 간단한 질문을 틀렸다
40개의 법률로 테스트했을 때는 기본 문제에 8/10으로 답할 수 있었는데, 전체 2,154개로 늘렸더니 "노동 시간은 하루에 몇 시간인가?", "정당방위의 요건은?"을 틀리기 시작했습니다.
Q「근로기준법의 법정 노동 시간은 하루에 몇 시간입니까」
→ 「문서에서 해당 정보를 찾을 수 없습니다」 ← 8시간이 나오지 않음
데이터를 늘렸는데 오히려 악화되었다. 이는 직관에 반하지만, 이유가 있습니다.
유사한 조문(distractor)이 늘어나면서, 정답 チャン크(Chunk)가 상위로 올라오지 못하게 되는 것입니다.
2. 우선 평가를 어떻게 할 것인가: 하네스(Harness)는 "기계적 판정에 그침"
정밀도를 측정하는 평가 하네스(Golden Q&A로 검색 히트율·키워드 재현율·거부·비용을 자동 채점)를 돌렸지만, 여기서 중요한 깨달음이 있었습니다.
| 하네스가 측정할 수 있는 것 | 측정할 수 없는 것 |
|---|---|
| 올바른 출처 "파일"을 가져왔는가 | 조문 단위로 맞는가 |
| ... | ... |
실제로 어떤 질문은 출처는 올바른 법률을 가져왔으므로 = 하네스상으로는 합격에 가깝지만, 사람이 읽어보면 "8시간을 답하지 않았다"라고 한눈에 실패를 알 수 있습니다. 기계적 판정은 핵심적인 결락을 찾아내지 못합니다.
→ 운용 결론: 하네스는 회귀(개선/악화)의 방향을 측정하는 도구. 절대적인 정확성은 **원본(이번에는 e-Gov의 정본 페이지)으로의 직링크를 사용한 수작업 스팟 체크(Spot Check)**로 확인한다.
(출처에 공식 URL을 붙이는 구현은 이 수작업 확인을 위해서이기도 합니다.)
3. 원인 분리: 3가지 실험
"왠지 チャンキング(Chunking) 때문인가"라며 손을 움직이기 전에, 저렴한 실험부터 순서대로 분리했습니다.
실험 A: top-k를 5 → 15로 (= LLM에 전달하는 건수를 늘림)
결과: 오히려 악화. 일부 질문이 "입력이 너무 깁니다"라며 거부되었습니다.
이유: 비용 억제를 위해 설정한 **입력 토큰 상한(max_input_tokens)**이 15건분의 문맥을 초과함.
→ 설정은 연동된다. top-k를 올린다면 입력 상한도 올리지 않으면 역효과가 난다는 배움.
실험 B: 입력 토큰 상한을 높임 (top_k=10)
결과: 잘못된 거부는 해소되었으나, Q1·Q2는 여전히 실패. 게다가 인용 원천이 1mm도 변하지 않음 (동일한 distractor가 상위를 차지한 채 유지됨).
→ 이로써 "문맥 부족" 설은 기각. 문제는 전달하는 양이 아니라 검색의 질이라고 확정.
실험 C: チャンキング(Chunking) A/B (메모리 내에서 순위 비교)
동일한 법령 풀(대상 + distractor)에 대해, "고정 길이 800자"와 "조(條) 단위"로 정답 チャン크(Chunk)가 몇 위로 올라오는지를 비교. 여기서 구조상의 버그를 발견했습니다.
4. 발견: 제목과 캡션이 구조적으로 어긋나 있었다
e-Gov의 법령 데이터는 이런 구조입니다 (형법·발췌):
### 제35조
(35조의 본문)
(정당방위) ← 36조의 제목인데, 35조 뒤·36조 앞에 놓여 있음
...
즉 "정당방위"라는 단어는 제35조 측에 섞여 들어가 있고, 정작 중요한 제36조 본문(요건)에는 그 단어가 없다. 그래서 "정당방위란"으로 검색해도 제36조에 닿지 않습니다. 이것은 자르는 방식의 문제였습니다.
5. 재정비: 구조 기반(조 단위) チャンキング(Chunking)
여기서 중요한 사실: チャン크(Chunk) 분할을 결정하는 것은 Bedrock이 아니라, 자신의 코드입니다.
Bedrock(Titan)은 "문장 → 벡터"를 만들 뿐입니다. 어떻게 자를지는 완전히 이쪽의 관할입니다.
그래서 법령용 チャン커(Chunker)를 구현했습니다 (3가지 고안):
- 조(条) 단위: 제목 「제32조」와 본문을 반드시 동일한 청크(Chunk)로 구성 (분절 문제 해소)
- 캡션 결합: 이전 조문에 섞여 있는
(정당방위)와 같은 정보를 다음 조문으로 이동 - 법령명 프리픽스(Prefix): 「근로기준법 제32조」를 앞에 붙여 고유명사 일치와 출처성을 강화 (유사한 조문을 가진 타 법령과의 구별에 효과적)
법령은 「조(条)」가 의미의 최소 단위이므로, 이는 실질적인 **시맨틱 チャンキング (Semantic Chunking)**입니다.
임베딩(Embedding)으로 경계를 검출하는 본격적인 방식은 구조가 없는 산문(Prose)을 위한 것이며, 구조가 있는 법령에는 이 정도까지는 필요하지 않았습니다.
6. 결과: 실패했던 기본 문제가 해결됨
동일한 4개 법령(대상 + distractor)을 **고정 길이(Fixed-length)**와 조 단위로 각각 투입하여, 실제 기기에서 답변을 비교했습니다:
| 질문 | 고정 길이(800자) | 조 단위 (개선판) |
|---|---|---|
| 노동시간은 하루에 몇 시간인가 | ❌ 「찾을 수 없음」 | ✅ 「근기법 제32조... 하루 8시간」이라고 정답 |
| 정당방위의 요건 | ❌ 장(章) 제목만 출력 | ✅ 「급박하고 부당한 침해 / 자기 또는 타인의 권리 / 부득이하게」 + 과잉방위까지 정답 |
| 해고 예고는 며칠 전인가 (대조군) | ✅ 정답 | ✅ 정답 (출처 스코어는 오히려 향상) |
실패했던 2문제가 모두 해결되었으며, 기존의 정답은 회귀(Regression) 없이 유지되었습니다. 출처 표시도 「근로기준법 > 제32조 (노동시간)」와 같이 읽기 쉬워졌습니다.
(※ 전체 데이터 및 운영 규모에서의 재평가 결과는 데이터 재투입 완료 후 추가하겠습니다.)
7. 그럼에도 チャンキング(Chunking)으로 해결되지 않는 것 (솔직한 한계)
「노동시간은 하루에 몇 시간인가」라는 질문에 대해, 「일반직 직원의 근무시간법」 또한 “하루 8시간”을 실제로 규정하고 있기 때문에, 의미상으로는 둘 다 비슷하게 가깝습니다. 조 단위화를 통해 근로기준법의 순위는 올라가겠지만, 질문에 「어느 법의 노동시간인가」가 포함되지 않는 모호함은 チャンキング만으로는 없앨 수 없습니다.
이는 다음 단계의 영역입니다:
- 라우팅 (Routing): 먼저 「근로기준법에 관한 이야기」라고 판정하여 검색 범위를 좁힘
- 리랭킹 (Reranking): 1차 검색을 넓게 가져가고, 관련도가 높은 순으로 다시 정렬 (현재는 전용 재정렬 모델을 사용하지 않고, 코사인 유사도(Cosine Similarity)의 단순 거리 순으로 정렬)
- 하이브리드 검색 (Hybrid Search): 벡터(Vector) + 키워드(Keyword) (고유명사의 완전 일치를 포착)
요약 (배운 점)
- 「전부 넣으면 똑똑해진다」는 오해입니다. 데이터가 늘어나면 유사한 문서 간의 경합이 늘어나 정밀도가 떨어질 수 있습니다.
- 평가는 기계 판정에만 의존하지 마세요. 테스트 허니스(Harness)로 회귀 여부를 확인하면서, 원본 링크를 통해 수동으로 확인해야 합니다.
- 설정은 연동됩니다. top-k만 높이면 입력 토큰(Input Token) 제한에 걸려 역효과가 날 수 있습니다.
- チャンキング(Chunking)은 직접 제어할 수 있습니다 (Bedrock은 임베딩과 생성만 제공). 구조에 따라 자르면 효과적입니다.
- 그럼에도 남는 모호함은 라우팅/리랭킹으로 대처합니다 (다음 편).
숫자(순위·스코어)는 필자의 환경에서 측정한 실측치이며, 코퍼스(Corpus)나 설정에 따라 변동됩니다. RAG의 정밀도 개선은 **「어디가 병목(Bottleneck)인지 실험으로 구분하고, 비용이 적게 드는 방법부터 순서대로 적용하는 것」**이 결국 가장 빠르다는 것을 실감했습니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기