Skip to content

feat(retrieval): add pluggable cross-encoder reranker - #93

Open
vcvyg wants to merge 1 commit into
ob-labs:mainfrom
vcvyg:issue-49-pluggable-reranker
Open

feat(retrieval): add pluggable cross-encoder reranker#93
vcvyg wants to merge 1 commit into
ob-labs:mainfrom
vcvyg:issue-49-pluggable-reranker

Conversation

@vcvyg

@vcvyg vcvyg commented Jul 17, 2026

Copy link
Copy Markdown

Summary

  • add a batched CrossEncoderReranker that implements the existing reranker protocol and lazily loads the optional Sentence Transformers dependency
  • make heuristic, llm, and cross_encoder selectable through retrieval settings while preserving the existing LLM reranking path
  • document configuration and add a reproducible recall/latency benchmark with stub-backed unit coverage

Validation

  • uv run ruff check src/contextseek tests/unit_tests scripts/benchmark_rerankers.py
  • uv run pytest tests/ -q --ignore=tests/unit_tests/test_powermem_plug.py (451 passed, 8 skipped)
  • uv run --extra rerank python scripts/benchmark_rerankers.py --device cpu --rounds 5

Closes #49

Copilot AI review requested due to automatic review settings July 17, 2026 11:12
@vcvyg

vcvyg commented Jul 17, 2026

Copy link
Copy Markdown
Author

#49

Copilot AI 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.

Pull request overview

This PR introduces a pluggable retrieval reranker option by adding a lazily-loaded Sentence Transformers cross-encoder implementation, wiring it into settings-driven configuration, and documenting/benchmarking the new path.

Changes:

  • Added CrossEncoderReranker (batched scoring, lazy dependency import) and exposed it via retrieval module exports.
  • Added reranker_mode=cross_encoder configuration via RetrievalSettings + factory wiring, and injected the reranker into ContextSeek retrieval.
  • Added unit tests, documentation updates, and a small benchmark script for recall/latency comparison.

Reviewed changes

Copilot reviewed 16 out of 17 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
uv.lock Adds sentence-transformers and updates lock resolution to support the new optional extra.
pyproject.toml Introduces rerank extra and includes sentence-transformers in all.
src/contextseek/retrieval/components.py Implements CrossEncoderReranker with lazy model loading and batched prediction.
src/contextseek/retrieval/init.py Re-exports CrossEncoderReranker from retrieval package.
src/contextseek/config/settings.py Adds cross-encoder configuration fields to RetrievalSettings.
src/contextseek/config/factory.py Adds build_reranker() to construct non-LLM rerankers based on settings.
src/contextseek/config/init.py Exports build_reranker for external configuration assembly.
src/contextseek/config/strategies.py Updates comment/documentation for reranker_mode in RetrievalStrategy.
src/contextseek/client/contextseek.py Injects configured reranker into retrieval; preserves existing LLM rerank behavior.
tests/unit_tests/test_settings.py Adds settings/factory coverage for cross-encoder reranker selection and validation.
tests/unit_tests/retrieval/test_reranker_features.py Adds stub-backed unit tests for cross-encoder reranking behavior and fallback.
scripts/benchmark_rerankers.py Adds reproducible benchmark script for heuristic vs cross-encoder recall/latency.
docs/en/reference/settings.md Documents new RETRIEVAL_CROSS_ENCODER_* settings and mode.
docs/zh/reference/settings.md Chinese settings reference updates for cross-encoder mode/settings.
docs/en/concepts/retrieval-model.md Documents cross-encoder reranker usage and configuration.
docs/en/concepts/reranker-benchmark.md Adds benchmark note and reference results table.
.env.example Adds example env vars for cross-encoder reranker configuration.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +807 to +814
try:
scores = list(model.predict(pairs))
if len(scores) != len(to_score):
raise ValueError("cross-encoder returned an unexpected score count")
for item, score in zip(to_score, scores):
item["_score"] = round(float(score), 6)
except Exception: # noqa: BLE001
return pre_ranked
Comment on lines +68 to 71
# Rerank mode: "heuristic" (default), "llm", or "cross_encoder"
reranker_mode: str = "heuristic"
# Limit number of candidates scored by LLM in reranking
llm_rerank_top_n: int = 20
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.

Pluggable reranker in the retrieval orchestrator

2 participants