code wiki / (root) / nx_recall_rerank.nx

nx_recall_rerank.nx source

↩ module page · 56 lines · 2392 B

1// nx_recall_rerank.nx -- the SOVEREIGN semantic reranker: score (query, doc) by dense 2// cosine over PPMI-SVD / concept embeddings (nx_cosine_similarity). 3// 4// module: nishi-core.search.recall_rerank 5// depends: nx_tier.nx, nx_cosine_similarity.nx, syscalls.nx 6// capability: CORE_COMPUTE 7// wired_status: LIBRARY (daemon wiring = R2b; embedding source = nx_ppmi_svd / nx_semppmi_build) 8// genealogy_id: salton_1971_smart (vector space) + two_stage_retrieve_then_rerank 9// 10// WHY (3rd-party debt-eating, good form): nx_rag_rerank PUNTS the semantic judgment to 11// an EXTERNAL LLM (Claude now, "Nishi-LLM the destination") -- a non-sovereign crutch. 12// This organ replaces that punt with a sovereign, integer-deterministic, gate- 13// MEASURABLE reranker: the two-stage pattern's stage 2 (retrieve+fuse in R1 -> rerank 14// the shortlist here by joint query-doc semantic similarity). No external dependency, 15// bit-exact reproducible. The fast tier of the reranker; the no-float LLM-reranker 16// (nx_nofloat_llm) is the latency-tolerant escalation tier (R5). 17 18import "nx_tier.nx" 19import "nx_cosine_similarity.nx" 20import "syscalls.nx" 21 22// Semantic score per candidate: signed Q10 cosine(query_emb, doc_emb[c]) over `dim`. 23// doc_embs is a flat ncand*dim matrix (row c = candidate c's embedding). out_cos[c]. 24func rr_semantic_scores(query_emb: *nx_int, dim: nx_int, doc_embs: *nx_int, ncand: nx_int, out_cos: *nx_int) -> nx_int { 25 var c: nx_int = 0 26 while c < ncand { 27 let row: *nx_int = ((doc_embs as i64) + c * dim * 8) as *nx_int 28 out_cos[c] = nx_cosine_similarity(query_emb, dim, row, dim) 29 c = c + 1 30 } 31 return 0 32} 33 34// Order candidate ids by semantic score DESC (ties -> lower id). out_order[ncand]. 35// Selection sort -- the reranked shortlist is small (post-fusion top-N). 36func rr_order_by_cos(cos: *nx_int, ncand: nx_int, out_order: *i64) -> i64 { 37 let used: *u8 = sys_mmap(ncand) 38 var i: i64 = 0 39 while i < ncand { used[i] = 0 as u8; i = i + 1 } 40 var r: i64 = 0 41 while r < ncand { 42 var best: i64 = 0 - 1 43 var j: i64 = 0 44 while j < ncand { 45 if used[j] == (0 as u8) { 46 if best < 0 { best = j } 47 else { if cos[j] > cos[best] { best = j } } 48 } 49 j = j + 1 50 } 51 out_order[r] = best 52 used[best] = 1 as u8 53 r = r + 1 54 } 55 return 0 56}