feat(agent): selectable fusion; adopt the measured 0.4/0.6 default weights

BENCHMARKS.md has recorded since the weight sweep that the 0.7/0.3 default is
strictly dominated by 0.4/0.6 over the full LongMemEval haystack, but the
shipping code never adopted it: unified_search and the OpenClaw backend both
passed 0.7/0.3. Re-running the sweep here (500 questions, real MiniLM
embeddings on a GPU) reproduces it — turn-level Hit@1 51.6% vs 44.2%, Hit@5
81.4% vs 79.2%, Hit@10 87.8% vs 85.8%, MRR 0.6430 vs 0.5856 — so both now use
hybrid::DEFAULT_FUSION, which is that operating point and carries the
reasoning. A unit test pins it.

Fusion is also selectable now. hybrid::Fusion is either Weighted { vector,
keyword } or Rrf { k }; hybrid::fuse applies either to one candidate list per
stage, and merge_vector_keyword / hybrid_search delegate to it, so the public
API is unchanged. New HDF5Memory::hybrid_search_with and
hybrid::hybrid_search_fused take a Fusion. Reciprocal rank fusion was
implemented but reachable only as a free function over a linear scan, so it
had never been compared with the weighted sum on equal terms; it is now a mode
in the LongMemEval bench (measurement to follow).

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
This commit is contained in:
osobh
2026-09-19 16:57:51 -07:00
co-authored by Claude Opus 5
parent b23946e62d
commit 29baabbed2
7 changed files with 256 additions and 79 deletions
+20
View File
@@ -2,6 +2,26 @@
## Unreleased
### Retrieval quality
- `clawhdf5-agent`: **the default fusion weights are now the measured ones.**
A sweep of every 0.1 step over the full LongMemEval haystack (500 questions,
real MiniLM embeddings) shows the long-standing `0.7/0.3` default is
*strictly dominated* by `0.4/0.6` — turn-level Hit@1 51.6% vs 44.2%, Hit@5
81.4% vs 79.2%, Hit@10 87.8% vs 85.8%, MRR 0.643 vs 0.586, and better at
session level too. The finding was recorded in `BENCHMARKS.md` but had never
been applied: `unified_search` and the OpenClaw backend both hardcoded
`0.7/0.3`. They now use `hybrid::DEFAULT_FUSION`. **Callers passing weights
to `hybrid_search` explicitly are unaffected** — pass `0.4`/`0.6` (or use
`hybrid_search_with`) to get the tuned behaviour.
- `clawhdf5-agent`: fusion is now selectable. New `hybrid::Fusion`
(`Weighted { vector, keyword }` or `Rrf { k }`), `hybrid::fuse`,
`hybrid::hybrid_search_fused` and `HDF5Memory::hybrid_search_with`.
Reciprocal rank fusion existed but was unreachable from the store, so it had
never been measured against the weighted sum; the LongMemEval bench now has
an `RRF` mode.
## Unreleased
### HDF5 Read Path
- **Selection reads cost what the selection costs.** `read_*_selection` decoded
the *entire* dataset and then picked elements out, so a 64 x 64 window of a