feat(vector_io): add classifier reranker type for post-retrieval chunk filtering - #5890
Conversation
…k filtering Add "classifier" as a new reranker type that scores chunks by quality or answerability (rather than relevance) and filters below a confidence threshold. Uses the same inference rerank API as neural reranking but with a different objective model. Refs: ogx-ai#5728 Signed-off-by: Varsha Prasad Narsing <vnarsing@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> Signed-off-by: Varsha Prasad Narsing <varshaprasad96@gmail.com>
|
can you test the retrieval benchmark suite to see the performance? |
|
This pull request has been automatically marked as stale because it has not had activity within 60 days. It will be automatically closed if no further activity occurs within 30 days. |
Classifier Reranker Benchmark AnalysisI ran a comparative analysis of the classifier reranker concept using BEIR/nfcorpus (50 queries, ~3600 documents) to determine whether classifier-based chunk filtering provides retrieval quality improvements. Setup
Two models were tested as the classifier:
Finding 1: Score DistributionThe current Qwen3-Reranker produces an extremely narrow score range, making threshold-based filtering impossible. The CrossEncoder uses the full 0–1 range.
Qwen3's 0.006 std means all scores are essentially the same value. The default Finding 2: Relevance DiscriminationDoes the classifier actually assign higher scores to relevant chunks (per BEIR ground truth)?
The CrossEncoder discriminates 3x better between relevant and irrelevant chunks. Qwen3's 1.15x separation is essentially noise. Finding 3: Retrieval Quality (Threshold Sweep)How does filtering at various thresholds affect retrieval metrics? Qwen3-Reranker (current classifier):
CrossEncoder/ms-marco-MiniLM-L6-v2:
Finding 4: Root CauseThe current classifier reranker calls
Recommendations
Reproducing these results# Start OGX with local config (sqlite-vec + sentence-transformers)
OPENAI_API_KEY=<key> uv run ogx run benchmarking/rag/config-local.yaml --insecure
# Run baseline BEIR benchmark
uv run python benchmarking/rag/run_benchmark.py \
--benchmark beir --dataset nfcorpus --search-mode hybrid \
--provider ogx --base-url http://localhost:8321/v1 --no-resume
# Run comparative analysis
uv run python benchmarking/rag/analyze_classifier.py |
|
nice! |
Summary
Add
"classifier"as a new reranker type that scores chunks by quality or answerability (rather than relevance) and filters below a confidence threshold. Uses the same inference rerank API as neural reranking — the difference is the objective model and the filtering behavior.Refs: #5728
Motivation
Vector search ranks by embedding similarity, but similarity ≠ usefulness. Rerankers (
"neural") re-score by relevance but don't assess chunk quality — whether a chunk is complete, non-redundant, and likely to produce a correct answer. A classifier model trained on "did this chunk lead to a correct answer?" captures a different signal than "is this chunk similar to the query?"As discussed in #5728, a classifier with probability output is functionally a reranker. Rather than introducing a separate abstraction, this implements the classifier as a reranker type — same mechanism, different objective.
Usage
Changes
vector_store.py: AddRERANKER_TYPE_CLASSIFIERconstant,apply_classifier_rerank()method, wire intoquery_chunks()dispatch. Extract_extract_chunk_texts()helper to deduplicate text extraction between neural and classifier rerankers.openai_vector_store_mixin.py: Handleranker="classifier"in_build_reranker_params().models.py: Document"classifier"as valid ranker value inSearchRankingOptions.Design decisions
default_reranker_modelfrom config when no explicit model providedrankeris not"classifier"Test plan
9 tests covering: threshold filtering, keeps above threshold, zero threshold, no model fallback, inference error, correct model passthrough, out-of-bounds index, all-filtered empty response, constant definition.
Signed-off-by: Varsha Prasad Narsing vnarsing@redhat.com
🤖 Generated with Claude Code