package memory import ( "strings" "git.yeij.top/AskaEth/Cyrene_v2/internal/runtime/embedding" ) // 本文件收拢排名里的**关键词侧**:TF-IDF 打分与用于匹配的索引文本。 // 它们与语义侧(retrieve_semantic.go / retrieve_fallback.go)对称, // 拆开的目的是让 retrieve.go 保持可读(文件 ≤500 行,AGENTS §10)。 // keywordScores 用内存内 TF-IDF 倒排索引(embedding.Index)为每条条目 // 与 query 打分,复用 embedding 包的分词器。得分 // 以最大值为基准归一化到 [0,1],以便与语义 // 得分可比。 func (r *Retriever) keywordScores(items []MemoryItem, query string) map[string]float64 { scores := make(map[string]float64, len(items)) index := embedding.NewIndex[string]() for _, it := range items { index.Add(keywordText(it), it.ID) } hits := index.Search(query) if len(hits) == 0 { return scores } max := hits[0].Score if max <= 0 { return scores } for _, h := range hits { scores[h.ID] = h.Score / max } return scores } // keywordText 是用于关键词匹配的索引文本:content 加 tags。 func keywordText(it MemoryItem) string { if len(it.Tags) == 0 { return it.Content } return it.Content + " " + strings.Join(it.Tags, " ") }