청킹 전략 3종 비교 — 「1 조항 = 1 청크」를 재본 적이 없다
무엇을
고정 길이 · 시멘틱 · 「1 조항 = 1 청크」 세 방식으로 각각 인덱스를 적재해 Recall@5·MRR 을 대조한다.
왜 — 미결 항목에 2026-08-27 부터 열려 있다
우리는 「1 조항 = 1 청크」 고정이고 근거도 있다 — 청크가 조항 경계를 넘나들면
doc_id 정확 일치 채점이 깨진다(청크 하나에 doc_id 를 하나만 달 수 있다).
다만 재본 적이 없다. 상용(LG CNS AICC)은 시멘틱 청킹을 쓴다고 밝히고 있다(9.3.1).
재적재가 1초라 비용이 거의 없다 — 안 재고 있는 이유가 비용은 아니다.
먼저 정해야 하는 것 — 채점 방식
시멘틱·고정 길이로 가면 청크마다 «대표 조항 ID» 를 달아야 지금 채점기가 그대로 돈다. 안 달면 Recall 이 «정답을 못 찾아서» 가 아니라 «채점이 못 알아봐서» 떨어지고, 그 둘은 구분이 안 된다. 측정 방법을 먼저 적고 그다음 잰다.
완료 조건
- 세 방식의 Recall@5·MRR 을 같은 골든셋(v1-150)·같은 커밋에서 낸다
- 대표 조항 ID 부여 규칙을 코드와 문서 양쪽에 적는다
- 「1 조항 = 1 청크」가 이기면 그대로 두고 그 사실을 기록한다 — 바꾸지 않는 것도 결과다
- 바꾸기로 하면 결정 기록(
2xx)을 쓴다 — 채점 기준이 바뀌는 변경이다
2026-09-15 — 「1 조항 = 1 청크」를 그대로 둔다. 재 보니 가장 높다
채점 방식을 먼저 정했다
- 대표 조항 ID = 청크 안에서 글자를 가장 많이 차지한 조항(동률이면 앞 조항).
Chunk.doc_id에 넣으면 검색 어댑터·채점기가 그대로 돈다 - 그 규칙이 깎는 몫을 보려고 느슨 채점을 함께 냈다 — 청크가 덮은 조항 중 하나라도 정답이면 적중. ⚠ 느슨 값은 운영에서 못 쓰는 값이다(카드에는 조항 하나를 띄워야 한다). «대표 ID 때문에 잃은 몫» 을 읽는 용도다
- 규칙은
ai/apps/retrieval/domain/services/chunking_strategies.py머리말과 테스트(test_chunking_strategies.py)에 고정했다 - 파일(TERM·MANUAL·POLICY) 경계는 넘지 않는다. 고정·시멘틱 청크는 제목을 본문 앞에 넣는다 — 조항 청크가
title필드로 보는 정보를 똑같이 쓰게
실측
측정일 2026-09-15 · 커밋 38f2fc3-dirty · 골든셋 v1-150 B 항목 n96 · 지식베이스 98조항 · KoE5 · CPU
ELASTICSEARCH_URL=http://localhost:9200 .venv/bin/python scripts/compare_chunking.py
실험 인덱스 cgexp-chunk-* (측정 후 삭제) · 결과 data/processed/chunking-compare/2026-09-15.json
전략 청크 평균자 경계넘음 │ 검색 엄격 R@5 hits MRR │ 느슨 R@5 hits
article 98 121 0 │ bm25 0.833 80/96 0.659 │ 0.833 80/96
article 98 121 0 │ dense 0.979 94/96 0.885 │ 0.979 94/96
fixed 200/50 94 196 89 │ bm25 0.760 73/96 0.564 │ 0.781 75/96
fixed 200/50 94 196 89 │ dense 0.896 86/96 0.728 │ 0.927 89/96
semantic p90 79 175 41 │ bm25 0.552 53/96 0.483 │ 0.812 78/96
semantic p90 79 175 41 │ dense 0.625 60/96 0.568 │ 0.938 90/96
- article 줄이 본 인덱스 값(
compare_retrievers.py)과 같다 — 실험 인덱스 적재·채점 경로가 틀리지 않았다는 확인 - 시멘틱은 대표 ID 규칙에 크게 깎인다(dense 엄격 60 → 느슨 90건). 청크 79개 중 41개가 조항을 두 개 이상 덮는다 — 조항들이 비슷한 말(서류·발급·신분증)로 이어져 의미 경계가 조항 경계와 안 맞는다
- 느슨 채점으로 봐줘도 이기지 못한다 — dense 기준 article 94 > semantic 90 > fixed 89. 「채점이 못 알아봐서」를 빼고도 진다
- 고정 200/50 · percentile 90 은 골든셋으로 고르지 않은 값이다. 다른 값에서는 달라질 수 있다 — 다만 느슨 채점의 상한이 이미 article 아래라 뒤집힐 여지는 작다
결론
바꾸지 않는다. 결정 기록은 쓰지 않았다 — 채점 기준이 바뀌는 변경이 없다. 이 결과가 조항이 짧고(중앙 121자) 경계 표시가 있는 지금 지식베이스에 대한 것이라는 점은 남긴다. 상용(LG CNS)이 시멘틱을 쓰는 이유는 경계 표시가 없는 긴 문서라서일 수 있다.