Documentation
¶
Overview ¶
Package search fuses results from multiple retrieval strategies (vector, keyword) into a single ranking, via either Reciprocal Rank Fusion (Fuse) or convex-combination score fusion (FuseScores), then re-ranks the result.
Index ¶
- Constants
- Variables
- func Dedup(results []store.Scored, limit int) []store.Scored
- func Fuse(lists [][]store.Scored, k int, rrfK float64) []store.Scored
- func FuseScores(lists [][]store.Scored, weights []float64, k int) []store.Scored
- func Rerank(results []store.Scored, now time.Time) []store.Scored
- func RerankTemporal(results []store.Scored, query string, now time.Time, w RerankWeights, ...) []store.Scored
- func RerankWith(results []store.Scored, now time.Time, w RerankWeights) []store.Scored
- type AnchorExtractor
- type RegexAnchorExtractor
- type RerankWeights
- type TimeAnchor
Constants ¶
const DefaultFusionAlpha = 0.5
DefaultFusionAlpha is the vector-leg weight in FuseScores; the keyword leg gets 1-alpha. 0.5 weights both legs equally.
const DefaultRRFK = 5.0
DefaultRRFK is the RRF damping constant; larger values flatten the contribution of top ranks. The classic value is 60, but with deep per-leg pools that lets many both-leg candidates outscore a memory ranked first in a single leg (2/(60+20) > 1/(60+0)); a steeper decay keeps single-leg hits dominant. 5 is at the low end of the [2,5] plateau measured on LongMemEval-S and LoCoMo.
const DefaultTemporalBoost = 0.40
Temporal targeting boosts candidates dated near the time a query references ("what did I do three weeks ago") rather than near now, which the monotonic recency factor cannot do. It only fires when the query names a relative time.
DefaultTemporalBoost is the additive bonus a perfectly on-target candidate gets on the [0,1] composite score; it ramps to 0 by 3x the tolerance.
Variables ¶
var DefaultRerankWeights = RerankWeights{Relevance: 0.80, Recency: 0.05, Importance: 0.15}
DefaultRerankWeights is the production composite. Recency is a deliberately light tie-breaker: benchmarking on LongMemEval-S showed that heavier recency weighting buries correct-but-older memories (the gold session is not always the most recent), so relevance dominates and recency only decides near-ties.
Functions ¶
func Dedup ¶
Dedup drops results whose normalized content matches an earlier (higher-ranked) result, keeping the first occurrence. It preserves order and returns at most limit results (limit <= 0 means no cap).
func Fuse ¶
Fuse combines several best-first result lists into one ranking via Reciprocal Rank Fusion: each memory's fused score is the sum over lists of 1/(rrfK + rank), where rank is its 0-based position in that list. Memories are deduplicated by ID. The top k are returned, best-first.
func FuseScores ¶
FuseScores combines best-first result lists by a weighted sum of their min-max-normalized scores (relative score fusion): within each list the scores are scaled so the best is 1 and the worst 0, then each memory's normalized scores are summed, weighted per list. Unlike RRF this preserves score magnitude, so a leg's standout hit outranks one that is middling in both legs. weights align with lists by index; absent weights default to 1. The top k are returned best-first (k <= 0 returns all); ties keep first-seen order.
func RerankTemporal ¶ added in v0.0.4
func RerankTemporal( results []store.Scored, query string, now time.Time, w RerankWeights, ex AnchorExtractor, boost float64, ) []store.Scored
RerankTemporal re-ranks with the composite weights, then — when ex resolves a relative-time reference in query — adds a date-proximity bonus toward (now - anchor) so a candidate dated near the referenced time can climb past a marginally-more-similar one. With no time reference (or no extractor) it is exactly RerankWith. boost <= 0 also degrades to plain composite re-rank.
func RerankWith ¶
RerankWith re-scores a fused result list with a composite of normalized relevance, access recency, and stored importance, then returns it best-first. The input Score is treated as the relevance signal (e.g. an RRF score) and is normalized by the maximum in the set so it mixes sanely with the [0,1] recency/importance factors. Order is stable for equal composite scores.
Types ¶
type AnchorExtractor ¶ added in v0.0.4
type AnchorExtractor interface {
Anchor(query string) (TimeAnchor, bool)
}
AnchorExtractor resolves a query's relative-time reference, if any. The regex implementation is the no-LLM default; an LLM extractor (looser phrasing like "a couple weeks before my trip") can plug in via the same interface.
type RegexAnchorExtractor ¶ added in v0.0.4
type RegexAnchorExtractor struct{}
RegexAnchorExtractor matches common English relative-time phrases, firing only on templated expressions.
func (RegexAnchorExtractor) Anchor ¶ added in v0.0.4
func (RegexAnchorExtractor) Anchor(query string) (TimeAnchor, bool)
Anchor implements AnchorExtractor.
type RerankWeights ¶
type RerankWeights struct {
Relevance, Recency, Importance float64
}
RerankWeights weights the composite ranking signals. Relevance (query similarity) dominates; recency and importance are secondary tie-breakers so a fresh or explicitly-important memory can edge a marginally-more-similar one.
type TimeAnchor ¶ added in v0.0.4
TimeAnchor is a resolved relative-time reference: an answer is expected roughly Days before the query's "now", give or take Tolerance days.