Maximal Marginal Relevance Diversification
Implement `mmr(query, docs, k, lam)` where `docs` maps id to embedding. Iteratively select the doc maximising `lam * sim(query, d) - (1 - lam) * max(sim(d, s) for s in selected)` (the max term is 0 when nothing is selected yet), using cosine similarity. Ties go to the smaller id. Return up to `k` ids in selection order.
Top-k by relevance alone returns near-duplicates (the same paragraph from three versions of a document), wasting context window on redundant evidence. MMR trades relevance for novelty with one knob: lam = 1 is pure relevance, lam = 0 is pure diversity. Caching pairwise similarities against the selected set keeps it O(k * n) instead of recomputing; in practice you run MMR on a reranked top-50 to top-100, not the whole corpus.
Try it first.
tests.py · 7 passing
docs = {
"a": [1.0, 0.0, 0.0],
"a_dup": [0.99, 0.01, 0.0],
"b": [0.6, 0.8, 0.0],
"c": [0.0, 0.0, 1.0],
}
q = [1.0, 0.2, 0.0]
assert mmr(q, docs, 4, lam=1.0) == sorted(docs, key=lambda d: -_cos(q, docs[d]))
div = mmr(q, docs, 2, lam=0.5)
assert div == ["a_dup", "b"]
assert mmr(q, docs, 2, lam=1.0) == ["a_dup", "a"]
assert set(mmr(q, docs, 10)) == set(docs)
assert mmr(q, {}, 3) == []
assert mmr(q, docs, 0) == []
try:
mmr(q, docs, 2, lam=1.5)
assert False
except ValueError:
passHow do you pick lam? Tune it on an eval set where the metric rewards coverage (for example nugget recall or answer completeness), because nDCG with duplicate-tolerant labels will always pick lam = 1. Alternatives: cluster-then-pick, or dedupe by source document before reranking, which is cheaper and often enough.