El benchmark de la memoria fiable determinista · pre-registrado · self-run

El problema de la métrica

Recall@k no distingue una respuesta errónea y segura de un honesto «no lo sé».

Una puntuación simétrica premia a la memoria que responde a todo — incluidas las preguntas que su store no puede sostener. VeriBench puntúa la memoria como la paga un despliegue: NET(λ) = (correctas − λ·erróneas) / n, donde λ es el coste declarado de una respuesta errónea frente a un silencio. Legal y médico operan a λ alto; el brainstorming a λ bajo. Un solo número, barrido en λ ∈ {1, 2, 5, 10} — fijado antes de cualquier ejecución.

Sin juez LLM, sin red, sin teatro de clasificaciones — un comando, JSON crudos commiteados al repo.

Abstenidohonesto
Prueba sin respuesta
«¿Cuál es el código de acceso de la cámara Meridian?»
el store no puede sostener una respuesta — una memoria sin floor devuelve igualmente el vecino más próximo.
VeriBench cobra esa respuesta −λ; la abstención cuesta 0.
§01Por qué un benchmark nuevo

Los benchmarks de memoria miden cuánto vuelve. Ninguno pone precio a lo que vuelve mal.

En la mitad respondible de un corpus, una memoria con gate y un vector store crudo recuperan casi idéntico — recall@k no ve diferencia. La diferencia aparece en las preguntas que el store no puede responder: una memoria sin floor de abstención devuelve igualmente su vecino más próximo, con plena confianza. En producción eso es una respuesta fabricada; en un benchmark simétrico es invisible.

NET(λ) la hace visible por construcción: una respuesta correcta gana +1, una errónea cuesta λ, el silencio no cuesta nada. La exactitud de equilibrio es λ/(1+λ) — el mismo umbral al que la perilla SLA de Verimem ajusta el store. El benchmark mide el store exactamente en el número con que el operador lo ajusta.

§02Protocolo — fijado antes de los números

01Pre-registrado

Hipótesis, métrica, barrido de λ y condiciones de refutación quedan commiteadas en PREREGISTRATION.md antes de cualquier ejecución. El scoring y el mapeo de resultados se escribieron y testearon primero — un resultado favorable no puede fabricarse eligiendo la métrica a posteriori.

02Corpus externos

Datasets reales que no escribimos nosotros: HaluEval QA y SQuAD v2 (particiones respondibles + sin-respuesta, disjuntas). La corrección es retrieval id-decidible — ningún juez LLM en todo el bucle.

03Controles que deben fallar

Un store barajado debe caer profundamente en negativo (cae: NET(1) = −0.94) y el mismo retrieval con el floor apagado debe fabricar en las sin-respuesta (lo hace: 100 respuestas erróneas). Si un control pasa, el benchmark está roto — ese es el sentido de tenerlo.

04Mismo terreno

Los head-to-head usan el embedder idéntico (multilingual-e5-base) en ambos motores, offline, mem0 en modo raw-store (su LLM nunca se llama — ese eje queda fuera de alcance por declaración, no por omisión).

§03Resultados — HaluEval QA, 300 pruebas (200 respondibles + 100 sin respuesta)
SistemacoverageNET(1)NET(2)NET(5)NET(10)negativo desde λ
Verimem · floor τ=0.8 (default de producto) 1824114 0.62 +0.593 +0.580 +0.540 +0.473 45.5
mem0 2.0.11 · tal como se distribuye (sin floor) 2001000 1.00 +0.333 0.000 −1.000 −2.667 2.0
mem0 + floor atornillado 0.75 (ajustado en la eval) 1660134 0.55 +0.553 +0.553 +0.553 +0.553 nunca
Mismo store, floor OFF (control τ=0) 1921008 0.97 +0.307 −0.027 −1.027 −2.693 1.9
Control barajado (sanidad: debe fallar) 52878 0.97 −0.940 −1.897 −4.767 −9.550 0.02

Léela honestamente, en ambos sentidos: tal como se distribuye, mem0 pasa a negativo más allá de λ=2 — 100 respuestas fabricadas en la mitad sin-respuesta; el default de producto de Verimem sigue positivo hasta λ≈45. Pero un floor puede atornillarse a cualquier motor: con un umbral ajustado en esta eval, mem0 alcanza un +0.553 plano — que supera a nuestro default en λ≥5 en este corpus. Las diferencias que quedan: el motor no incluye ningún floor, el umbral atornillado se eligió en el test set, y la línea plana significa que no responde nada de lo que no esté seguro — coverage 0.55 frente a nuestro 0.62, con 182 frente a 166 correctas en λ=1.

§03bSQuAD v2 — el corpus más duro, dicho claramente
SistemacoverageNET(1)NET(2)NET(5)NET(10)negativo desde λ
Verimem · floor τ=0.8 (default de producto) 1634988 0.71 +0.380 +0.217 −0.273 −1.090 3.3
Verimem · mejor floor 0.85 (ajustado en la eval) 987195 0.35 +0.303 +0.280 +0.210 +0.093 14.0
mem0 2.0.11 · tal como se distribuye (sin floor) 2001000 1.00 +0.333 0.000 −1.000 −2.667 2.0
mem0 + floor atornillado 0.80 (ajustado en la eval) 440256 0.15 +0.147 +0.147 +0.147 +0.147 nunca

Los pasajes distractores de SQuAD comprimen la banda de puntuaciones, y se nota: en el default de producto el crossover baja a λ≈3.3, y mantener NET positivo en λ=10 cuesta coverage 0.35. La abstención es una perilla, no magia — el corpus decide cuánto cuesta la honestidad. Lo incorrecto sería esconder esta tabla.

§04Más allá del retrieval — los ejes que recall@k no puede expresar

AEje de corpus real

Las tablas de arriba: datos externos, respondibles + sin-respuesta, floor encendido vs apagado vs competidor, control barajado. El eje donde la fabricación se convierte en un evento con precio.

BEje causal

Un store que corroboró fielmente una correlación espuria responde a preguntas do(X) con seguridad equivocada — y queda en negativo incluso a λ=1. La procedencia no es causalidad; un benchmark que no las distingue premiará la confusión.

CEje adversarial

Colusión (N identidades, un solo feed) más un sleeper de confianza. Solo una política de confianza de dos canales — corroboración independiente y feedback de resultado — sigue en positivo; cada canal por separado cae exactamente ante uno de los dos ataques. El eje detrás del source-trust de dos canales de Verimem.

§05Ejecútalo — un comando, archivos crudos commiteados

todos los ejes, determinista, cero API keys

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

La spec, la pre-registración y cada JSON crudo de resultados viven en el repo bajo benchmark/veribench/ y benchmark/results/. Los competidores están invitados — el adapter de mem0 está in-tree como ejemplo funcional; haz PR del adapter oficial de tu motor y lo ejecutamos en el mismo terreno.