데이터 정리 — 중복 문서·Chroma 재빌드
2026-07-27 · 코퍼스 100건 → 98건. 인덱스 유령 청크 제거.
1. 완전 중복 문서 2쌍 발견
원본 파일 해시를 대조해 바이트 단위로 동일한 파일 2쌍을 찾았다.
md5sum data/raw/files/* | awk '{print $1}' | sort | uniq -d| 쌍 | 파일 A | 파일 B |
|---|---|---|
| 1 | 한국한의학연구원_통합정보시스템 고도화 | 국가과학기술지식정보서비스_통합정보시스템 고도화 |
| 2 | 한국보건산업진흥원_의료기기산업 종합정보시스템 | BioIN_의료기기산업 종합정보시스템(2차) |
같은 사업이 기관명만 다르게 두 번 수집된 것. 파일 내용은 100% 동일.
영향: 문서 수 뻥튀기, 같은 내용 청크가 두 벌씩 검색돼 노이즈, 라우터가 어느 쪽을 고를지 애매해짐.
처리 — 골든셋이 그 문서들을 쓰는지 먼저 확인(안 씀 → 평가 영향 없음)한 뒤,
국가과학기술지식정보서비스·BioIN 쪽을 제거.
grep -E "한의학연구원|국가과학기술지식|한국보건산업|BioIN" data/goldenset.jsonl # 0건지운 것은 세 곳 모두: data/raw/files/*.hwp · data/extracted/*.json ·
data/raw/data_list.csv의 해당 행.
CSV를 안 지우면 파이프라인이
MetaMatchError: CSV↔파일 매칭 실패로 전체 중단된다. (원본 안전장치가 제대로 작동한 것 — 짝이 안 맞는 상태로 인덱싱되는 걸 막아준다) CSV 편집은 행 번호가 아니라 파일명 셀 정확일치로 지웠다 — 사업명이 비슷한 유지 대상(한의학연구원·보건산업진흥원)을 실수로 지우지 않기 위해.
2. 유령 청크 — 재인덱싱만으로는 안 지워진다
중복 파일을 지우고 --force 재인덱싱했는데도 지운 문서의 청크가 Chroma에 남아 있었다.
| 재인덱싱 후 | 기대값 | |
|---|---|---|
| 전체 청크 | 30,003 | 27,982 |
| 청크 문서 수 | 99 | 97 |
| 국과기 유령 | 253청크 | 0 |
| BioIN 유령 | 303청크 | 0 |
원인: 인덱싱이 upsert(덮어쓰기)만 하고 사라진 문서를 지우지 않는다. 그래서 재인덱싱을 반복할수록 옛 잔재가 계속 쌓인다.
처리: Chroma 디렉토리를 통째로 비우고 처음부터 재빌드.
mv data/chroma <백업경로> # 지우기 전 백업
PYTHONPATH=. uv run python scripts/run_pipeline.py --force결과: 청크 27,982 · 문서 97 · 유령 0 · 게이트 통과. (98건 중 케빈랩 1건은 추출 타임아웃이라 카드만 있고 청크 없음 — 정상)
교훈: 문서를 지우거나 코퍼스를 크게 바꿀 땐
--force재인덱싱만으로 부족하다. Chroma를 비우고 새로 지어야 깨끗하다.
3. 중복 제거가 평가 점수를 실제로 올렸다
같은 26문항 골든셋으로 전후 비교:
| 지표 | 중복 있을 때 | 제거 후 | 변화 |
|---|---|---|---|
| judge 정확성 | 3.23 | 3.62 | ↑ |
| Answer Correctness | 0.505 | 0.685 | ↑ 크게 |
| 값 정확도(직답) | 0.6 | 0.8 | ↑ |
| Context Precision | 0.841 | 0.73 | ↓ (표본 6문항, 변동 범위) |
| Context Recall | 1.0 | 1.0 | = |
| 거절 정확도 | 1.0 | 1.0 | = |
Answer Correctness가 0.505 → 0.685로 오른 게 핵심. 같은 내용이 두 벌씩 검색을 오염시켜 답이 부실해지던 게 풀린 것으로 보인다.
이 기록은 data/eval/eval_history.md에도 한 줄로 남겼다(요약 숫자만 커밋,
NDA 원문 없음 — gitignore 예외 처리).
관련
- 요건 추출은 참가자격 매칭 — 추출 정확도 디버깅
- 디스크가 꽉 차 재빌드가 실패하던 건 운영 트러블슈팅 — 디스크·터널·포트포워딩