~/wiki

reranker registry

---
title: Reranker Registry
category: concepts
created: 2025-12-20
updated: 2025-01-04
tags: [reranker-registry, retrieval-optimization, model-registry, dependency-management, fallback-patterns, rag-architecture, albert-reranker, bge-reranker, cohere-reranker, interface-consistency, production-issues, hardcoded-keys, registry-bypass, optional-dependencies, undefined-variables, silent-failures, critical-bugs, category-5-bugs, dynamic-model-selection, registry-implementation-bugs, assistant-rh-bugs, runtime-crashes, model-availability, configuration-management, registry-isolation]
sources: [raw/conversations/2025-10-23-codex-assistant-rh-c34c0439.md]
confidence: high
---

# Reranker Registry

Architecture pattern for managing multiple reranking models in RAG systems, providing dynamic model selection, fallback mechanisms, and consistent interfaces across different reranking implementations. Critical for production systems where reranker availability and performance requirements vary.

## Core Concept

A reranker registry abstracts the complexities of managing multiple reranking models behind a unified interface, allowing runtime selection based on:

- Model availability and performance characteristics
- Domain-specific requirements (legal, medical, technical)
- Language and regional considerations
- Infrastructure constraints and costs

## Implementation Challenges

### Registry Bypass Issues

The assistant-rh system demonstrates critical registry implementation failures. The October 2025 Codex analysis revealed that the public reranker interface completely bypasses the registry pattern:

```python
# BUG: Registry ignored, hardcoded keys only
def rerank(self, model_name: str, query: str, documents: List[str]):
    if model_name == "albert":
        return self._albert_rerank(query, documents)
    elif model_name == "rerank-small":
        return self._small_rerank(query, documents)
    else:
        # BUG: Returns undefined variable or silent no-op
        return undefined_fallback_result  # NameError!

This implementation fails because:

  • Registry configuration is ignored
  • Only two hardcoded keys are supported
  • BGE and Cohere models are unavailable despite UI options
  • Undefined variables cause runtime crashes
  • No graceful degradation for unknown models

Missing Fallback Mechanisms

Production reranker registries must handle:

  • Model unavailability (network issues, API limits)
  • Dependency conflicts (conflicting model versions)
  • Resource constraints (GPU memory, CPU limitations)
  • Version compatibility (model API changes)

Without proper fallback mechanisms, any registry failure cascades to complete system failure.

Architecture Patterns

Registry-First Design

class RerankerRegistry:
    def __init__(self):
        self.models = {}
        self.fallback_chain = []
        
    def register(self, name: str, model_class: Type, **kwargs):
        try:
            model = model_class(**kwargs)
            self.models[name] = model
        except ImportError as e:
            logger.warning(f"Failed to load {name}: {e}")
            
    def get_reranker(self, name: str) -> Optional[BaseReranker]:
        if name in self.models:
            return self.models[name]
        
        # Fallback chain
        for fallback_name in self.fallback_chain:
            if fallback_name in self.models:
                logger.info(f"Using fallback {fallback_name} for {name}")
                return self.models[fallback_name]
                
        raise RerankerNotAvailableError(f"No reranker available for {name}")

Optional Dependency Management

Handle missing dependencies gracefully:

def register_optional_models(registry: RerankerRegistry):
    # BGE Reranker (requires sentence-transformers)
    try:
        from bge_reranker import BGEReranker
        registry.register("bge", BGEReranker, model_name="BAAI/bge-reranker-base")
    except ImportError:
        logger.info("BGE reranker not available - install sentence-transformers")
    
    # Cohere Reranker (requires cohere API key)
    try:
        from cohere_reranker import CohereReranker
        if os.getenv("COHERE_API_KEY"):
            registry.register("cohere", CohereReranker)
    except (ImportError, KeyError):
        logger.info("Cohere reranker not available")
        
    # Always-available fallback
    registry.register("albert", AlbertReranker)  # Local model
    registry.set_fallback_chain(["albert"])

Interface Consistency

All rerankers must implement the same interface:

from abc import ABC, abstractmethod

class BaseReranker(ABC):
    @abstractmethod
    def rerank(self, query: str, documents: List[str]) -> List[RankedDocument]:
        pass
        
    @property
    @abstractmethod  
    def max_documents(self) -> int:
        """Maximum documents this reranker can handle"""
        pass
        
    @property
    @abstractmethod
    def supports_languages(self) -> List[str]:
        """Languages supported by this reranker"""
        pass

Production Considerations

Health Checking

Registry should monitor model health:

class HealthAwareRegistry(RerankerRegistry):
    def __init__(self):
        super().__init__()
        self.health_status = {}
        
    def health_check(self, name: str) -> bool:
        """Check if reranker is functioning correctly"""
        try:
            reranker = self.models[name]
            test_result = reranker.rerank("test", ["document"])
            self.health_status[name] = True
            return True
        except Exception as e:
            logger.error(f"Health check failed for {name}: {e}")
            self.health_status[name] = False
            return False
            
    def get_healthy_reranker(self, name: str) -> BaseReranker:
        if self.health_check(name):
            return self.models[name]
        
        # Try fallbacks
        for fallback in self.fallback_chain:
            if self.health_check(fallback):
                return self.models[fallback]
                
        raise NoHealthyRerankerError("No healthy rerankers available")

Configuration Management

External configuration for production flexibility:

# reranker_config.yaml
rerankers:
  albert:
    class: "AlbertReranker"
    model_path: "/models/albert-french-legal"
    max_documents: 100
    
  bge:
    class: "BGEReranker"
    model_name: "BAAI/bge-reranker-base"
    max_documents: 50
    optional: true  # Don't fail if unavailable
    
  cohere:
    class: "CohereReranker"  
    api_key_env: "COHERE_API_KEY"
    model: "rerank-multilingual-v2.0"
    optional: true

fallback_chain: ["albert", "bge"]
default_reranker: "albert"

Performance Optimization

Registry can implement performance-aware selection:

class PerformanceAwareRegistry(RerankerRegistry):
    def __init__(self):
        super().__init__()
        self.performance_stats = {}
        
    def select_optimal_reranker(self, 
                              document_count: int,
                              latency_requirements: float) -> str:
        """Select best reranker for given constraints"""
        candidates = []
        
        for name, model in self.models.items():
            if document_count <= model.max_documents:
                avg_latency = self.performance_stats.get(name, {}).get('latency', float('inf'))
                if avg_latency <= latency_requirements:
                    candidates.append((name, avg_latency))
                    
        if candidates:
            # Return fastest qualifying reranker
            return min(candidates, key=lambda x: x[1])[0]
        
        # Fallback to default if no candidates meet requirements
        return self.default_reranker

Anti-Patterns to Avoid

Hard-Coded Model Selection

# ANTI-PATTERN: Hard-coded model selection
def rerank_documents(query: str, docs: List[str]) -> List[str]:
    if len(docs) > 50:
        return albert_rerank(query, docs)  # Hard-coded choice
    else:
        return bge_rerank(query, docs)     # Hard-coded choice

Silent Registry Failures

# ANTI-PATTERN: Silent failures mask problems
def get_reranker(name: str):
    try:
        return registry.get(name)
    except Exception:
        return None  # Silent failure - caller doesn't know it failed

Configuration Coupling

# ANTI-PATTERN: Configuration tightly coupled to code
class RerankerFactory:
    def create_reranker(self, name: str):
        if name == "albert":
            return AlbertReranker("/hardcoded/path/albert")  # Inflexible
        elif name == "bge":
            return BGERe