Skip to content

feat(rerank): bound reranker input width (max_chars_per_doc) - #2999

Open
chethanuk wants to merge 1 commit into
volcengine:mainfrom
chethanuk:feat/2880-rerank-max-chars
Open

feat(rerank): bound reranker input width (max_chars_per_doc)#2999
chethanuk wants to merge 1 commit into
volcengine:mainfrom
chethanuk:feat/2880-rerank-max-chars

Conversation

@chethanuk

Copy link
Copy Markdown
Contributor

Summary

Adds an optional RerankConfig.max_chars_per_doc that truncates each document to N characters before it is sent to rerank_batch inside HierarchicalRetriever._rerank_scores. This bounds the reranker's input width so a single oversized abstract can no longer overflow the model and fail the whole batch open to vector scores — the exact failure #2880 describes.

This is v0 of a deliberately small PR ladder (follow-ups: truncation-observability counter, provider-portable score_threshold, forwarding token-truncation to providers). max_docs + score-fusion were evaluated and dropped — the rerank batch is already count-bounded by GLOBAL_SEARCH_TOPK=10 and limit*2, so per-doc width is the axis that actually matters here.

How it works

flowchart TD
    A["global_results → document abstracts"] --> B{"cap = max_chars_per_doc"}
    B -- "cap == 0  (default, OFF)" --> C["model_inputs = documents<br/>byte-identical parity"]
    B -- "cap &gt; 0" --> D["truncate each doc to cap chars<br/>MODEL INPUT only"]
    C --> E["rerank_batch(query, model_inputs)"]
    D --> E
    E --> F["scores scatter back onto full result dict<br/>stored / returned abstract untouched"]
    F --> G["score &gt; threshold → keep / recurse"]
Loading

Behavior

  • default=0 = unbounded, byte-identical parity with previous behavior (if cap > 0 else documents passes the original list through untouched).
  • Field(default=0, ge=0, strict=True) rejects negatives and string coercion; extra="forbid" makes a typo'd key fatal.
  • Soft-warn (never reject) when a non-zero cap is below the ~200-char cross-encoder stability floor.
  • Truncation applies to the model input only — the score scatters back onto the full result dict, so stored and returned abstracts are untouched.
  • Enforced only in _rerank_scores, at both rerank sites (global + child recursion); the query is never truncated.
  • Codepoint slice (str[:cap]) — safe for CJK/multibyte, not grapheme-aware (documented). The char≠token gap for CJK is a known limitation closed by the token-forwarding follow-up.

Tests / docs

Extends tests/retrieve/test_hierarchical_retriever_rerank.py with the full matrix: cap=0 parity, truncation at both sites, query-not-truncated, boundaries (0/≥len/len+1/1), multibyte + empty, fail-open with the cap on (length invariant intact), QUICK-mode skip, and config rejection (-1, "5", typo key). The pre-existing default-off parity guard remains. Unit suite green; ruff check + format clean. Rerank-table rows added to docs/en/guides/01-configuration.md and docs/zh/guides/01-configuration.md.

Recommended-ON value: 2000 chars (~500 EN tokens) for 512-token rerankers (BGE/MiniLM/VikingDB) — above the instability floor, below the model window. CJK caveat: 2000 chars ≠ 500 tokens, so a char cap can still overflow a 512-token reranker (closed by the token-forwarding follow-up).

Review

Inline review-bot feedback (gemini-code-assist / qodo / codeant-ai) was triaged comment-by-comment and independently verified: the one valid item (test-log warning-spam) was fixed; the getattr guard and the strict-int "env var" concern were declined with rationale (the config loader expands unquoted ${VAR} into a JSON number that strict=True accepts, and this is the only strict numeric field in the repo). No production behavior changed.

Closes #2880

@chethanuk
chethanuk force-pushed the feat/2880-rerank-max-chars branch from 7dc1e47 to 9d96ae7 Compare July 4, 2026 02:56
@chethanuk

Copy link
Copy Markdown
Contributor Author

Please review cc: @qin-ctx @ZaynJarvis @zhoujh01 @yufeng201 @chenjw - Please let me know if you require any changes, or if the project is currently accepting contributions

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

[Feature]: Configurable rerank batch limits (max_docs + max_chars_per_doc) for latency-sensitive recall

1 participant