Improve MemFuse recall via hybrid ranking and candidate generation.
Add RRF fusion with English word-level lexical scoring, tiered keyword fetch, and vector margin expansion (0.15/200) to fix pre-rank truncation; wire DashScope embedding bench path and update baseline to 28.8% recall@20. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -25,6 +25,7 @@ import {
|
||||
summarizeMemFuseBench,
|
||||
} from '../memory-v2-memfuse-bench.mjs';
|
||||
import { resolveEmbeddingModuleSpecifier } from '../memory-v2-recall-benchmark.mjs';
|
||||
import { loadMemindEnvFiles } from './memind-runtime-profile.mjs';
|
||||
|
||||
function parseArgs(argv) {
|
||||
const options = {
|
||||
@@ -102,6 +103,12 @@ async function loadEmbedder(specifier) {
|
||||
if (typeof embed !== 'function') {
|
||||
throw new Error(`Embedding module must export embedText, embedQuery or default: ${specifier}`);
|
||||
}
|
||||
if (typeof imported.prefetchEmbedTexts === 'function') {
|
||||
embed.prefetchEmbedTexts = imported.prefetchEmbedTexts.bind(imported);
|
||||
}
|
||||
if (typeof imported.flushEmbeddingCache === 'function') {
|
||||
embed.flushEmbeddingCache = imported.flushEmbeddingCache.bind(imported);
|
||||
}
|
||||
return embed;
|
||||
}
|
||||
|
||||
@@ -168,6 +175,7 @@ function printReport(report) {
|
||||
}
|
||||
|
||||
async function main() {
|
||||
loadMemindEnvFiles(process.cwd());
|
||||
const options = parseArgs(process.argv.slice(2));
|
||||
if (options.help) {
|
||||
usage();
|
||||
@@ -195,6 +203,27 @@ async function main() {
|
||||
const embedText = options.embeddingModule
|
||||
? await loadEmbedder(options.embeddingModule)
|
||||
: null;
|
||||
const prefetchEmbedTexts = embedText?.prefetchEmbedTexts ?? null;
|
||||
|
||||
if (options.embeddingModule) {
|
||||
const resolved = resolveEmbeddingModuleSpecifier(options.embeddingModule);
|
||||
const imported = await import(resolved);
|
||||
if (typeof imported.probeEmbeddingAvailability === 'function') {
|
||||
const probe = await imported.probeEmbeddingAvailability();
|
||||
if (!probe.available) {
|
||||
process.stderr.write(
|
||||
`Embedding probe failed (${probe.reason}).\n` +
|
||||
'Set MEMIND_EMBEDDING_API_KEY / OPENAI_API_KEY, or MEMIND_EMBEDDING_PROVIDER=ollama.\n',
|
||||
);
|
||||
return options.strict ? 1 : 0;
|
||||
}
|
||||
if (!options.quiet) {
|
||||
process.stderr.write(
|
||||
`embedding probe ok: provider=${probe.provider} model=${probe.model} dims=${probe.dimensions}\n`,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let lastScenario = null;
|
||||
const report = await runMemFuseBench({
|
||||
@@ -207,6 +236,7 @@ async function main() {
|
||||
candidateLimit: options.candidateLimit,
|
||||
includeSourceTags: options.sourceTags,
|
||||
embedText,
|
||||
prefetchEmbedTexts,
|
||||
onProgress: options.quiet
|
||||
? null
|
||||
: (event) => {
|
||||
|
||||
Reference in New Issue
Block a user