retrieve

package
v0.12.1 Latest Latest
Warning

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

Go to latest
Published: Oct 26, 2026 License: MIT Imports: 10 Imported by: 0

Documentation

Overview

learned.go implementa la señal aprendida del ranking: pares query→read. Cuando un agente busca y luego lee un resultado servido, ese par es un juicio de relevancia (click-through). Se acumula por (término, nodo) en la DB y vuelve al ranking como un canal RRF EXTRA — aditivo y acotado por 1/(k+rank), igual que el PRF: puede reforzar, nunca dominar ni desplazar un match fresco.

Package retrieve fusiona varios canales de búsqueda (BM25 sobre mensajes, BM25 sobre nodos del índice y —opcional— vectores) en un único ranking mediante Reciprocal Rank Fusion (RRF); la fecha solo desempata. El agente es el reranker final: rerankea leyendo los hits; acá solo se ordenan candidatos baratos.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func FTSQuery added in v0.4.0

func FTSQuery(raw string) string

FTSQuery convierte un query en lenguaje natural en una query FTS5 robusta: tokeniza, descarta stopwords y, por cada término, emite el literal exacto MÁS el prefijo de su stem (`"stem"*`) para matchear variantes morfológicas (programación↔programar) en ambas direcciones. Todo se combina con OR y BM25 rankea: el documento que matchea más términos (y más raros) sube solo. El término exacto sigue presente, así que el match preciso no se pierde. Devuelve "" si no queda ningún token utilizable.

func RecordRead added in v0.9.0

func RecordRead(store db.Store, nodeID string, now int64)

RecordRead registra un read como señal aprendida. Atribuye el read a la búsqueda MÁS RECIENTE de la ventana que sirvió este nodo (esa es la query que llevó al click), y luego consume el nodo de TODOS los logs que lo sirvieron: así un read repetido, o una ráfaga de queries casi idénticas, cuentan una vez y no inflan el par. Best-effort: nunca rompe el read.

func ServedNodeIDs added in v0.9.0

func ServedNodeIDs(results []Scored) []string

ServedNodeIDs extrae de un resultado fusionado los node IDs del store personal que se le sirvieron al agente: nodos por su ID directo y mensajes por el nodo de su chat. Es el universo contra el que un read posterior puede correlacionar (correlación estricta: solo se aprende lo que fue servido).

Types

type Channel

type Channel struct {
	Name  string
	Items []Item
}

Channel es una lista de items ya ordenada por relevancia (mejor primero).

func VectorChannel

func VectorChannel(store db.Store, query string, top int, allowed []string) (*Channel, error)

VectorChannel arma el canal de embeddings (capa opcional). Devuelve nil si los embeddings están apagados o el backend no responde (la búsqueda sigue con BM25 + estructura). Hace cosine de la query contra los vectores de los nodos y devuelve los top como Items de nodo. allowed (scope) vacío = sin filtro.

type Item

type Item struct {
	Kind      string // "message" | "node"
	ID        string // id del mensaje o del nodo
	ChatID    string
	Title     string // título del chat/nodo (path corto)
	Source    string // codex | claude
	Role      string // rol (hits de mensaje)
	NodeKind  string // project|chat|commit (hits de nodo)
	Content   string // snippet o summary
	Timestamp int64
	// StoreID es el origen del item en lectura federada: "" = store personal,
	// si no el nombre del team store. Participa de itemKey, así un mismo ID local
	// en stores distintos (p.ej. tras promover un chat) no colapsa en uno.
	StoreID string
}

Item es un candidato de cualquier canal, normalizado para fusionar y mostrar.

type Option

type Option func(*config)

Option configura la fusión.

func WithRRFK

func WithRRFK(k float64) Option

WithRRFK fija la constante k de RRF (default 60).

func WithRecencyWeight

func WithRecencyWeight(w float64) Option

WithRecencyWeight fija el peso del boost de recencia (default 0). Ojo con la escala: entre el rank 1 y el 10 de un canal RRF hay ~0.004, así que un peso de 0.02 ya ordena por fecha y no por relevancia. Medido sobre un store real (preguntas con chat correcto conocido), 0.02 llevaba el MRR de 0.76 a 0.15. Sin peso, la fecha igual desempata items de score idéntico.

type Params added in v0.4.0

type Params struct {
	Query   string   // query en lenguaje natural
	Top     int      // máximo de resultados (default 10)
	Roles   []string // roles de mensaje a incluir (ya resueltos; nil = todos)
	Allowed []string // scope: chatIDs visibles (nil = sin filtro)
	Mode    string   // "hybrid" (default) | "keyword" | "semantic"
	Expand  bool     // activar PRF (expansión por relevancia)
	// Learned activa el canal aprendido (pares query→read; solo store personal).
	// Los llamadores no lo activan: medido sobre un store real con preguntas
	// nuevas, bajaba el MRR de 0.76 a 0.52, porque basta un término compartido
	// para que suban los nodos más leídos. La señal se sigue registrando, así un
	// uso más estricto (p.ej. solo con queries casi repetidas) puede retomarla.
	Learned bool
}

Params configura una búsqueda completa.

type Scored

type Scored struct {
	Item
	Score float64
}

Scored es un item con su score fusionado.

func Fuse

func Fuse(channels []Channel, limit int, options ...Option) []Scored

Fuse combina los canales por RRF + recencia y devuelve los top `limit`.

func Search(store db.Store, p Params) ([]Scored, error)

Search corre el pipeline completo de recuperación y devuelve los resultados ya fusionados por RRF (la fecha solo desempata): canales léxicos (BM25 sobre mensajes y nodos, con stem-prefix vía FTSQuery), vectores opcionales, y —si Expand— un canal extra de Pseudo-Relevance Feedback. Centraliza lo que antes estaba duplicado en el CLI y el MCP. El agente sigue siendo el reranker final que lee los hits.

Jump to

Keyboard shortcuts

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