feat(*): expose the RRF damping constant and rebalance skill source fusion - #290
feat(*): expose the RRF damping constant and rebalance skill source fusion#290ypflll wants to merge 2 commits into
Conversation
RRF_K was a module constant at 60, the value classic RRF uses for TREC-scale runs of ~1000 hits. Skill sources return ~10 hits, where 60 flattens the whole rank ladder to a 15% score spread -- narrower than the 1.0/0.85 gap between source weights. Weight then decides the order outright and a source's internal rank stops mattering: with the shipped settings no EverOS or Hub hit could ever reach the output unless the same skill also surfaced from Local, which contradicts the weighted blend the config docstring describes. Expose it as skill_forge.router.rrf_k and lower the default to 10. That restores the ladder to an 82% spread, so each source's top hit competes on rank, and it keeps the cross-source agreement bonus proportionate: at 60 two rank-10 hits outscored a single rank-1 hit, at 10 they do not. Local's weight tightens to 0.96 so the three sources interleave rather than tier. No retrieval-quality data backs 10 over 60. The change is motivated by the strict-tiering behaviour above, not by a measured improvement. Co-authored-by: Claude (claude-opus-5) <noreply@anthropic.com>
|
Reviewed 3585376 read-only; tests were run in an isolated worktree, this repo's No blocking findings: no correctness defect, all 9 checks green, and both Tiers: [before-merge] fix in this PR - [describe] wording only, but must land Verified sound, so nobody redoes it: the strict-tiering premise holds (at k=60, R1 [before-merge] Stale formula in the file this PR is about R2 [describe] The description's numbers invert under the weights this PR ships R3 [describe] + [follow-up] Existing installs get only half the change R4 [before-merge] Canonical docs still carry the old weight R5 [follow-up] The headline behaviour claim has no test N1 [nit] The commit type is |
The module docstring in fusion.py still stated the formula with k = 60 and reused the name k for the damping constant, which now collides with the output-cap argument of the same name. CONTEXT.md still described Local's source weight as 1.0. Also assert the ordering the shipped config produces instead of only describing it: the interleave held solely in prose, and the value assertion in test_skill_router_defaults gives no signal that slot order moved. docs/architecture/skill_hub_retrieval.svg carries the same stale formula. Left untouched: repository policy excludes SVG assets from commits. Co-authored-by: Claude (claude-opus-5) <noreply@anthropic.com>
|
All six addressed. R1 fusion.py module docstring now writes the formula with rrf_k and flags Thanks for recomputing the numbers -- R2 was a real error in the permanent |
|
Close-out: all six addressed. Re-verified independently on 2cc24c3 rather than
The two follow-ups logged in the description are not blocking: seeding |
Summary
RRF_Kwas a module constant at 60 -- the value classic RRF uses for TREC-scaleruns of ~1000 hits. Skill sources return ~10 hits (
top_k=5xover_fetch_factor=2),and at that list length 60 flattens the entire rank ladder to a 15% score spread:
That 15% ladder is narrower than the 17.6% gap between the old Local (1.0) and
Hub (0.85) weights, so weight decided the order outright and a source's internal
rank stopped mattering. The concrete consequence with the shipped settings:
Local's rank-10 hit (1.0/70 = 0.014286) still outscored Hub's rank-1 hit
(0.85/61 = 0.013934), and over-fetch caps each source at 10 hits, so a run with
disjoint results returned Local's own top-5 verbatim. Neither EverOS nor Hub
could place a hit unless the same skill also surfaced from Local. That
contradicts the weighted blend the
weightsdocstring describes, and it silentlydisabled the EverOS source whose whole purpose is surfacing auto-evolved skills
Local does not have.
Two knobs move here, and they do different jobs:
rrf_k60 -> 10 removes the tiering. It restores the ladder to an 82%spread, so each source's top hit competes on rank. This is the load-bearing
change: at
rrf_k=10with the old weights untouched the sources alreadyinterleave (Local#1, Local#2, EverOS#1, Hub#1, Local#3).
weights.local1.0 -> 0.96 fine-tunes slot order. It narrows thesource-weight gap from 17.6% to 12.9%, which moves EverOS#1 ahead of Local#2.
It does not remove a tier.
Resulting order with two hits per source, asserted in
test_shipped_defaults_interleave_the_three_sources:Lowering
rrf_kalso brings the cross-source agreement bonus back towardproportionate, though it does not fully fix it. At
rrf_k=60a pair of rank-10hits from EverOS+Hub scored (0.9+0.85)/70 = 0.025 against Local rank-1 at
1.0/61 = 0.0164, a 1.52x margin -- two weak agreements beat one strong single
hit. At
rrf_k=10the same pair scores 1.75/20 = 0.0875 against Local rank-1 at0.96/11 = 0.08727, so the margin collapses to 1.003x. The pair still edges
ahead; it no longer dominates. Sizing that bonus deliberately is left as
follow-up work.
No retrieval-quality data backs 10 over 60. The change is motivated by the
strict-tiering behaviour above contradicting the stated design intent, not by a
measured improvement. Reviewers who prefer the old ordering can restore it with
{"skillForge": {"router": {"rrfK": 60, "weights": {"local": 1.0}}}}-- thepoint of the change is that the value is reachable at all.
Type
Verification
Every new test was mutation-checked, so none of them pass vacuously:
rrf_k=self._rrf_kinrouter.pytest_rrf_k_reaches_the_fusionrrf_k=...infactory.pytest_rrf_k_forwarded_from_config,test_rrf_k_defaults_to_config_defaultweights.localback to 1.0test_shipped_defaults_interleave_the_three_sourcesrrf_kdefault back to 60test_shipped_defaults_interleave_the_three_sourcesWithout the first two a dropped hop would silently fall back to the module
default, leaving the config looking effective while doing nothing.
Risk
This changes default behaviour, not just the availability of a knob. Any
deployment running more than one skill source gets a different ordering after
this lands. Single-source deployments are unaffected: with one source RRF is
order-preserving, so neither
rrf_knor the weights change anything.Installs that have already onboarded get only half of it.
init_extension_block_defaultswritesrouter.weightswithsetdefault, so anexisting
config.jsonkeepslocal: 1.0permanently and has norrfKkey atall. Those installs pick up
rrf_k=10from the code default on top of the oldweights, landing on Local#1, Local#2, EverOS#1, Hub#1, Local#3 rather than the
after-table order. Seeding
rrfKduring onboarding is left as follow-up(
over_fetch_factor,dedup_byandtop_kare unseeded too, so this matchesexisting practice).
rrf_merge_weightedandSkillForgeRouterboth acceptrrf_k=Nonemeaning "usethe module default", so existing library callers are untouched. No consumer reads
rrf_scoreas an absolute value, so the ~5.5x magnitude shift crosses nothreshold.
Rollback is config-only: set
skillForge.router.rrfKback to 60 andweights.localback to 1.0. No code redeploy required.docs/architecture/skill_hub_retrieval.svgstill renders the formula with theold constant. Left untouched because repository policy excludes SVG assets from
commits; it needs regenerating separately.
Related Issues
N/A