---
title: "Reranking Models"
description: "Reranking models refine initial memory retrieval candidates by scoring query-document relevance through specialized neural architectures, cloud APIs, and language model evaluators. Positioned downs..."
last_updated: "2026-10-11T17:37:10.25946+00:00"
canonical_url: "https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/llm-providers/reranking-models"
---

<details>
<summary>Relevant source files</summary>

The following files were used as context for generating this wiki page:

- [mem0-ts/src/oss/src/rerankers/cross_encoder.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cross_encoder.ts)
- [mem0-ts/src/oss/src/memory/index.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/memory/index.ts)
- [mem0/reranker/sentence_transformer_reranker.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/sentence_transformer_reranker.py)
- [mem0/memory/main.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/memory/main.py)
- [mem0/reranker/cohere_reranker.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/cohere_reranker.py)
- [mem0/reranker/huggingface_reranker.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/huggingface_reranker.py)
- [mem0/reranker/llm_reranker.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/llm_reranker.py)
- [integrations/claude-code-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/claude-code-plugin/core/memory_core.py)
- [integrations/codex-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/codex-plugin/core/memory_core.py)
- [mem0-ts/src/oss/src/utils/factory.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/utils/factory.ts)
- [integrations/cursor-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/cursor-plugin/core/memory_core.py)
- [integrations/agent-plugin-core/python/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/agent-plugin-core/python/memory_core.py)
- [integrations/antigravity-plugin/core/memory_core.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/antigravity-plugin/core/memory_core.py)
- [mem0/reranker/zero_entropy_reranker.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/zero_entropy_reranker.py)
- [mem0-ts/src/oss/src/rerankers/cohere.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cohere.ts)
- [mem0-ts/src/oss/src/rerankers/llm.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/llm.ts)
- [mem0/reranker/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/__init__.py)
- [mem0-ts/src/oss/src/rerankers/zeroentropy.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/zeroentropy.ts)
- [mem0/utils/factory.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/utils/factory.py)
- [mem0/configs/rerankers/__init__.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/__init__.py)
- [integrations/hermes-plugin-mem0/_backend.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/hermes-plugin-mem0/_backend.py)
- [integrations/openclaw/recall.ts](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/integrations/openclaw/recall.ts)
- [mem0/utils/scoring.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/utils/scoring.py)
- [mem0/configs/rerankers/config.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/config.py)
- [mem0/configs/rerankers/huggingface.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/huggingface.py)
- [mem0/configs/rerankers/sentence_transformer.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/sentence_transformer.py)
- [mem0/configs/rerankers/zero_entropy.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/zero_entropy.py)
- [mem0/configs/rerankers/cohere.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/cohere.py)
- [mem0/configs/rerankers/llm.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/llm.py)
- [mem0/vector_stores/vertex_ai_vector_search.py](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/vector_stores/vertex_ai_vector_search.py)
</details>

## Overview

Reranking models refine initial memory retrieval candidates by scoring query-document relevance through specialized neural architectures, cloud APIs, and language model evaluators. Positioned downstream of vector and keyword searches across both Python and TypeScript runtimes, the reranking subsystem elevates high-precision matches before results are returned to agent pipelines.

Sources: [mem0/reranker/cohere_reranker.py:16-36](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/cohere_reranker.py#L16-L36), [mem0/reranker/sentence_transformer_reranker.py:21-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/sentence_transformer_reranker.py#L21-L51), [mem0-ts/src/oss/src/utils/factory.ts:217-242](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/utils/factory.ts#L217-L242)

## Reranker Interface and Factory Integration

### TypeScript Reranker Implementation and Result Data Structures

The [Typescript Core](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/typescript-core/typescript-core) defines the contract for search rerankers via the `Reranker` interface and the `RerankResult` data structure. Every concrete provider implementation — including `CrossEncoderReranker`, `CohereReranker`, `LLMReranker`, and `ZeroEntropyReranker` — implements an asynchronous `rerank` method accepting a query string, an array of candidate document strings, and an optional `topK` constraint.

```typescript
export interface RerankResult {
  index: number;
  rerankScore: number;
}

export interface Reranker {
  rerank(
    query: string,
    documents: string[],
    topK?: number,
  ): Promise<RerankResult[]>;
}
```
Sources: [mem0-ts/src/oss/src/rerankers/cross_encoder.ts:2-3](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cross_encoder.ts#L2-L3), [mem0-ts/src/oss/src/rerankers/cohere.ts:2-3](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cohere.ts#L2-L3)

Each reranking driver handles empty document collections by immediately returning an empty array without making external API calls or invoking local models. When operational failures occur during reranking, drivers execute safe fallback behavior: they catch the error, emit a warning via `console.warn`, assign a fallback relevance score (`0.0` for API and neural rerankers, `0.5` for prompt-based LLM scoring), preserve the original candidate indices, and slice the results to `topK` if specified.

> [!WARNING]
> Rerankers fall back to the original candidate order with neutral scores when runtime execution fails. Consumers should verify whether a returned score of `0.0` or `0.5` represents a genuine relevance metric or a fallback exception recovery path.

Sources: [mem0-ts/src/oss/src/rerankers/cross_encoder.ts:57-96](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cross_encoder.ts#L57-L96), [mem0-ts/src/oss/src/rerankers/cohere.ts:58-86](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cohere.ts#L58-L86), [mem0-ts/src/oss/src/rerankers/llm.ts:37-56](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/llm.ts#L37-L56), [mem0-ts/src/oss/src/rerankers/zeroentropy.ts:54-83](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/zeroentropy.ts#L54-L83)

### Python Reranker Package Exports

The Python search architecture organizes its reranking subsystem around the `BaseReranker` abstract base class and exposes concrete implementations through its package module initialization. Consumers import reranker drivers directly from the module namespace.

| Reranker Class | Module File | Primary Function |
| :--- | :--- | :--- |
| `BaseReranker` | `mem0/reranker/base.py` | Abstract base class defining the standard rerank interface |
| `CohereReranker` | `mem0/reranker/cohere_reranker.py` | Cloud-based reranking via the Cohere API client |
| `HuggingFaceReranker` | `mem0/reranker/huggingface_reranker.py` | Local sequence classification via Hugging Face inference |
| `LLMReranker` | `mem0/reranker/llm_reranker.py` | Prompt-based relevance scoring via language models |
| `SentenceTransformerReranker` | `mem0/reranker/sentence_transformer_reranker.py` | Cross-encoder scoring using Sentence Transformers |
| `ZeroEntropyReranker` | `mem0/reranker/zero_entropy_reranker.py` | ZeroEntropy API-driven relevance reranking |

Sources: [mem0/reranker/__init__.py:5-18](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/__init__.py#L5-L18)

## Cohere API Reranking Driver

### Configuration Settings and Parameters

The Cohere reranking driver is configured using dedicated parameter classes across both runtimes. In Python, `CohereRerankerConfig` inherits from `BaseRerankerConfig` and defines specific attributes for model selection, document text return behavior, and chunking limits. In TypeScript, corresponding options are supplied via the general `RerankerConfig` interface.

| Parameter Name | Python Default | TypeScript Default | Description |
| :--- | :--- | :--- | :--- |
| `model` | `"rerank-v3.5"` | `"rerank-v3.5"` | The Cohere rerank model identifier |
| `return_documents` | `False` | `false` | Whether to return the document texts in the response |
| `max_chunks_per_doc` | `None` | `undefined` | Maximum number of chunks per document |
| `top_k` / `topK` | `None` | `undefined` | Number of top documents to return |

Sources: [mem0/configs/rerankers/cohere.py:8-16](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/cohere.py#L8-L16), [mem0-ts/src/oss/src/rerankers/cohere.ts:5-28](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cohere.ts#L5-L28)

### Client Lifecycle and Peer Loading

Initialization differs between runtimes regarding dependency management and connection handling. The Python driver checks `COHERE_AVAILABLE` during instantiation and immediately raises an `ImportError` if the `cohere` package is missing. It resolves the API key from `config.api_key` or falls back to the `COHERE_API_KEY` environment variable before instantiating `cohere.Client`.

```python
        if not COHERE_AVAILABLE:
            raise ImportError("cohere package is required for CohereReranker. Install with: pip install cohere")
        
        self.config = config
        self.api_key = config.api_key or os.getenv("COHERE_API_KEY")
        if not self.api_key:
            raise ValueError("Cohere API key is required. Set COHERE_API_KEY environment variable or pass api_key in config.")
            
        self.model = config.model
        self.client = cohere.Client(self.api_key)
```
Sources: [mem0/reranker/cohere_reranker.py:26-35](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/cohere_reranker.py#L26-L35)

The TypeScript driver employs a lazy loading pattern via `loadPeer` to import the optional `cohere-ai` peer only when reranking is executed, avoiding mandatory dependency installation for consumers that do not use Cohere.

```typescript
  private async createClient(): Promise<any> {
    const sdk = await loadPeer(
      "cohere-ai",
      "Cohere reranker",
      () => import("cohere-ai"),
    );
    return new sdk.CohereClient({ token: this.apiKey });
  }
```
Sources: [mem0-ts/src/oss/src/rerankers/cohere.ts:44-51](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cohere.ts#L44-L51)

> [!WARNING]
> Both client implementations require a valid Cohere API key. If `COHERE_API_KEY` is omitted from both the runtime configuration and the environment variables, initialization fails with a runtime error.

Sources: [mem0/reranker/cohere_reranker.py:30-32](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/cohere_reranker.py#L30-L32), [mem0-ts/src/oss/src/rerankers/cohere.ts:17-22](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cohere.ts#L17-L22)

### Scoring Behavior and Fallback Execution

When executing `rerank`, the Python driver extracts text content from incoming dictionary objects by inspecting keys in priority order: `'memory'`, `'text'`, `'content'`, or falling back to string conversion of the entire document. It calls `self.client.rerank` with `model`, `query`, `documents`, `top_n`, `return_documents`, and `max_chunks_per_doc`, then maps `result.relevance_score` to each document's `'rerank_score'` field.

```python
            response = self.client.rerank(
                model=self.model,
                query=query,
                documents=doc_texts,
                top_n=top_k or self.config.top_k or len(documents),
                return_documents=self.config.return_documents,
                max_chunks_per_doc=self.config.max_chunks_per_doc,
            )
```
Sources: [mem0/reranker/cohere_reranker.py:65-73](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/cohere_reranker.py#L65-L73)

If the remote Cohere API call raises an exception, both runtimes catch the error, log a warning, and execute fallback logic. They assign a relevance score of `0.0` to all documents while preserving their original relative ordering and applying any requested `top_k` slice.

Sources: [mem0/reranker/cohere_reranker.py:84-93](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/cohere_reranker.py#L84-L93), [mem0-ts/src/oss/src/rerankers/cohere.ts:75-86](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cohere.ts#L75-L86)

## Hugging Face Cross-Encoder Scoring

### Configuration and Model Initialization

The Hugging Face reranker configuration is defined by `HuggingFaceRerankerConfig`, which extends `BaseRerankerConfig` with model defaults, device placement, batch processing limits, and score normalization parameters.

| Option | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `model` | `Optional[str]` | `"BAAI/bge-reranker-base"` | The Hugging Face model identifier to use for reranking |
| `device` | `Optional[str]` | `None` | Device to run the model on (`'cpu'`, `'cuda'`, etc.) |
| `batch_size` | `int` | `32` | Batch size for processing documents |
| `max_length` | `int` | `512` | Maximum length for tokenization |
| `normalize` | `bool` | `True` | Whether to normalize scores |

Sources: [mem0/configs/rerankers/huggingface.py:7-17](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/huggingface.py#L7-L17)

In the Python runtime, `HuggingFaceReranker` checks if the `transformers` package is available at import time, raising an `ImportError` if it is missing. During initialization, it automatically selects `"cuda"` if PyTorch detects an available GPU, or falls back to `"cpu"`. It loads both the tokenizer and sequence classification model from the configured model ID, moves the model to the target device, and puts it into evaluation mode.

```python
        if self.config.device is None:
            self.device = "cuda" if torch.cuda.is_available() else "cpu"
        else:
            self.device = self.config.device

        self.tokenizer = AutoTokenizer.from_pretrained(self.config.model)
        self.model = AutoModelForSequenceClassification.from_pretrained(self.config.model)
        self.model.to(self.device)
        self.model.eval()
```
Sources: [mem0/reranker/huggingface_reranker.py:30-62](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/huggingface_reranker.py#L30-L62)

The TypeScript implementation (`CrossEncoderReranker`) utilizes a lazy-loading pattern via `load()` to import `@huggingface/transformers` and its native ONNX runtime bindings only when a rerank operation executes. This prevents the ONNX native runtime from being pulled into every `new Memory()` instantiation, avoiding version collisions with FastEmbed.

```typescript
  private load() {
    if (!this.loaded) {
      this.loaded = (async () => {
        const { AutoModelForSequenceClassification, AutoTokenizer } =
          await import("@huggingface/transformers");
        const options: any = {};
        if (this.device) options.device = this.device;
        const model = await AutoModelForSequenceClassification.from_pretrained(
          this.modelId,
          options,
        );
        const tokenizer = await AutoTokenizer.from_pretrained(this.modelId);
        return { model, tokenizer };
      })();
    }
    return this.loaded;
  }
```
Sources: [mem0-ts/src/oss/src/rerankers/cross_encoder.ts:29-50](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cross_encoder.ts#L29-L50)

> [!NOTE]
> In `CrossEncoderReranker`, configuration parameters `batchSize` and `showProgressBar` are accepted strictly for config parity with the Python SDK but operate as no-ops because memory searches rerank candidate sets in a single forward pass.

Sources: [mem0-ts/src/oss/src/rerankers/cross_encoder.ts:12-15](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cross_encoder.ts#L12-L15)

### Logit Extraction and Score Normalization

Cross-encoder models emit unbounded raw logits during inference. To convert these into interpretable relevance scores in the `[0, 1]` range without set-relative distortion, both implementations apply a sigmoid function (`1 / (1 + e^-x)`) when `normalize` is enabled.

```python
    @staticmethod
    def _normalize_scores(scores: List[float]) -> List[float]:
        if not scores:
            return []
        arr = np.asarray(scores, dtype=float)
        return (1.0 / (1.0 + np.exp(-arr))).tolist()
```
Sources: [mem0/reranker/huggingface_reranker.py:63-81](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/huggingface_reranker.py#L63-L81)

In TypeScript, logit rows are extracted from model execution outputs, checked for array structure, and mapped through a local `sigmoid` helper.

```typescript
const sigmoid = (x: number) => 1 / (1 + Math.exp(-x));
```
Sources: [mem0-ts/src/oss/src/rerankers/cross_encoder.ts:4-4](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cross_encoder.ts#L4-L4)

```typescript
      const { logits } = await model(inputs);
      const rows: unknown[] = logits.tolist();

      const scored = rows.map((row, index) => {
        const logit = Array.isArray(row) ? (row[0] as number) : (row as number);
        return {
          index,
          rerankScore: this.normalize ? sigmoid(logit) : logit,
        };
      });
```
Sources: [mem0-ts/src/oss/src/rerankers/cross_encoder.ts:72-81](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/cross_encoder.ts#L72-L81)

> [!WARNING]
> Sigmoid normalization replaces legacy min-max scaling. Min-max scaling forced the lowest-ranked document to `0.0` and collapsed single-document or entirely tied score sets to zero, whereas per-document sigmoid scoring evaluates each item on its own individual merit.

Sources: [mem0/reranker/huggingface_reranker.py:66-76](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/huggingface_reranker.py#L66-L76)

## Sentence Transformer Reranker Pipeline

### Configuration Options and Defaults

The `SentenceTransformerReranker` relies on `SentenceTransformerRerankerConfig` for parameter initialization. If initialized with a dictionary or a generic `BaseRerankerConfig`, the pipeline maps fields to default values.

| Field | Type | Default Value | Description |
| :--- | :--- | :--- | :--- |
| `provider` | `str` | `"sentence_transformer"` | Reranker provider identifier |
| `model` | `Optional[str]` | `"cross-encoder/ms-marco-MiniLM-L-6-v2"` | Cross-encoder model name |
| `device` | `Optional[str]` | `None` | Device specification (`'cpu'`, `'cuda'`, etc., auto-detected if `None`) |
| `batch_size` | `int` | `32` | Batch size for processing documents |
| `show_progress_bar` | `bool` | `False` | Whether to display a progress bar during inference |
| `api_key` | `Optional[str]` | `None` | API key for authentication when applicable |
| `top_k` | `Optional[int]` | `None` | Maximum number of top documents to return |

```python
class SentenceTransformerRerankerConfig(BaseRerankerConfig):
    """
    Configuration class for Sentence Transformer reranker-specific parameters.
    Inherits from BaseRerankerConfig and adds Sentence Transformer-specific settings.
    """

    model: Optional[str] = Field(default="cross-encoder/ms-marco-MiniLM-L-6-v2", description="The cross-encoder model name to use")
    device: Optional[str] = Field(default=None, description="Device to run the model on ('cpu', 'cuda', etc.)")
    batch_size: int = Field(default=32, description="Batch size for processing documents")
    show_progress_bar: bool = Field(default=False, description="Whether to show progress bar during processing")
```
Sources: [mem0/configs/rerankers/sentence_transformer.py:7-16](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/sentence_transformer.py#L7-L16)

```python
# Convert to SentenceTransformerRerankerConfig if needed
if isinstance(config, dict):
    config = SentenceTransformerRerankerConfig(**config)
elif isinstance(config, BaseRerankerConfig) and not isinstance(config, SentenceTransformerRerankerConfig):
    # Convert BaseRerankerConfig to SentenceTransformerRerankerConfig with defaults
    config = SentenceTransformerRerankerConfig(
        provider=getattr(config, 'provider', 'sentence_transformer'),
        model=getattr(config, 'model', 'cross-encoder/ms-marco-MiniLM-L-6-v2'),
        api_key=getattr(config, 'api_key', None),
        top_k=getattr(config, 'top_k', None),
        device=None,  # Will auto-detect
        batch_size=32,  # Default
        show_progress_bar=False,  # Default
    )
```
Sources: [mem0/reranker/sentence_transformer_reranker.py:34-47](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/sentence_transformer_reranker.py#L34-L47)

> [!CAUTION]
> If the `sentence-transformers` package is not installed in the Python environment, `SentenceTransformerReranker.__init__` raises an immediate `ImportError` instructing the user to run `pip install sentence-transformers`.

Sources: [mem0/reranker/sentence_transformer_reranker.py:31-33](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/sentence_transformer_reranker.py#L31-L33)

### Document Extraction and Scoring Workflow

When `rerank` is invoked, the pipeline parses incoming documents by checking for specific text keys (`memory`, `text`, or `content`), falling back to string conversion if none are present. It pairs each extracted document text with the search query, passes the pairs into the `CrossEncoder` model predict method, and sorts the results in descending order by score.

```python
# Extract text content for reranking
doc_texts = []
for doc in documents:
    if 'memory' in doc:
        doc_texts.append(doc['memory'])
    elif 'text' in doc:
        doc_texts.append(doc['text'])  
    elif 'content' in doc:
        doc_texts.append(doc['content'])
    else:
        doc_texts.append(str(doc))

try:
    # Create query-document pairs
    pairs = [[query, doc_text] for doc_text in doc_texts]

    scores = self.model.predict(
        pairs,
        batch_size=self.config.batch_size,
        show_progress_bar=self.config.show_progress_bar,
    )
    if isinstance(scores, np.ndarray):
        scores = scores.tolist()

    # Combine documents with scores
    doc_score_pairs = list(zip(documents, scores))

    # Sort by score (descending)
    doc_score_pairs.sort(key=lambda x: x[1], reverse=True)

```
Sources: [mem0/reranker/sentence_transformer_reranker.py:67-96](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/sentence_transformer_reranker.py#L67-L96)

> [!NOTE]
> If model prediction or score processing raises an exception, the reranker catches the error, logs a warning, and falls back to the original document order with a default `rerank_score` of `0.0`, applying any configured `top_k` slice to the fallback collection.

Sources: [mem0/reranker/sentence_transformer_reranker.py:111-120](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/sentence_transformer_reranker.py#L111-L120)

## LLM Prompt-Based Evaluator

### Configuration and System Prompt Architecture

The LLM-based reranker evaluates document relevance by leveraging language model generations guided by a strict system prompt and deterministic generation parameters. In Python, the `LLMRerankerConfig` class controls model initialization through parameters including provider, model name, API keys, temperature, maximum tokens, and optional nested LLM configurations.

| Parameter | Type | Default Value | Description |
| :--- | :--- | :--- | :--- |
| `model` | `str` | `"gpt-5-mini"` | LLM model identifier for reranking evaluations |
| `api_key` | `Optional[str]` | `None` | Authentication API key for the LLM provider |
| `provider` | `str` | `"openai"` | LLM provider backend identifier |
| `top_k` | `Optional[int]` | `None` | Maximum number of top documents returned after reranking |
| `temperature` | `float` | `0.0` | Sampling temperature for deterministic scoring |
| `max_tokens` | `int` | `100` | Maximum token limit for the LLM response |
| `scoring_prompt` | `Optional[str]` | `None` | Deprecated custom prompt template (used as system message) |
| `llm` | `Optional[Dict[str, Any]]` | `None` | Nested configuration dictionary with provider and config keys |

```python
model: str = Field(
    default="gpt-5-mini",
    description="LLM model to use for reranking"
)
api_key: Optional[str] = Field(
    default=None,
    description="API key for the LLM provider"
)
provider: str = Field(
    default="openai",
    description="LLM provider (openai, anthropic, etc.)"
)
top_k: Optional[int] = Field(
    default=None,
    description="Number of top documents to return after reranking"
)
temperature: float = Field(
    default=0.0,
    description="Temperature for LLM generation"
)
max_tokens: int = Field(
    default=100,
    description="Maximum tokens for LLM response"
)
scoring_prompt: Optional[str] = Field(
    default=None,
    description="Custom prompt template for scoring documents"
)
llm: Optional[Dict[str, Any]] = Field(
    default=None,
    description="Nested LLM configuration with 'provider' and 'config' keys. "
    "Overrides top-level provider/model/api_key when provided.",
)
```
Sources: [mem0/configs/rerankers/llm.py:22-54](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/llm.py#L22-L54)

> [!WARNING]
> Setting a custom `scoring_prompt` triggers a `DeprecationWarning` advising that the configuration attribute is deprecated and will be removed in a future version, with the provided string automatically mapped to the system message.

Sources: [mem0/reranker/llm_reranker.py:64-74](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/llm_reranker.py#L64-L74)

Both Python and TypeScript implementations utilize a system prompt defining an explicit relevance scoring rubric ranging from `0.0` to `1.0`.

```
          LLM Prompt-Based Relevance Scoring Rubric
         ┌───────────────────────────────────────────┐
         │ 1.0 = Perfectly relevant & answers query  │
         │ 0.8-0.9 = Highly relevant with good info │
         │ 0.6-0.7 = Moderately relevant            │
         │ 0.4-0.5 = Slightly relevant              │
         │ 0.0-0.3 = Not relevant                   │
         └───────────────────────────────────────────┘
```
Sources: [mem0/reranker/llm_reranker.py:78-89](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/llm_reranker.py#L78-L89), [mem0-ts/src/oss/src/rerankers/llm.ts:5-14](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/llm.ts#L5-L14)

### Response Parsing and Score Extraction

To prevent prompt injection and flooding attacks, both runtimes truncate queries and document texts to a maximum length of `4000` characters using `_MAX_INPUT_LEN`. The user message combines the safe query and safe document into a structured prompt format before invoking the underlying LLM client.

```python
safe_query = query[: self._MAX_INPUT_LEN]
safe_doc = doc_text[: self._MAX_INPUT_LEN]
user_message = f"Query: {safe_query}\n\nDocument: {safe_doc}"

response = self.llm.generate_response(
    messages=[
        {"role": "system", "content": self._system_prompt},
        {"role": "user", "content": user_message},
    ]
)
```
Sources: [mem0/reranker/llm_reranker.py:138-147](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/llm_reranker.py#L138-L147)

```typescript
private async score(query: string, document: string): Promise<number> {
  const safeQuery = query.slice(0, MAX_INPUT_LEN);
  const safeDoc = document.slice(0, MAX_INPUT_LEN);
  const userMessage = `Query: ${safeQuery}\n\nDocument: ${safeDoc}`;

  const response = await this.llm.generateResponse([
    { role: "system", content: SYSTEM_PROMPT },
    { role: "user", content: userMessage },
  ]);
```
Sources: [mem0-ts/src/oss/src/rerankers/llm.ts:58-66](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/llm.ts#L58-L66)

The score extraction logic parses raw LLM output text by searching for decimal numbers first, falling back to integers, and clamping the resulting floating-point value between `0.0` and `1.0`. If parsing fails or no valid number matches, the system returns a fallback score of `0.5`.

```python
def _extract_score(self, response_text: str) -> float:
    """Extract numerical score from LLM response."""
    # Prefer a decimal, fall back to an integer, then clamp: out-of-range outputs
    # like "2.0"/"5" become 1.0 instead of being mis-parsed into a stray 0/1 digit.
    matches = re.findall(r'-?\d+\.\d+', response_text) or re.findall(r'-?\d+', response_text)

    if matches:
        score = float(matches[0])
        return min(max(score, 0.0), 1.0)  # Clamp between 0.0 and 1.0

    # Fallback: return 0.5 if no valid score found
    return 0.5
```
Sources: [mem0/reranker/llm_reranker.py:94-105](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/llm_reranker.py#L94-L105)

```typescript
private extractScore(responseText: string): number {
  const matches =
    responseText.match(/-?\d+\.\d+/g) || responseText.match(/-?\d+/g);

  if (matches && matches.length > 0) {
    const score = parseFloat(matches[0]);
    return Math.min(Math.max(score, 0.0), 1.0);
  }

  return 0.5;
}
```
Sources: [mem0-ts/src/oss/src/rerankers/llm.ts:76-86](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/llm.ts#L76-L86)

> [!CAUTION]
> Out-of-range numerical outputs such as `"2.0"` or `"5"` are clamped to `1.0` by the clipping function `min(max(score, 0.0), 1.0)`, preventing mis-parsed numbers from corrupting relative document rankings.

Sources: [mem0/reranker/llm_reranker.py:96-102](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/llm_reranker.py#L96-L102), [mem0-ts/src/oss/src/rerankers/llm.ts:81-82](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/llm.ts#L81-L82)

## ZeroEntropy API Reranking Client

### ZeroEntropy Reranker Configuration and Initialization

The ZeroEntropy reranker integration relies on the `zeroentropy` package across both Python and TypeScript runtimes, utilizing the default model identifier `"zerank-1"` when no explicit model is provided. In Python, `ZeroEntropyReranker` validates package availability via an `ImportError` guard and inspects configuration or environment variables for `ZERO_ENTROPY_API_KEY`.

```python
def __init__(self, config):
    """
    Initialize Zero Entropy reranker.

    Args:
        config: ZeroEntropyRerankerConfig object with configuration parameters
    """
    if not ZERO_ENTROPY_AVAILABLE:
        raise ImportError("zeroentropy package is required for ZeroEntropyReranker. Install with: pip install zeroentropy")

    self.config = config
    self.api_key = config.api_key or os.getenv("ZERO_ENTROPY_API_KEY")
    if not self.api_key:
        raise ValueError("Zero Entropy API key is required. Set ZERO_ENTROPY_API_KEY environment variable or pass api_key in config.")

    self.model = config.model or "zerank-1"

    # Initialize Zero Entropy client
    if self.api_key:
        self.client = ZeroEntropy(api_key=self.api_key)
    else:
        self.client = ZeroEntropy()  # Will use ZERO_ENTROPY_API_KEY from environment

```
Sources: [mem0/reranker/zero_entropy_reranker.py:19-41](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/zero_entropy_reranker.py#L19-L41)

In the TypeScript runtime, `ZeroEntropyReranker` employs a lazy peer loading utility to dynamically import `zeroentropy` only upon the first execution, preventing unnecessary dependency requirements for consumers that do not use ZeroEntropy.

```typescript
private async getClient(): Promise<any> {
  if (this.clientInstance) return this.clientInstance;
  if (!this.clientPromise) {
    this.clientPromise = this.createClient();
  }
  this.clientInstance = await this.clientPromise;
  return this.clientInstance;
}

private async createClient(): Promise<any> {
  const sdk = await loadPeer(
    "zeroentropy",
    "ZeroEntropy reranker",
    () => import("zeroentropy"),
  );
  return new sdk.ZeroEntropy({ apiKey: this.apiKey });
}
```
Sources: [mem0-ts/src/oss/src/rerankers/zeroentropy.ts:31-47](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/zeroentropy.ts#L31-L47)

| Parameter | Type | Default | Description |
| :--- | :--- | :--- | :--- |
| `model` | `str` | `"zerank-1"` | Model identifier for ZeroEntropy reranking (`zerank-1`, `zerank-1-small`) |
| `api_key` | `Optional[str]` | `None` | Authentication API key checked against `ZERO_ENTROPY_API_KEY` |
| `top_k` | `Optional[int]` | `None` | Maximum number of top documents returned after reranking |

Sources: [mem0/configs/rerankers/zero_entropy.py:17-28](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/configs/rerankers/zero_entropy.py#L17-L28)

> [!WARNING]
> Both Python and TypeScript implementations require a valid API key, raising a `ValueError` if neither `config.api_key` nor the `ZERO_ENTROPY_API_KEY` environment variable is defined.

Sources: [mem0/reranker/zero_entropy_reranker.py:30-32](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/zero_entropy_reranker.py#L30-L32), [mem0-ts/src/oss/src/rerankers/zeroentropy.ts:15-20](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/zeroentropy.ts#L15-L20)

### Batch Relevance Scoring and Error Fallback

During execution, `rerank` extracts document texts from keys including `'memory'`, `'text'`, or `'content'`, falling back to string conversion if none match. It then submits the query and text array to `client.models.rerank`, maps the resulting relevance scores to each document index, sorts candidates in descending order by score, and applies the `top_k` limit.

```python
def rerank(self, query: str, documents: List[Dict[str, Any]], top_k: int = None) -> List[Dict[str, Any]]:
    """
    Rerank documents using Zero Entropy's rerank API.

    Args:
        query: The search query
        documents: List of documents to rerank
        top_k: Number of top documents to return

    Returns:
        List of reranked documents with rerank_score
    """
    if not documents:
        return documents

    # Extract text content for reranking
    doc_texts = []
    for doc in documents:
        if 'memory' in doc:
            doc_texts.append(doc['memory'])
        elif 'text' in doc:
            doc_texts.append(doc['text'])  
        elif 'content' in doc:
            doc_texts.append(doc['content'])
        else:
            doc_texts.append(str(doc))

    try:
        # Call Zero Entropy rerank API
        response = self.client.models.rerank(
            model=self.model,
            query=query,
            documents=doc_texts,
        )

        # Create reranked results
        reranked_docs = []
        for result in response.results:
            original_doc = documents[result.index].copy()
            original_doc['rerank_score'] = result.relevance_score
            reranked_docs.append(original_doc)

        # Sort by relevance score in descending order
        reranked_docs.sort(key=lambda x: x['rerank_score'], reverse=True)

        # Apply top_k limit
        if top_k:
            reranked_docs = reranked_docs[:top_k]
        elif self.config.top_k:
            reranked_docs = reranked_docs[:self.config.top_k]

        return reranked_docs
```
Sources: [mem0/reranker/zero_entropy_reranker.py:42-93](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/zero_entropy_reranker.py#L42-L93)

```typescript
async rerank(
  query: string,
  documents: string[],
  topK?: number,
): Promise<RerankResult[]> {
  if (documents.length === 0) return [];

  try {
    const client = await this.getClient();
    const response = await client.models.rerank({
      model: this.model,
      query,
      documents,
    });

    const scored: RerankResult[] = response.results.map((result: any) => ({
      index: result.index,
      rerankScore: result.relevance_score,
    }));
    scored.sort((a, b) => b.rerankScore - a.rerankScore);

    const finalTopK = topK || this.topK;
    return finalTopK ? scored.slice(0, finalTopK) : scored;
```
Sources: [mem0-ts/src/oss/src/rerankers/zeroentropy.ts:49-71](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/zeroentropy.ts#L49-L71)

> [!TIP]
> If the ZeroEntropy API call throws an exception, both clients fail open by catching the error, logging a warning, and returning documents in their original order with a fallback `rerank_score` of `0.0` up to the requested `top_k` limit.

Sources: [mem0/reranker/zero_entropy_reranker.py:95-104](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0/reranker/zero_entropy_reranker.py#L95-L104), [mem0-ts/src/oss/src/rerankers/zeroentropy.ts:72-82](https://github.com/blade47/mem0/blob/b7ad69afda6b6ed030347c66d48a13e4de9dec08/mem0-ts/src/oss/src/rerankers/zeroentropy.ts#L72-L82)

## Related

- [Multi-Signal Retrieval](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/python-core/multi-signal-retrieval)
- [Typescript Core](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/technical/typescript-core/typescript-core)


## Sitemap

See the full [sitemap](https://www.doc0.dev/docs/faa36707-7c28-4f69-a18f-700ff61c704e/llms.txt) for all pages in this wiki.
