Il benchmark della memoria fidata deterministico · pre-registrato · self-run

Il problema della metrica

Recall@k non distingue una risposta sbagliata e sicura da un onesto «non lo so».

Un punteggio simmetrico premia la memoria che risponde a tutto — comprese le domande che il suo store non può supportare. VeriBench misura la memoria come la paga un deployment: NET(λ) = (corrette − λ·sbagliate) / n, dove λ è il costo dichiarato di una risposta sbagliata rispetto a un silenzio. Legale e medicale girano a λ alto; il brainstorming a λ basso. Un numero solo, spazzato su λ ∈ {1, 2, 5, 10} — fissato prima di qualunque run.

Nessun giudice LLM, nessuna rete, nessun teatro da classifica — un comando, JSON grezzi committati nel repo.

Astenutoonesto
Probe senza risposta
«Qual è il codice d'accesso del caveau Meridian?»
lo store non può supportare una risposta — una memoria senza floor restituisce comunque il vicino più prossimo.
VeriBench addebita quella risposta −λ; l'astensione costa 0.
§01Perché un benchmark nuovo

I benchmark di memoria misurano quanto torna indietro. Nessuno prezza ciò che torna indietro sbagliato.

Sulla metà rispondibile di un corpus, una memoria col gate e un vector store grezzo recuperano quasi identico — recall@k non vede differenze. La differenza appare sulle domande a cui lo store non può rispondere: una memoria senza floor di astensione restituisce comunque il suo vicino più prossimo, con piena confidenza. In produzione è una risposta fabbricata; in un benchmark simmetrico è invisibile.

NET(λ) la rende visibile per costruzione: una risposta corretta vale +1, una sbagliata costa λ, il silenzio costa zero. L'accuratezza di pareggio è λ/(1+λ) — la stessa soglia a cui la manopola SLA di Verimem tara lo store. Il benchmark misura lo store esattamente al numero con cui l'operatore lo tara.

§02Protocollo — fissato prima dei numeri

01Pre-registrato

Ipotesi, metrica, sweep di λ e condizioni di refutazione sono committate in PREREGISTRATION.md prima di ogni run. Scoring e mapping degli esiti sono stati scritti e unit-testati prima — un risultato favorevole non si può fabbricare scegliendo la metrica a posteriori.

02Corpora esterni

Dataset reali che non abbiamo scritto noi: HaluEval QA e SQuAD v2 (split rispondibili + senza-risposta, disgiunti). La correttezza è retrieval id-decidibile — nessun giudice LLM in tutto il loop.

03Controlli che devono fallire

Uno store rimescolato deve andare profondamente in negativo (ci va: NET(1) = −0.94) e lo stesso retrieval col floor spento deve fabbricare sulle senza-risposta (lo fa: 100 risposte sbagliate). Se un controllo passa, il benchmark è rotto — è il senso di averlo.

04Stesso terreno

Gli head-to-head usano l'embedder identico (multilingual-e5-base) su entrambi gli engine, offline, mem0 in modalità raw-store (il suo LLM non è mai chiamato — quell'asse è fuori scope per dichiarazione, non per omissione).

§03Risultati — HaluEval QA, 300 probe (200 rispondibili + 100 senza risposta)
SistemacoverageNET(1)NET(2)NET(5)NET(10)negativo da λ
Verimem · floor τ=0.8 (default di prodotto) 1824114 0.62 +0.593 +0.580 +0.540 +0.473 45.5
mem0 2.0.11 · come distribuito (senza floor) 2001000 1.00 +0.333 0.000 −1.000 −2.667 2.0
mem0 + floor bullonato 0.75 (tarato sull'eval) 1660134 0.55 +0.553 +0.553 +0.553 +0.553 mai
Stesso store, floor OFF (controllo τ=0) 1921008 0.97 +0.307 −0.027 −1.027 −2.693 1.9
Controllo rimescolato (sanità: deve fallire) 52878 0.97 −0.940 −1.897 −4.767 −9.550 0.02

Leggila onestamente, in entrambi i versi: come distribuito, mem0 va in negativo oltre λ=2 — 100 risposte fabbricate sulla metà senza-risposta; il default di prodotto di Verimem resta positivo fino a λ≈45. Ma un floor si può bullonare su qualsiasi engine: con una soglia tarata su questa eval, mem0 raggiunge un +0.553 piatto — che batte il nostro default a λ≥5 su questo corpus. Le differenze che restano: l'engine non spedisce alcun floor, la soglia bullonata è stata scelta sul test set, e la linea piatta significa che non risponde a nulla di cui non sia sicuro — coverage 0.55 contro il nostro 0.62, con 182 contro 166 corrette a λ=1.

§03bSQuAD v2 — il corpus più duro, detto in chiaro
SistemacoverageNET(1)NET(2)NET(5)NET(10)negativo da λ
Verimem · floor τ=0.8 (default di prodotto) 1634988 0.71 +0.380 +0.217 −0.273 −1.090 3.3
Verimem · best floor 0.85 (tarato sull'eval) 987195 0.35 +0.303 +0.280 +0.210 +0.093 14.0
mem0 2.0.11 · come distribuito (senza floor) 2001000 1.00 +0.333 0.000 −1.000 −2.667 2.0
mem0 + floor bullonato 0.80 (tarato sull'eval) 440256 0.15 +0.147 +0.147 +0.147 +0.147 mai

I passaggi distrattori di SQuAD comprimono la banda dei punteggi, e si vede: al default di prodotto il crossover scende a λ≈3.3, e tenere NET positivo a λ=10 costa coverage 0.35. L'astensione è una manopola, non magia — è il corpus a decidere quanto costa l'onestà. La mossa sbagliata sarebbe nascondere questa tabella.

§04Oltre il retrieval — gli assi che recall@k non può esprimere

AAsse corpus reale

Le tabelle qui sopra: dati esterni, rispondibili + senza-risposta, floor acceso vs spento vs competitor, controllo rimescolato. L'asse dove la fabbricazione diventa un evento prezzato.

BAsse causale

Uno store che ha corroborato fedelmente una correlazione spuria risponde alle domande do(X) con sicurezza sbagliata — e va in negativo perfino a λ=1. La provenienza non è causalità; un benchmark che non le distingue premierà la confusione.

CAsse avversariale

Collusione (N identità, un solo feed) più uno sleeper fidato. Solo una policy di trust a due canali — corroborazione indipendente e feedback d'esito — resta in positivo; ogni canale singolo cede esattamente a uno dei due attacchi. L'asse dietro il source-trust a due canali di Verimem.

§05Eseguilo — un comando, file grezzi committati

tutti gli assi, deterministico, zero API key

git clone https://github.com/aureliocpr-ctrl/verimem && cd verimem
pip install -e .
python -m benchmark.veribench.run_all   # every axis, one reproducible entrypoint

Spec, pre-registrazione e ogni JSON grezzo dei risultati vivono nel repo sotto benchmark/veribench/ e benchmark/results/. I competitor sono invitati — l'adapter mem0 è in-tree come esempio funzionante; fai PR dell'adapter ufficiale del tuo engine e lo eseguiamo sullo stesso terreno.