> ## 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

![MMR stage showing diversity-aware result selection](https://mintcdn.com/mixpeek/TwtTrae3Fi3EFJ72/assets/retrievers/mmr.svg?fit=max\&auto=format\&n=TwtTrae3Fi3EFJ72\&q=85\&s=8fefbc19aa3cb6a1bc6afcd028b5aff8)

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)

## 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

```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"
    }
  }
}
```

## 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": {
        "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_name": "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.

## 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](https://docs.mixpeek.com/docs/retrieval/stages/rerank.md) - Pure relevance re-scoring
* [Sort Relevance](https://docs.mixpeek.com/docs/retrieval/stages/sort-relevance.md) - Simple score sorting
* [Sample](https://docs.mixpeek.com/docs/retrieval/stages/sample.md) - Random diversity


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.