mirror of
https://github.com/qdrant/qdrant-client.git
synced 2026-09-29 09:28:05 -05:00
* fix(local): match core's MMR tie-breaking Local mode ordered MMR results differently from core whenever two candidates tied exactly, on relevance or on MMR score. The MMR score itself was already correct; the selection rules around it were not: * the first point was seeded from `candidate_ids[0]`, i.e. whatever `search` happened to return first, instead of the most relevant candidate; * `np.argmax` picked the *first* maximum, while core's `max_by_key` returns the *last* one on ties; * pending candidates were kept in an order-preserving list, while core holds them in an `IndexSet` and drops the selected one with `swap_remove`, which moves the last candidate into the freed slot and therefore changes the order candidates are visited in - and so which one wins a tie. Reproduce the three rules in `_mmr`. The divergence was spotted on a MAX_SIM multivector field with DOT, but it is specific to neither: plain dense vectors and EUCLID diverge the same way once an exact tie is constructed. The added congruence tests keep relevance scores distinct on purpose: core orders equally relevant candidates by search order, which is not stable, so only ties in the MMR score can be asserted on. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> * refactor: move utils from collection, move tests * tests: update comments --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>