项目文件夹

文件
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

86 行
3.0 KiB
Go

package rerank
import "sort"
// ProximitySignal scores a candidate by its Random-Walk-with-Restart
// (Personalized PageRank) proximity to the query's strongest seed
// matches. It is the graph-centrality spine of retrieval: where BM25
// answers "does this symbol's text match the query", proximity answers
// "is this symbol structurally central to the code the query is really
// about" — the function the matched seeds call, the type they share, the
// handler they converge on.
//
// The walk is seeded from the top text/vector matches in the candidate
// set (see selectCentralitySeeds) and run over the call/reference graph;
// the stationary distribution concentrates probability on nodes reachable
// from the seeds along many short, high-provenance paths. Seeds score
// near 1.0; their close neighbourhood scores high; unrelated candidates
// decay to 0. Unlike fan-in (raw in-degree) or HITS (global authority),
// proximity is query-personalized — a utility with huge global fan-in
// scores low unless it sits near the query's seeds.
//
// The contribution is the per-candidate centrality precomputed once per
// Rerank in Context.prepare and normalised to [0,1]. When no centrality
// provider is wired (cold graph, no adjacency snapshot) the signal
// degrades cleanly to 0.
type ProximitySignal struct{}
func (ProximitySignal) Name() string { return SignalProximity }
func (ProximitySignal) Contribute(_ string, c *Candidate, ctx *Context) float64 {
if ctx == nil || c == nil || c.Node == nil || ctx.centralityScores == nil {
return 0
}
return ctx.centralityScores[c.Node.ID]
}
// defaultCentralitySeeds caps how many of the strongest candidates seed
// the RWR walk. A small set keeps the walk focused on the query's true
// anchors (and the walk cheap); too many seeds dilute the restart vector
// across loosely related matches.
const defaultCentralitySeeds = 8
// selectCentralitySeeds picks the RWR seed node IDs from a candidate
// batch: the candidates with the best available retrieval rank (text
// rank preferred, vector rank as a fallback), capped at maxSeeds. These
// are the matches we are most confident about; the walk radiates outward
// from them. Deterministic: ties break on node ID.
func selectCentralitySeeds(cands []*Candidate, maxSeeds int) []string {
if maxSeeds <= 0 {
maxSeeds = defaultCentralitySeeds
}
type ranked struct {
id string
rank int
}
const maxInt = int(^uint(0) >> 1)
rs := make([]ranked, 0, len(cands))
for _, c := range cands {
if c == nil || c.Node == nil || c.Node.ID == "" {
continue
}
r := maxInt
if c.TextRank >= 0 && c.TextRank < r {
r = c.TextRank
}
if c.VectorRank >= 0 && c.VectorRank < r {
r = c.VectorRank
}
rs = append(rs, ranked{id: c.Node.ID, rank: r})
}
sort.Slice(rs, func(i, j int) bool {
if rs[i].rank != rs[j].rank {
return rs[i].rank < rs[j].rank
}
return rs[i].id < rs[j].id
})
if len(rs) > maxSeeds {
rs = rs[:maxSeeds]
}
seeds := make([]string, len(rs))
for i, r := range rs {
seeds[i] = r.id
}
return seeds
}