> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mixpeek.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# MMR (Maximal Marginal Relevance)

> Diversify search results by balancing relevance with result variety

<Frame>
  <img src="https://mintcdn.com/mixpeek/TwtTrae3Fi3EFJ72/assets/retrievers/mmr.svg?fit=max&auto=format&n=TwtTrae3Fi3EFJ72&q=85&s=8fefbc19aa3cb6a1bc6afcd028b5aff8" alt="MMR stage showing diversity-aware result selection" width="1000" height="400" data-path="assets/retrievers/mmr.svg" />
</Frame>

The MMR (Maximal Marginal Relevance) stage diversifies search results by iteratively selecting documents that are both relevant to the query and different from already-selected documents. This prevents redundant results and surfaces a broader range of relevant content.

<Note>
  **Stage Category**: SORT (Reorders with diversity)

  **Transformation**: N documents → top\_k documents (diverse selection)
</Note>

## When to Use

| Use Case                     | Description                            |
| ---------------------------- | -------------------------------------- |
| **Reduce redundancy**        | Avoid showing near-duplicate results   |
| **Exploration**              | Surface different aspects of a topic   |
| **Coverage**                 | Ensure results span multiple subtopics |
| **Recommendation diversity** | Show varied options                    |

## When NOT to Use

| Scenario               | Recommended Alternative |
| ---------------------- | ----------------------- |
| Pure relevance ranking | `rerank`                |
| Simple sorting         | `sort_by_field`         |
| Already diverse corpus | Skip MMR                |
| Very small result sets | Not enough to diversify |

## Parameters

| Parameter               | Type    | Default | Description                                     |
| ----------------------- | ------- | ------- | ----------------------------------------------- |
| `lambda`                | float   | `0.7`   | Balance: 0 = max diversity, 1 = max relevance   |
| `top_k`                 | integer | `25`    | Number of results to return                     |
| `diversity_feature_uri` | string  | *auto*  | Feature URI of the embedding used for diversity |

## Lambda Parameter

The `lambda` parameter controls the relevance-diversity trade-off:

| Lambda | Behavior                            |
| ------ | ----------------------------------- |
| `1.0`  | Pure relevance (no diversification) |
| `0.7`  | Slightly favor relevance            |
| `0.5`  | Balanced (default)                  |
| `0.3`  | Favor diversity                     |
| `0.0`  | Maximum diversity                   |

## Configuration Examples

<CodeGroup>
  ```json Balanced MMR theme={null}
  {
    "stage_name": "mmr",
    "stage_type": "sort",
    "config": {
      "stage_id": "mmr",
      "parameters": {
        "lambda": 0.5,
        "top_k": 10
      }
    }
  }
  ```

  ```json High Diversity theme={null}
  {
    "stage_name": "mmr",
    "stage_type": "sort",
    "config": {
      "stage_id": "mmr",
      "parameters": {
        "lambda": 0.3,
        "top_k": 15
      }
    }
  }
  ```

  ```json Relevance-Focused theme={null}
  {
    "stage_name": "mmr",
    "stage_type": "sort",
    "config": {
      "stage_id": "mmr",
      "parameters": {
        "lambda": 0.8,
        "top_k": 10
      }
    }
  }
  ```

  ```json Custom Diversity Feature theme={null}
  {
    "stage_name": "mmr",
    "stage_type": "sort",
    "config": {
      "stage_id": "mmr",
      "parameters": {
        "lambda": 0.5,
        "top_k": 20,
        "diversity_feature_uri": "mixpeek://text_extractor@v1/multilingual_e5_large_instruct_v1"
      }
    }
  }
  ```
</CodeGroup>

## How MMR Works

The MMR algorithm iteratively selects documents using:

```
MMR = argmax[λ × Sim(doc, query) - (1-λ) × max(Sim(doc, selected_docs))]
```

1. **First Selection**: Choose the most relevant document
2. **Subsequent Selections**: Balance relevance against similarity to already-selected documents
3. **Repeat**: Until top\_k documents are selected

### Example Selection Process

| Iteration | Selected     | Reason                                 |
| --------- | ------------ | -------------------------------------- |
| 1         | Doc A (0.95) | Highest relevance                      |
| 2         | Doc C (0.82) | High relevance, different from A       |
| 3         | Doc E (0.78) | Good relevance, different from A & C   |
| 4         | Doc B (0.90) | Skipped earlier due to similarity to A |

## Output Schema

```json theme={null}
{
  "document_id": "doc_123",
  "content": "Document content...",
  "score": 0.85,
  "mmr": {
    "relevance_score": 0.92,
    "diversity_penalty": 0.07,
    "mmr_score": 0.85,
    "selection_order": 3
  }
}
```

## Performance

| Metric         | Value               |
| -------------- | ------------------- |
| **Latency**    | 10-50ms             |
| **Complexity** | O(N × top\_k)       |
| **Memory**     | O(N) embeddings     |
| **Cost**       | Free (no API calls) |

## Common Pipeline Patterns

### Search + MMR

```json theme={null}
[
  {
    "stage_name": "semantic_search",
    "stage_type": "filter",
    "config": {
      "stage_id": "feature_search",
      "parameters": {
        "searches": [
          { "feature_uri": "mixpeek://text_extractor@v1/multilingual_e5_large_instruct_v1", "query": { "input_mode": "text", "value": "{{INPUT.query}}" }, "top_k": 100 }
        ],
        "final_top_k": 100
      }
    }
  },
  {
    "stage_name": "mmr",
    "stage_type": "sort",
    "config": {
      "stage_id": "mmr",
      "parameters": {
        "lambda": 0.5,
        "top_k": 10
      }
    }
  }
]
```

### Search + Filter + MMR + Enrich

```json theme={null}
[
  {
    "stage_name": "hybrid_search",
    "stage_type": "filter",
    "config": {
      "stage_id": "feature_search",
      "parameters": {
        "searches": [
          { "feature_uri": "mixpeek://text_extractor@v1/multilingual_e5_large_instruct_v1", "query": { "input_mode": "text", "value": "{{INPUT.query}}" }, "top_k": 50 }
        ],
        "final_top_k": 50
      }
    }
  },
  {
    "stage_name": "structured_filter",
    "stage_type": "filter",
    "config": {
      "stage_id": "attribute_filter",
      "parameters": {
        "conditions": {
          "field": "metadata.category",
          "operator": "in",
          "value": ["tech", "science", "business"]
        }
      }
    }
  },
  {
    "stage_name": "mmr",
    "stage_type": "sort",
    "config": {
      "stage_id": "mmr",
      "parameters": {
        "lambda": 0.6,
        "top_k": 15
      }
    }
  },
  {
    "stage_name": "llm_enrichment",
    "stage_type": "enrich",
    "config": {
      "stage_id": "llm_enrich",
      "parameters": {
        "model": "gpt-4o-mini",
        "prompt": "Summarize in one sentence",
        "output_field": "summary"
      }
    }
  }
]
```

### Diverse RAG Pipeline

```json theme={null}
[
  {
    "stage_name": "semantic_search",
    "stage_type": "filter",
    "config": {
      "stage_id": "feature_search",
      "parameters": {
        "searches": [
          { "feature_uri": "mixpeek://text_extractor@v1/multilingual_e5_large_instruct_v1", "query": { "input_mode": "text", "value": "{{INPUT.query}}" }, "top_k": 50 }
        ],
        "final_top_k": 50
      }
    }
  },
  {
    "stage_name": "mmr",
    "stage_type": "sort",
    "config": {
      "stage_id": "mmr",
      "parameters": {
        "lambda": 0.4,
        "top_k": 8
      }
    }
  },
  {
    "stage_name": "summarize",
    "stage_type": "reduce",
    "config": {
      "stage_id": "summarize",
      "parameters": {
        "provider": "openai",
        "model_name": "gpt-4o",
        "prompt": "Synthesize diverse perspectives on: {{INPUT.query}}\n\n{{DOCUMENTS}}"
      }
    }
  }
]
```

## MMR vs Rerank

| Aspect   | MMR                   | Rerank                |
| -------- | --------------------- | --------------------- |
| Goal     | Diversity + relevance | Maximum relevance     |
| Method   | Embedding similarity  | Cross-encoder scoring |
| Speed    | Fast (10-50ms)        | Slower (50-100ms)     |
| Best for | Exploration, coverage | Precision, accuracy   |

## Tuning Lambda

| Use Case         | Recommended Lambda        |
| ---------------- | ------------------------- |
| News aggregation | 0.3-0.4 (high diversity)  |
| Product search   | 0.5-0.6 (balanced)        |
| Technical docs   | 0.7-0.8 (relevance focus) |
| Legal/compliance | 0.8-0.9 (high precision)  |

<Tip>
  Start with lambda=0.5 and adjust based on user feedback. If users complain about redundant results, lower lambda. If they miss relevant results, raise it.
</Tip>

## Error Handling

| Error               | Behavior                    |
| ------------------- | --------------------------- |
| Missing embeddings  | Fall back to relevance sort |
| Empty input         | Return empty                |
| top\_k > input size | Return all documents        |
| Invalid lambda      | Clamp to \[0, 1]            |

## Related

* [Rerank](/retrieval/stages/rerank) - Pure relevance re-scoring
* [Sort Relevance](/retrieval/stages/sort-relevance) - Simple score sorting
* [Sample](/retrieval/stages/sample) - Random diversity
