Skip to content

chunk size 1000 일 때 청크결과 안나오는 오류 수정 - #337

Merged
HeechanKim-Genon merged 2 commits into
developfrom
fix/336-code-serving-chunk_size-1000-no-result
Jul 27, 2026
Merged

chunk size 1000 일 때 청크결과 안나오는 오류 수정#337
HeechanKim-Genon merged 2 commits into
developfrom
fix/336-code-serving-chunk_size-1000-no-result

Conversation

@inoray

@inoray inoray commented Jul 24, 2026

Copy link
Copy Markdown
Collaborator

fix(#336): chunk_size 전달 시 청크 결과 안 나오는 오류 수정 + 청킹 옵션 정리

개요

chunking_processor(코드서빙 /chunker)를 호출할 때 chunk_size(예: 1000)를 kwargs 로 넘기면
결과가 안 나오는(0청크로 보이는) 오류를 수정한다. 원인 분석 과정에서 발견한 동일 부류의 크래시와,
청킹 옵션 config 네이밍/중복도 함께 정리했다.

결론 요약: chunk_overlap 은 무관(범인 아님)했고, 진짜 트리거는 chunk_size 였다. 토큰 분할 경로가
켜지면서 doc_items 가 빈 그룹이 생겨 pydantic 검증에서 예외가 나 요청 전체가 실패했다.

원인 (root cause)

  • chunk_size 를 넘기면 max_tokens > 0 이 되어 토큰 분할 경로(split_only 5.5단계)가 켜진다.
  • 분할 결과 중 텍스트(헤더 라인)만 있고 doc_items 가 빈 그룹이 생기는데, get_current_chunk()
    빈 텍스트만 방어하고 빈 items 는 방어하지 않아 DocMeta(doc_items=[]) 로 생성 → pydantic
    min_length=1 ValidationError__call__ 밖으로 전파 → "결과 없음".
  • 트레이스백:
    chunking_processor.py get_current_chunk → DocMeta(doc_items=[])
    pydantic ValidationError: doc_items List should have at least 1 item after validation, not 0
    
  • (별개) parse-format 경로에서는 chunk_overlap > chunk_size 일 때 langchain
    RecursiveCharacterTextSplitterValueError 로 크래시하는 동일 부류 문제도 존재했다.

주요 변경

1) 크래시 수정 (핵심)

  • 빈 doc_items 그룹 스킵: get_current_chunk() 가드를 if not merged_texts or not merged_items:
    로 확장(빈 items 그룹은 청크로 만들지 않음). 모든 DocChunk 생성이 이 단일 지점을 거치고 호출부가 이미
    None 을 스킵하므로 크래시가 사라진다.
  • 빈 그룹 생성 자체 방지: split_items_evenly_by_tokens() 가 폭 0 범위 (a,a) 를 만들지 않도록
    if a < b 필터 추가.
  • overlap 클램프: parse-format 문자 splitter 에서 chunk_overlap = min(max(overlap,0), chunk_size-1)
    로 클램프해 overlap >= size 크래시(ValueError) 방지.
  • 위 세 가지는 GenosSmartChunker 청킹 로직이 복제된 활성 3종
    (chunking/intelligent/convert) + BOK 적재·첨부 legacy 사본
    에 lockstep 반영.
    attachment_processor 문자 splitter(_char_split_text 단일 지점)에도 overlap 클램프 반영.

2) 청킹 옵션 config 정리 (attachment 정렬)

  • parse-format 문자 splitter 설정을 attachment_processor 와 동일한 recursive 네이밍으로 통일
    (기존 genericrecursive).
  • 요청 kwargs 에 recursive_chunk_overlap 별칭 정리.

3) chunk_size 통합

  • docling(GenosSmartChunker max_tokens)과 parse-format 문자 splitter 크기를 단일 chunking.chunk_size
    로 통합(호출 kwargs chunk_size 는 원래부터 두 경로를 모두 제어). recursive.chunk_size 및 관련 size
    kwargs 별칭(recursive_chunk_size/generic_chunk_size/generic_chunk_overlap) 제거.
  • recursive: 블록에는 docling 대응 개념이 없는 chunk_overlap 만 남김.
  • 공통값 chunk_size: 10000 유지(docling 불변). parse-format 은 0/미설정 시 코드 기본값
    1000000(사실상 미분할)로 대체.

영향 파일

  • facade/chunking_processor.py — 크래시 가드/클램프, config 읽기(recursive), _chunk_text_elements(공통 크기).
  • facade/intelligent_processor.py, facade/convert_processor.py — get_current_chunk 가드 + split 폭0 필터.
  • facade/attachment_processor.py_char_split_text overlap 클램프.
  • facade/legacy/BOK_적재용_{규정,내부,외부}.py, facade/legacy/BOK_첨부용.py — 동일 가드/클램프 lockstep.
  • resource/chunking_processor_config.yaml, resource_dev/chunking_processor_config.yaml — chunk_size 공통화,
    genericrecursive, recursive.chunk_size 제거.

하위 호환 / 동작 변경

  • 동작 변경(의도): parse-format 텍스트(txt/md/csv 등)가 이제 공통 chunk_size(기본 10000자) 기준으로
    분할된다(직전엔 사실상 미분할). docling 경로는 불변.
  • 하위 호환: 제거된 size kwargs 별칭은 chunking_processor 밖에서 참조가 없어 영향 없음.
    기존 정상 호출/정상 overlap 케이스는 결과 불변.

검증 (preprocessor venv, in-process)

  • 수정 전: docling chunk_size=1000ValidationError(doc_items ... at least 1 item) 로 실패.
  • 수정 후: sample1.docling.json + chunk_size=100042청크 정상 출력(빈 items 그룹만 드롭).
  • parse-format: 공통 chunk_size=10000 적용 확인, chunk_size=500 시 더 잘게, overlap>size 도 크래시 없이 클램프.
  • 회귀: chunk_overlap 단독/정상 overlap, docling 기본 경로 결과 불변. 코드 컴파일 + 두 YAML 파싱 OK.

커밋

해시 요약
00e15434 chunk size 1000 일 때 청크결과 안나오는 오류 수정

Summary by CodeRabbit

  • Bug Fixes
    • Prevented document processing failures when chunk overlap is equal to or larger than the chunk size.
    • Prevented creation of empty chunks during token-based and header-only document splits.
    • Improved handling of parse-format chunk sizes and overlap settings, including safer defaults and validation.
  • Documentation
    • Updated chunking configuration guidance to clarify size, overlap, and fallback behavior.

@gemini-code-assist

Copy link
Copy Markdown

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@inoray inoray self-assigned this Jul 24, 2026
@coderabbitai

coderabbitai Bot commented Jul 24, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@inoray, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 44 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: a6690ae0-3845-4643-891b-987666c52d93

📥 Commits

Reviewing files that changed from the base of the PR and between 00e1543 and 8daf726.

📒 Files selected for processing (3)
  • genon/preprocessor/facade/chunking_processor.py
  • genon/preprocessor/resource/chunking_processor_config.yaml
  • genon/preprocessor/resource_dev/chunking_processor_config.yaml
📝 Walkthrough

Walkthrough

The chunking processors now bound recursive splitter overlap values, use recursive-specific parse-format configuration, and avoid creating DocChunks or token ranges for empty item groups across current and legacy implementations.

Changes

Chunking Safety

Layer / File(s) Summary
Parse-format parameter resolution
genon/preprocessor/resource/chunking_processor_config.yaml, genon/preprocessor/resource_dev/chunking_processor_config.yaml, genon/preprocessor/facade/chunking_processor.py
Parse-format splitting now uses recursive overlap settings, shared chunk sizing, large defaults when unset, and overlap clamping to chunk_size - 1.
Empty token-group filtering
genon/preprocessor/facade/chunking_processor.py, genon/preprocessor/facade/convert_processor.py, genon/preprocessor/facade/intelligent_processor.py, genon/preprocessor/facade/legacy/BOK_적재용_*.py
Token split ranges exclude zero-width intervals, and chunk construction skips groups without merged text or document items.
Recursive overlap clamping
genon/preprocessor/facade/attachment_processor.py, genon/preprocessor/facade/legacy/BOK_첨부용.py
Recursive splitter callers cap overlap below the configured chunk size.
Estimated code review effort: 3 (Moderate) ~20 minutes

Possibly related issues

  • genonai/doc-parser-ingestion#89 — Covers the same safe handling of chunk_size/chunk_overlap and empty doc_items at a different processing layer.

Possibly related PRs

Suggested reviewers: heechankim-genon

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title matches the main bug fix and clearly describes the user-visible issue at chunk_size=1000.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/336-code-serving-chunk_size-1000-no-result

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
genon/preprocessor/facade/legacy/BOK_첨부용.py (1)

1680-1685: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Resolve legacy defaults using the recursive option names first.

This path still falls back to generic_chunk_size and generic_chunk_overlap on Lines 1678-1681, so the recursive_* values supplied by the current configuration/defaults are ignored whenever chunk_size or chunk_overlap is absent. Use recursive_* first, retaining generic_* only as a backward-compatible fallback.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@genon/preprocessor/facade/legacy/BOK_첨부용.py` around lines 1680 - 1685, Update
the legacy chunk-size and chunk-overlap default resolution before the clamping
logic: when either value is absent, read the corresponding recursive_chunk_size
or recursive_chunk_overlap option first, then fall back to generic_chunk_size or
generic_chunk_overlap for compatibility. Preserve the existing integer
conversion and bounds handling after resolution.
🧹 Nitpick comments (1)
genon/preprocessor/facade/chunking_processor.py (1)

975-976: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use itertools.pairwise() for adjacent cut ranges.

Ruff reports B905/RUF007 on these successive-pair iterations. Replace each zip(cuts[:-1], cuts[1:]) with pairwise(cuts) after importing pairwise from itertools.

  • genon/preprocessor/facade/chunking_processor.py#L975-L976: use pairwise(cuts).
  • genon/preprocessor/facade/convert_processor.py#L1287-L1288: use pairwise(cuts).
  • genon/preprocessor/facade/intelligent_processor.py#L1292-L1293: use pairwise(cuts).
  • genon/preprocessor/facade/legacy/BOK_적재용_규정.py#L775-L776: use pairwise(cuts).
  • genon/preprocessor/facade/legacy/BOK_적재용_내부.py#L716-L717: use pairwise(cuts).
  • genon/preprocessor/facade/legacy/BOK_적재용_외부.py#L771-L772: use pairwise(cuts).
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@genon/preprocessor/facade/chunking_processor.py` around lines 975 - 976,
Replace each adjacent-cut iteration with itertools.pairwise(cuts), importing
pairwise in all affected modules:
genon/preprocessor/facade/chunking_processor.py lines 975-976,
genon/preprocessor/facade/convert_processor.py lines 1287-1288,
genon/preprocessor/facade/intelligent_processor.py lines 1292-1293,
genon/preprocessor/facade/legacy/BOK_적재용_규정.py lines 775-776,
genon/preprocessor/facade/legacy/BOK_적재용_내부.py lines 716-717, and
genon/preprocessor/facade/legacy/BOK_적재용_외부.py lines 771-772; preserve each
existing a < b filtering behavior.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@genon/preprocessor/facade/chunking_processor.py`:
- Around line 2586-2602: Update the chunk-size and overlap resolution in the
shown preprocessing logic to distinguish absent kwargs from explicit values:
preserve an explicit chunk_size=0 and convert it to the effective no-split
default of 1,000,000 rather than falling back to common_size, while retaining
configured fallback behavior when the key is absent. Handle an explicitly null
recursive_chunk_overlap safely by falling back to overlap_default before int
conversion, and keep the existing final clamping behavior.

---

Outside diff comments:
In `@genon/preprocessor/facade/legacy/BOK_첨부용.py`:
- Around line 1680-1685: Update the legacy chunk-size and chunk-overlap default
resolution before the clamping logic: when either value is absent, read the
corresponding recursive_chunk_size or recursive_chunk_overlap option first, then
fall back to generic_chunk_size or generic_chunk_overlap for compatibility.
Preserve the existing integer conversion and bounds handling after resolution.

---

Nitpick comments:
In `@genon/preprocessor/facade/chunking_processor.py`:
- Around line 975-976: Replace each adjacent-cut iteration with
itertools.pairwise(cuts), importing pairwise in all affected modules:
genon/preprocessor/facade/chunking_processor.py lines 975-976,
genon/preprocessor/facade/convert_processor.py lines 1287-1288,
genon/preprocessor/facade/intelligent_processor.py lines 1292-1293,
genon/preprocessor/facade/legacy/BOK_적재용_규정.py lines 775-776,
genon/preprocessor/facade/legacy/BOK_적재용_내부.py lines 716-717, and
genon/preprocessor/facade/legacy/BOK_적재용_외부.py lines 771-772; preserve each
existing a < b filtering behavior.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f5f1b969-029a-45c8-8d36-1ce5e2be7b89

📥 Commits

Reviewing files that changed from the base of the PR and between 4d5520c and 00e1543.

📒 Files selected for processing (10)
  • genon/preprocessor/facade/attachment_processor.py
  • genon/preprocessor/facade/chunking_processor.py
  • genon/preprocessor/facade/convert_processor.py
  • genon/preprocessor/facade/intelligent_processor.py
  • genon/preprocessor/facade/legacy/BOK_적재용_규정.py
  • genon/preprocessor/facade/legacy/BOK_적재용_내부.py
  • genon/preprocessor/facade/legacy/BOK_적재용_외부.py
  • genon/preprocessor/facade/legacy/BOK_첨부용.py
  • genon/preprocessor/resource/chunking_processor_config.yaml
  • genon/preprocessor/resource_dev/chunking_processor_config.yaml

Comment thread genon/preprocessor/facade/chunking_processor.py Outdated
@inoray
inoray requested a review from HeechanKim-Genon July 27, 2026 00:38
@HeechanKim-Genon
HeechanKim-Genon merged commit 10dc64e into develop Jul 27, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

code serving, chunk api 호출 시 chunk_size 1000 일 때 결과 출력하지 않는 버그

2 participants