Chunky - RAG 청킹 도구킷 치트시트
Chunky는 신뢰할 수 있는 RAG 수집 파이프라인 구축을 위한 오픈소스 도구킷입니다. 청킹 단계(종종 간과되는)에 초점을 맞추고 있습니다. PDF를 Markdown으로 변환하고, 문서를 정제하며, 청킹 전략을 검사하고 나란히 비교할 수 있고, 청크 메타데이터를 강화합니다. 검색 품질은 문서를 어떻게 분할하는지에 따라 제한되기 때문에, Chunky의 가치는 청킹 단계를 보이고 조정 가능하게 만드는 것입니다.
설치
| 방법 | 명령어 |
|---|
| pip | pip install chunky |
| uv | uv add chunky |
| 소스에서 | git clone https://github.com/GiovanniPasq/chunky && cd chunky && pip install -e . |
| 확인 | python -c "import chunky; print('ok')" |
파이프라인 단계
| 단계 | 목적 |
|---|
| Convert | PDF/문서를 깔끔한 Markdown으로 변환 |
| Clean | 보일러플레이트, 아티팩트 제거 |
| Chunk | 선택된 전략을 사용하여 텍스트 분할 |
| Inspect | 결과 청크 시각화 |
| Compare | 여러 전략 실행 및 비교 |
| Enrich | 메타데이터 첨부 (제목, 소스, 위치) |
Convert & Clean
import chunky
# PDF를 깔끔한 Markdown으로 변환
md = chunky.to_markdown("report.pdf")
# 공통 아티팩트 정제 (헤더/푸터, 하이픈화, 노이즈)
md = chunky.clean(md)
| 함수 | 설명 |
|---|
to_markdown(path) | 문서를 Markdown으로 변환 |
clean(text) | 보일러플레이트 제거 및 정규화 |
청킹 전략
| 전략 | 기준으로 분할 |
|---|
| Fixed-size | 중복 포함 N 토큰/문자 |
| Recursive | 필요에 따라 문단 → 문장 → 단어 |
| Markdown / header-aware | 문서 구조 (#, ##, 섹션) |
| Semantic | 임베딩 유사도 경계 |
| Token-aware refinement | 작은 청크 병합, 큰 청크 분할 |
chunks = chunky.chunk(
md,
strategy="header_aware",
max_tokens=512,
overlap=64,
repeat_headers=True, # 테이블 분할 시 섹션 제목 반복
)
for c in chunks:
print(len(c.tokens), c.metadata["heading"])
Inspect & Compare
차별화 기능: 커밋 전에 각 전략이 생성하는 항목을 보고 비교합니다.
# 청크 경계 및 크기 검사
chunky.inspect(chunks) # 크기, 겹침, 경계
# 동일 문서에서 전략 비교
report = chunky.compare(
md,
strategies=["fixed", "recursive", "header_aware", "semantic"],
max_tokens=512,
)
print(report) # 전략별 통계: 개수, 크기 분포, 단편화
| 함수 | 표시 |
|---|
inspect(chunks) | 크기 분포, 겹침, 경계 |
compare(text, strategies=[...]) | 나란히 전략 메트릭 |
메타데이터 강화
| 메타데이터 | 검색에 사용 |
|---|
| Heading path | 맥락 확장 / 필터링 |
| Source + page | 인용 |
| Position/index | 정렬 및 이웃 조회 |
| Token count | 프롬프트 시간 예산 관리 |
enriched = chunky.enrich(chunks, source="report.pdf")
# 각 청크.metadata에는 이제 제목 경로, 페이지, 소스, 인덱스 포함
일반적인 워크플로우
# 엔드 투 엔드: PDF → 깔끔한 Markdown → header-aware 청크 → 강화됨
import chunky
md = chunky.clean(chunky.to_markdown("manual.pdf"))
chunks = chunky.chunk(md, strategy="header_aware", max_tokens=512, overlap=64)
chunks = chunky.enrich(chunks, source="manual.pdf")
# chunk.text를 임베드하고, chunk.metadata를 벡터 DB 옆에 저장
# 추측이 아닌 증거로 전략 선택
print(chunky.compare(md, strategies=["recursive", "header_aware", "semantic"]))
Chunky vs 다른 접근법
| 측면 | Chunky | 프레임워크 기본 splitters | Docling |
|---|
| 전략 비교 | 1급 | 수동 | 제한적 |
| Conversion + clean | 기본 제공 | 별도 | 기본 제공 |
| 최적 | 청킹 단계 튜닝 | 빠른 시작 | 전체 파싱 + 청크 |
Docling과 짝을 이루어 파싱하고 벡터 DB와 저장 — Chunky의 역할은 분할을 제대로 하는 것입니다.
리소스