Skip to content
Changelog

Get diverse search results with the MMR reranker

September 23, 20261 min read

Set reranker=MMRReranker() on Agno's Knowledge, and a help-center search for "I can't sign in to my account" also returns the SSO and two-factor recovery articles. Plain vector search can spend most of its results on three versions of the same password-reset article. The SSO article and two-factor recovery, which the user might have needed, fell off the list.

MMR, short for Maximal Marginal Relevance, picks results one at a time. Each pick discounts the remaining candidates by how similar they are to what it has already chosen, so a repeat of an answer ranks below a different answer.

from agno.knowledge.knowledge import Knowledge
from agno.knowledge.reranker import MMRReranker
 
knowledge = Knowledge(
    vector_db=vector_db,
    reranker=MMRReranker(lambda_mult=0.5),
)

The query "I can't sign in to my account" against six help articles in PgVector, top 4 results, real output. Plain vector search returns Locked out after failed attempts, Password reset email, then two repeats of the password reset article for web and mobile. MMRReranker with lambda_mult 0.5 keeps Locked out after failed attempts and Password reset email, then brings in Sign in with SSO and Recover two-factor access.

lambda_mult sets the trade-off. 1.0 ranks by relevance alone, 0.0 by difference alone, and the default of 0.5 balances the two. MMRReranker fetches five candidates per requested result by default (candidate_multiplier=5), because it needs a pool to choose from. It embeds your query with the same embedder that indexed the documents.

MMR needs an embedding on every search result. PgVector, Qdrant vector and hybrid search, Chroma and LanceDB return one. Milvus, MongoDB, Redis, Valkey and Qdrant keyword search don't, and MMRReranker raises an error there so you never get unreranked results by surprise. Pinecone returns vectors when you build it with return_vectors=True.

Keep the order that Knowledge.search() returns. MMR scores each document against the ones it already chose, so its reranking_score values aren't in descending order, and sorting by them undoes the diversity.

See the cookbook, and learn more about the MMR reranker and reranking in the documentation.

Frequently asked questions

Set reranker=MMRReranker() on your Knowledge. MMR picks results one at a time and discounts each candidate by how similar it is to the ones already picked, so repeats of the same answer drop down the list.

lambda_mult trades relevance against diversity. At 1.0 MMR ranks on relevance only, at 0.0 on difference only, and the default is 0.5.

MMR works on vector databases that return an embedding with each search result, which covers PgVector, Chroma, LanceDB, and Qdrant vector and hybrid search. Milvus, MongoDB, Redis, Valkey and Qdrant keyword search return no embedding, so MMR raises an error there. Pinecone needs return_vectors=True.

No. MMR scores each document against the ones already chosen, so its scores are not in descending order. Use the results in the order Knowledge.search() gives them.

Shipped around the same time