search

package
v0.7.28 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Sep 12, 2026 License: AGPL-3.0 Imports: 8 Imported by: 0

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

View Source
const DefaultFusionAlpha = 0.5

DefaultFusionAlpha is the vector-leg weight in FuseScores; the keyword leg gets 1-alpha. 0.5 weights both legs equally.

View Source
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.

View Source
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 maximum relevance amplification a perfectly on-target candidate gets (score × (1 + boost) at zero distance); it ramps to 0 by 3x the tolerance. Multiplicative so proximity can reorder comparably relevant candidates without letting a date-near but weakly relevant memory displace a strong match.

Variables

View Source
var DefaultRerankWeights = RerankWeights{Relevance: 0.80, Quality: 0.20}

DefaultRerankWeights is the production composite: relevance plus a single normalized quality term. On a freshly-ingested, single-tier corpus every memory has equal salience/confidence/access and uniform recency, so the quality term is constant and ranking reduces to relevance order — the benchmarked behavior is preserved. In real, multi-tier use a corroborated, frequently-recalled durable fact outranks an equally-relevant one-off observation, so low-value bulk memories sink by construction.

Functions

func Dedup

func Dedup(results []store.Scored, limit int) []store.Scored

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

func Fuse(lists [][]store.Scored, k int, rrfK float64) []store.Scored

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

func FuseScores(lists [][]store.Scored, weights []float64, k int) []store.Scored

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 Rerank

func Rerank(results []store.Scored, now time.Time) []store.Scored

Rerank re-scores a fused result list with the default composite weights.

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 — scales each score by a date-proximity factor 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

func RerankWith(results []store.Scored, now time.Time, w RerankWeights) []store.Scored

RerankWith re-scores a fused result list with a composite of normalized relevance, access recency, and effective importance, then returns it best-first (the assessed value when the LLM set one, else stored importance). 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, now time.Time) (TimeAnchor, bool)
}

AnchorExtractor resolves a query's time reference, if any, against the query's "now" (absolute references like "in March" need it). 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 time phrases — relative ("3 weeks ago") and absolute ("in March", "March 14th", "last summer", "in 2025") — firing only on templated expressions.

func (RegexAnchorExtractor) Anchor added in v0.0.4

func (RegexAnchorExtractor) Anchor(query string, now time.Time) (TimeAnchor, bool)

Anchor implements AnchorExtractor. Relative phrases resolve without now; absolute references (month, month+day, season, year) resolve to the most recent past occurrence relative to now and are skipped when now is zero.

type RerankWeights

type RerankWeights struct {
	Relevance, Recency, Importance, Quality float64
}

RerankWeights weights the composite ranking signals. Relevance (query similarity) dominates; the rest are secondary. Quality folds salience (tier+importance), corroboration (confidence), reinforcement (access) and recency into one number (Memory.Quality), and is the production secondary signal; Recency/Importance are retained as separable terms for the tuning bench. Weights need not sum to 1 — only relative ordering matters.

The quality term is relevance-modulated (it scales the candidate's own relevance rather than adding a flat bonus), like the temporal boost: an off-topic memory has little score to amplify, so tier salience reorders comparably-relevant candidates without lifting irrelevant durables into low-signal windows.

type TimeAnchor added in v0.0.4

type TimeAnchor struct {
	Days      int
	Tolerance int
}

TimeAnchor is a resolved relative-time reference: an answer is expected roughly Days before the query's "now", give or take Tolerance days.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL