fix(recall): keep only matched atoms and filter evidence by focus entities

This commit is contained in:
2026-02-12 00:05:19 +08:00
parent 9f279d902f
commit 111cd081f6
2 changed files with 80 additions and 15 deletions

View File

@@ -723,18 +723,21 @@ async function locateAndPullEvidence(anchorHits, queryVector, rerankQuery, lexic
// 6g. 收集 L0 atoms + L1 top-1 配对
// ─────────────────────────────────────────────────────────────────
const atomsList = getStateAtoms();
const atomsByFloor = new Map();
for (const atom of atomsList) {
if (typeof atom.floor !== 'number' || atom.floor < 0) continue;
if (!atomsByFloor.has(atom.floor)) atomsByFloor.set(atom.floor, []);
atomsByFloor.get(atom.floor).push(atom);
// 仅保留“真实 dense 命中”的 L0 原子:
// 旧逻辑按 floor 全塞,容易把同层无关原子带进来。
const atomById = new Map(getStateAtoms().map(a => [a.atomId, a]));
const matchedAtomsByFloor = new Map();
for (const hit of (anchorHits || [])) {
const atom = hit.atom || atomById.get(hit.atomId);
if (!atom) continue;
if (!matchedAtomsByFloor.has(hit.floor)) matchedAtomsByFloor.set(hit.floor, []);
matchedAtomsByFloor.get(hit.floor).push({
atom,
similarity: hit.similarity,
});
}
const denseFloorMaxMap = new Map();
for (const a of (anchorHits || [])) {
const cur = denseFloorMaxMap.get(a.floor) || 0;
if (a.similarity > cur) denseFloorMaxMap.set(a.floor, a.similarity);
for (const arr of matchedAtomsByFloor.values()) {
arr.sort((a, b) => b.similarity - a.similarity);
}
const l0Selected = [];
@@ -744,15 +747,15 @@ async function locateAndPullEvidence(anchorHits, queryVector, rerankQuery, lexic
for (const item of reranked) {
const floor = item.floor;
const rerankScore = item._rerankScore || 0;
const denseSim = denseFloorMaxMap.get(floor) || 0;
const floorAtoms = atomsByFloor.get(floor) || [];
for (const atom of floorAtoms) {
// 仅收集该 floor 中真实命中的 L0 atoms
const floorMatchedAtoms = matchedAtomsByFloor.get(floor) || [];
for (const { atom, similarity } of floorMatchedAtoms) {
l0Selected.push({
id: `anchor-${atom.atomId}`,
atomId: atom.atomId,
floor: atom.floor,
similarity: denseSim,
similarity,
rerankScore,
atom,
text: atom.semantic || '',