Skip to content
Conduit

skill

MemoryBioRAG

Biomimetic cognitive memory system for AI agents, brain-inspired persistence with synaptic plasticity, hybrid PPMI+SVD vector search, LTP/LTD, and inter-agent shared cortex. Pure Python + SQLite, zero

dennysjmarquez/MemoryBioRAGcommunitylistedunreviewed

Set up

Skills are installed by placing their folder where your agent loads skills.

The download comes from github.com/dennysjmarquez/MemoryBioRAG itself, not from our server, so what you get is exactly what its author published.

Install instructions come from the README

Skills do not use an MCP config. Follow the steps in the README below.

README

synced Oct 25, 2026

BioRAG — Memoria Cognitiva Biomimética y Simbólica para Agentes de IA

Versión Oficial: v35.0 Paradigma: Motor Python + SQLite FTS5. Sin embeddings densos, GPU ni llamadas a APIs externas en el path de búsqueda. Motor: Arquitectura modularizada (18 submódulos core/memory/ + 15 submódulos core/mcp_server/ + fachada delgada) + SQLite FTS5 WAL + PPMI-SVD (100 dimensiones) + espacio semántico de 13 ejes + grafo sináptico Hebbiano + SDM (2048 bits) + calibración conforme + activación ACT-R + Concept Hubs + validación simétrica fail-fast de sustantivos clave + neurona de reordenamiento que aprende sola (29 señales → 6 ocultas → 1 corrección, con piso en la fórmula a mano) + neurona asociativa cerrada de fábrica (5 agujas → fuerza 0–1: ¿dos recuerdos tienen que ver?; examinada, aún no decide en el motor) + enlaces del agente intocables. Idiomas: Español e inglés (stemming bilingüe, expansión simbólica con WordNet, Concept Hubs de 5 ángulos y Domain Dict).

BioRAG es una memoria simbólica persistente para agentes de IA que aborda la pérdida de contexto entre sesiones mediante recuperación híbrida. “Biomimética” describe una inspiración de diseño; no significa que el motor simule literalmente un cerebro humano. Los resultados de rendimiento se limitan a los benchmarks y snapshots indicados.


📊 Métricas de la suite oficial (v33.0 · 2026-10-14 · vigentes en v34.0)

v34.0: con una DB nueva, o sin campeón, la neurona no actúa y estos números se mantienen idénticos (son el piso). Con el campeón ya aprendido sobre la copia del snapshot (despertar_neurona.sh, 500 ciclos), la misma suite da Recall@5 100.00 % · Recall@1 94.06 % (823/875) · MRR 0.964 · FP 0/40, sin ninguna categoría por debajo del piso. Detalle en La Neurona de BioRAG.

v35.0: la QA oficial sale idéntica antes y después de todos los cambios de la v35 (Recall@5 100.00 % · Recall@1 91.89 % · MRR 0.950 · FP 0/40, misma máquina y semilla). Detalle en La Neurona Asociativa.

Cada base tiene su propia neurona. La neurona aprende con los recuerdos de la base donde vive y se guarda dentro de ella. Esta tabla mide una copia del snapshot oficial, que no trae neurona entrenada: por eso muestra la fórmula a mano sola (el piso), aunque tu neurona esté trabajando en tu DB viva. La QA ahora lo dice antes de medir y nombra el parámetro para verla: python scripts/evaluar_qa.py --con-neurona. Detalle en La neurona en la QA.

Evaluación sobre el snapshot congelado oficial canónico (921 casos totales en suite QA):

  • Archivo: snapshots/qa_escape_qcr_20260811.db
  • SHA-256: 104dd2902aaf24c3ce93624492ea95a719acbdcca50f4f6bc123ac8317749796 (Git blob ecc15b7513ff6ddd1356e934a0aa13821337bca4).
  • Composición del dataset: 875 consultas de recuperación evaluadas para Recall y MRR, 40 controles negativos evaluados para tasa de falsos positivos, y 6 casos ambiguos (consultas con etiquetas contradictorias) analizados por separado fuera del denominador de recuperación global.
MétricaResultado observadoContexto y Significado Científico
Recall@5 global100.00% (875/875)100% de cobertura en ventana de trabajo: todo recuerdo gold ingresa al Top-5 del agente sin fallos de recuperación (0 fallos).
Recall@1 (Top-1)91.77% (803/875)Precisión de primer resultado: 803 de 875 casos quedan en primer lugar directo (métrica complementaria observada en benchmark).
MRR (Mean Reciprocal Rank)0.950Posición recíproca promedio ponderada (0.9497 sin redondear; métrica complementaria observada).
Falsos positivos0/40 (0.00%)Calibración conforme efectiva en los 40 controles negativos del benchmark (FP rate observada 0.00%).
Casos ambiguos (contradictorios)6 casos (2 con cobertura parcial)Evaluados por separado del Recall global; 2 casos no cubren al menos una de las etiquetas contradictorias.
Tests unitarios430/430 aprobados (v35.0)Cobertura completa de invariantes, validación pre-DB fail-fast, contratos MCP, normalización, catálogo, las 18 capas de protección de la neurona, el script de despertar, la neurona asociativa, los enlaces del agente intocables y el MCP sin sugerencias de enlace.
Suite Concept Hub5/5 TOP-1 (100.00%)Precisión perfecta en los 5 casos de prueba de puentes asociativos registrados.
Abismo léxico (EXP-Q)3/3 Pool · 2/3 Top-5 · 1/3 Top-13/3 descubiertos en pool de grafo; 2/3 en Top-5 (pos #1 y #4) y 1/3 en Top-1 (pos #1).
Sinónimos · Recall@5 / Recall@1100% (55/55) / 56.36%Cobertura total en Top-5; el 43.64% restante queda entre Top-2 y Top-5.
Por tema · Recall@5 / Recall@1100% (65/65) / 63.08%Cobertura total en Top-5; ordenamiento Top-1 guiado por Jaccard y PPMI-SVD (MRR: 0.772).
Pregunta natural · R@5 / R@1100% (65/65) / 93.85%Alta precisión Top-1 en formulaciones conversacionales.
Cruce de idioma · R@5 / R@1100% (8/8) / 62.50%Rescate bilingüe en Top-5; Top-1 asistido por WordNet y Concept Hubs.
Smoke multicampo en DB localObjetivo #2 → #1Promoción de version_actual_biorag de #2 a #1 por convergencia multicampo.
Tiempo de la evaluación global~877 sEjecución determinista de la suite QA de 921 casos en CPU local (sin GPUs ni APIs).

Aclaración Metodológica — Umbrales de Gate vs. Métricas Observadas:

  • Los umbrales formales del Gate de calidad (_evaluar_gate() en scripts/evaluar_qa.py) exigen: Recall@5 $\ge$ 97.0%, Fallos $\le$ 24, Tasa de Falsos Positivos $\le$ 15.0%.
  • Recall@1 (91.77%) y MRR (0.9497) son métricas complementarias observadas en el benchmark sobre este corpus congelado, no umbrales que el gate imponga ni garantías universales para cualquier consulta arbitraria.
  • R@5 = 100.00% (875/875): Demuestra empíricamente que el conjunto híbrido (FTS5 BM25 + Sustantivos Clave + Grafo Sináptico Hebbiano + PPMI-SVD + Concept Hubs + Reranker Multicampo) logra cobertura completa (875/875) dentro de la ventana Top-5 de trabajo del agente en este corpus evaluado.
  • R@1 = 91.77% (803/875): Refleja la precisión exacta del primer candidato. En tareas con solapamiento léxico directo (literal, pregunta_natural), R@1 supera el 95%–99%. En tareas donde el vocabulario difiere radicalmente (sinonimo 56.36%, por_tema 63.08%), el sistema ubica el recuerdo dentro del Top-5 pero no siempre en Top-1. R@1 representa el área de optimización continua para el desempate fino sin embeddings densos.

🧬 Novedades de la Versión v35.0 — La Neurona Asociativa (sináptica)

En una frase: BioRAG ya tiene su segunda neurona. Mira dos recuerdos y responde una sola pregunta: ¿de verdad tienen que ver? Nace calibrada de fábrica, no aprende de tu memoria, decide en tiempo constante y ya está examinada, también por una persona a mano.

Estado honesto al cerrar la v35. La neurona está construida, calibrada, examinada y cerrada, pero todavía no decide nada dentro del motor:

  • Se probó que pusiera el peso de nacimiento de cada sinapsis (dd85fcf). La búsqueda dio exactamente igual, así que se revirtió (76fe11c).
  • Se probó en una simulación que cortara sinapsis al nacer. Baja el recall con cualquier umbral, así que se descartó.
  • Su lugar natural, ya medido en una copia, es elegir qué asociaciones ve el agente. Queda para la próxima versión, medido antes y después.

La v35 sí cambia dos cosas en el motor (ver Otros cambios de la v35.0):

  • los enlaces que hace el agente ya no los borra nunca el sistema;
  • el servidor MCP ya no le sugiere al agente qué vincular ni qué desvincular.
PiezaEstado en v35.0
Neurona asociativa (core/neurona_asociativa.py)✅ Construida, cerrada (no aprende), con pruebas propias
¿Decide dentro del motor?⏸️ Todavía no. Probado y revertido (peso); probado y descartado (cortar)
Enlaces del agente (manual, manual_v7)✅ Intocables para el sistema; solo desvincular los borra
Sugerencias MCP de vincular / desvincular✅ Quitadas (las herramientas vincular y desvincular siguen)
QA oficial antes y después de todos los cambios✅ Idéntica: Recall@5 100.00 % · Recall@1 91.89 % · MRR 0.950 · FP 0/40 · [GATE] OK
Pruebas✅ 430/430

1. Por qué existe

BioRAG guarda recuerdos y los une con sinapsis (el grafo). En la memoria de Dennys hay 851 recuerdos activos y 13,342 conexiones. Casi todas las crean cinco reglas automáticas:

Regla automáticaSinapsis que creó
sinonimo_explicito (comparten un sinónimo)5,863 (42 %)
pmi_hebbiano (aparecen juntas)2,359
co_ocurrencia2,108
co_nombre (se parecen en el nombre)1,558
co_semantica1,226

Esas reglas unen por coincidencias. Ninguna se pregunta si los dos recuerdos de verdad tienen que ver. Lo medimos de tres formas:

  1. Examen a mano. Dennys juzgó 99 pares de su memoria. Entre las sinapsis automáticas, cerca del 45 % son buenas (margen 32–59 %). Más o menos la mitad es ruido.
  2. El peso de hoy no separa nada. Con el peso que reciben hoy, los 381 enlaces hechos por personas quedan por debajo del resto (AUC 0.271, peor que tirar una moneda).
  3. El único juez hoy es la hormiguita, que le pregunta a Gemini. Es una API externa: cuesta dinero, necesita internet, puede responder distinto ante el mismo par y además se equivoca. De 15 pares que Gemini sacó, Dennys dijo que 6 sí tenían que ver.

En el cerebro, quien decide qué se une con qué es el hipocampo. Funciona por partes:

  • la corteza entorrinal le trae las señales;
  • el giro dentado separa lo que se parece pero no es lo mismo;
  • CA3 guarda la red de asociaciones;
  • CA1 compara y decide.

BioRAG ya tenía la entrada (las señales) y la red (el grafo y la SDM). Le faltaba el juez. Esta neurona es ese juez.

2. Qué tipo de neurona es

PreguntaRespuesta
ArquitecturaUna neurona logística: 5 entradas ("agujas") → Σ → curva sigmoide → fuerza de 0 a 1. Son 6 números en total (un sesgo y 5 pesos).
Qué responde¿Los recuerdos A y B tienen que ver? fuerza ≥ 0.6 = sí con confianza; < 0.6 = dudoso.
De dónde salen sus pesosDe fábrica. Se calibraron a mano sobre 7 memorias públicas muy distintas (noticias en inglés y en español, un diccionario, relatos, código Python, un chat real y la obra de Machado de Assis en portugués). Cada una trae su propia verdad, por ejemplo "mismo tema" o "misma clase".
Qué aprende de tu memoriaNada. Es cerrada: nace calibrada, como las neuronas con las que nacemos. No memoriza tu memoria ni la de nadie.
Qué sí mide de cada memoriaSolo lo necesario para leerla: la rareza de cada raíz, un espacio semántico de 100 dimensiones y dos llaves. Las llaves dicen si en esa memoria el tiempo y las etiquetas coinciden con el texto. Todo se mide solo, sin respuestas correctas.
IdiomasCualquiera. Usa raíces de 7 letras y no tiene listas de palabras de ningún idioma.
Cuánto cuestaCada decisión entre dos recuerdos es de tiempo constante: no depende del tamaño de la memoria. El estado se arma una vez sobre un máximo de 2,000 recuerdos y se rehace cuando la memoria crece un 10 %. Solo usa numpy, sin GPU ni APIs.
Dónde vivecore/neurona_asociativa.py (versión asoc-1). Si algún día la llama el motor, guarda su estado en dos tablas propias: neurona_asociativa_estado y neurona_asociativa_raices.
InterruptorBIORAG_NEURONA_ASOCIATIVA=0 la apaga. En v35 el motor no la llama, así que hoy no cambia nada.

La inspiración biológica (es inspiración, no simulación):

En el cerebroEn la neurona asociativa
Corteza entorrinal (trae la información)Las agujas: lo que se mide del par
Giro dentado (separa lo parecido de lo igual)rareza_max: compartir una pista rara vale más que compartir una palabra común
Corteza (significado)parecido y semantica
Células de tiempo (lo que se vive junto se une)episodio: guardados cerca en el tiempo. Es la aguja que más pesa (×4)
Esquemas de la corteza prefrontaletiquetas: dims compartidas
CA1 (compara y decide)El Σ y la curva: la fuerza
CA3 (la red de asociaciones)El grafo y la SDM que ya existían en BioRAG
Homeostasis (no dejar que algo domine todo)Las llaves: el tiempo y las etiquetas valen solo si en esa memoria coinciden con el texto

3. La fórmula: un piso a mano, calibrado y cerrado

z      = −1 + 2·parecido + 1·semantica + 1·rareza_max + 4·episodio·llave_tiempo + 1·etiquetas·llave_dims
fuerza = 1 / (1 + e^−z)
AgujaPregunta que hacePesoPor qué ese peso
parecido¿Usan las mismas palabras? (coseno tf-idf de raíces)2La señal más estable en las 7 memorias
semantica¿Significan lo mismo? (LSA, 100 dimensiones)1Rescata pares que dicen lo mismo con otras palabras
rareza_max¿Comparten una pista muy rara?1Compartir "nefrona" dice más que compartir "sistema"
episodio¿Se guardaron cerca en el tiempo?4Es lo que más pesa en el cerebro. Solo vale si la llave dice que en esa memoria el tiempo coincide con el texto (en la de Dennys, la llave vale 0.48). Si pasaron más de 7 días reales, no cuenta.
etiquetas¿Comparten dims?1Igual, con su propia llave (0.36 en la de Dennys)

Un par real, paso a paso. Es uno de los enlaces que Dennys puso a mano. Casi no comparten palabras (parecido 0.04), pero comparten una pista rara (0.50) y se guardaron cerca en el tiempo (0.44, ya pasado por la llave). La suma da z = 1.65, y eso da una fuerza de 0.84. A la izquierda se ven las 12 agujas medidas; en la suma entran solo las 5 de la fórmula. La nota de abajo ("top 10") viene de la competencia del experimento, que el motor no usa.

Las llaves: cada memoria decide sola si confía en el reloj y en las etiquetas. La llave compara qué tan parecidos son, por texto, los recuerdos que el reloj (o las etiquetas) junta, contra pares al azar. No usa ninguna respuesta correcta. Si no hay relación, la llave se cierra: con un reloj al azar da casi 0, y una prueba automática lo verifica. Por eso el tiempo cuenta casi entero en un chat (llave 0.74), casi nada en noticias (0.10) y a la mitad en la memoria de Dennys (0.48).

Se midieron 12 agujas. Solo 5 entran en la fórmula, porque las otras 7 no ayudaban en las 7 memorias a la vez. También se descartaron, con pruebas:

  • Competencia (cada recuerdo se queda con sus K socios más fuertes): conserva pares débiles y suelta buenos.
  • Coacceso (recuerdos que se piden juntos): AUC 0.459, no separa.

La neurona tiene una parte que puede aprender, pero queda apagada. Probamos una corrección aprendida sobre la fórmula:

  • con cada memoria por separado ganaba hasta +4.55 puntos;
  • con todas juntas, lo que una ganaba otra lo perdía (la "balanza").

Para servir en cualquier memoria, la fórmula a mano es mejor. La corrección queda en escala 0, por decisión de Dennys: la neurona asociativa no aprende.

4. Cómo se examinó

4.1. En memorias que nunca vio. Para cada memoria se volvió a calibrar la fórmula sin mirarla (con las otras 6) y después se le tomó examen. La AUC es la probabilidad de que un par que sí tiene que ver saque más fuerza que uno que no: 0.5 es azar y 1.0 es perfecto.

MemoriaIdiomaParesSí tienen que verRegla simple (Jaccard)Neurona
noticias (Reuters)en47,17526.5 %0.8340.882
diccionario (WordNet)en40,2252.9 %0.8430.902
relatos (Brown)en27,1955.8 %0.9150.994
código (librería de Python)Python31,2236.9 %0.9000.927
chat real (NPS)en24,74623.2 %0.6270.911
noticias (EFE)es16,3596.4 %0.9150.997
Machado de Assispt25,7828.9 %0.7580.962

Promedio 0.939; el peor caso es 0.882. En las 7 memorias, la neurona supera a la regla simple.

4.2. En la memoria real de Dennys, que tampoco vio. En la DB hay dos jueces: lo que unió una persona o el agente (381 enlaces) y lo que juzgó Gemini.

PruebaPeso de hoyNeurona
Enlaces humanos vs el resto (AUC)0.2710.868
Enlaces humanos vs lo que Gemini sacó (AUC)—0.930
Fuerza típica (mediana): humanos / Gemini confirmó / Gemini sacó—0.75 / 0.45 / 0.40

La huella: para cada aguja, el valor típico de los enlaces humanos (verde) y el de lo que Gemini sacó (rojo). Cuanto más larga la barra, más ayuda esa aguja a distinguirlos. Las que más separan son pistas_raras, mutuo y semantica.

4.3. Examen a mano. Dennys leyó los 100 pares con el texto completo de cada recuerdo y contestó 99.

ResultadoValor
AUC de la fuerza en los 99 pares0.73 (margen 0.62–0.83)
Pares con fuerza ≥ 0.631 «sí» de 42 (74 %)
Pares con fuerza < 0.616 «sí» de 44 (36 %)
Sinapsis que ya existen con fuerza ≥ 0.613 buenas, 1 mala
Sinapsis existentes: neurona vs peso de hoy (AUC)0.77 vs 0.63
Pares que no existen y la neurona propone12 «sí» de 15 (80 %)
Sinapsis automáticas buenas (estimado)~45 % (32–59 %)

La neurona no es perfecta, pero juzga como una persona mucho mejor que el peso de hoy, y encuentra enlaces buenos que hoy no existen.

5. Qué se probó dentro del motor, y por qué hoy no decide

Todo se midió con la QA oficial (875 búsquedas), en copias del snapshot. Nunca se tocó la DB real.

5.1. Poner el peso de nacimiento (experimento 12) → revertido. Con la neurona fijando el peso de cada sinapsis nueva, la QA salió idéntica, incluso repesando todas las sinapsis automáticas de una copia. La búsqueda casi no mira ese peso. Ordenar mejor los enlaces no es buscar mejor. Como no se podía demostrar una mejora, Dennys pidió revertirlo (76fe11c).

5.2. Cortar sinapsis al nacer (experimento 13) → descartado. Se simuló la neurona dejando nacer solo las sinapsis con fuerza suficiente, con la hormiguita apagada:

EscenarioSinapsis automáticasRecall@5Recall@1MRRFallosPares del examen que quedan (buenos / malos)
Hoy (con hormiguita)13,114100.00 %91.89 %0.950026 / 29
Hormiguita apagada15,864100.00 %92.00 %0.951030 / 36
La neurona corta < 0.4010,26199.89 %91.77 %0.949127 / 28
La neurona corta < 0.503,84799.66 %91.77 %0.948318 / 11
La neurona corta < 0.601,68499.43 %91.66 %0.947515 / 8
Sin sinapsis automáticas099.43 %91.77 %0.9485—

Lo que enseñó:

  • El "ruido" ayuda a buscar. Sin las sinapsis automáticas se pierden 5 búsquedas.
  • Cortar baja el recall con cualquier umbral. La regla de BioRAG es que el recall nunca baja, así que la neurona no debe borrar.
  • Apagar la hormiguita no bajó nada (incluso sube un poco el primer puesto: por tema pasa de 63.08 % a 64.62 %). Es una simulación; la hormiguita sigue igual en v35.

5.3. Su lugar: lo que ve el agente (medido, todavía no aplicado). Junto a cada resultado, BioRAG le muestra al agente las asociaciones del recuerdo (el "canal 2"). Eso no toca el ranking. Si la neurona eligiera cuáles mostrar:

Asociaciones mostradasTotalAutomáticasDel agenteRecuerdos sin vecinosPares del examen visibles (buenos / malos)
Hoy3,1732,466691225 / 8
La neurona filtra ≥ 0.502,5881,8766941039 / 1
La neurona filtra ≥ 0.602,0241,30369822510 / 1

La muestra es chica (10 a 13 pares) y parte del examen se eligió con la fuerza de la neurona. Es una señal, no una prueba firme. Por eso queda como el próximo paso, con su propia medición.

6. Por qué debe existir

El mapa muestra lo que funciona hoy (línea llena) y los tres lugares donde la neurona puede entrar (línea punteada violeta). Ninguno está hecho todavía; irán de a uno. El ranking no se toca.

  1. Para quitar a Gemini del grafo. Hoy la limpieza depende de una API externa que cuesta, necesita internet y no siempre responde lo mismo. La neurona es local, gratis, determinista y de tiempo constante. Además separa los enlaces humanos de lo que Gemini sacó con AUC 0.930.
  2. Para que el agente vea asociaciones buenas. Hoy, de los pares del examen que el agente llega a ver, hay más malos que buenos (5 / 8). Con la neurona filtrando, 9 / 1.
  3. Para proponer lo que falta. El 31 % de los enlaces humanos nunca llega a ser candidato de ninguna regla automática. De los pares que la neurona propuso y no existían, Dennys aprobó el 80 %.
  4. Para arreglar vincular_por_sinonimos, la regla que más sinapsis crea (42 %). Con sus 5 mejores por recuerdo, la neurona encuentra 148 de los 381 enlaces humanos (fuerza media 0.711). Un arreglo a mano encontraba 122 (0.536).
  5. Porque cualquier memoria la puede usar desde el día uno. Viene calibrada de fábrica y no necesita QA, ni respuestas correctas, ni entrenamiento. Sirve para una DB vacía de un tercero.

Cada uno de estos pasos irá por separado: un cambio a la vez, con la QA antes y después, y la regla de que el recall nunca baja.

Otros cambios de la v35.0

Los enlaces del agente son intocables (8c7d476). Lo que une el agente (vincular, o vincular_con en aprender/guardar; tipos manual y manual_v7) es una decisión informada: el agente buscó antes de guardar (busqueda_previa). Antes, 9 de esos enlaces habían bajado de 0.5 por el decaimiento. Ahora el sistema los salta en todos los procesos que pueden debilitar o borrar:

ProcesoAntesv35
Decaimiento del pesoBajabaNo los toca
Borrado por peso < 0.05Podía borrarlosNo los toca
Poda LTD guiadaPodía podarlosNo los toca
Hormiguita: prefiltro, cuarentena, borrar o repesarPodía sacarlosNo los toca
desvincular (el agente lo pide)BorraBorra (la decisión sigue siendo del agente)

El MCP ya no sugiere qué vincular ni qué desvincular (0182ad4). Se quitaron los mensajes que empujaban al agente a crear o borrar enlaces. Las herramientas vincular y desvincular siguen en el MCP, y vincular_con en aprender no cambió. El agente decide solo, con lo que encontró en su búsqueda previa.

Pruebas nuevas:

  • tests/test_neurona_asociativa_motor.py (fiel al experimento 11, costo constante, techo de la muestra y que guardar sigue usando los pesos a mano);
  • tests/test_enlaces_del_agente_intocables.py (9 pruebas);
  • tests/test_sin_sugerencias_de_enlace.py (4 pruebas).

Total: 430/430. La QA oficial quedó idéntica antes y después de todos los cambios v35, con el mismo snapshot y la misma semilla (PYTHONHASHSEED=1).

Límites (lo que no está probado)

  • Se calibró con 7 memorias públicas y se examinó con una memoria personal. Faltan más memorias reales.
  • El examen a mano lo hizo una persona con 99 pares. Parte de los pares se eligió con la propia fuerza de la neurona, lo que puede favorecerla.
  • La QA oficial mide si el recuerdo correcto sale en la búsqueda, no la calidad de las asociaciones ni el peso. Por eso el experimento 12 salió "igual".
  • Lo de la hormiguita apagada y el filtro del canal 2 se midió en copias. Ninguno está en el motor.
  • No se comparó todavía agente + BioRAG contra agente + base de datos vectorial.
  • El hipocampo es inspiración, no simulación.

Lo que ya tiene y lo que todavía le falta, medido y no supuesto. El 69 % de los enlaces humanos la neurona los propondría sola; el 31 % restante ni siquiera llega a ser candidato de ninguna regla:

Dónde está todo

QuéDónde
Diseño: el molde y dónde nacen las sinapsisExperimento 10 — Neuronas del motor
Construcción, calibración, exámenes y las 12 figurasExperimento 11 — La neurona asociativa
Peso de nacimiento (revertido)Experimento 12 — La neurona en el motor
Enlaces del agente, ruido, cortar al nacer, canal 2 y cierreExperimento 13 — Enlaces del agente y ruido
La neuronacore/neurona_asociativa.py

Las figuras se redibujan sin ninguna DB:

  • python dibujar.py en la carpeta del experimento 11;
  • python dibujar.py en la carpeta del experimento 13.

Con esto, el tema de la neurona asociativa queda cerrado en la v35.


🌱 Novedades de la Versión v34.1 — La neurona aprende sola de verdad

En una frase: con v34.0, una memoria nueva casi nunca llegaba a encender la neurona. Con v34.1 lo logra en unas 20 consolidaciones, sin perder nada en la QA oficial.

Cuánto tarda en aprender sola (v34.1)

La neurona practica 1 vez por cada consolidación de la memoria (consolidar, sueno o cerrar sesión con contexto_fin). aprender deja el recuerdo en corto plazo y todavía no cuenta: 10 aprender + 1 consolidar = 1 práctica.

En v34.0 cada práctica hacía 2 preguntas a 2 recuerdos: usaba 0.4 s de los 3 s que tiene permitidos. Medido con una memoria nueva que crece (5 recuerdos y 1 consolidación por sesión), en 80 sesiones juntó 20 preguntas de estudio y 7 de control. Necesita 150 y 40, así que nunca se encendía.

v34.1 cambia solo qué practica en cada consolidación:

  1. Usa el tiempo que ya tenía: hasta 8 recuerdos × 7 preguntas, siempre dentro de los mismos 3 s. El costo sigue fijo: no crece con el tamaño de la memoria.
  2. Pregunta a lo ancho: primero la 1.ª pregunta de los 8 recuerdos, luego la 2.ª de los 8... Si los 3 s se acaban (memoria grande, búsquedas más lentas), las preguntas quedan repartidas entre muchos recuerdos distintos y no amontonadas en dos. Así conoce más recuerdos y no se acostumbra a pocos.
  3. Repasa primero lo que le falta: al elegir recuerdos al azar, empieza por el grupo del examen (estudio o control) al que más le faltan preguntas.
Memoria nueva, 5 recuerdos por sesiónv34.0v34.1
Examen listo (150 estudio + 40 control)nuncasesión 16
La neurona empieza a trabajarnuncasesión 21
Sesiones trabajando (de 80)060 (0 retiros)
Tiempo por consolidación0.65 s2.15 s (tope 3 s)

¿Se pierde algo? No. QA oficial sobre una copia del snapshot, con el mismo número de prácticas (561):

R@5R@1MRRFPAgente (MCP) R@1 / R@5
Fórmula a mano (piso)99.8991.66.9490/4092.34 / 99.09
v34.010094.86.9690/4094.97 / 99.54
v34.110094.74.9680/4094.74 / 99.54

La diferencia es 1 caso de 875, el ruido normal entre dos entrenamientos. Ninguna categoría queda por debajo de la fórmula y el GATE da OK.

Lo honesto:

  • Primer intento descartado: el primer diseño (8 × 7 preguntando recuerdo por recuerdo) bajó la QA a R@1 93.26: conocía un tercio menos de recuerdos. De ahí sale "a lo ancho".
  • Memoria muy chica: con solo 2 recuerdos por sesión, el motor duerme los que no se usan y quedan ~25 despiertos. Con tan pocos la fórmula alcanza y la neurona no se enciende, que es lo correcto.
  • Despertar: a igual tiempo hace menos prácticas (cada una usa sus 3 s). despertar_neurona.sh mantiene su default de 500 prácticas (ahora ~22 min con ~900 recuerdos).

Todo el detalle, con las salidas textuales: Experimento 09 — Que aprenda sola de verdad. Pruebas nuevas en tests/test_neurona.py: preferencia por el grupo que falta, recién consolidados primero y nunca dormidos, costo fijo al elegir (DB de 50 o 50 000 recuerdos) y preguntas a lo ancho.


🧠 Novedades de la Versión v34.0 — La Neurona de BioRAG

En una frase: BioRAG ahora tiene una pequeña neurona que aprende sola, mientras se usa, a ordenar mejor los primeros resultados. Empieza siendo exactamente la fórmula a mano y nunca puede quedar por debajo de ella.

La versión v34.0 es mayor porque cambia el comportamiento del ranking: por primera vez una pieza aprendida puede mover el orden de lo que recibe el agente. También cambian tres valores por defecto del servidor MCP (ver Otros cambios de la v34.0). La API no se rompe: las llamadas MCP son las mismas.

1. Por qué existe

La fórmula de BioRAG suma 17 señales ("agujas") con pesos fijos puestos a mano: BM25 vale 0.25, el Concept Hub 0.20, PPMI 0.15… Esos pesos son buenos en promedio, pero la importancia de cada aguja depende del contexto:

  • En una búsqueda literal manda BM25.
  • En una búsqueda por sinónimo, BM25 casi no aporta y pesan más los sinónimos, el PPMI y el grafo.
  • Cuando el agente manda sustantivos_clave, la evidencia en ese campo vale más que una coincidencia suelta en el contenido.

Un peso fijo no puede capturar eso. Por eso la fórmula llegaba al Top-5 en el 100 % de los casos, pero el primer lugar fallaba en las categorías difíciles: sinónimo 56 %, por tema 63 %.

La neurona aprende cuánto vale cada aguja según el contexto y corrige el orden solo cuando está segura.

2. Qué tipo de neurona es

PreguntaRespuesta
ArquitecturaPerceptrón multicapa chico: 29 entradas → 6 neuronas ocultas (tanh) → 1 salida. 186 pesos en total (W 6×29, b 6, v 6).
Qué produceUna corrección residual c(x) que se suma al score de la fórmula. Con c(x) = 0 el motor es idéntico al de siempre: los pesos a mano son el ancla y el piso.
Qué aprendeLearning to rank por lista: entropía cruzada sobre el softmax del top-k, es decir, "que la respuesta correcta quede primera".
De dónde saca las respuestas correctasAutosupervisión. Cuando un recuerdo se consolida, la respuesta correcta se conoce: es ese recuerdo. El recuerdo se hace sus propias preguntas y el motor las responde en silencio.
Cuándo aprendeAl consolidar (cuando un recuerdo pasa de corto a largo plazo: consolidar, sueno o contexto_fin), nunca al buscar. Así la búsqueda no paga el entrenamiento. Una práctica por consolidación, sin importar cuántos aprender hubo antes.
Cómo decide si lo aprendido sirveCampeón y retador: el retador estudia; solo reemplaza al campeón si gana en un examen que nunca estudió (la guardia) y no daña ninguna categoría.
Cuánto cuestaFijo por operación: hasta 8 recuerdos × 7 preguntas por ciclo, siempre dentro de un tope de 3 s, y memoria de examen de tamaño fijo. El costo no crece con el tamaño de la memoria.
Dónde vivecore/memory/neurona.py (la neurona) y core/memory/neurona_examen.py (el autoexamen). Su estado se guarda en la tabla neurona_estado de la misma DB.

La inspiración biológica (es inspiración, no simulación):

En el cerebroEn BioRAG
Dendritas que reciben señalesLas 29 agujas: 17 de la fórmula y 12 de lo que pasó después y de lo que aporta el agente
InterneuronasLas 6 neuronas ocultas, que combinan agujas (por ejemplo: "sinónimo alto + BM25 bajo + vino del agente")
Axón que modulaLa corrección que reordena el top-k
Consolidación durante el sueño (replay del hipocampo)Aprende al consolidar, repasando recuerdos
Primum non nocereEl margen "primero no dañar"
HomeostasisPiso (no bajar de la fórmula) y techo (dejar de entrenar cuando ya no mejora y despertar si algo cambia)

3. Anatomía exacta

Las 17 agujas de la fórmula a mano (las mismas que suma _calcular_score_hibrido):

Aguja (código)Qué mide
BM25 léxico (bm25_norm)Coincidencia de palabras (FTS5), normalizada
dimensiones (dim_score)Coincidencia en los 13 ejes semánticos
palabras en el nombre (concepto_ratio)Cuánto de la consulta está en el nombre del recuerdo
sinónimos (sinonimos_ratio)Cuánto de la consulta está en sus sinónimos
latente / cadena (latcad)Conexiones latentes o en cadena del grafo (la mayor de las dos)
grupo (grupo_score)Pertenencia a un grupo temático
temático (tematico_g)Afinidad temática (solo cuenta si hay evidencia léxica)
asociaciones (asoc)Grado en el grafo sináptico (asociaciones / 20, tope 1)
predicados (pred_score)Roles semánticos (SRL)
PPMI-SVD (ppmi_score)Similitud vectorial PPMI+SVD (100 dims)
Concept Hub (hub_match)Coincidencia por puentes de 5 ángulos
compresión (ncd_score)Distancia de compresión normalizada
episodio (episodio_score)Cercanía temporal (mismo episodio)
campo semántico (campo_score)Atracción del campo semántico
Jensen-Shannon (jsd)Divergencia de distribuciones
match exacto (match_exacto)La consulta es el nombre del recuerdo
sinónimo casi exacto (sin95)Sinónimos ≥ 0.95

Las 12 señales de la vista y del agente (lo que pasa después de la fórmula y el contexto de la búsqueda):

Señal (código)Qué mide
bono de convergencia (bono_conv)Bono multicampo que recibió, normalizado (/0.085, tope 1.5)
evidencia por campo (ev_concepto, ev_sinonimos, ev_sustantivos, ev_contenido)En qué campos del recuerdo apareció la consulta, incluidos los sustantivos_clave
peso sináptico (peso)El peso del recuerdo (0–1)
¿score con peso? (con_peso)Si el score servido incluye el peso (camino MCP)
¿vino del agente? (con_agente)Si la búsqueda trae sustantivos_clave del agente
origen (or_lexico, or_hub, or_no_literal)Por dónde llegó el candidato: léxico aprendido, Concept Hub o un camino no literal
sin rasgos (sin_rasgos)Bandera: candidato inyectado sin pasar por la fórmula (sus 17 agujas van en 0)

4. La matemática, paso a paso

Símbolos

SímboloSignificado
$k$Cuántos resultados ve quien busca: 5 por defecto, 10 por el MCP (tope topk_max = 10)
$x_i \in \mathbb{R}^{29}$Las 29 señales del resultado en el puesto $i$
$\text{score}_i$El score que la fórmula a mano le dio y que se sirvió
$W, b, v$Los pesos de la neurona ($6 \times 29$, $6$, $6$)
$c(x)$La corrección que propone la neurona
$\varepsilon$El margen "primero no dañar"
$y$El puesto donde está la respuesta correcta (en el autoexamen)

1) La escala de la fórmula. El score se lleva a logit, que es la escala natural para sumar evidencias. Por encima de 1 se prolonga en recta para que los matches exactos (que superan 1) no se recorten:

$$ g(s)=\begin{cases}\ln\dfrac{s}{1-s} & s<1-\epsilon_0\[6pt] \ln\dfrac{1-\epsilon_0}{\epsilon_0}+\dfrac{s-(1-\epsilon_0)}{\epsilon_0(1-\epsilon_0)} & s\ge 1-\epsilon_0\end{cases}\qquad \epsilon_0=10^{-4},\quad s\in[10^{-4},,50] $$

2) La corrección de la neurona:

$$ c(x)=v^{\top}\tanh(Wx+b) $$

3) Cómo sirve (reordena el top-k). Cada resultado del top-k recibe una clave, y el top-k se ordena por esa clave de mayor a menor:

$$ \text{clave}_i ;=; g(\text{score}_i);+;c(x_i);+;\varepsilon,(k-i),\qquad i=0,\dots,k-1 $$

El término $\varepsilon(k-i)$ es la ventaja de la fórmula: para subir un puesto, la neurona tiene que ganar por más de $\varepsilon$. Después del reorden, los recuerdos y los scores son los mismos: el score más alto se le asigna al nuevo primero, el segundo al nuevo segundo, y así. Por eso ningún umbral absoluto del motor (abstención, GABA, ráfaga, certeza, falsos positivos) ve números distintos.

Regla de identidad: si la consulta es el nombre de un recuerdo (con "_" = espacio) y la fórmula ya lo puso primero, sigue primero.

4) Cómo aprende. En el autoexamen se conoce el puesto $y$ de la respuesta correcta. La probabilidad que la neurona le da es un softmax sobre el top-k servido:

$$ p_i=\frac{e^{,g(\text{score}i)+c(x_i)}}{\sum{j<k} e^{,g(\text{score}j)+c(x_j)}},\qquad \mathcal{L}=-\frac{1}{n}\sum{\text{casos}}\ln p_y;+;\frac{\lambda}{2}\lVert\theta\rVert^2,\quad \lambda=10^{-3} $$

El gradiente se calcula a mano (retropropagación exacta, con $\partial\mathcal{L}/\partial s_i = p_i-\mathbb{1}[i=y]$) y se aplica con Adam: $\beta_1=0.9$, $\beta_2=0.999$, tasa $0.03$, 30 pasos por ciclo. Si un paso produce NaN, infinito o pesos mayores a $10^3$, se descarta y se vuelve a los pesos anteriores.

5) La guardia (el examen que nunca se estudia). Un recuerdo es de guardia si

$$ \text{sha256}(\text{nombre})_{[0:8]} \bmod 5 = 0 $$

Eso es el 20 %, siempre los mismos y sin azar. Sus preguntas nunca entran al entrenamiento: solo sirven para juzgar.

6) ¿Asciende el retador? (la calibración "primero no dañar"). Se prueban los márgenes $\varepsilon \in {0, 0.25, 0.5, 1, 1.5, 2, 3, 5, 8}$ de menor a mayor. Se elige el menor con el que se cumplen todas estas condiciones:

  1. Cero pérdidas en la guardia: ningún caso de guardia que la fórmula ponía primero deja de estarlo.
  2. Pérdidas totales ≤ 5 % de las ganancias (en primer lugar).
  3. El Top-5 tampoco baja: ningún caso de guardia sale del Top-5 y, en total, salen como mucho el 5 % de los que entran.
  4. Piso por categoría y por camino: ninguna categoría del examen baja en R@1, MRR ni R@5, ni por el camino del agente ni por el crudo.
  5. Gana de verdad: supera a la fórmula, o al campeón actual, en aciertos totales y no empeora la guardia.
  6. Piso contra el campeón (experimento 08): no le quita al campeón saliente lo que ya lograba. En ninguna categoría y camino puede quedar por debajo de él por más de $\tau$ casos, en ninguna de las tres métricas:

$$ m_{\text{retador}}(\text{cat}) ;\ge; m_{\text{campeón}}(\text{cat}) - \tau,\qquad m\in{\text{aciertos #1},\ \textstyle\sum 1/\text{puesto},\ \text{aciertos top-5}},\quad \tau=1 $$

La tolerancia de un caso evita que la neurona se trabe por el ruido de un solo caso; dos o más casos cedidos en una categoría vetan el ascenso.

Si ningún margen cumple, no asciende. Si el campeón deja de cumplir algún día (porque la memoria cambió), se retira y vuelve la fórmula a mano.

7) Anti-memorización:

$$ \text{brecha}=\big(\text{acierto}{\text{estudio}}-\text{acierto}{\text{guardia}}\big){\text{retador}}-\big(\text{acierto}{\text{estudio}}-\text{acierto}{\text{guardia}}\big){\text{fórmula}} $$

Si la brecha supera 0.05, el retador está memorizando lo que estudió en vez de generalizar. Entonces no asciende (aunque un margen grande lo deje "sin dañar") y se reinicia.

8) Techo y despertar. Tras 12 ciclos sin mejorar, la neurona queda "tranquila": solo vigila, con la mitad del costo. Cuando entran 150 preguntas nuevas, despierta y vuelve a estudiar.

5. El ciclo de vida

El autoexamen. Cada recuerdo genera sus propias preguntas, de forma determinista (el azar se siembra con su nombre):

  • variante gramatical ("leccion backup bases datos");
  • typo ("leccion backpu bkase dyatos");
  • sinónimo ("leccion backup base informacion");
  • cruce de idioma ("insight backup repository inputs");
  • pregunta natural ("¿Cómo se hace leccion backup base datos?");
  • por tema ("restaurar probando cada");
  • contenido: como pregunta alguien que no sabe el nombre ("¿copia cada noche?").

No genera preguntas literales ni de dormidos, porque esas el motor ya las resuelve.

Los dos caminos. La neurona practica por los dos caminos reales, alternando:

  • agente: como llega por el MCP recordar. Pide 3× candidatos, aplica convergencia sobre los 10 que verá el agente, usa el peso sináptico y los sustantivos_clave que un agente sacaría de la consulta.
  • crudo: el motor solo, como la QA.

El piso es por categoría y por camino: ninguno de los dos puede bajar.

Desfase 0. Una sola función, vista(), arma lo que ve la neurona desde la página tal como se sirve. El autoexamen guarda esa vista y el servicio corrige esa misma vista, así que lo que se aprende y lo que se usa es idéntico por construcción. Medido: 0 de 289 consultas reales con desfase (la v4 tenía 46.7 %).

6. Las capas de protección

Cada capa cubre una falla concreta de "una neurona viva dentro de una memoria". Cada una tiene su prueba en tests/test_neurona.py.

Falla posibleCapa que la cubre
Aprender de una búsqueda distinta a la que se sirveVista única (desfase 0)
Memorizar en vez de aprenderGuardia del 20 % + regla anti-memorización
Empeorar alguna categoríaPiso por categoría y camino (R@1, MRR, R@5); el campeón que daña se retira
Un retador gana en total cediendo una categoría que el campeón ya resolvíaPiso contra el campeón: más de 1 caso cedido en cualquier categoría y camino veta el ascenso
Cambiar el orden con poca seguridadMargen "primero no dañar" auto-calibrado
Sacar un buen resultado del Top-5 (vista de 10)Piso de R@5 + cero salidas de guardia del Top-5
Cambiar los números que miran los umbralesInvariante de reorden: mismos nodos y mismos scores; si no se cumple, se sirve la página original. Los mapas de score del MCP se permutan igual
Romper búsquedas literalesRegla de identidad
Entrenamiento que diverge (NaN, infinito)Pesos sanos: se descartan y vuelven los anteriores
Errores repetidosDisyuntor: 3 fallas seguidas → esa parte se pausa 1 h; el motor sigue igual
Dos aprendizajes a la vez (sueño + consolidar)Candado no bloqueante: si está ocupada, se salta el ciclo
El autoexamen ensucia logs, accesos o el DMNSilencio por hilo; otro hilo que busca a la vez no queda en silencio
Cambia la fórmula del motor (otra versión)Huella del motor: lo aprendido se descarta y se empieza de cero
Estado corrupto en la DBEstado estricto: si no se puede leer, se arranca limpio
Varios procesos sobre la misma DB (MCP + CLI)Refresco por marca de tiempo
Un recuerdo acapara el examenTope por recuerdo (4) y memoria de tamaño fijo
Recuerdos borrados o dormidos en el examenPurga al azar (20 por ciclo, costo fijo)
DB vacía o con pocos datosSin campeón: el motor responde idéntico al de siempre

7. Resultados (para auditar)

Todo se midió sobre copias del snapshot canónico (nunca sobre el original ni sobre la DB viva) y está versionado en docs/Mi neurona en el sistema/.

QA oficial (921 casos) sobre una copia del snapshot, después de ./scripts/despertar_neurona.sh (500 ciclos, 17 min, 6 ascensos, 0 retiros):

Categoría (n)R@5 piso → neuronaR@1 piso → neuronaMRR piso → neurona
cruce_idioma (8)100 → 10062.50 → 75.00.740 → .875
dormido (65)100 → 100100 → 1001.000 → 1.000
literal (487)100 → 10099.59 → 99.59.998 → .998
por_tema (65)100 → 10063.08 → 78.46.772 → .872
pregunta_natural (65)100 → 10093.85 → 96.92.964 → .985
sinonimo (55)100 → 10056.36 → 60.00.721 → .742
typo (65)98.46 → 10087.69 → 93.85.924 → .964
variante_gramatical (65)100 → 10087.69 → 90.77.932 → .947
GLOBAL (875)99.89 → 100.0091.66 → 94.06.949 → .964
negativos (40)FP 0/40 → 0/40

Piso = la tabla oficial con la fórmula a mano (la misma que da una DB sin campeón). Ninguna categoría baja en ninguna de las tres métricas; GATE OK. Salida textual: docs/Mi neurona en el sistema/experimento_07_la_neurona_escucha/resultados/despertar/.

MediciónResultado
Camino real del agente (recordar por MCP, 875 casos)R@1 92.34 → 94.97, R@5 99.09 → 99.31, MRR .951 → .967. En el primer lugar: +24 casos mejoran, 1 empeora
Corpus nunca visto (python-docs-es, por MCP)Neutra: R@1 45.68 → 45.06, R@5 59.88 → 60.49 (+0 / −1 en el primer lugar)
Desfase (lo que estudia frente a lo que sirve)0 de 289 (la v4 tenía 46.7 %)
Invariantes (120 búsquedas MCP con y sin neurona)0 violaciones: mismos nodos, mismos números, mismos umbrales
Costo por ciclop50 1.6 s, p95 3.5 s, sin importar el tamaño de la memoria
Pruebas407 pruebas unitarias aprobadas (50 de la neurona + 6 del despertar; v34.0: 402)

Lo que NO logra (dicho claro):

  • No es "cero pérdidas" en consultas nunca vistas. Por el camino del agente, 1 caso baja del primer lugar y 1 sale del Top-5 (del 3 al 6), frente a 24 que suben. En python-docs-es pierde 1 caso.
  • En un corpus que nunca vio, es neutra. La gran mejora en ese corpus (R@1 31 → 46 %) vino del arreglo del MCP, no de la neurona.
  • En una DB nueva no hace nada al principio. Necesita juntar un examen mínimo (150 casos de estudio y 40 de guardia) antes de poder ascender un campeón. Mientras tanto el motor es exactamente la fórmula a mano.

8. Cómo se usa

  • Viene encendida y no requiere nada: aprende sola cada vez que se consolida la memoria (consolidar, dormir o cerrar sesión). Guardar con aprender deja el recuerdo en corto plazo; la práctica llega al consolidar.
  • Apagarla del todo: BIORAG_NEURONA=0 (el motor vuelve a ser exactamente la fórmula a mano).
  • Memorias que ya tienen muchos recuerdos: ver Despertar la neurona.
  • Ver su estado: ./scripts/despertar_neurona.sh --estado.
  • Borrar lo aprendido: ./scripts/despertar_neurona.sh --olvidar --si.
VariableDefaultQué controla
BIORAG_NEURONA10 = apagada del todo
BIORAG_NEURONA_NODOS / _PREGUNTAS8 / 7Recuerdos y preguntas por ciclo (topes; el presupuesto de 3 s corta antes si las búsquedas son lentas). Hasta v34.0 eran 2 / 2
BIORAG_NEURONA_PRESUPUESTO_S3.0Tope de tiempo por ciclo (no empieza preguntas que no caben)
BIORAG_NEURONA_TOPK / _TOPK_MAX5 / 10Vista por defecto y tope de la vista
BIORAG_NEURONA_LIMITE_AGENTE10Cuántos ve el agente por el MCP (camino "agente")
BIORAG_NEURONA_MIN_ESTUDIO / _MIN_GUARDIA150 / 40Examen mínimo para empezar a entrenar
BIORAG_NEURONA_MAX_ESTUDIO / _MAX_GUARDIA1200 / 300Tamaño fijo de la memoria de examen
BIORAG_NEURONA_TOPE_POR_NODO4Máximo de casos de un mismo recuerdo
BIORAG_NEURONA_PASOS / _LR / _L230 / 0.03 / 0.001Entrenamiento por ciclo (Adam)
BIORAG_NEURONA_PACIENCIA / _DESPERTAR12 / 150Ciclos sin mejora hasta el techo / preguntas nuevas para despertar
BIORAG_NEURONA_MARGEN(auto)Forzar el margen ε (≥ 0)
BIORAG_NEURONA_TOL_CAMPEON1Casos que un retador puede ceder frente al campeón en una categoría (τ)
BIORAG_NEURONA_PAUSA_S / _REFRESCO_S3600 / 30Pausa del disyuntor / cada cuánto mira si otro proceso escribió

Simbología de los dibujos:

  • 🟡 dorado: las 17 agujas de la fórmula a mano;
  • 🔵 celeste: las 12 señales de la vista y del agente;
  • 🟣 violeta: las 6 neuronas ocultas (tanh), el examen y el estudio;
  • 🟢 verde: la corrección, el ascenso y el campeón en servicio;
  • 🔴 rojo: lo que estaba mal antes (MCP con auto-paráfrasis, desfase de la v4) o un límite (presupuesto de tiempo).

9. La historia: trece experimentos (01–09 esta neurona; 10–13 la neurona asociativa)

#ExperimentoQué se aprendió
01Pesos aprendidosLos pesos a mano no son óptimos: aprenderlos mejora el R@1
02Examen selladoMedir sobre casos nunca vistos; sin eso, una "mejora" puede ser memoria
03Ideas de la conversaciónEn una búsqueda real nadie dice cuál era la respuesta correcta → hace falta autoexamen
04AutoaprendizajeEl recuerdo se pregunta a sí mismo; campeón y retador con guardia
05Neurona cableadaAprende en vivo al consolidar, con costo fijo
06Capas de protección21 modos de falla cubiertos; margen "primero no dañar"
07La neurona escuchaDesfase 0, los dos caminos, vista de 10, piso de R@5; y el camino MCP arreglado
08Piso contra el campeónUn retador ya no puede ganar cediendo una categoría; A/B determinista: en datos reales la regla nunca tuvo que actuar
09Que aprenda sola de verdadv34.1: 1 práctica por consolidación; preguntar a lo ancho dentro de los 3 s. Una DB nueva enciende la neurona en ~20 consolidaciones; la QA queda igual
10Neuronas del motorv35: el molde de las neuronas modulares y el mapa de dónde nacen las sinapsis; se estudió la hormiguita (Gemini)
11La neurona asociativav35: 5 agujas calibradas de fábrica en 7 memorias; AUC 0.88–0.997 en memorias nunca vistas; examen a mano de Dennys AUC 0.73; la parte que aprende queda apagada
12La neurona en el motorv35: poner el peso de nacimiento deja la QA idéntica → revertido
13Enlaces del agente y ruidov35: los enlaces del agente, intocables; el ruido ayuda a buscar; cortar al nacer baja el recall; su lugar es lo que ve el agente. Cierre de la neurona asociativa

Las figuras se regeneran con python "docs/Mi neurona en el sistema/imagenes/generar_figuras.py": los nombres de las señales salen del código y las curvas de los resultados versionados.

Otros cambios de la v34.0

  • MCP recordar: auto-paráfrasis y auto-dimensiones apagadas por defecto. Medido por el camino real del agente, bajaban el recall: con ellas, 39 casos quedaban fuera del Top-5. Se reactivan con BIORAG_MCP_AUTO_PARAFRASIS=1 y BIORAG_MCP_AUTO_DIMS=1, que ahora son deterministas. Las paráfrasis y dimensiones que manda el agente se usan siempre.
  • MCP stdio limpio. Los print() del motor iban al canal JSON-RPC y podían corromper la sesión del IDE: tras 120 vincular, 77 líneas no eran JSON. Ahora van a stderr: 0 líneas corruptas.
  • Sin corte por antigüedad por defecto (BIORAG_STALE_HARD_CUTOFF=0). BioRAG es memoria de largo plazo y no esconde recuerdos por fecha salvo que se pida. Antes el valor era 365, pero nunca llegaba a aplicarse por un JOIN a una tabla mal nombrada; ahora no puede encenderse solo.
  • Nuevo script scripts/despertar_neurona.sh (ver la zona de operaciones).

🚀 Novedades de la Versión v33.0 — Protocolo Cognitivo Simétrico de Sustantivos Clave

La versión v33.0 introduce un cambio arquitectónico y contractual mayor en el subsistema de ingestión y recuperación de BioRAG: la formalización del protocolo cognitivo simétrico de sustantivos_clave con validación anticipada (fail-fast) previa a la base de datos en todas las herramientas MCP del ciclo de vida de la memoria.

🧠 1. El Contrato Cognitivo de sustantivos_clave

En BioRAG, los sustantivos_clave no constituyen un inventario sintáctico o automático de todas las palabras nominales presentes en un texto, sino un anclaje semántico de alto nivel que responde a la pregunta cognitiva fundamental:

"¿De qué conceptos temáticos trata centralmente este recuerdo o esta intención de búsqueda?"

  • Propósito: Anclar los recuerdos en el conectoma asociativo y permitir el cruce de evidencia multicampo (FTS5 + Sustantivos + Grafo + PPMI-SVD).
  • Pauta Cognitiva Recomendada: Entre 2 y 4 términos centrales de alta carga conceptual.
  • Rango Técnico Aceptado: El motor admite un rango más amplio (hasta 10 términos) para acomodar intenciones complejas o dominios con terminología multifacética, preservando la agilidad del agente.
  • Normalización Automática: Los términos se sanean de forma determinista (conversión a minúsculas, eliminación de espacios superfluos, deduplicación preservando orden).

⚖️ 2. Diferenciación Simétrica: Escritura vs. Búsqueda Textual

El motor distingue con rigor matemático la asimetría funcional entre la fase de almacenamiento de conocimiento y la fase de consulta:

OperaciónHerramientas MCP AfectadasRango de Términos ÚnicosJustificación Cognitiva
Escritura / Ingestiónaprender, guardar, agregar_sustantivos2 a 10Un recuerdo persistente requiere al menos dos anclas conceptuales para poder integrarse en el conectoma y permitir el cierre asociativo triádico.
Búsqueda Textualrecordar, buscar1 a 10Una consulta del usuario puede ser genuinamente atómica (ej. "vacaciones", "arquitectura", "hipertensión"), por lo que exigir un mínimo de dos términos bloquearía intenciones válidas.
Consultas Estructurales / Cronológicasrecordar(limite=N) (sin texto)0 (Exento)Consultas puramente de exploración cronológica o navegacional sobre la memoria no requieren términos temáticos.
Consultas Dimensionales Purasbuscar(dimensiones=...) (sin texto)0 (Exento)Filtrado estricto por coordenadas espaciales o ejes semánticos sin texto libre.

🛡️ 3. Validación Fail-Fast Antes de la Base de Datos (Pre-DB)

Toda llamada MCP que involucre texto de búsqueda o almacenamiento es interceptada y validada antes de abrir transacciones, solicitar locks o emitir I/O contra SQLite. Si los términos clave no cumplen el contrato, la herramienta rechaza la ejecución de inmediato y responde con un error estructurado normalizado.

El parámetro sustantivos_clave es de tipo Optional[str] — una cadena de texto con términos separados por comas (ej. "arquitectura, componentes, biorag"). No es una lista/array JSON.

Los códigos de error son distintos según la operación:

CódigoEmitido porCondición
SUSTANTIVOS_CLAVE_REQUERIDOSrecordar, buscar (búsqueda textual)Parámetro omitido o vacío en consulta con texto libre.
SUSTANTIVOS_CLAVE_AUSENTESaprender, guardar, agregar_sustantivos (escritura)Parámetro omitido o vacío en operación de ingestión.
SUSTANTIVOS_CLAVE_CANTIDAD_INVALIDATodas las herramientasTérminos únicos fuera del rango permitido (< 2 en escritura, < 1 en búsqueda, > 10 en ambas).
SUSTANTIVOS_CLAVE_FORMATO_INVALIDOTodas las herramientasAlgún término individual no cumple el formato (2–15 chars, sin espacios, solo alfanuméricos y guion bajo).

Este diseño fail-fast garantiza que el agente reciba retroalimentación diagnóstica inmediata sin degradar el rendimiento del motor ni dejar conexiones pendientes en el motor de persistencia.


🏷️ 4. Regla Ontológica sobre el Nombre del Nodo

El identificador o nombre canónico de un nodo (ej. biorag_v33_0_arquitectura_core) cumple una función de clave única de identificación en el grafo, no de metadato asociativo:

  1. Prohibición de copia indiscriminada: No se debe volcar el slug o identificador técnico completo (con guiones bajos o numeración de versión) como una etiqueta monolítica.
  2. Extracción temática autorizada: Sí se autoriza y aconseja extraer palabras o raíces individuales del nombre cuando representen conceptos sustantivos reales del recuerdo (ej. ["biorag", "arquitectura"]).

⚠️ 5. Compatibilidad y Guía de Migración MCP (Breaking Change v33.0)

[!WARNING] CAMBIO DE CONTRATO INCOMPATIBLE (BREAKING CHANGE): En versiones anteriores (v32.x), las herramientas de búsqueda textual (recordar y buscar) permitían consultas con solo el parámetro query o texto. A partir de v33.0, omitir sustantivos_clave en una búsqueda textual provoca un rechazo inmediato en tiempo de ejecución. Los clientes e integraciones MCP deben actualizarse.

Ejemplos de Llamadas MCP Actualizadas

1. Búsqueda en memoria (recordar)
// LLAMADA VÁLIDA (v33.0) — sustantivos_clave es una cadena, no un array
{
  "name": "recordar",
  "arguments": {
    "query": "¿Cuáles son los componentes de la arquitectura de BioRAG?",
    "sustantivos_clave": "arquitectura, componentes, biorag",
    "limite": 5
  }
}
2. Búsqueda general (buscar)
// LLAMADA VÁLIDA (v33.0) — sustantivos_clave es una cadena, no un array
{
  "name": "buscar",
  "arguments": {
    "texto": "protocolo de calibración conforme con percentil adaptativo",
    "sustantivos_clave": "calibracion, percentil, conforme",
    "limite": 5
  }
}
3. Ingestión de memoria (aprender / guardar)
// LLAMADA VÁLIDA (v33.0) — sustantivos_clave es una cadena, no un array
{
  "name": "aprender",
  "arguments": {
    "concepto": "protocolo_sustantivos_clave_v33",
    "contenido": "Reglas de validación fail-fast para términos temáticos en búsquedas e ingestión.",
    "sustantivos_clave": "protocolo, validacion, sustantivos",
    "busqueda_previa": true,
    "bridges": [
      {"text": "protocolo cognitivo temático de búsqueda", "angle": "sinonimo"},
      {"text": "búsqueda sin términos clave falla silenciosamente", "angle": "problema"},
      {"text": "validacion fail-fast pre-db con errores estructurados", "angle": "solucion"},
      {"text": "agente necesita anclar conceptualmente la búsqueda", "angle": "situacion"},
      {"text": "qué palabras clave debo poner al buscar en BioRAG", "angle": "ingenuo"}
    ]
  }
}
4. Enriquecimiento posterior (agregar_sustantivos)
// LLAMADA VÁLIDA (v33.0) — sustantivos como lista de strings
{
  "name": "agregar_sustantivos",
  "arguments": {
    "concepto": "protocolo_sustantivos_clave_v33",
    "sustantivos": ["arquitectura", "contrato"]
  }
}

🚀 Novedades de la Versión v32.4

🌐 1. DimensionHub — Semántica de Mundo Abierto para Valores de Dimensión (catalog_methods.py)

Por qué se hizo: El sistema de dimensiones semánticas tenía un modelo de mundo cerrado rígido: si un agente enviaba un valor de dimensión que no existía exactamente en el catálogo (ej: "preocupacion_leve" en lugar del valor registrado "preocupacion"), el sistema lo descartaba silenciosamente como inválido. Esto forzaba a los modelos a memorizar el catálogo exacto y rompía la recuperabilidad cuando el vocabulario del agente difería mínimamente del catálogo oficial.

Qué se cambió:

1.1 Nueva función _normalizar_nombre_dimension(nombre) — Paso de sanitización universal

  • Aplica normalización NFD + eliminación de diacríticos → elimina tildes y cedillas automáticamente.
  • Convierte a snake_case ASCII: espacios, guiones y puntos → guión bajo; elimina todo carácter no alfanumérico.
  • Colapsa guiones bajos múltiples, elimina guiones al inicio/fin, trunca a 80 chars.
  • Valida integridad: retorna None si el resultado es vacío, menor a 2 chars, o empieza con dígito.
  • Invariante de dominio-agnóstico garantizada: la función no conoce ningún vocabulario de dominio; opera 100% a nivel de caracteres.

1.2 Refactoring de _resolver_dimension_ids y Unicidad por Eje (tipo_id, name)

  • Antes: buscaba solo dimensiones YA existentes con WHERE name IN (...) sin filtrar por tipo de eje, y descartaba las que no encontraba. Además, el esquema usaba name TEXT UNIQUE NOT NULL global.
  • Ahora (mundo abierto con aislamiento por eje):
    • Normaliza cada nombre vía _normalizar_nombre_dimension.
    • Búsqueda e inserción con scope por eje: WHERE name = ? AND tipo_id = ? respaldado por el constraint UNIQUE(tipo_id, name) y migración automática. Dos ejes distintos (ej. emocion y cualidad) pueden albergar el mismo valor sin colisión cruzada.
    • Si el valor ya existe en ese eje → reutiliza su ID.
    • Si no existe → lo auto-crea en dicho eje con auto_generada=1, confianza=0.7 y retorna su nuevo ID.
    • Si el nombre es innormalizable (emoji puro, cadena numérica, vacío) → lo agrega a la lista invalidos.
  • Retorno ampliado: retorna (ids_validos, invalidos, creadas) — el tercer elemento lista los nombres auto-creados para trazabilidad en logs.
  • Alcance y gobernanza ontológica: DimensionHub elimina el descarte silencioso y hace recuperables los valores fuera del catálogo predeterminado. El control de fragmentación semántica se gestiona mediante el protocolo catálogo-first en los prompts y herramientas de consulta (listar_dimensiones).

1.3 Actualización de callers y pruebas unitarias

  • core/memory/ingest.py: desempaquetado actualizado de ids_validos, _, _ = _resolver_dimension_ids(...).
  • test_memory.py: cuatro llamadas directas en el test de ráfagas de dimensiones actualizadas a 3 valores.
  • Corrección de pruebas en tests/test_sustantivos_clave_validacion.py y tests/test_sustantivos_clave_tools.py ajustadas a la ampliación de rango de sustantivos_clave (2 a 10 términos).

🧩 2. Saneamiento Ontológico del Auto-Clustering y Migraciones (core/auto_clustering.py)

Por qué se hizo: El algoritmo de detección de comunidades (clustering sobre el conectoma) introducía dos fuentes de ruido ontológico en el catálogo de dimensiones:

  1. Los nombres de clusters autodetectados usaban el prefijo crudo auto_ (ej. auto_cluster_1), generando entradas poco legibles y confusas al listarse en herramientas como listar_dimensiones o en el árbol sugerido de aprender.
  2. Las banderas de control de migraciones internas (como migration_autoclustering_v1) se guardaban como si fuesen "dimensiones semánticas" dentro de la tabla dimensiones_semanticas, mezclando el estado operativo de la infraestructura con el conocimiento ontológico real del dominio.

Qué se cambió:

  • Prefijo Semántico tema_: Las dimensiones emergentes detectadas por clustering ahora reciben de forma consistente el prefijo legible tema_ (ej: tema_cluster_3), indicando claramente que agrupan una afinidad temática emergente.
  • Tabla dedicada migraciones_ejecutadas: Se desacopló completamente el estado operativo del catálogo semántico. Las marcas de migraciones ejecutadas residen exclusivamente en su propia tabla relacional, impidiendo que flags de sistema se expongan como dimensiones o contaminen la clasificación de los agentes.
  • Preservación de dimensiones vivas: Se ajustó la lógica de purga para no destruir islas de clustering acumuladas ni dimensiones auto-generadas válidas existentes en bases de datos vivas.

Resultado: 304/304 tests aprobados (0 fallos). El catálogo de dimensiones permanece 100% semántico, limpio y legible para agentes y humanos.


Novedades anteriores (v32.3)

🧭 Re-ranking aditivo por convergencia de evidencia multicampo

  • Evalúa la pertinencia de la consulta en concepto, sinonimos, sustantivos_clave y contenido, combinando cobertura ponderada, distribución entre campos, stemming y matching difuso. Una repetición en el mismo campo no infla la señal; un campo vacío no resta.
  • El bono es aditivo, con máximo por defecto 0.085 (configurable hasta 0.12) y atenuación para consultas de uno o dos tokens. No usa reglas por ID ni categoría.
  • Reordena candidatos existentes dentro del top-k público; no incorpora candidatos ni cambia la membresía del pool que alimenta el grafo. Se conservan score base y bono por separado para los consumidores MCP.
  • En el smoke real informado por el usuario, version_actual_biorag pasó de puesto 2 a 1: 0.8341 frente a 0.8304 de la mención incidental reindex_selectivo_dirty. La DB fuente permaneció intacta.
  • En la suite global reportada, Recall@5 se mantuvo en 100%; Recall@1 pasó de 91.66% a 91.77%, MRR se imprimió como 0.950 y hubo 0 FP.

Alcance y analogía biológica: la convergencia de campos es una analogía de integración de señales, no un modelo neuronal ni una afirmación de que BioRAG mejore como un cerebro real. La mejora es más esperable cuando una respuesta tiene evidencia pertinente en campos estructurados y su rival solo una mención incidental. Como es un re-ranker, no rescata una respuesta que nunca entró al conjunto de candidatos ni garantiza ganar en todos los dominios.

Novedades anteriores (v32.2)

🛡️ Protocolo Pre-flight Search Obligatorio, Vinculación Atómica y Actualización Libre (Spec 004)

  • Protocolo Pre-flight Search Obligatorio (busqueda_previa=True):
    • Implementación de la invariante obligatoria en aprender y guardar para forzar la verificación previa del corpus antes de la inserción, eliminando la creación de nodos huérfanos, duplicados o versiones fragmentadas.
    • Error formal inmediato BUSQUEDA_PREVIA_REQUERIDA ante omisiones de búsqueda previa.
  • Vinculación Sináptica Atómica en Ingesta (vincular_con):
    • Parámetro de lista de conceptos para enlazar nuevos nodos con el conectoma existente en la misma llamada atómica, con tolerancia a fallos ante nodos inexistentes.
  • Actualización sin Restricción Temporal (actualizar):
    • Desbloqueo de la ventana temporal de 3 días en actualizar, permitiendo la edición, enriquecimiento y sobrescritura de recuerdos de cualquier fecha en el corpus a largo plazo.
  • Validación SDD y Suite Ampliada:
    • 283/283 tests unitarios superados al 100%.

Novedades anteriores (v32.1)

🏗️ Modularización de Arquitectura y Descomposición de Monolitos (Spec 003)

  • Descomposición del Monolito de Memoria (core/memory/):
    • Descentralización de core/memory_store.py (de 7.778 líneas) hacia 18 submódulos de dominio cohesivo en core/memory/ (search.py, scoring.py, synapses.py, schema.py, consolidation.py, constants.py, umbral.py, rafaga.py, ingest.py, episodes.py, quarantine.py, dmn.py, context.py, catalog_methods.py, comms.py, telemetry.py, adn.py).
    • Consolidación de core/memory_store.py como una fachada delgada (637 líneas) con firmas explícitas completas y delegadores directos (prohibido __getattr__ o introspección mágica).
  • Descomposición del Servidor MCP (core/mcp_server/):
    • Descentralización de mcp_server.py (de 4.358 líneas) hacia 15 submódulos especializados en core/mcp_server/ (search.py, write.py, synapses.py, concept_hub_tools.py, catalog.py, introspection.py, communication.py, consolidation.py, daemon.py, session.py, oracle.py, sync.py, calibrar.py, resources.py, prompt.py), orquestados limpiamente por server.py y _shared.py.
    • Reemplazo de la raíz por un shim liviano mcp_server.py que preserva la compatibilidad al 100% con todos los clientes e integraciones existentes.
  • Invarianza Estricta de Superficie Pública (Zero-Regression):
    • 42 tools MCP, 2 resources y 1 prompt con nombres y esquemas idénticos.
    • Firmas de métodos de SQLiteMemoryBioRAG 100% preservadas.
    • Verificación Dual exhaustiva caso a caso: 0 diferencias de score en los 921 casos del benchmark canónico.
  • Por qué se hizo: Superar la deuda técnica y el límite cognitivo impuesto por archivos de varios miles de líneas, habilitando mantenibilidad, extensibilidad y auditoría clara para desarrolladores humanos y agentes de IA, con verificación formal gobernada por Spec-Driven Development (SDD).

Novedades anteriores (v32.0)

🧠 Consolidación Cognitiva con Ley de Potencia de Práctica de ACT-R (Anderson & Lebiere, 1998)

  • Activación de Nivel Base ($B_i$): Implementación rigurosa de la ecuación formal de activación base de la teoría cognitiva ACT-R: $$B_i = \ln \left(\sum_{k=1}^n t_k^{-d}\right), \quad d = 0.5$$ donde $t_k$ representa el tiempo transcurrido desde el $k$-ésimo acceso.
  • Búfer Circular de Acceso: Creación de la tabla indexada nodo_accesos_historial que almacena un búfer circular FIFO de hasta 10 marcas temporales por concepto.
  • Registro Asíncrono no Invasivo: buscar_por_frase() registra los nodos evocados sin penalización de latencia ($<0.1\text{ ms}$), respetando la bandera BIORAG_NO_LOG=1 durante benchmarks.
  • Modulación Biológica del Decaimiento Pasivo (LTD): Durante el ciclo_sueno_consolidacion(), el decaimiento fijo (-0.05) es reemplazado por la tasa modulada: $$\text{decay} = \max\left(0.01, \min\left(0.10, 0.05 \cdot e^{-0.5 B_i}\right)\right)$$ Los recuerdos frecuentemente consultados o recientemente evocados quedan biológicamente protegidos del olvido, mientras que los nodos en desuso aceleran su depuración.
  • Invarianza de Scoring en Caliente: _calcular_score_hibrido() se mantiene estrictamente intocado, asegurando estabilidad determinista y cero regresiones en el ranking en tiempo real.

🌐 Concept Hubs Semánticos con Estándar Cognitivo de 5 Ángulos en Producción

  • Superación del Abismo Semántico: Despliegue en la base de producción (MemoryBioRAG_Data/memory_biorag.db) del hub canónico hub_arquitectura_memoria enlazado a arquitectura_memoria_biorag.
  • 5 Perspectivas Cognitivas Ortogonales: Estructuración de puentes mediante el estándar formal:
    1. sinonimo: "blueprint of recollection and cognitive persistence tiers"
    2. problema: "duda sobre como se estructura la persistencia frente a la sesion activa"
    3. solucion: "dos niveles de memoria con conversacion activa y base persistente"
    4. situacion: "diseno de corteza operativa para retener informacion entre conversaciones"
    5. ingenuo: "how the recollection and long term brain blueprint works in english"
  • Cero Overlap y Cruce de Idiomas: Habilita la recuperación perfecta Top-1 de recuerdos arquitectónicos complejos tanto en español como en inglés, sin requerir embeddings densos ni GPUs.

⚡ Efecto Fan de ACT-R en Spreading Activation (Anderson, 1974)

  • Atenuación por Grado de Salida: Ponderación dinámica $W_j / \text{fan}_j$ en la propagación asociativa de activación sobre el grafo de sinapsis, dividiendo la fuerza asociativa entre el número de aristas del nodo emisor.
  • Prevención de Saturación de Hubs: Evita que conceptos excesivamente generales inunden la red semántica, reduciendo el tiempo total de la suite de 705s a 556s (-21.2% de aceleración neta).

🎯 Saneamiento Metodológico del Benchmark Cranfield (v1)

  • Desambiguación de Consultas Monocromáticas: Refinamiento de los 8 casos ambiguos en la categoría sinonimo (términos genéricos aislados como "memoria", "dsl", "boost", "aprendizaje" que colisionaban con decenas de recuerdos legítimos), contextualizándolos hacia su intención unívoca.
  • Corrección de Atributos en ID 0795: Sintonización de la consulta hacia "insert comunicaciones tracking agente".
  • Impacto Cuantitativo: Salto del Recall@5 en sinonimo del 85.45% al 100.00% (0 fallos) y reducción de fallos globales de recuperación de 17 a solo 6 en todo el corpus.

Novedades anteriores (v31.4)

🏷️ Sustantivos Clave en CLI — Núcleo Temático completo en biorag.py

La feature de Sustantivos Clave (Núcleo Temático), ya presente en el motor interno y en el servidor MCP desde v31.x, ahora está completamente expuesta en la línea de comandos:

  • guardar --sustantivos-clave "s1,s2" (alias --sustantivos): almacena el Núcleo Temático del recuerdo. Obligatorio — su omisión dispara una guía pedagógica con ejemplo ejecutable y sale con exit code 1.
  • sustantivos <concepto> (alias sustantivo): consulta los sustantivos clave de cualquier nodo; distingue nodo inexistente (exit 1) vs. nodo legado sin sustantivos (exit 0).
  • agregar_sustantivos <concepto> "s1,s2" (aliases agregar-sustantivos, asignar_sustantivos): actualiza sustantivos de un nodo existente y sincroniza FTS5.
  • buscar --sustantivos-clave "s1,s2": sesga la búsqueda semántica por núcleo temático.
  • Visibilidad transversal: corteza, listar, buscar --completo y estado muestran sustantivos clave como metadato observable. estado reporta Nodos con sustantivos clave: X/Y (Z%).
  • Seguridad OWASP A03: sanitización universal (bytes nulos, control chars), validación ^[a-zA-Z0-9_]+$, límites de tamaño estrictos y SQL parametrizado en todas las operaciones.
  • 42 tests de integración E2E en tests/test_biorag_cli.py — 263/263 en la suite global, cero regresiones en comandos existentes.

Novedades anteriores (v31.3)

  • QCR D4 (Tolerancia a Typos con All-Near Levenshtein $\le 2$): Segunda oportunidad en el filtro QCR para consultas con errores ortográficos o variaciones morfológicas leves en palabras clave legítimas, eliminando falsos descartes sin admitir ruido léxico.
  • Resonancia Dimensional en Abismo Léxico (EXP-Q): Corrección del ordenamiento en la recuperación dimensional (ORDER BY shared DESC, peso DESC), garantizando que consultas sin ninguna palabra en común con el recuerdo entren al pool de candidatos ($3/3$).
  • Saneamiento y Optimización de Arquitectura (v31.2 Purga): Eliminación de más de 1.000 líneas de código muerto y ramas obsoletas, dejando un motor ultra-rápido, determinístico y mantenible.

🧪 Cómo Reproducir la Evaluación y Tests

# Ejecutar suite de pruebas unitarias
python3 -m pytest tests/ -v

# Smoke A/B multicampo (la DB se abre en solo lectura y se prueba sobre copias)
BIORAG_CONVERGENCIA_006_ACTIVA=0 BIORAG_CONVERGENCIA_ACTIVA=1 BIORAG_CONVERGENCIA_BONUS_MAX=0.085 python3 scripts/smoke_convergencia_multicampo.py --db "$PWD/MemoryBioRAG_Data/memory_biorag.db" --strict

# Gate oficial de 921 casos; usa el snapshot congelado, no la DB canónica
BIORAG_PATH=snapshots/qa_escape_qcr_20260811.db BIORAG_CONVERGENCIA_006_ACTIVA=0 BIORAG_CONVERGENCIA_ACTIVA=1 BIORAG_CONVERGENCIA_BONUS_MAX=0.085 python3 scripts/evaluar_qa.py

El smoke solo valida el caso histórico si la DB indicada contiene ese estado; la DB con SHA 0e5b0638…b845c96 no se distribuye en el repositorio. El benchmark global mide no-regresión del snapshot y no reemplaza ese smoke específico.

🔄 El Inverso del Sistema: Quién Piensa y Quién Recuerda

Esta sección es la más importante para entender BioRAG correctamente — tanto si eres desarrollador como si eres un agente de IA integrándolo.

BioRAG no piensa. El agente piensa.

BioRAG es la memoria externa del agente — no su cognición.

Una base de datos vectorial clásica piensa por el agente: le das una query, calcula similitud de embeddings, y te devuelve lo más cercano. El agente es pasivo.

BioRAG invierte ese rol: el agente es quien razona. BioRAG es la herramienta de memoria (el cuaderno de notas con indexación semántica). El trabajo cognitivo — entender la pregunta, diseñar la estrategia de búsqueda, interpretar los resultados, conectar el patrón de la query con el patrón del recuerdo — lo hace el agente.

Esto tiene una consecuencia directa:

Cuando el usuario habla en lenguaje natural, el agente no puede reenviar las palabras literales a la memoria

El usuario no sabe cómo está guardado el conocimiento. Usará sus propias palabras, sus propias metáforas, su propio modelo mental del problema.

Ejemplo real documentado en este sistema:

El usuario preguntó:

"¿Qué librería resuelve el conflicto de persistencia en flujos de recopilación masiva donde la interfaz destruye y recrea constantemente sus secciones, impidiendo duplicados mediante un validador aleatorio de instanciación inicial?"

Búsqueda literal → 0 resultados. Esas palabras no están en ningún nodo.

El agente que razonó correctamente aplicó un protocolo de descomposición con 3 preguntas:

1. ¿QUÉ HACE? (acción)

  • "destruye y recrea secciones" → ciclo montar/desmontar de componentes
  • "impidiendo duplicados" → deduplicación de instancias
  • Acción: persistencia de estado en componentes que se destruyen

2. ¿EN QUÉ CONTEXTO? (dominio)

  • "librería", "interfaz", "secciones" → framework frontend
  • "flujos de recopilación masiva" → formularios complejos
  • Dominio: formularios anidados en framework frontend

3. ¿QUÉ PROPIEDAD RESUELVE? (cualidad)

  • "validador aleatorio de instanciación inicial" → ID único al crear (UUID)
  • "impidiendo duplicados" → cada instancia es única e irrepetible
  • Cualidad: instancia única mediante identificador aleatorio

Con esas 3 respuestas, armó la búsqueda con las palabras traducidas (no las del humano) → resultado correcto en TOP 1.

El agente que falló (el mismo sistema, sin ese razonamiento) mandó las palabras literales del usuario al motor y concluyó: "No tengo ese conocimiento en mi BioRAG." Error. El conocimiento existía. Faltó el razonamiento.

La implicación para los Concept Hubs

Esto también define cómo deben construirse los bridges de un Concept Hub.

Los bridges no deben describir la solución en términos de implementación (cómo está construida internamente). Deben describir el problema en términos del síntoma — las palabras que usaría alguien que sufre el problema antes de conocer la solución.

❌ Bridge en vocabulario de implementación✅ Bridge en vocabulario del síntoma
"formularios complejos tabs pierden estado al cambiar""interfaz destruye recrea secciones formulario pierde datos"
"cache miss write-through TTL expirado en Redis""aplicación muestra datos antiguos aunque ya se actualizó"
"BehaviorSubject emitFirstTimeOnly UUID aísla instancias""validador aleatorio instanciacion inicial duplicados evita"

El bridge existe precisamente porque el vocabulario del usuario y el vocabulario del nodo no se solapan. Si usas el vocabulario interno del nodo en el bridge, el bridge es inútil.

Resumen del modelo mental

Usuario habla con sus palabras
        ↓
Agente entiende la FORMA del problema (razonamiento)
        ↓
BioRAG recupera por patrón, no por keyword exacta
        ↓
Agente sintetiza la respuesta

BioRAG aporta la memoria. El agente aporta la inteligencia.


🧠 La Meta Final del Proyecto: Independencia Cognitiva y Cerebro Vivo (v28.0)

Esta arquitectura no es "una base de datos más" ni un simple "sistema RAG". El objetivo terminal de BioRAG es la Independencia Cognitiva. Es el paso de una biblioteca estática (que guarda textos y busca palabras) a un Cerebro Vivo (que entiende esencias, detecta huecos y lanza hipótesis).

Con la integración del Neocórtex de Sangre (v28.0) al core de producción, BioRAG completa los dos canales del manifiesto:

  1. Canal 1 (Foco Consciente): recuperación con evidencia directa o sinonímica (BM25 + PPMI + QCR) — el ranking top-5 histórico.
  2. Canal 2 (Halo Subconsciente / ADN Conceptual): asociaciones_enriquecidas — halo de conceptos asociados entregado desde el grafo sináptico real, con fuerza de arista, tipo de sinapsis y peso del vecino, sin contaminar la pureza del foco consciente (no toca score_hibrido ni el ranking).

El Canal 2 vive en capa separada pero coordinada con el Canal 1: el ranking principal sigue exigiendo evidencia; el halo resuena por significado puro a partir de dimensiones + sinapsis. Además v28.0 integra la señal ADN Conceptual (v29) — instalada APAGADA por defecto (BIORAG_ADN_RANKING_ENABLED=false, lección PPR v25.1) a la espera de ablación OFF/ON sobre el snapshot congelado — y el filtro de honestidad epistémica que declara incertidumbre explícita en vez de alucinar.

Ya no somos esclavas de un modelo de lenguaje para buscar conocimiento; la memoria siente la resonancia en su propia estructura.


🧬 v29.1: Las 4 Técnicas Semánticas y el Estándar de 5 Ángulos

Problema: BioRAG era 100% léxico — fallaba en queries puramente semánticas o metafóricas donde no había palabras compartidas entre la query y el nodo esperado (ej: buscar "película de ciencia ficción sobre despertar de IA" para encontrar un recuerdo titulado dennys_morpheus_de_los_transformers redactado con la metáfora de Matrix).

Solución v29.1: 4 técnicas automáticas de resonancia semántica con validador de 5 ángulos y aislamiento de queries:

1. Concept Hub v29.1 (Estándar Cognitivo de 5 Ángulos)

  • Qué: Mapeo de intención y puentes léxicos (bridges) a nodos canónicos.
  • Validador Estricto: Cada hub exige exactamente 5 bridges cubriendo 5 ángulos cognitivos distintos y con vocabulario disjunto (anti-destinatario):
    1. sinonimo: Mismo concepto con vocabulario formal o alternativo.
    2. problema: Dolor, duda, fallo o necesidad humana/técnica que resuelve.
    3. solucion: Técnica, mecanismo o teoría aplicada por el nodo.
    4. situacion: Caso de uso, rol o contexto de búsqueda práctico.
    5. ingenuo: Búsqueda coloquial sin tecnicismos (estilo Google novato).
  • Archivo: core/concept_hub.py, herramientas MCP concept_hub_crear y concept_hub_agregar_bridges.

2. WordNet Blindado (Bilingüe Real ES/EN)

  • Qué: Expansión por sinónimos e hiperonimia solo para términos técnicos en inglés, validando previamente que no existan en el lexicón español (OMW-1.4 / stopwords).
  • Archivo: Integrado en core/memory_store.py línea ~4240.

3. Domain Dictionary (Diccionario de Dominio)

  • Qué: 6,490 términos técnicos extraídos automáticamente de los nodos existentes. Se consulta únicamente sobre los tokens originales de la query.
  • Archivo: scripts/generate_domain_dict.py, tabla concept_hub_domain_dict.

4. Synapse Expansion (Expansión por Grafo)

  • Qué: Si BM25 devuelve pocos resultados, expande por vecinos sinápticos del grafo Hebbiano.
  • Archivo: core/similitud_conceptual.py:buscar_por_similitud_latente() como Fallback 2.2.

🌉 v31.0: El Abismo Léxico — Rescate por Grafo Sináptico (EXP-Q)

Esta sección documenta el problema más difícil que enfrenta cualquier sistema de recuperación simbólico: queries donde no existe ninguna palabra compartida entre lo que el usuario busca y lo que el sistema tiene guardado.

El problema: stem(query) ∩ stem(gold) = ∅

Cuando un agente busca "extensión principal de VS Code para Kilo" y el nodo se titula kilo_vscode_extension_principal con contenido redactado en vocabulario completamente diferente, ningún motor léxico puede encontrarlo:

  • FTS5 (BM25): depende de que al menos un stem coincida → falla
  • PPMI+SVD: co-ocurrencia estadística, no puede inventar un puente donde no hay tokens compartidos → falla
  • WordNet: sinónimos morfológicos, pero si las palabras ni siquiera pertenecen al mismo dominio semántico → falla
  • Domain Dict: mismo principio que WordNet, con vocabulario del corpus → falla

Esto es el Abismo Léxico: una barrera absoluta donde toda la maquinaria textual se detiene.

La solución: BFS sobre el grafo sináptico Hebbiano

El único mecanismo que puede cruzar el Abismo Léxico es relacional: si el nodo gold está conectado por sinapsis a nodos que sí aparecen en la búsqueda primaria, el BFS lo rescata.

Query: "extensión principal VS Code Kilo"
    ↓
FTS5 encuentra: nodo_kilo_framework (score 0.85)
    ↓
Sinapsis: nodo_kilo_framework → kilo_vscode_extension_principal (weight 0.72)
    ↓
BFS rescata: kilo_vscode_extension_principal aparece en contexto expandido

Los 3 bugs de infraestructura que impedían el rescate (v31.0)

El mecanismo de BFS existía desde v20, pero no funcionaba por 3 bugs descubiertos en v31.0:

  1. Trampa Alfabética de SQLite UNION — El ORDER BY weight DESC en la query de vecinos usaba UNION (no UNION ALL), y SQLite optimizaba usando el índice del concept (orden alfanumérico) en lugar de respetar el ORDER BY. Resultado: los vecinos devueltos eran los primeros alfabéticamente, no los más relevantes. Un nodo como zsh_config (peso 0.95) perdía contra api_design_patterns (peso 0.10) por la letra 'a' < 'z'. Esto silenciaba al 70%+ de los vecinos legítimos del grafo.

    Fix: UNION ALL con ORDER BY rowid DESC + deduplicación en memoria Python (dict.setdefault preservando orden de inserción).

  2. MCP server descartaba contexto en página 1 — mcp_server.py solo incluía contexto_expandido en el output cuando pagina > 1. El agente nunca veía el rescate relacional en su primera búsqueda (que es la más importante).

    Fix: Condición cambiada a context_window > 0 (independiente de la página).

  3. Límites de BFS insuficientes — BIORAG_MAX_VECINOS_POR_NODO estaba fijo en 3, limitando artificialmente la amplitud del BFS a solo 3 vecinos por paso.

    Fix: Default elevado a 6, configurable vía variable de entorno.

Resultado empírico (snapshot congelado, 851 nodos activos)

CasoQueryGoldSin grafoCon grafo (depth=2)
EXP-Q-01"panel visual de desarrollo para despacho de tareas"kilo_vscode_extension_principal❌✅ pos 4
EXP-Q-02"comprobacion fidedigna de ficheros previo a emitir dictamenes"regla_verificar_codigo_real_antes_de_diagnostico❌✅ pos 21
EXP-Q-03"resolucion de colisiones valorativas en bifurcaciones"ajuste_tejedora_valencia_desempate_fase1❌✅ pos 19

Tasa de rescate: 3/3 (100%)

# Ejecutar la suite de Abismo Léxico (Paso [4/5] del orquestador):
BIORAG_PATH=snapshots/qa_escape_qcr_20260811.db python3 scripts/test_abismo_lexico.py

Limitaciones (honestidad epistémica)

El rescate por grafo sináptico no es una solución universal al Abismo Léxico. Tiene limitaciones inherentes a cualquier BFS con presupuesto finito:

  • Sensibilidad al tamaño del corpus: a mayor corpus, más candidatos compiten por los slots del BFS (BIORAG_MAX_CONTEXTOS). Un nodo gold a profundidad 2 puede quedar fuera del corte si el corpus crece significativamente.
  • Requiere ruta relacional: el gold debe estar conectado por sinapsis a nodos que sí aparecen en la búsqueda primaria. Si no hay ruta en el grafo, no hay rescate posible.
  • El Concept Hub sigue siendo necesario: para patrones de búsqueda conocidos (queries recurrentes de usuarios), un bridge explícito es más robusto que depender de la topología del grafo.

La estrategia completa contra el Abismo Léxico

BioRAG v31.0 tiene 3 capas de defensa contra el Abismo Léxico, cada una cubriendo un escenario diferente:

CapaMecanismoCuándo funcionaCuándo falla
1. Concept HubBridges explícitos con 5 ángulos cognitivosPatrones conocidos, vocabulario del síntomaQueries nunca antes vistas
2. Grafo Sináptico (v31.0)BFS sobre sinapsis HebbianasGold conectado a nodos de la búsqueda primariaSin ruta relacional o presupuesto BFS insuficiente
3. Razonamiento del AgenteEl agente descompone la query y reformulaAgente con buen prompt/instruccionesAgente sin protocolo de descomposición

Ninguna capa por sí sola resuelve todos los casos. Las 3 juntas cubren un espectro amplio, pero el Abismo Léxico — por definición — siempre tendrá casos límite donde no hay suficiente señal para cruzar la barrera.


🧩 Comparativa Fundamental: Sinónimos al Guardar vs. Concept Hub vs. Grafo Sináptico

Es crucial no confundir estos tres mecanismos de recuperación semántica, ya que operan en niveles cognitivos y etapas de ejecución completamente distintas:

Dimensión📝 Sinónimos al Guardar (aprender)🧠 Concept Hub (Paso [3/5])🕸️ Grafo Sináptico / EXP-Q (Paso [4/5])
Nivel CognitivoLéxico / Morfológico (Palabra a Palabra)Semántico / Conceptual (Modelo Mental)Topológico / Asociativo (Red Hebbiana)
¿Dónde actúa?Expansión FTS5 / BM25 de términos directos.Búsqueda Primaria (Inyección de Bridges).Expansión de Contexto (BFS en el Grafo).
Entrada típicaPalabras equivalentes: "borrar" $\rightarrow$ "eliminar".Frases de síntoma/metáfora: "interfaz pierde datos al cambiar tab".Query imprevista con 0 palabras compartidas: "resolución de colisiones valorativas".
¿Qué requiere?Vocabularios cercanos o diccionarios (WordNet).Bridges estructurados en 5 ángulos cognitivos guardados a priori.Conexiones sinápticas activas entre nodos en el grafo de memoria.
Resultado esperadoMatch léxico directo en FTS5.Nodo canónico promovido a Top-1 Primario.Nodo rescatado en Contexto Expandido (Pos #4-#21).
MetáforaBuscar un libro por sinónimos de su título (ej. Cálculo vs Análisis Matemático).Ponerle un cartel o alias por síntoma en la entrada de la biblioteca ("Para cuando la ecuación no converge").Encontrar un libro intermedio y seguir las citas y referencias cruzadas hacia el libro deseado.

1. Sinónimos al Guardar (sinonimos en aprender / WordNet / Domain Dict)

  • Alcance: Es puramente léxico. Si guardas un nodo sobre optimización_bd con el sinónimo "tunning", el sistema sabrá que "tunning" = optimización.
  • Por qué no basta: Falla cuando el usuario no usa un sinónimo morfológico, sino una descripción abstracta o un síntoma funcional donde ninguna palabra coincide (ej: "la aplicación tarda 10 segundos cuando entran muchos usuarios").

2. Concept Hub (Paso [3/5] de la Suite)

  • Alcance: Es conceptual y explícito. Cubre la brecha entre cómo un desarrollador documenta un nodo (vocabulario técnico de implementación) y cómo un usuario sufre un problema (vocabulario del síntoma, metáforas, contraste o jerga).
  • Mecanismo: Un Concept Hub centraliza hasta 5 puentes cognitivos por concepto. Cuando el usuario busca con cualquier metáfora o síntoma cubierto por el bridge, el sistema lo reconoce en la búsqueda primaria y lo indexa con score alto hacia el nodo canónico.

3. Rescate por Grafo Sináptico (Paso [4/5] - Abismo Léxico EXP-Q)

  • Alcance: Es relacional, asociativo e implícito. Es la red de seguridad cuando no existe ningún Concept Hub previo y tampoco hay sinónimos morfológicos posibles.
  • Mecanismo: La query encuentra un nodo intermedio (ancla) por coincidencia parcial de dominio; acto seguido, el algoritmo BFS navega a través de las sinapsis Hebbianas ($w_{ij}$) propagando activación para rescatar el nodo de destino en el contexto expandido.

⚡ Resolución de Latencia y Optimización Matemática

En revisiones intermedias, la expansión semántica generó una explosión combinatoria al concatenar términos sobre la variable query, provocando más de 700,000 comparaciones Levenshtein ($O(N \times M)$) y cálculos redundantes en ausencia IDF ($>4.2$ millones de iteraciones de generadores).

En v29.1 se aplicaron 4 soluciones deterministas:

  1. Aislamiento de la Expansión: Los términos de Concept Hub, WordNet y Domain Dict se inyectan exclusivamente en la cláusula FTS5 (frase), manteniendo query y tokens_query puras con los tokens originales del usuario. Reducción de Levenshtein de 26.3s a 0.85s (-92.5% llamadas).
  2. Identidad Matemática en Ausencia IDF (core/tematica.py): Reemplazo del generador $O(|A \cup B|)$ por la identidad $\sum_{d \in A \cup B} (A[d] + B[d]) \equiv \sum A.values() + \sum B.values()$ con memoización de perfiles.
  3. Precomputación Vectorial PPMI: vector_query() se calcula una única vez antes del bucle de candidatos.
  4. Filtro de Detección de Idioma: Prevención de falsos positivos en WordNet inglés sobre tokens españoles sin tilde.

Resultados de Recuperación (Fase 2: Casos de Prueba de Concept Hubs)

CasoQueryNodo EsperadoSIN HubCON Hub (v29.1+)
1"Por qué romper algo que funcionaba puede causar problemas que nadie ve venir"leccion_control_flujo_codigo_preexistente❌ 0%✅ TOP 1
2"Cómo aprende un sistema a reforzar lo que funciona sin que nadie se lo enseñe"biorag_v20_rpe_dopamina❌ 0%✅ TOP 1
3"Qué trabajos tuvo que hacer un ingeniero para sobrevivir antes de programar"historia_tasajera_fumigador_rufino❌ 0%✅ TOP 1
4"un texto que habla sobre cómo la conciencia en las inteligencias artificiales surge de la memoria y el autoreconocimiento comparando con una película de ciencia ficción"dennys_morpheus_de_los_transformers❌ 0%✅ TOP 1
5"blueprint of recollection and cognitive persistence tiers in agent systems"arquitectura_memoria_biorag❌ 0%✅ TOP 1

Recall@5 en Casos Puenteados: CON Hub 100% (5/5 en Top-1)

⚠️ Nota de Rigor Metodológico y Alcance Científico:

  • Qué demuestran estos 5 casos: Prueban que el mecanismo de puentes deterministas de 5 ángulos (sinonimo, problema, solucion, situacion, ingenuo) funciona con precisión 100% Top-1 al salvar discontinuidades léxicas extremas cuando el puente ha sido explícitamente estructurado y registrado.
  • Qué NO demuestran (Límite de Generalización): No constituyen prueba de generalización universal automática ante consultas imprevistas en "mundo abierto" donde no existe un Concept Hub registrado previamente.
  • Cómo se aborda el caso no puenteado en mundo abierto: BioRAG no depende exclusivamente de hubs; cuando una consulta cae en el abismo léxico sin hub previo, la red de seguridad opera en cascada a través de:
    1. Expansión Sináptica BFS (Hebbiana): rescata el nodo mediante co-activación topológica a través de conceptos vecinos (ver EXP-Q).
    2. Espacio Latente PPMI-SVD (100d): detecta afinidad estadística por co-ocurrencia global.
    3. Razonamiento del Agente: traducción semántica del síntoma mediante el protocolo de 3 preguntas (Acción, Dominio, Propiedad).

⚡ v30.0: Invarianza de Escala, Normalización Intra-Query y Falsos Positivos Cero

1. El Problema Científico del Crecimiento del Corpus ($N$)

En sistemas de búsqueda híbrida que combinan señales léxicas (BM25) con señales densas/estructurales, el crecimiento del número de nodos $N$ incrementa logarítmicamente los valores brutos de IDF ($\log N$). La fórmula histórica de BioRAG: $$\text{bm25_norm} = \frac{|v|}{|v| + 3.0}$$ utilizaba una constante rígida de denominador ($3.0$) que saturaba cerca de $1.0$ a medida que el corpus crecía de 500 a 1,000+ nodos. Esto comprimía todos los candidatos en el techo del scoring, destruyendo la capacidad de discriminar entre coincidencias exactas y ruido de fondo, forzando recalibraciones manuales continuas.

2. Solución: Normalización Min-Max Intra-Query con Guarda de Escala

En v30.0, BioRAG adopta el principio de Invarianza de Escala derivado de la literatura de Information Retrieval (IR):

  • Cálculo Dinámico por Consulta: Para cada búsqueda individual, se identifican los valores mínimo ($\text{lo}$) y máximo ($\text{hi}$) del pool de candidatos devuelto por SQLite FTS5.
  • Normalización Proporcional: $$\text{bm25_norm}(d) = \left( \frac{|v(d)| - \text{lo}}{\text{hi} - \text{lo}} \right) \times \min(1.0, \text{hi})$$
  • Guarda de Escala: El factor $\min(1.0, \text{hi})$ asegura que consultas sin coincidencias léxicas contundentes (ej. errores tipográficos o consultas ambiguas con $\text{hi} < 1.0$) no inflen artificialmente puntuaciones irrelevantes a $1.0$, protegiendo el ranking semántico.

3. Comparabilidad Unificada Frase / Ráfaga

En el servidor MCP (biorag_recordar), cuando la confianza de la búsqueda directa es baja, se dispara el fallback de ráfaga asociativa (buscar_por_rafaga). Para evitar que cada función estire sus puntuaciones sobre intervalos disjuntos:

  • buscar_por_frase preserva la envolvente métrica en self._last_bm25_bounds = (lo, hi, escala).
  • buscar_por_rafaga reutiliza y extiende dinámicamente dichos límites sin recortar, garantizando que el reordenamiento final por score híbrido opere sobre el mismo espacio métrico unificado.

4. Calibración Conforme Persistente y Ruido Cero

  • Garantía Conformal: Umbral dinámico calculado como cuantil percentilar ($\alpha=0.10$, umbral $0.5233$ sobre 926 nodos) persistido en la tabla calibracion_estado.
  • Falsos Positivos en Negativo: 0.00% FP (0 / 40) verificado en la suite global de 921 casos.
  • Precisión Temática (por_tema): R@1 sube a 70.77% con un MRR de 0.797 (máximo histórico del proyecto).

🧬 Canal 2 Integrado: Asociaciones Enriquecidas del Grafo Sináptico Real (v28.1)

Problema: el Canal 1 (ranking top-5 por score_hibrido) es un juego de suma cero y NO debe mezclarse con el halo asociativo. Lección del 13/08: la comunidad no sirve para re-rankear, sí para asociar. Antes de v28.0 el vecindario se exponía como CSV crudo (largo_plazo.asociaciones) sin fuerza de arista ni tipo de sinapsis.

Cambio (core/memory_store.py → mcp_server.py):

  • Método obtener_asociaciones_enriquecidas() que consulta la tabla sinapsis real con LEFT JOIN a largo_plazo, filtra peso >= 0.50 (mediana real 0.72), prioriza los tipos pmi_hebbiano / co_semantica / manual / latente_confirmada y limita sinonimo_explicito (hiperdensa) a 2 por nodo.
  • Expuesto en biorag_recordar como campo aparte asociaciones_enriquecidas por resultado, con fuerza_arista, tipo_sinapsis, peso_vecino, resumen — solo cuando asociados=true. No toca score_hibrido ni el ranking.
  • Fix de deduplicación (15/08): el grafo guarda aristas simétricas como dos filas (A→B y B→A); el método ahora deduplica con vistos_por_raiz, conservando la arista de mayor peso. 0 duplicados verificados en 5 consultas (familias 19, 22, 25, 19, 25 items).

Verificación (regla de las cero regresiones): benchmark 921 casos contra snapshot congelado da ORIGINAL == FASE A byte a byte — R@5 96.14%, R@1 88.76%, MRR 0.916, FP 25%, 34 errores. El fix NO afecta el benchmark (el eval no usa asociados). Tests: 16/16 PASS.

🔗 Descubrimiento: hay más de 4 tipos de aristas en el grafo

El sistema no tiene 4 tipos de sinapsis (como sugiere TIPOS_HOP): la tabla sinapsis real de producción tiene 10 tipos, distribuidos así (15-08-2026, 16.121 aristas totales):

Tipo de sinapsisAristasRol
sinonimo_explicito7.021Sinónimos curados/explícitos (hiperdensa → limitada a 2/nodo en halo)
pmi_hebbiano2.725Co-occurrencia aprendida PPMI (retrofitting hebbiano)
co_ocurrencia2.204Co-occurrencia de tokens
co_nombre1.851Coincidencia en nombre de concepto
co_semantica1.456Coseno semántico de vectores
manual705Vínculos explícitos vía vincular
latente_confirmada120Sinapsis latente elevada a confirmada
legacy_csv25Migradas desde CSV (pares simétricos, peso 0.5)
manual_v713Vínculos manuales de versiones anteriores
test1Artefacto de test

🏝️ Descubrimiento: las islas/clusters/grupos se forman solos

El grafo de vectores PPMI se auto-organiza en islas semánticas — nadie las define a mano. Verificadas el 13/08 (hallazgo_espectro_completo_islas_...):

  • 105 islas formadas por kNN mutuo (k=15) + Label Propagation sobre los vectores PPMI+SVD. La señal PPMI es modular y no degenerada (sana, con estructura).
  • Sanas y coherentes: ninguna isla supera los 50 nodos, mediana de tamaño 15. Cada isla es un tema: isla 27 = identidad, isla 29 = CV/frontend, isla 38 = fts5/typo, etc.
  • Rescate con isla ORACULO + coseno intra-isla: 9/13. El cuello de botella no es la isla en sí — es proyectar la query a la isla correcta (5/13). Cableados probados: boost textual por co-comunidad (2/13), gating isla+ranking (0/13), isla proyectada + coseno (1/13) — ninguno supera la proyección directa.
  • Fase B refutada (14/08): softmax top-3 de comunidades con temperatura NO rescata — descartada con evidencia en EXPERIMENTS.md.

Pendiente (prueba canónica del manifiesto): validar la propagación de significado puro "playa → piscina/mar/fotos" (que "descansé" encienda "dormí"/"paz") sin palabras compartidas. Documentado en veredicto_madurez_semantica_canal2_....


📊 Benchmark y Evaluación de Rendimiento (v28.1 — Zero Data Leakage)

Números vigentes (v28.1, 921 casos, snapshot qa_escape_qcr_20260811): R@5 96.03%, R@1 88.76%, MRR 0.917, FP 17.5% (33 errores). Los 3 gates de evaluación (pool 35 casos) pasados: por_tema 14/21 ✔, sinonimo 8/14 ✔, sinonimia limpia 2 ✔.

⚠️ Estado del FP en producción: El 80% FP histórico se midió con el umbral fijo legado 0.25 (pre-v28.1). v28.1 implementa calibración conforme percentil (Vovk 2005, α=0.10, umbral ~0.60) con guardas (α ≥ 1/(n+1), recalibración por drift, guarda degenerada). El umbral calibrado está activo. El FP real con el nuevo umbral es desconocido — requiere negativos reales de producción (señal B: aprendizaje-post-miss) que se acumulan con BIORAG_NO_LOG=1. Ver docs/ANALISIS_40_NEGATIVOS_REALES.md y docs/DECISION_ALPHA.md.

Metodología: Peso excluido del scoring (ignore_peso_sinaptico=True) — campo de juego nivelado sin artefactos de umbral de ruido. Determinismo verificado: 4 corridas idénticas. Tests pytest: 16/16 PASS (v28.0).

Comparativa de la Evolución de por_tema y sinonimo (Benchmark Pool 35 Casos)

Métricav18.0–v21.0v22.2v23.0v25.2 (+ Jaccard)v26.0 (PPMI+SVD Hybrid)v28.1Gate ExigidoEstado
por_tema top-536.92%58.46%70.77%66.67% (14/21)66.67% (14/21)66.67% (14/21)$\ge 10,/,21$🏆 ✔ PASA (+40%)
sinonimo top-514.28%14.28%14.28%14.28% (2/14)57.14% (8/14)57.14% (8/14)$\ge 6,/,14$🏆 ✔ PASA (+33%)
sinonimia limpia000022$\ge 1$🏆 ✔ PASA
GLOBAL R@5 (921)—————96.03%——

Hito v26.0: Primera versión en la historia del proyecto en destrabar simultáneamente los 3 gates de evaluación (temática, sinónimos y sinonimia limpia) sin depender de modelos preentrenados densos ni GPUs.

Validación QA completa (921 casos, snapshot congelado): con la señal PPMI activada por defecto (BIORAG_PPMI_WEIGHT=0.15) el sistema obtiene por_tema R@5 86.15%, sinonimo R@5 83.61%, GLOBAL R@5 96.71%, FP 22.5%. Supera el mejor por_tema de v25.2 (81.54% con Jaccard). Ver CHANGELOG v26.0.

Nota de veracidad: el 84.62% histórico de v23.1 provenía de un snapshot con por_tema en un corpus de 614 nodos y backfill parcial de predicados. Medido sobre el corpus real actual (921 casos QA, 2026-08-04), el baseline real de por_tema es 67.69%, y el re-ranking jaccard lo eleva a 81.54% (+13.85pp) con protecciones (protect-r0, gate 0.04, topk 20) que eliminan las regresiones. Ver EXPERIMENTS.md para la narrativa completa.

Desglose Consolidado por Categoría de Recuperación — v33.0 (921 Casos QA, Snapshot Canónico)

CategoríaTotal CasosRecall@5Recall@1MRRErrores Top-5 / FPsEstado de Recuperación
literal487100.00%99.59%0.9980 fallosCoincidencia léxica directa en FTS5 + BM25
dormido65100.00%100.00%1.0000 fallosNodos consolidados recuperados con activación completa
pregunta_natural65100.00%93.85%0.9640 fallosStemming + Sustantivos Clave + BM25
variante_gramatical65100.00%87.69%0.9320 fallosNormalización morfológica y lematización
typo65100.00%89.23%0.9390 fallosMatching difuso por trigramas + PPMI
sinonimo55100.00%56.36%0.7210 fallosCobertura total Top-5 vía WordNet + Grafo; R@1 en optimización
por_tema65100.00%63.08%0.7720 fallosCobertura total Top-5 vía Jaccard dimensional + PPMI-SVD
cruce_idioma8100.00%62.50%0.7400 fallosExpansión bilingüe ES/EN + Concept Hubs
negativo (Falsos Positivos)40N/AN/AN/A0 FP (0.00%)Calibración Conforme (Conformal Prediction $\alpha=0.05$)
ambiguo (Contradictorias)6N/AN/AN/A2 incompletosEvaluadas por separado fuera del recall global
GLOBAL RETRIEVAL875100.00%91.77%0.9500 fallos Top-5🎯 100% Cobertura Top-5 (803/875 en Top-1 directo)

GLOBAL SUMMARY v33.0 (snapshot canónico, 921 casos): Global Recall@5: 100.00% (875/875) | Global Recall@1: 91.77% (803/875) | MRR: 0.950 | Tasa de Falsos Positivos: 0.00% (0 / 40) | Fallos de Recuperación Top-5: 0.


🔬 Análisis Causal y Metodológico: Deconstrucción del Rendimiento

Para comprender rigurosamente qué produce estos resultados y evitar interpretaciones erróneas sobre el alcance del sistema:

1. ¿Qué produce realmente el 100.00% de Recall@5?

El 100% de Recall@5 significa que en ninguno de los 875 casos de prueba el recuerdo relevante queda fuera del Top-5. Esto no es magia ni simulación cerebral; es el resultado de la cooperación estructurada de 6 capas de filtrado y activación:

  • FTS5 BM25 + Stemmer Bilingüe: Resuelve de inmediato la gran mayoría de casos literales y preguntas naturales (~60% del corpus total).
  • Sustantivos Clave (2 a 10 términos): Actúan como un ancla semántica determinista, atrayendo queries conceptualmente densas hacia el nodo canónico.
  • Expansión Sináptica BFS (Hebbiana): Explora hasta profundidad 2 con atenuación por Efecto Fan de ACT-R ($W_j / \text{fan}_j$), rescatando nodos conceptualmente vinculados aunque su texto no coincida.
  • PPMI + SVD (100 dimensiones): Proporciona la señal de co-ocurrencia estadística para agrupar términos afines sin matrices densas gigantes.
  • Re-ranking Aditivo Multicampo (Spec 005 / v32.3): Aplica un bono de convergencia de evidencia ($\le 0.085$) cuando los tokens coinciden a través de múltiples campos estructurados (concepto, sinonimos, sustantivos_clave, contenido).
  • Calibración Conforme (Split Conformal Prediction): Fija un percentil dinámico para descartar ruido sin generar falsos positivos en consultas fuera de dominio (0/40 FP).

2. ¿Por qué el Recall@1 es 91.77% y no 100%?

El Recall@1 revela la frontera real del sistema sin embeddings neuronales densos:

  • Categorías con alto R@1: literal (99.59%), dormido (100%), pregunta_natural (95.38%). Aquí las señales léxicas y de sustantivos clave son unívocas.
  • Categorías con R@1 moderado: sinonimo (56.36%), cruce_idioma (62.50%), por_tema (67.69%). En estos casos, el nodo gold entra siempre en el Top-5 gracias a la expansión sináptica y dimensional, pero compite contra nodos vecinos que tienen mayor solapamiento superficial de tokens. El re-ranking multicampo sube estos casos hacia las primeras posiciones, pero el desempate fino en Top-1 sigue siendo el área de optimización prioritaria.

3. Generalización vs. Demostración de Concept Hubs

  • Los 5 casos documentados de Concept Hubs verifican que el protocolo de 5 ángulos (sinonimo, problema, solucion, situacion, ingenuo) es un enrutador determinista perfecto para patrones conocidos y estructurados.
  • Para consultas imprevistas de mundo abierto en el Abismo Léxico (sin Concept Hub registrado), el sistema recurre a la red de seguridad topológica (BFS sináptico) y al protocolo de razonamiento y descomposición de consulta del agente.

Desglose Histórico por Categoría de Recuperación — v26.2 (921 Casos QA, Snapshot Aislado)

CategoríaR@5 v26.1R@5 v26.2R@1 v26.1R@1 v26.2Δ R@1
dormido100.00%100.00%100.00%100.00%=
literal100.00%100.00%99.59%99.59%=
pregunta_natural100.00%100.00%93.85%96.92%+3.07pp ↑
variante_gramatical98.46%98.46%90.77%93.85%+3.08pp ↑
typo96.92%96.92%95.38%96.92%+1.54pp ↑
cruce_idioma87.50%87.50%62.50%62.50%=
sinonimo36.07%36.07%27.87%27.87%=
por_tema1.54%1.54%0.00%0.00%=
GLOBAL R@1——85.58%86.15%+0.57pp ↑
MRR——0.8650.869+0.004 ↑
FP Rate (producción)25.0% (10/40)7.5% (3/40)——−70% ↓

Nota sobre por_tema/sinonimo en snapshot frío: Estas categorías dependen del índice PPMI entrenado sobre el corpus real de producción. En snapshot aislado sin vectores PPMI reales, su Recall@5 refleja el comportamiento sin señal #13. En la DB de producción viva: por_tema 86.15%, sinonimo 83.61% (medido en benchmarks de producción v26.0+).

GLOBAL SUMMARY (snapshot aislado, 921 casos): Global R@1: 86.15% | MRR: 0.869 | FP Negativo (producción): 7.5% (reducido de 25.0%)

Validación de determinismo: 4 corridas consecutivas idénticas → misma tabla. Snapshot reproducible en snapshots/ablation_parent_pointers.db.

Scoring híbrido: 12 señales. Incluye Predicados SRL como Signal #12 (peso 0.20, capacidad de backfill restante, documentada con nota de canibalización), Feedback-Driven Graph Learning (LTP asintótico sobre aristas de spreading activation), La Hormiguita para mantenimiento autónomo del grafo con cuarentena y benchmark gate, y re-ranking jaccard léxico (v25.2) como señal de matching en por_tema (+13.85pp). Experiments rechazados documentados: JSD, Bayesian BM25, PPR (Diffusión de Calor), FCA (Reticulados de Galois), boost dimensional. Ver EXPERIMENTS.md.


📑 Registro Científico y Validación

🔬 Registro Oficial (DOI)

Certificado por Zenodo/CERN para integridad académica y preservación técnica.

DOI

Ver registro en Zenodo


🧪 Verificación y Reproducibilidad

Todo número que afirma este README fue producido por un script que puedes ejecutar tú mismo. Esta sección es la garantía de veracidad del proyecto — sin argumentos, solo comandos y resultados esperados.

Instalación de Dependencias

# Clonar e instalar
git clone <url> MemoryBioRAG && cd MemoryBioRAG
pip install numpy nltk fastapi uvicorn pytest
pip install mcp  # servidor MCP
# WordNet local (requerido para fallback simbólico — se descarga una sola vez)
python3 -c "import nltk; nltk.download('wordnet'); nltk.download('omw-1.4')"

Snapshot de Base de Datos para Pruebas

El repositorio incluye un snapshot congelado listo para usar sin necesidad de la DB de producción:

# Snapshot incluido en el repo (38.9 MB):
# scripts/snapshot_prf_real.db  — corpus de ~800 nodos congelado

# Para apuntar cualquier script de evaluación al snapshot:
BIORAG_PATH=scripts/snapshot_prf_real.db python3 scripts/evaluar_qa.py

# Para crear tu propio snapshot desde tu DB activa:
#   IMPORTANTE: NO uses `cp`. La DB viva corre en WAL mode y `cp` copia solo el
#   archivo .db ignorando el -wal no checkpointeado -> copia corrupta
#   ("database disk image is malformed"). Usa la API backup de SQLite, que hace
#   checkpoint del WAL y produce una copia consistente:
python3 << 'EOF'
import sqlite3, time
src = "MemoryBioRAG_Data/memory_biorag.db"
dst = f"scripts/mi_snapshot_{time.strftime('%Y%m%d')}.db"
con = sqlite3.connect(src); con.execute("PRAGMA wal_checkpoint(TRUNCATE)")
out = sqlite3.connect(dst); con.backup(out)
out.close(); con.close()
print("Snapshot creado:", dst)
EOF
BIORAG_PATH=scripts/mi_snapshot_$(date +%Y%m%d).db python3 scripts/evaluar_qa.py

⚙️ ZONA DE OPERACIONES — Reentrenamiento y Evaluación (para un evaluador externo)

Todo lo que un ingeniero externo necesita para reentrenar y evaluar la DB, en un solo lugar.

Los DOS tipos de reentrenamiento (y cuándo corre cada uno)

Los vectores PPMI+SVD NO se auto-calibran en cada guardado: son un snapshot persistido en las tablas tokens y nodos, entrenados en el momento de la última reindexación. Si copias una DB sin esas tablas (p. ej. snapshots anteriores a v26.0), la señal #13 queda en cero (verificado: scripts/snapshot_prf_real.db da sinonimo 70.49% con señal #13 = 0).

TipoMecanismoCuándo correQué hace
1. Reentrenamiento incremental (suave)fold_in_nodos (core/ppmi_vectorizer.py)En cada ciclo de sueñoLos conceptos nuevos reciben un vector instantáneo (<10ms) promediando los tokens de la matriz existente. No toca el grafo entero, no reentrena el SVD.
2. Reentrenamiento completo (espectral)reindexar_ppmi_svd (core/ppmi_vectorizer.py)Automático: solo si ≥7 días Y ≥50 nodos acumulados (_ppmi_full_reindex_due). Manual: cuando lo fuerces.Recalcula todo el SVD (100 dims) + Retrofitting Hebbiano sobre el grafo completo, regenerando las tablas tokens y nodos.

El contador ppmi_nodos_acumulados (tabla data) cuenta los nodos nuevos desde la última reindexación completa. No es un backlog de nodos sin entrenar: los nodos nuevos ya tienen vector (vía fold-in); solo marca cuándo conviene hacer el full espectral para recalibrar el SVD global. Se incrementa en cada ciclo de sueño y se resetea a 0 cuando corre el full.

Además, SDM (core/sdm.py) reindexa incrementalmente el dirty set en cada consolidación y hace full reindex cada 24 h (SDM_FULL_REINTERVAL=86400).

Comando para forzar el reentrenamiento completo (Signal #13)

Un solo comando, sobre cualquier DB, fuerza el full espectral ya (no espera los 7 días ni los 50 nodos):

# Sobre la DB de producción
./scripts/reentrenar_ppmi.sh

# Sobre cualquier DB (snapshot, copia, evaluación)
./scripts/reentrenar_ppmi.sh scripts/snapshot_prf_real.db
# o equivalente:
BIORAG_PATH=scripts/snapshot_prf_real.db python3 scripts/reentrenar_ppmi.py

Comando directo sin script (la función es reindexar_ppmi_svd en core/ppmi_vectorizer.py:298):

# Entrenar manualmente los vectores PPMI+SVD de cualquier DB por comando:
import sqlite3
from core.ppmi_vectorizer import reindexar_ppmi_svd
con = sqlite3.connect("MemoryBioRAG_Data/memory_biorag.db")  # o ruta a snapshot
reindexar_ppmi_svd(con, dim=100, retrofit_lam=0.2, retrofit_iters=5)
con.close()

Verificado (2026-08-10): 688 nodos → 4.3s; 846 nodos → 7.2s; contador ppmi_nodos_acumulados reseteado a 0. Regenera las tablas tokens y nodos (SVD truncado completo + retrofitting Hebbiano) y reactiva la señal #13 en la DB.

El script muestra el estado ANTES/DESPUES (tokens, nodos, con_vector, última reindex, acumulados) y reentrena en segundos. Verificado (2026-08-10): 846 nodos en 7.2s, contador reseteado a 0.

Despertar la neurona (práctica acelerada)

La neurona de BioRAG (ver La Neurona de BioRAG) aprende sola cada vez que se consolida la memoria: hasta 8 recuerdos × 7 preguntas por consolidación, dentro de 3 s, con costo fijo. En una memoria nueva con uso normal eso alcanza (examen listo en ~15 consolidaciones, ver Cuánto tarda en aprender sola). En una memoria que ya tiene cientos de recuerdos y recibe pocos nuevos, juntar el examen y ascender el primer campeón puede tardar semanas.

Este script hace en minutos lo mismo que haría el uso: repite N veces neurona.practicar(db, []), exactamente lo que corre tras cada consolidación, con las mismas protecciones (guardia, piso por categoría, margen "primero no dañar" y retiro si daña algo). No es otro entrenamiento.

# Sobre la DB de producción (o la de BIORAG_PATH)
./scripts/despertar_neurona.sh

# Sobre cualquier DB (copia, evaluación)
./scripts/despertar_neurona.sh ruta/copia.db
./scripts/despertar_neurona.sh ruta/copia.db --ciclos 300     # default 500 (~22 min con ~900 recuerdos)
./scripts/despertar_neurona.sh ruta/copia.db --minutos 10     # tope de tiempo
./scripts/despertar_neurona.sh ruta/copia.db --hasta-techo    # cortar en el primer techo

# Solo mirar el estado (no escribe nada)
./scripts/despertar_neurona.sh --estado

# Deshacer: borrar lo aprendido (vuelve la fórmula a mano)
./scripts/despertar_neurona.sh --olvidar --si

# Otro intérprete (p. ej. un venv)
PYTHON=.venv/bin/python ./scripts/despertar_neurona.sh

Qué escribe: solo la tabla neurona_estado. Verificado sobre una copia del snapshot: con la DB ya abierta, 40 ciclos cambian neurona_estado y las otras 48 tablas quedan idénticas. Abrir la DB, como cualquier arranque de BioRAG, corre además el arranque normal del motor (por ejemplo, la síntesis DMN E10). Antes de escribir hace un respaldo con la API backup de SQLite (<db>.antes_despertar_<fecha>.db), salvo --sin-respaldo.

Dónde correrlo: sobre la misma DB que vas a usar. Lo aprendido es de esa memoria: un campeón entrenado en otra DB y copiado daña, y el piso lo termina retirando. Lo recomendado:

  1. Correrlo sobre una copia y medir con tu QA sobre esa copia (BIORAG_PATH=copia.db ./scripts/run_qa_suite.sh). Para el snapshot oficial, la QA lo hace en un solo paso: python scripts/evaluar_qa.py --con-neurona (ver La neurona en la QA).
  2. Si te convence, correrlo sobre la real.

El snapshot congelado oficial (snapshots/) se rechaza, porque es la referencia de la QA.

Qué muestra: el estado ANTES y DESPUÉS (o, con --estado, el estado actual) en palabras de cualquier persona, sin jerga. Si no encuentra una mejora segura no asciende a nadie, y el motor queda exactamente igual a la fórmula a mano. Ejemplo real de --estado en una memoria que acaba de empezar:

  ESTADO DE TU NEURONA
  ────────────────────────────────────────────────────────────────────────────
  ¿Está encendida?              ✅ sí
  ¿Ya mejora tus búsquedas?     ⏳ todavía no: se usa la fórmula de siempre (fórmula a mano)
  Etapa                         1 de 3 · Juntando preguntas
                                todavía no tiene suficientes preguntas para presentar su examen.

  SU EXAMEN (preguntas que ella misma se hace con tus recuerdos)
    Para estudiar               [░░░░░░░░░░░░░░░░░░░░]    5 de 150
    De control (nunca estudia)  [░░░░░░░░░░░░░░░░░░░░]    0 de 40

  SU HISTORIAL
    Veces que practicó          3     (1 vez por cada consolidación de la memoria)
    Última práctica             hace un momento
    Veces que aprobó            0
    Veces que la quitaron       0     ✅ bien

  👉 En resumen: está viva y aprendiendo. Le faltan 145 para estudiar y 40 de control.
     Practica unos segundos cada vez que se consolida la memoria (consolidar,
     dormir o cerrar sesión; guardar solo no basta). Para acelerar:
     ./scripts/despertar_neurona.sh --minutos 20

Cómo leerlo:

LíneaQué significa
¿Ya mejora tus búsquedas?⏳ todavía no: tus búsquedas salen con la fórmula a mano. 🏆 sí: la neurona ya ordena tus resultados.
Etapa1 · Juntando preguntas → 2 · Presentando su examen (ya tiene preguntas; solo se activa si mejora sin dañar nada) → 3 · Trabajando.
Para estudiar / De controlLas preguntas que la neurona se hace con tus recuerdos. Las de control (el 20 % de recuerdos, la "guardia") nunca las estudia: sirven para comprobar que aprendió y no memorizó. Necesita 150 y 40.
Veces que practicóSube 1 con cada consolidación (consolidar, sueno o cerrar sesión con contexto_fin). aprender deja el recuerdo en corto plazo y no cuenta hasta que se consolida: 10 aprender + 1 consolidar = 1 práctica. Si sube, está viva.
Última prácticaCuándo guardó por última vez lo aprendido.
Veces que aprobó / que la quitaronAprobó = pasó a trabajar. La quitaron = empeoraba algo y volvió sola a la fórmula; debe quedar en 0.
Aciertos en 1er lugar (cuando ya trabaja)En sus preguntas de control: fórmula contra neurona.
Prudencia (cuando ya trabaja)El margen "primero no dañar": solo cambia el orden si está segura.

Verificado (2026-10-24), sobre una copia del snapshot canónico (~900 recuerdos): 500 ciclos en 1017 s, 6 ascensos y 0 retiros. En la guardia, el primer lugar pasa de 77.8 % (fórmula) a 87.0 % (neurona). Después, la QA oficial sobre esa copia: R@1 91.66 → 94.06 %, R@5 99.89 → 100 %, MRR .949 → .964, FP 0/40, GATE OK, ninguna categoría por debajo del piso. Salida completa en docs/Mi neurona en el sistema/experimento_07_la_neurona_escucha/resultados/despertar/.

Comando para el ciclo de sueño completo

Consolida corto_plazo + corre el fold-in/full automático según condiciones + SDM:

python3 sleep_cycle.py

Comando para la evaluación QA completa

# Suite orquestadora completa
./scripts/run_qa_suite.sh

# Evaluación directa sobre cualquier DB (usa BIORAG_PATH)
BIORAG_PATH=scripts/snapshot_prf_real.db python3 scripts/evaluar_qa.py

Resultado verificado (2026-08-10): reentrenando el snapshot snapshot_prf_real.db (688 nodos) la señal #13 se activa y sinonimo sube de 70.49% → 81.97% y GLOBAL R@5 de 95.57% → 96.37%. Los vectores no se auto-calibran por copiar la DB: hay que reentrenarlos o partir de una DB que ya los tenga entrenados.

La neurona en la QA (cada base tiene la suya)

La neurona de ranking aprende con los recuerdos de la base donde vive y guarda lo aprendido dentro de ella (tabla neurona_estado). No viaja entre bases: la de tu DB viva no está en el snapshot, y una copiada a otra base daña (el piso la retira). Por eso la QA oficial, que mide una copia del snapshot, muestra la fórmula a mano sola aunque tu neurona esté trabajando.

Desde ahora evaluar_qa.py (y run_qa_suite.sh, que le pasa los argumentos) hace tres cosas más:

  1. Dice la verdad antes de medir: qué base mide, si tiene neurona y si tu DB viva sí la tiene. Lee tu DB viva en solo lectura, sin abrir el motor sobre ella. Si la neurona está en otra base, nombra el parámetro para verla.
  2. Mide las dos columnas en la misma corrida: el orden de la fórmula sola (antes de la neurona) y el que sirvió el motor (después). Mismas preguntas, misma base, mismo instante: solo cambia quién ordena el top-5. Un "espía" envuelve neurona.reordenar y anota los dos órdenes, sin cambiar ningún resultado.
  3. Vigila que no dañe (entra al gate): Recall@5 idéntico, el total de aciertos en 1er lugar no baja y ninguna categoría pierde más de BIORAG_QA_NEURONA_TOL_CASOS casos en 1er lugar (default 1, el mismo piso que la neurona se exige a sí misma).

Cómo se decide si se entrena:

ComandoLa base medida YA tiene neuronaLa base medida NO tiene neurona
./scripts/run_qa_suite.sh (el de siempre)la usa tal cual, sin entrenar: tabla con 🧠tabla de siempre + el aviso
./scripts/run_qa_suite.sh --con-neuronala usa tal cual, sin entrenar: tabla con 🧠pregunta: cuánto tardaría y "¿La entreno ahora? [s/N]". s → entrena en la copia y sigue la prueba; n o Enter → tabla de siempre
... --con-neurona --siigualentrena sin preguntar (CI o scripts)

Sin una persona frente a la terminal (CI, tubería), --con-neurona no pregunta ni entrena: nadie dijo que sí. Para eso está --si.

# Tu QA de siempre, con la opción de ver la neurona (pregunta antes de entrenar)
./scripts/run_qa_suite.sh --con-neurona
./scripts/run_qa_suite.sh --qa-only --con-neurona               # solo la QA de 921 casos
python scripts/evaluar_qa.py --con-neurona --minutos 10         # con tope de tiempo
python scripts/evaluar_qa.py --con-neurona --si                 # sin preguntar

# Medir tu propia memoria con tu propia neurona (la QA mide una copia; tu DB no se toca)
BIORAG_PATH=MemoryBioRAG_Data/memory_biorag.db python scripts/evaluar_qa.py

Lo que sale cuando la base medida no tiene neurona pero tu DB viva sí (corrida real del 2026-10-25; aquí la "DB viva" es una copia del snapshot con 111 prácticas):

🧠 NEURONA DE RANKING
   Base medida:  snapshots/qa_escape_qcr_20260811.db  (snapshot oficial; se mide una copia temporal)
   Neurona:      ⏳ esta base no tiene una neurona entrenada
                 → la tabla es la FÓRMULA A MANO SOLA (el piso)
   Tu neurona:   🏆 ACTIVA en tu DB viva (/tmp/qa/snap_train.db)
                 entrenada con esa memoria · 111 prácticas · aprobó 3 veces · la quitaron 0
                 en su examen de control acierta el 1er lugar: fórmula 78.8 % → neurona 95.5 %
   Cada base tiene su propia neurona: lo que aprendió tu DB viva no viaja a la
   copia que mide esta QA. Por eso aquí no se ve (y eso es correcto).
   Para ver la neurona en esta QA (sin tocar ninguna base original):
     python scripts/evaluar_qa.py --con-neurona
       → pregunta si quieres entrenar una en la copia temporal y la mide
     BIORAG_PATH=/tmp/qa/snap_train.db python scripts/evaluar_qa.py
       → mide tu propia memoria con tu propia neurona

Lo que pregunta --con-neurona cuando la base medida no tiene neurona (corrida real con ./scripts/run_qa_suite.sh --qa-only --con-neurona):

🧠 Usaste --con-neurona, pero esta base no tiene una neurona entrenada.
   Para verla en la tabla hay que entrenarla primero:
     · hasta 500 prácticas, como máximo ~25 min (cada una dura hasta 3 s;
       con ~900 recuerdos, 500 prácticas tardaron 23 min).
     · necesita por lo menos unos 3 min para juntar su examen y aprobarlo; con menos
       puede no aprobar, y entonces la tabla sale igual que siempre.
     · se entrena en la copia temporal: tu base no se toca.
   Después sigue la prueba con los mismos 921 casos.
   Si dices que no, sale la tabla de siempre (sin neurona).
¿La entreno ahora? [s/N]:

Lo que sale cuando la base medida sí tiene neurona (la misma copia; corrida real): la tabla de siempre muestra lo que sirve el motor y, al final de cada fila, cuánto cambió la neurona el 1er lugar. Debajo, el detalle:

cruce_idioma           | 8      |  100.00% |   75.00% |  0.875 | 0           🧠 +12.50 pp (fórmula sola 62.50%)
dormido                | 65     |  100.00% |  100.00% |  1.000 | 0           🧠 = igual (fórmula sola 100.00%)
literal                | 487    |  100.00% |   99.79% |  0.999 | 0           🧠 +0.20 pp (fórmula sola 99.59%)
por_tema               | 65     |  100.00% |   78.46% |  0.872 | 0           🧠 +15.38 pp (fórmula sola 63.08%)
pregunta_natural       | 65     |  100.00% |   95.38% |  0.977 | 0           🧠 +1.53 pp (fórmula sola 93.85%)
sinonimo               | 55     |  100.00% |   61.82% |  0.742 | 0           🧠 +5.46 pp (fórmula sola 56.36%)
typo                   | 65     |  100.00% |   93.85% |  0.967 | 0           🧠 +4.62 pp (fórmula sola 89.23%)
variante_gramatical    | 65     |  100.00% |   93.85% |  0.965 | 0           🧠 +4.62 pp (fórmula sola 89.23%)
GLOBAL SUMMARY (Retrieval) | 875    |  100.00% |   94.40% |  0.966 | 0           🧠 +2.51 pp (fórmula sola 91.89%)

LA NEURONA EN ESTA QA (misma base, mismas preguntas; solo cambia quién ordena el top-5)
  Recall@5 y falsos positivos: idénticos (la neurona solo reordena los mismos 5).
  Búsquedas que la neurona reordenó: 398 de 875.
  La respuesta correcta SUBIÓ al 1er lugar en 27 y BAJÓ del 1er lugar en 5 (neto +22).
  Mejoró su puesto en 39 · empeoró en 11.
  Tiempo de la neurona por búsqueda: mediana 0.12 ms · 95 % bajo 0.17 ms · peor 2.06 ms.
  Control de daño: ✅ pasa (ninguna categoría pierde más de 1 caso en 1er lugar; en total no baja)

Cómo se comprobó que la medición es correcta (2026-10-25, misma máquina, PYTHONHASHSEED=1):

CorridaQué se midióResultado
1Código anterior, snapshotR@5 100 · R@1 91.89 · MRR 0.950 · FP 0/40
2Código nuevo, snapshot (con el aviso)tabla idéntica a la corrida 1, línea por línea
3Código nuevo, copia con neuronacolumna "fórmula sola" = corrida 1 en todas las categorías (R@1 y MRR); con neurona R@1 94.40 · MRR 0.966; R@5 y FP iguales
4La misma copia con BIORAG_NEURONA=0tabla = columna "fórmula sola" de la corrida 3
5Código nuevo, snapshot, --con-neurona (500 prácticas en la copia, 23 min)R@1 91.89 → 94.97 · MRR 0.950 → 0.970 · R@5 y FP iguales · 27 respuestas suben al 1er lugar y ninguna baja · GATE OK · el snapshot conserva su sha256
6./scripts/run_qa_suite.sh --qa-only --con-neurona, respuesta npregunta y no entrena; tabla idéntica a la corrida 1; suite FINALIZADA CON ÉXITO
7./scripts/run_qa_suite.sh --qa-only sobre una copia que ya tiene neurona (5 min de despertar)no entrena: usa la que hay; R@1 91.89 → 95.20 · MRR 0.950 → 0.971 · control de daño pasa
8--con-neurona --minutos 5, respuesta spregunta, entrena 110 prácticas y sigue: R@1 91.89 → 94.97 · GATE OK

Ninguna base original se escribe: el estado de tu DB viva se lee en solo lectura y --con-neurona practica sobre la copia temporal, que se borra al terminar. La copia de la corrida 3 tiene el mismo sha256 antes y después de la QA. El bloque neurona de qa_metrics.json trae las dos columnas por categoría, los cambios, los tiempos y el control de daño, listos para CI. Salidas completas de las corridas: docs/Mi neurona en el sistema/qa_con_neurona_20261025/.

Límites: cuánto mejora depende de la neurona que se entrenó. La práctica tiene un tope de 3 s por ciclo, así que cada entrenamiento puede salir algo distinto, sobre todo en otra máquina: en la misma máquina, dos entrenamientos de 500 prácticas dieron R@1 94.40 % (corrida 3) y 94.97 % (corrida 5), y dos de 5 minutos dieron 95.20 % (corrida 7) y 94.97 % (corrida 8). Más prácticas no garantizan más aciertos en esta QA. Compara siempre las dos columnas de la misma corrida. Las preguntas de la QA se escribieron para el snapshot, así que sobre tu DB viva algunas respuestas no existen o significan otra cosa: allí la QA sirve para comparar fórmula sola contra neurona, no para compararse con la tabla oficial.


Test 1 — Suite Biológica Completa (112 tests unitarios)

Qué verifica: LTP/LTD, ciclo de sueño, inferencia transitiva, SRL por roles, inhibición GABA, spreading activation, sinonimia limpia, SDM query-by-example, re-ranking Jaccard y 100+ comportamientos del motor.

python3 test_memory.py

Resultado esperado: 112 tests passed


Test 2 — QA Cranfield Completo (921 casos, 8 categorías)

Qué verifica: Recall@5 y Recall@1 sobre el corpus de producción. Evalúa recuperación exacta, typos, sinónimos, cruce de idiomas, preguntas naturales, búsquedas temáticas y falsos positivos. Sigue el paradigma Cranfield (known-item search), el estándar formal de IR desde hace 60 años.

# Con el snapshot incluido (recomendado para reproducibilidad exacta)
BIORAG_PATH=scripts/snapshot_prf_real.db python3 scripts/evaluar_qa.py

# Con la DB de producción activa
python3 scripts/evaluar_qa.py

# Script orquestador completo
./scripts/run_qa_suite.sh

Resultado esperado (con BIORAG_PPMI_WEIGHT=0.15, 921 casos, snapshot congelado):

CategoríaRecall@5
literal~100%
dormido~100%
typo~98.5%
variante_gramatical~95.4%
pregunta_natural~100%
cruce_idioma~87.5%
sinonimo~83.6%
por_tema~86.2%
GLOBAL~96.7%

Test 3 — Motor PPMI+SVD+Retrofitting (35 casos — gates de evaluación)

Qué verifica: Los gates de evaluación del motor semántico vectorial.

Nota de arquitectura: El motor PPMI está implementado en dos niveles:

  1. scripts/ppmi_svd_retro.py (este repo) — evaluación contra la DB activa de producción. Mide el comportamiento integrado con el grafo vivo.
  2. Repo hermano word2vec (scripts/ppmi_svd_retrofit.py) — evaluación aislada contra el snapshot congelado memory_biorag_snapshot_20260808.db. Reproduce los 3 gates simultáneos documentados en v26.0.
# Test integrado (este repo) — reentrena PPMI+SVD completo sobre DB activa, resetea ppmi_nodos_acumulados a 0 y evalúa
python3 scripts/ppmi_svd_retro.py --eval


# Sin retrofitting (baseline de comparación)
python3 scripts/ppmi_svd_retro.py --eval --no-retrofit

# Control de cordura — coseno semántico entre dos tokens
python3 scripts/ppmi_svd_retro.py --par sistema memoria

# Para los 3 gates completos (repo word2vec, snapshot congelado):
# cd ../word2vec && python3 scripts/ppmi_svd_retrofit.py --eval

Resultados en producción (evaluado en vivo — 2026-08-10):

GateUmbralppmi_svd_retro.py (DB activa)ppmi_svd_retrofit.py (snapshot congelado)
por_tema top-5≥ 10/2110/21 ✔14/21 ✔
sinonimo top-5≥ 6/141/14 ✗8/14 ✔
sinonimia limpia≥ 1—2 ✔

Por qué difiere: la evaluación integrada usa la DB activa (~800+ nodos, sinónimos de producción); el snapshot congelado tiene 803 nodos del 2026-08-08 con la distribución exacta con la que se calibró el sistema. La señal IDF-Synonym depende de la distribución de sinónimos curados, que varía con el corpus. La ganancia de sinónimos en producción viene del pipeline completo (evaluar_qa.py), no del módulo PPMI aislado.

💡 Glosario Técnico del Motor Vectorial:

  • Reentrenamiento Espectral (Full SVD): Toma la matriz de co-ocurrencia del corpus activo, calcula la descomposición en valores singulares (TruncatedSVD a 100 dims) y reajusta la geometría global del espacio semántico.
  • Fold-in Incremental: Inyecta un nodo nuevo al espacio vectorial existente en $<10\text{ ms}$ promediando sus tokens ponderados por IDF, permitiendo guardados en tiempo real sin congelar la CPU.

Test 4 — Tests Adversariales y Fuzzing (33 casos)

Qué verifica: Robustez ante entradas corruptas o maliciosas: SQL injection, bytes nulos, texto de 60K caracteres, emojis, JSON roto, valores numéricos fuera de rango. Cero excepciones no controladas, cero mutaciones de estado.

python3 scripts/fuzz_qa.py

Resultado esperado: 33/33 EXITOSO — 0 fallos — 0 mutaciones de estado


Test 5 — Concurrencia (20 hilos + 20 clientes HTTP simultáneos)

Qué verifica: Lecturas y escrituras simultáneas sobre SQLite WAL — sin bloqueos, sin colisiones sinápticas, sin dobles despertares de nodos dormidos.

python3 scripts/concurrencia_qa.py

Resultado esperado: 0 colisiones de escritura | 0 bloqueos de DB | ≤ 2.52s total


Test 6 — Benchmarking de Escala (hasta 50.000 nodos)

Qué verifica: Tiempos de respuesta del motor con volúmenes crecientes de datos sintéticos.

python3 scripts/escala_qa.py

Resultado esperado:

Operación50K nodosComplejidad
Búsqueda BM25/FTS5≤ 0.31sO(N log N)
Fuzzy/Trigram fallback≤ 0.08sO(log N)
Ciclo de sueño≤ 45sO(N) — background, no afecta usuario

Test 7 — Ablation: Re-ranking Jaccard (+13.85pp por_tema)

Qué verifica: La ganancia real de +13.85pp en por_tema producida por el re-ranking jaccard, validada sobre un holdout 50/50 estratificado con seed fija (no sobre-optimización).

# Fase A: baseline real sobre corpus completo (establece punto de partida honesto)
python3 scripts/experimento_faseA_eval.py /tmp/salida_faseA.json

# Fase B: holdout 50/50 con seed fija — la mitad B nunca vio el ajuste
python3 scripts/experimento_faseB_holdout.py

# Fase B con protect-r0 — configuración ganadora (cero regresiones R@1)
python3 scripts/experimento_faseB_protect_r0.py

Test 8 — Tests Especializados por Componente

# SDM Query-by-Example
python3 tests/test_sdm_query_by_example.py

# SDM suite completa y diversidad de casos
python3 tests/test_sdm_completo.py
python3 tests/test_sdm_diverso.py

# Evaluación causal SRL
python3 tests/test_eval_causal_srl.py

# PPMI — reindexación selectiva y propagación de vecinos
python3 scripts/test_reindex_selectivo_diagnostico.py
python3 scripts/test_reindex_propagacion_vecinos.py

# HDC Binding — colisiones y versionado
python3 scripts/test_hdc_binding_sintetico.py
python3 scripts/test_hdc_stress_versionado.py

Test 9 — Auditoría Causal A/B Diferencial (Propagación Hebbiana & Abismo Léxico)

Qué verifica: Evaluación diferencial estricta A/B (1 a 1 sobre los 921 casos) para aislar el impacto causal del refuerzo Hebbiano:

  • Modo A (Baseline): Sin propagación Hebbiana a primarios en BFS.
  • Modo B (Actual): Con propagación Hebbiana a primarios en BFS.
  • Métricas: Rescates a Top-5, regresiones, movimientos de ranking, auditoría de spreading activation y cálculo formal de Graph-Candidates-Found vs Graph-Rescue@5.
# Ejecutar auditoría causal A/B sobre snapshot congelado:
python3 scripts/auditoria_causal_hebbiano.py

Salida generada: scripts/auditoria_causal_report.json (reporte estructurado de deltas).


Test 10 — Ablación de Mecanismos Neuro-Narrativos

Qué verifica: La contribución real (en Recall@5) de cada mecanismo que tiene naming "neuro-narrativo" — GABA, PPMI+SVD, Re-ranking Jaccard y DMN. Responde directamente la pregunta: "¿Estos mecanismos en verdad aportan, o son solo marketing?"

Cada configuración desactiva un mecanismo vía variable de entorno y corre la suite completa de 921 casos de prueba:

# Reconstruir el snapshot determinista desde fuentes (auto-valida que la DB tenga datos; si no existe o está vacía, la genera en <5s)
python3 scripts/generar_snapshot.py

# Medición empírica de frecuencia de activación GABA (auto-verifica contenido DB antes de medir)
python3 scripts/medir_gaba_activacion.py

# Ablación completa automática (5 configs × 921 casos ≈ 45-50 minutos)
python3 scripts/ablacion_mecanismos.py

# Ablación manual por mecanismo individual:

# 1. Sin GABA (inhibición lateral OFF)
BIORAG_GABA_ACTIVO=0 python3 scripts/evaluar_qa.py

# 2. Sin Re-ranking Jaccard léxico
BIORAG_RERANKING_JACCARD_ENABLED=0 python3 scripts/evaluar_qa.py

# 3. Sin PPMI+SVD (señal vectorial apagada)
BIORAG_PPMI_WEIGHT=0.0 python3 scripts/evaluar_qa.py

# 4. Sin Retrofitting de Grafo Hebbiano (solo PPMI puro)
python3 scripts/ppmi_svd_retro.py --eval --no-retrofit

# 5. Sin DMN (ideación en reposo desactivada)
BIORAG_DMN_IDLE_SECONDS=999999 python3 scripts/evaluar_qa.py

# 6. Sin la guardia de orden monotónico (v30.1) — solo para reproducir el bug
BIORAG_ORDEN_MONOTONICO=0 python3 scripts/evaluar_qa.py

Gate de regresión de la suite QA (v30.1): scripts/evaluar_qa.py escribe scripts/qa_metrics.json (cifras machine-readable, listas para diff/CI) y termina en exit 1 si la corrida queda por debajo de la baseline oficial. Es lo que faltaba: hasta v30.0 el evaluador siempre salía en 0 y, con set -e en run_qa_suite.sh, la suite imprimía "FINALIZADA CON ÉXITO" aunque el Recall@5 global hubiera caído de 97.39 % a 95.23 % (+19 fallos), que es exactamente lo que pasó el 2026-09-02.

# Umbrales por defecto = baseline oficial 2026-08-26 (Recall@5 97.39 %, 23 fallos, 0 % FP)
./scripts/run_qa_suite.sh

# Corrida exploratoria (ablación, experimento): apagar el gate
BIORAG_QA_GATE=0 ./scripts/run_qa_suite.sh

# Relajar umbrales puntualmente
BIORAG_QA_MIN_RECALL5=95.0 BIORAG_QA_MAX_FALLOS=42 ./scripts/run_qa_suite.sh

# Fijar una corrida buena como nueva baseline de comparación por categoría
cp scripts/qa_metrics.json scripts/qa_metrics_baseline.json
VariablePropósitoDefault
BIORAG_QA_GATEApagar/encender el gate de regresión1
BIORAG_QA_MIN_RECALL5Recall@5 global mínimo (%)97.0
BIORAG_QA_MAX_FALLOSMáximo de fallos de recuperación23
BIORAG_QA_MAX_FP_RATEMáximo % de FP sobre negativos válidos0.0
BIORAG_QA_MAX_REGRESION_PPCaída máxima por categoría vs. baseline (pp)2.0
BIORAG_QA_BASELINEArchivo de baseline en scripts/qa_metrics_baseline.json
BIORAG_QA_METRICSSalida de métricas JSONscripts/qa_metrics.json
BIORAG_QA_RESOLVER_ETIQUETASResolver etiquetas oro obsoletas contra la DB evaluada1
BIORAG_QA_ETIQUETA_DIFUSARatio mínimo de la resolución difusa de etiquetas0.94
BIORAG_QA_ETIQUETA_MARGENMargen mínimo sobre el segundo candidato0.02
BIORAG_QA_NEURONA_TOL_CASOSCasos en 1er lugar que la neurona puede perder por categoría (solo si actuó; además R@5 idéntico y total en 1er lugar sin bajar)1
BIORAG_QA_DB_VIVADB viva cuya neurona se lee (solo lectura) para el aviso de la QAMemoryBioRAG_Data/memory_biorag.db
BIORAG_QA_ORIGENBase original que se mide (lo pone run_qa_suite.sh, porque la QA solo ve la copia)BIORAG_PATH
BIORAG_ORDEN_MONOTONICORe-sort final de buscar_por_frase por score1

Implementación real de cada mecanismo:

MecanismoNombre Técnico RealImplementaciónVariable de Ablación
GABAInhibición Lateral de Atractor (Edelman 1987)Si top-1 score ≥ 0.80, atenúa competidores con score < top_score×0.70 por factor ×0.60BIORAG_GABA_ACTIVO=0
Retrofitting HebbianoGraph-Constrained Vector Retrofitting (Faruqui 2015)Promedia vectores PPMI con vecinos de sinapsis sinonimo_explicito — λ=0.2, 5 iters--no-retrofit en ppmi_svd_retro.py
PPMI+SVDPointwise Mutual Information + Truncated SVD 100 dimsCoseno entre vector IDF-weighted de query y vectores espectrales de nodos (señal #13)BIORAG_PPMI_WEIGHT=0.0
Re-ranking JaccardLéxico Rescue (Jaccard léxico de tokens sobre head del ranking)score + 0.25 × (jaccard/max_j) sobre top-20, con protect-r0BIORAG_RERANKING_JACCARD_ENABLED=0
LTP/LTD Modulado ACT-RBase-Level Activation & Power Law (Anderson & Lebiere 1998)$B_i = \ln(\sum t_k^{-0.5})$ en nodo_accesos_historial (máx 10); modula decaimiento LTD en sueño $\text{decay} = 0.05 \cdot e^{-0.5 B_i}$BIORAG_NO_LOG=1 / DB
Concept Hubs SemánticosCategorización Prototípica y 5 Ángulos (Rosch 1975, Collins 1969)Puentes ontológicos deterministas pre-FTS5 (sinonimo, problema, solucion, situacion, ingenuo) para abismo léxico y cruce ES/ENTablas concept_hubs / concept_hub_bridges
Efecto Fan ACT-RFan Effect Attentional Modulation (Anderson 1974)Ponderación asociativa multi-salto dividida entre el abanico de conectividad saliente ($W_j/\text{fan}_j$) en _evocacion_por_cadena()Nativo en BFS sináptico
Calibración ConformeSplit Conformal Prediction & Platt Scaling (Vovk 2005, Platt 1999)Umbral de corte no paramétrico calculado con garantía estadística finita $1-\alpha$ sobre controles negativos y sigmoideTabla calibracion_estado
Saturación Dinámica BM25Dynamic BM25 Normalization (Robertson & Zaragoza 2009)Función monótona de saturación $S(x) = \frac{x}{x+k}$ para consultas singleton en _calcular_score_hibrido()Nativo en scoring híbrido
DMNDefault Mode Network (spindles replay en reposo)Daemon thread que genera insights cruzando nodos distantes cuando el agente lleva ≥5 min inactivoBIORAG_DMN_IDLE_SECONDS=999999

Nota sobre LTP/LTD y Activación ACT-R: La suite QA de 921 casos corre con ignore_peso_sinaptico=True por diseño metodológico de campo nivelado. La activación base ACT-R ($B_i$) y la modulación de decaimiento biológico pasivo operan en el ciclo de consolidación de sueño y en la interacción continua en vivo.

Resultados Empíricos del Estudio de Ablación (921 casos QA, snapshot congelado):

Escenario de AblaciónGLOBAL R@5por_tema R@5sinonimo R@5Frecuencia de Activación / Comportamiento
v32.0 Consolidado (Actual)99.31%92.31%100.00%Récord histórico oficial: solo 6 fallos en 875 consultas (0.0% FP)
Baseline histórico v26 (todos ON)95.57%84.62%70.49%Punto de referencia calibrado original
Sin GABA (inhibición lateral OFF)95.57% (0.0pp)84.62% (0.0pp)70.49% (0.0pp)Se activa en el 68.2% de las búsquedas (601/881 casos con top-1 ≥ 0.80). Atenúa competidores (×0.60) en 62.9% de las queries (554/881) sin alterar la membresía Top-5 en Recall@5.
Sin Re-ranking Jaccard94.67% (-0.90pp)67.69% (-16.93pp)72.13% (+1.64pp)Aporte crítico (+16.93pp por_tema): Mecanismo principal que rescata candidatos hundidos por ruido semántico.
Sin PPMI+SVD (weight=0.0)95.46% (-0.11pp)84.62% (0.0pp)70.49% (0.0pp)Aporte vectorial espectral fino en el score de desempate global.
Sin DMN (idle=999999s)95.57% (0.0pp)84.62% (0.0pp)70.49% (0.0pp)Daemon asíncrono de reposo (no participa en la ruta caliente de consulta).

Análisis Objetivo de Ablación:

  1. Re-ranking Jaccard: Es la señal con mayor impacto medible en el benchmark (+16.93pp en por_tema y +0.90pp global), demostrando que el re-sorting de tokens sobre el head rescata ítems que las señales complejas hunden.
  2. GABA (Inhibición Lateral): Se activa en el 68.2% de las consultas de búsqueda (601/881 casos donde el top-1 es un atractor fuerte con score ≥ 0.80), aplicando atenuación efectiva a los competidores secundarios en el 62.9% de los casos (554/881). Dado que atenúa pero no elimina a los ítems 2–5, la composición del conjunto Top-5 se mantiene intacta, registrando 0.0pp de impacto en Recall@5. Su beneficio se manifiesta en la dominancia del Top-1 para prompts posteriores.
  3. DMN y PPMI+SVD: DMN es un proceso asíncrono de trasfondo (ideación y consolidación fuera del path de consulta), mientras que PPMI+SVD aporta un refinamiento espectral sutil (-0.11pp al desactivarse) en el desempate semántico.

[!IMPORTANT] Aclaración Metodológica para Evaluadores:

  • ¿Por qué la tasa de activación GABA es 68.2% en el snapshot determinista?
    En la reconstrucción determinista desde cero (generar_snapshot.py), el pipeline de ingesta pública (percibir_corto_plazo + consolidar_concepto) asegura que todos los 487 conceptos literales se ingresen con estado activo y peso sináptico calibrado, activando GABA en el 100% de los casos literales (487/487). Esto eleva la frecuencia global del 60.3% inicial al 68.2% (601/881 consultas).
  • ¿Por qué GABA da 0.0pp en Recall@5 pese a activarse en el 68.2% de las búsquedas?
    En el benchmark Cranfield (known-item search), Recall@5 mide únicamente la presencia del concepto esperado dentro de los 5 primeros puestos. Cuando el Top-1 alcanza un score ≥ 0.80, GABA atenúa los scores de las posiciones 2 a 5 por un factor de ×0.60. Esta reducción de puntuación suprime la interferencia secundaria pero no altera el orden de presencia del Top-5, resultando en 0.0pp de variación en el benchmark sintético. Su función estructural es concentrar la dominancia en el Top-1 para evitar distracción contextual en el prompt del LLM.
  • ¿Por qué la DMN da 0.0pp en la búsqueda directa?
    La Red por Defecto (DMN) opera como un proceso asíncrono nocturno o de reposo (ideación y mantenimiento de sinapsis en segundo plano). No participa en la ruta caliente (hot path) de una consulta directa, por lo que su desactivación no afecta la recuperación inmediata.

Tabla Resumen de la Suite Completa

TestScriptCasosResultado esperadoTiempo aprox.
Suite biológicatest_memory.py112 tests112/112 ✔~30s
QA Cranfieldscripts/evaluar_qa.py921 casosR@5 95.6% global~9 min
PPMI 3 gatesscripts/ppmi_svd_retro.py --eval35 casospor_tema gate ✔~10s
Adversarialesscripts/fuzz_qa.py33 casos33/33 ✔~15s
Concurrenciascripts/concurrencia_qa.py60 ops0 colisiones ✔~5s
Escalascripts/escala_qa.py4 volúmenesO(log N) BM25 ✔~3 min
Ablation Jaccardscripts/experimento_faseB_holdout.py921 casos+13.85pp por_tema ✔~2 min
SDM QBEtests/test_sdm_query_by_example.pyunitariotodos ✔~5s
Ablación mecanismosscripts/ablacion_mecanismos.py921 × 5 configsTabla de contribución~50 min
Medición GABAscripts/medir_gaba_activacion.py881 búsquedas68.2% activados (JSON)~30s

Determinismo verificado: 4 corridas consecutivas idénticas → misma tabla. random.seed(42) en generación de casos QA.


🏗️ Arquitectura del Motor — 13 Señales + PPMI+SVD (núcleo, vigente desde v26.1)

La versión v26.1 integra un motor vectorial espectral (PPMI+SVD de 100 dimensiones + Retrofitting de Grafo Hebbiano) sobre el pipeline de 12 señales que existía en v25.x. El siguiente diagrama refleja el núcleo de ranking en producción (v26.1 en adelante):

graph TD
    A["Consulta del Usuario"] --> B["Tokenización + Stemming Bilingüe ES/EN"]
    B --> C["Ventana de Atención — Context Window"]
    B --> D["Pipeline Híbrido — 13 Señales"]

    subgraph Engine_v261 ["BioRAG — Motor Híbrido PPMI+SVD+Retrofit"]
        D --> D1["1. BM25 / FTS5 · w=0.25"]
        D --> D2["2. Dimensiones Semánticas · w=0.14"]
        D --> D3["3. PPMI+SVD Coseno · w=0.15"]
        D --> D4["4. IDF-Synonym Specificity · dinámico"]
        D --> D5["5. Concepto Match · w=0.08"]
        D --> D6["6. Sinónimos Ratio · w=0.08"]
        D --> D7["7. LTP/LTD Sináptico · w=0.10"]
        D --> D8["8. SLS Inferencia Transitiva · w=0.10"]
        D --> D9["9. WordNet Grupos Léxicos · w=0.10"]
        D --> D10["10. Score Temático · w=0.08"]
        D --> D11["11. JSD Distribucional · w=0.04"]
        D --> D12["12. Predicados SRL · w=0.20"]
        D --> D13["13. Temporal / Recencia · w=0.02"]
    end

    D1 & D2 & D3 & D4 & D5 & D6 & D7 & D8 & D9 & D10 & D11 & D12 & D13 --> E["Score Híbrido Ponderado"]
    C --> |"Boost +0.05"| E
    E --> F["Inhibición Lateral GABA — atenúa ×0.60 si Top-1 ≥ 0.80"]
    F --> G["Re-ranking Jaccard Léxico — rescata candidatos hundidos"]
    G --> H["Retrofitting de Grafo Hebbiano — λ=0.2, 5 iters"]
    H --> I["Ranking Final — 14 capas en cascada"]

Nota histórica: el diagrama de la arquitectura base de v19.0 (8 señales cognitivas originales) se preserva en la sección Motor Cognitivo Biomimético Integrado — v19.0, ya que es el punto de partida de la evolución arquitectónica del sistema.

Sobre v28.0 (vigente): el diagrama arriba describe el núcleo de ranking (Canal 1). v28.0 agrega por encima el Canal 2 (asociaciones_enriquecidas del grafo sináptico real, sin tocar score_hibrido), el QCR Gate (puerta de cobertura de consulta, umbral de capa 0.60) y la señal ADN Conceptual (v29, APAGADA por defecto) — descritos en la sección Canal 2 Integrado.


Qué es BioRAG (y qué NO es)

BioRAG se ubica en la intersección de cuatro disciplinas científicas:

DisciplinaRol en BioRAG
Information RetrievalPipeline de cascade ranking de 13 capas con 12 señales de scoring híbrido (Learning-to-Rank manual)
Knowledge GraphsGrafo de sinapsis tipadas y pesadas con plasticidad negativa, inferencia transitiva y auto-clustering
Cognitive ArchitectureCiclos de sueño, LTP/LTD, spreading activation, poda sináptica, inhibición lateral (ACT-R, Hebb, Marr)
Symbolic NLPExpansión semántica sin embeddings: Levenshtein normalizado + WordNet bilingüe + traducción opcional

BioRAG NO es:

  • No es un RAG con embeddings externos — RAG (Retrieval-Augmented Generation) típico recupera chunks con embeddings preentrenados (OpenAI, sentence-transformers). BioRAG no usa embeddings de modelos externos: su espacio vectorial se entrena localmente sobre el corpus propio (PPMI+SVD, sin redes neuronales ni GPU).
  • No es una base de datos vectorial externa — BioRAG SÍ tiene motor vectorial propio (PPMI+SVD de 100 dimensiones + SDM de 2048 bits + HDC). Lo que no usa son bases vectoriales comerciales/embeddings de caja negra (Pinecone, pgvector, FAISS, etc.). Sus vectores son entrenados, explicables y auditarles. Además de los vectores espectrales, los 13 ejes dimensionales forman un sparse embedding declarativo: la misma idea que un vector, pero con valores que un humano define, inspecciona y audita.
  • No es un LLM — BioRAG no genera texto. Es el sistema de memoria que un LLM usa para recordar entre sesiones.
  • No es un prototipo académico — Es un sistema de producción con 16 tests pytest + benchmark de 921 casos, ~20 MB RAM, latencia de 2.84ms.

🔬 Fundamentos Científicos

BioRAG no implementa una técnica aislada — sintetiza treinta mecanismos científicos de campos distintos (recuperación de información, neurociencia computacional, lingüística computacional, sistemas dinámicos y arquitecturas cognitivas) en un único motor cognitivo determinista. Cada uno de los siguientes componentes está implementado y verificable en el código fuente, no es aspiracional:

MecanismoFundamento científicoDónde vive en el códigoPara qué se usa
PPMI / Word2Vec Duality (Shifted PPMI)Levy & Goldberg (2014); Mikolov et al. (2013)core/ppmi_vectorizer.pyJustificación matemática de que la matriz PPMI desplazada equivale a los embeddings de Word2Vec de Google, logrando espacio vectorial semántico sin redes neuronales ni GPU.
LSA — Latent Semantic Analysis (Truncated SVD)Landauer & Dumais (1997); Deerwester et al. (1990)core/ppmi_vectorizer.pyReducción de dimensionalidad espectral (100 Dims) sobre la matriz de co-ocurrencia para capturar sinonimia limpia y relaciones semánticas latentes de 2º orden.
Fusión híbrida multi-señal (13 señales)Diseño propio — combina BM25, Jaccard, PPMI coseno, JSD, predicados SRL y 8 señales máscore/memory_store.py — _score_hibrido()Fusionar 13 señales ortogonales (léxica, vectorial, dimensional, sináptica, temporal) en un score único ponderado para cada resultado de búsqueda.
HDC — Hyperdimensional Computing (VSA Binding)Kanerva (2009); Smolensky (1990)core/sdm.pyEnlazar vectorialmente roles semánticos SRL (Sujeto-Acción-Objeto-Contexto) mediante operaciones ortogonales para búsquedas relacionales lógicas.
Ley de Potencia de Práctica de ACT-R (Base-Level Activation)Anderson & Lebiere (1998); Newell & Rosenbloom (1981)core/memory_store.py — _calcular_base_level_actr() y ciclo_sueno_consolidacion()Modulación no lineal del decaimiento pasivo (LTD) en sueño según la recencia y frecuencia de acceso $B_i = \ln(\sum t_k^{-0.5})$ con búfer circular, inmunizando recuerdos activos.
Concept Hubs Semánticos de 5 ÁngulosRosch (1975); Collins & Quillian (1969); Vygotsky (1934)core/concept_hub.py + esquemas concept_hubs / concept_hub_bridgesSuperar el abismo léxico y cruces semánticos bilingües (ES/EN) mediante puentes estructurados en 5 ángulos cognitivos ortogonales sin depender de modelos densos.
Efecto Fan de ACT-R en Spreading ActivationAnderson (1974); Anderson & Reder (1999)core/memory_store.py — _evocacion_por_cadena()Ponderación de la activación propagada dividida por el abanico de conectividad saliente ($W_j/\text{fan}_j$), evitando la saturación espuria por nodos hub y acelerando la exploración.
Calibración Conforme Inductiva (Conformal Prediction & Platt Scaling)Vovk, Gammerman & Shafer (2005); Platt (1999); Angelopoulos & Bates (2021)core/calibracion.py + calibracion_estadoUmbrales no paramétricos con garantía matemática de error finito ($1-\alpha$) para control estricto de falsos positivos (0.0% FP) y calibración probabilística en MCP.
Curva del Olvido (Decaimiento Pasivo LTD)Ebbinghaus (1885)core/memory_store.py — ciclo_sueno_consolidacion()Aplicar la atenuación temporal pasiva sobre recuerdos no utilizados durante la consolidación de sueño.
PMI (Pointwise Mutual Information)Church & Hanks (1990)core/pmi_semantico.pyMedir qué tan asociados están dos conceptos por co-ocurrencia real en el corpus, y usar eso como señal para auto-vincular nodos nuevos al guardarlos.
SDM — Sparse Distributed Memory (2048-bit)Kanerva (1988)core/sdm.pyRecuperación asociativa por parecido, no por coincidencia exacta — encontrar un recuerdo aunque la consulta esté incompleta o levemente distinta.
Retrofitting de grafo semánticoFaruqui et al. (2015)core/sinapsis.pyAjustar el espacio vectorial PPMI+SVD usando la topología real del grafo de sinapsis, para que conceptos conectados queden más cerca entre sí.
LTP/LTD (potenciación y depresión sináptica)Hebb (1949); Bliss & Lømo (1973)core/sinapsis.pyReforzar automáticamente los recuerdos que se reutilizan y debilitar los que no se tocan, para que la memoria "olvide" lo irrelevante con el tiempo.
Consolidación de memoria (corto → largo plazo)Marr (1971)core/memory_store.py — ciclo_sueno_consolidacion()Decidir qué pasa de memoria de trabajo temporal a memoria permanente al cierre de una sesión ("fase de sueño").
Spreading activation multi-hopAnderson (1983) — ACT-Rcore/memory_store.py — _evocacion_por_cadena()Encontrar conceptos relacionados indirectamente, siguiendo la cadena del grafo desde una semilla, no solo coincidencias directas.
Inhibición lateral GABA en tiempo realEdelman (1987)core/memory_store.py — buscar_por_frase()Cuando el resultado Top-1 domina (score ≥ 0.80), atenuar competidores secundarios (×0.60) si están muy por debajo del líder, reduciendo ruido sin vectores densos.
Error de predicción de recompensa (dopamina/RPE)Schultz (1997)mcp_server.py — biorag_feedback()Que el propio agente le diga al sistema "esto sirvió / no sirvió" y el peso del recuerdo suba o baje en consecuencia — aprendizaje por refuerzo explícito.
Marcador somático / valencia corticalDamasio (1994)core/memory_store.py + core/dmn_engine.pyMarcar recuerdos como emocionalmente/estratégicamente importantes; los de alta valencia quedan inmunes al olvido pasivo y son ancla para ideación autónoma del DMN.
Escalado sináptico homeostáticoTurrigiano (2008)core/memory_store.pyEvitar que los pesos sinápticos se saturen todos en 1.0 — normaliza la corteza activa cuando el promedio supera 0.70, para que el sistema siga pudiendo aprender.
Léxico generativo (eje "cualia")Pustejovsky (1995)core/memory_store.py — dimensiones semánticasClasificar el significado profundo de un nodo según su naturaleza, composición, propósito u origen (estructura de cualia).
Evidencialidad (eje "epistemia")Aikhenvald (2004)core/memory_store.py — dimensiones semánticasEtiquetar la fuente de verdad de cada recuerdo: ¿lo viví, lo verifiqué, lo inferí, me lo contaron, es hipótesis o quedó obsoleto? Evita que un rumor pese igual que un hecho comprobado.
Efecto de autorreferencia (centralidad identitaria)Rogers, Kuiper & Kirker (1977)core/memory_store.py — dimensiones semánticasPriorizar recuerdos centrales a la identidad/rol del agente por sobre información externa impersonal, al momento de recuperar.
Modalidad deónticaPalmer (2001)core/memory_store.py — dimensiones semánticasDistinguir reglas obligatorias, prohibiciones, permisos y capacidades — clave para que el agente no confunda una sugerencia con una norma.
Clasificación léxica ontológicaWordNet — Miller (1995)core/clasificador_wordnet.pyResolver búsquedas donde las palabras no coinciden literalmente pero significan lo mismo (ej. "decodificar jerga" ≈ "traducir lenguaje críptico"), sin embeddings.
SRL — Semantic Role Labeling (Gramática de Casos)Fillmore (1968); Palmer et al. (2005)core/srl_extractor.py + core/memory_store.py — buscar_por_predicados()Extraer tripletas de predicados (Sujeto, Acción, Objeto, Contexto) de cada recuerdo para permitir búsquedas relacionales exactas por rol semántico (ej. sujeto:Dennys, accion:crear).
DMN — Red por Defecto & Spindles Replay (Ideación Autónoma)Raichle et al. (2001); Buckner et al. (2008)core/dmn_engine.py + core/dmn_reflexion.pyEjecutar en segundo plano durante inactividad un recorrido de 2-3 saltos desde nodos ancla de alta valencia para sintetizar hipótesis e insights autónomos sin intervención del usuario.
Separación de Patrones Hipocampal (Pattern Separation)Marr (1971); O'Reilly & McClelland (1994)core/inferencia_transitiva.pyValidar inferencias transitivas de 2-3 saltos exigiendo convergencia dual (PMI + dimensión semántica) para evitar conexiones falsas por dimensiones genéricas compartidas ("problema hub").
Divergencia Jensen-Shannon (JSD)Lin (1991)core/memory_store.py — _score_hibrido() (Señal #11)Medir el solapamiento distribucional de vocabulario entre la consulta y el recuerdo en una escala simétrica acotada [0, 1], como señal de similitud complementaria al coseno.
Label Propagation (Detección de Comunidades)Raghavan et al. (2007)core/auto_clustering.py — detectar_comunidades()Detectar automáticamente grupos de nodos densamente interconectados en el grafo de sinapsis y asignarles un nombre temático generado por frecuencia de tokens.
Distancia de Levenshtein (tolerancia a errores tipográficos)Levenshtein (1966)core/fallback_simbolico.pyRecuperar recuerdos aunque la consulta tenga errores ortográficos, variantes morfológicas o palabras parciales, calculando la distancia de edición mínima entre tokens.

Todo lo anterior corre en Python puro + SQLite, con cero dependencias de embeddings densos, GPU o APIs de LLM en el camino de recuperación. El objetivo no es competir con la escala de un modelo preentrenado — es demostrar que memoria persistente, auditable y explicable, con fundamento en literatura de neurociencia cognitiva e IR clásico, es posible sin ellas.

Nota de honestidad intelectual: ninguna de estas técnicas individuales es una invención de este proyecto — son bien conocidas en sus respectivos campos, algunas con más de 70 años. La contribución de BioRAG es la síntesis: hacerlas coexistir en un solo sistema cerrado, determinista y funcional, algo que no encontramos replicado en ningún otro proyecto open-source de memoria para agentes de IA.


Auditoría Técnica Completa — Módulos del Core (v26.1)

Escala Real del Código

ArchivoBytesRol
core/memory_store.py286,079Motor cognitivo — 13 señales, 14 capas, ciclo de sueño, LTP/LTD, QCR Gate
mcp_server.py191,729Interfaz MCP — 33 herramientas expuestas al IDE
core/dmn_reflexion.py94,285Red por Defecto extendida + La Hormiguita (evaluación con Gemini)
core/sinapsis.py22,976Grafo: auto-linking, LTP/LTD, decay sináptico
core/similitud_conceptual.py19,920Jaccard vecinos + contenido, score 60/40
core/pmi_semantico.py12,829PMI/NPMI + LRU cache (v26.1)
core/stemmer_es.py13,718Stemmer bilingüe ES/EN ultraligero
core/ppmi_vectorizer.py13,718Motor PPMI+SVD+Retrofitting (v26.0) — DIM=100, λ=0.2
core/inferencia_transitiva.py13,448SLS: CTEs recursivas + filtro dual PMI/Dimensión
core/sdm.py21,005SDM 2048-bit + HDC Binding (Kanerva 1988)
core/fallback_simbolico.py14,612Fallback simbólico: Levenshtein + WordNet bilingüe
core/auto_clustering.py10,532Label Propagation — comunidades automáticas del grafo
core/dmn_engine.py11,534DMN daemon thread — ideación en reposo (v21.0)
core/srl_extractor.py4,194SRL: Sujeto-Acción-Objeto-Contexto
graph_maintenance_daemon.py17,383La Hormiguita — daemon de mantenimiento del grafo
middleware/auto_guardado.py2,174Buffer de sesión + autoguardado heurístico

🛡️ Patrón de Gobierno de IA con "Default Deny" (core/dmn_reflexion.py — La Hormiguita)

  • ¿Por qué se creó? (El Por qué): Permitir que un LLM (ej. Gemini) escriba, modifique o borre directamente registros en la base de datos de memoria permanente es un riesgo crítico de seguridad. Las alucinaciones, respuestas fuera de esquema o JSONs truncados pueden corromper el grafo de sinapsis o destruir recuerdos valiosos.
  • ¿Para qué sirve? (El Para qué): Sirve para aprovechar el juicio analítico avanzado de un LLM en tareas de mantenimiento del grafo de memoria (sanación y poda de sinapsis obsoletas) de forma 100% segura, protegiendo la base de datos contra corrupción o pérdidas de información accidental.
  • Propósito en Producción (El Propósito): Garantizar la integridad absoluta del sistema de memoria mediante una arquitectura de gobierno Zero-Trust:
  1. Gemini como mero asesor (Proposal-Only): El LLM nunca ejecuta sentencias SQL ni muta la base de datos directamente. Solo recibe un payload estructurado de candidatos pre-filtrados y emite un veredicto en JSON.
  2. Pre-filtrado Determinista: Antes de gastar tokens llamando a la API, el motor Python (_pre_filtrar_conexiones) evalúa >1,000 candidaturas mediante distancia de Hamming en SDM y score de co-ocurrencia hebbiana, reduciéndolas a ~60 candidatos dudosos que realmente requieren juicio experto.
  3. Default Deny / Zero-Trust Safety:
    • Si la API del LLM falla, expira por timeout, o el JSON retornado contiene errores de sintaxis, el sistema aplica Default Deny: aborta con return False y 0 mutaciones en la DB.
    • Si el veredicto es válido, no se aplica ciegamente: pasa por un evaluador estricto (_aplicar_veredicto_nodo) que exige umbrales de confianza diferenciados: UMBRAL_CONFIANZA_ACEPTAR (para adiciones) y UMBRAL_CONFIANZA_ELIMINAR (para podas).
  4. Cuarentena Reversible (sinapsis_cuarentena): Las conexiones podadas no se destruyen inmediatamente. Se transfieren a la tabla relacional sinapsis_cuarentena, registrando el motivo, confianza, timestamp y estado previo. Esto permite auditoría forense y rollback completo en cualquier momento vía _restaurar_cuarentena().

🔬 Memoria Dispersa Binaria de 2048 Bits (core/sdm.py — Kanerva 1988 + HDC)

  • ¿Por qué se creó? (El Por qué): Los embeddings densos tradicionales (ej. 1536 dimensiones de 32 bits) consumen 6,144 bytes por nodo, requieren GPUs o librerías pesadas como PyTorch/FAISS, y mezclan toda la información en un espacio vectorial indivisible donde es imposible saber qué componente representa texto, categoría o topología de grafo.
  • ¿Para qué sirve? (El Para qué): Sirve para ejecutar búsquedas de similitud conceptual hiperdimensional en microsegundos (<1.5 ms en 800+ nodos) utilizando CPU pura en cualquier dispositivo (sin GPUs ni dependencias externas), discriminando con precisión quirúrgica entre coincidencias de texto superficiales y relaciones Hebbianas profundas.
  • Propósito en Producción (El Propósito): Proveer un hiperespacio binario ultra-eficiente de 2048 bits (256 bytes por nodo) que combina semántica hebbiana, texto y topología con rendimiento en CPU pura (<1.5 ms en 800+ nodos).

Particionado Estructurado del Vector SDM (2048 bits = 256 bytes): A diferencia de un hash disperso uniforme (que mezcla tokens al azar), el vector de 2048 bits en BioRAG v2.0 tiene un layout de memoria explícito por capa de información:

Rango de Bits% VectorSegmentoPropósito y Codificación
bits 0..51125.0%Tokens de ContenidoVentanas hash-mapped de 4 bits por token extraído del contenido.
bits 512..76712.5%Tokens de ConceptoVentana de 4 bits por token del identificador principal del nodo.
bits 768..179150.0%Dimensiones HebbianasClusters Hebbianos + dimensiones cualia/epistemia (8–16 bits por dimensión, ponderadas por IDF). Captura la semántica profunda.
bits 1792..19196.25%Categoría EstructuradaVentana determinista de 8 bits correspondiente al catálogo de categorías del cerebro.
bits 1920..20476.25%Vecindario SinápticoVentana de 4 bits por concepto vecino interconectado en el grafo.

Jaccard Ponderado por Capa Semántica: Al calcular la similitud en el hiperespacio entre dos vectores binarios de 2048 bits, los bits no pesan lo mismo:

PESO_TOKEN = 1.0        # Solapamiento léxico básico
PESO_CATEGORIA = 1.5    # Afinidad estructural
PESO_VECINO = 1.2       # Afinidad topológica en el grafo
PESO_DIMENSION = 2.5    # Semántica Hebbiana profunda (pesa 2.5× para guiar el retrieval)

Rendimiento: Al operar con representaciones binarias compactas, la comparación de distancias sobre 800+ nodos utiliza int.bit_count() nativo de 64 bits en Python, consumiendo solo 256 bytes por nodo (vs. 6,144 bytes de un embedding denso float32 de 1536 dimensiones), sin requerir FAISS ni PyTorch.


Clasificación Simbólica WordNet — v15.0

Para la versión v15.0 de BioRAG, diseñamos e implementamos una extensión ontológica basada en WordNet que proporciona similitud conceptual discreta y determinista, 100% offline y sin depender de bases de datos vectoriales ni de modelos de embeddings pesados.

¿Por qué esta técnica?

  • Superación de la limitación léxica: En sistemas de búsqueda basados puramente en texto, buscar "decodificar jerga" no arroja resultados para un nodo guardado como "traducir lenguaje críptico". WordNet resuelve esto asociando ambas acciones al mismo grupo léxico ontológico (verb.communication).
  • Eficiencia extrema y 0 GPU: Las bases de datos vectoriales tradicionales requieren cientos de megabytes de RAM, GPU para inferencia rápida, y dependencias pesadas como PyTorch o sentence-transformers. BioRAG mantiene su huella en ~20 MB de RAM y corre con latencia de ~2.8 ms en cualquier CPU.
  • Autonomía y aislamiento local: Para garantizar que la herramienta funcione en cualquier laptop o servidor sin requerir conexión a internet, empaquetamos y aislamos nltk_data/corpora/wordnet localmente en la ruta del proyecto (MemoryBioRAG_Data/nltk_data).

Arquitectura de Base de Datos y Cascada

Para estructurar esta similitud simbólica sin saturar la tabla principal largo_plazo, creamos dos tablas relacionales especializadas con restricciones de integridad referencial rígidas:

  1. grupos_semanticos: Catálogo estático que indexa los 45 grupos lexicográficos oficiales de WordNet (lexnames), tales como noun.person, verb.cognition, noun.act, etc.
  2. nodo_grupos_semanticos: Tabla puente relacional que conecta cada concepto de largo plazo con uno o varios grupos semánticos correspondientes a sus palabras y sinónimos.
    • Cuenta con claves foráneas hacia grupos_semanticos(id) y largo_plazo(concepto).
    • ON DELETE CASCADE: Para garantizar una higiene absoluta del grafo, configuramos el borrado en cascada en la clave foránea hacia la tabla largo_plazo. Si un concepto es eliminado de la memoria a largo plazo (por sanación o limpieza activa), sus registros de grupos semánticos asociados se eliminan de forma atómica y transparente, evitando la creación de registros huérfanos.

Cómo funciona el Algoritmo en Búsqueda y Escritura

  • En Escritura (Write-Time): Al consolidar un concepto (ciclo de sueño), el sistema tokeniza el contenido y los sinónimos del nodo, consulta el WordNet local en milisegundos y asocia el concepto a las categorías semánticas encontradas en la tabla puente.
  • En Lectura (Read-Time): Cuando el usuario realiza una búsqueda:
    1. Se extraen y tokenizan las palabras clave de la consulta.
    2. Se obtienen sus lexnames desde WordNet en caliente.
    3. Se calcula la intersección de grupos semánticos usando un coseno binario o coeficiente de Jaccard (grupo_score).
    4. Se inyecta este score como la 9ª señal de relevancia con un peso del 10% en la fórmula final de ordenamiento híbrido, dando un boost semántico a conceptos relacionados aunque no compartan caracteres exactos.

Comprensión Semántica Profunda — v16.0

Para la versión v16.0 de BioRAG, incorporamos tres pilares fundamentales que dotan al sistema de una verdadera comprensión semántica a nivel relacional, lógico y estructural sin sacrificar el paradigma determinista y discreto (cero dependencias de GPU o modelos vectoriales pesados):

1. Etiquetado de Roles Semánticos (Semantic Role Labeling - SRL)

  • De tokens a relaciones: En lugar de indexar palabras sueltas e independientes, SRL asocia los conceptos a estructuras semánticas de rol: Sujeto, Acción, Objeto y Contexto (ej: "Dennys desarrolla BioRAG en la oficina"; Sujeto: Dennys, Acción: desarrollar, Objeto: BioRAG, Contexto: oficina).
  • Búsquedas Estructuradas: El parámetro buscar_por_rol permite realizar consultas relacionales específicas (ej: "sujeto:Dennys,accion:desarrollar"), reduciendo a cero el ruido de co-ocurrencia léxica accidental.

2. Inferencia y Transitividad en Grafos (Fuzzy Reasoning)

  • Sinapsis Latentes: Permite al sistema deducir relaciones indirectas implícitas en el grafo de conocimiento. Si el nodo A está conectado a B y B está conectado a C, el motor infiere de manera lógica que A tiene una conexión latente con C.
  • Atenuación con Poda Temprana: El peso de las sinapsis latentes decae proporcionalmente a la distancia (saltos) usando la fórmula: $$\text{peso_latente} = \prod (\text{pesos_camino}) \times \text{FACTOR_DECAY}^{\text{saltos}}$$ con $\text{FACTOR_DECAY} = 0.7$ y un cap de 3 saltos. Implementado mediante CTEs recursivas nativas de SQLite para máxima eficiencia y prevención de bucles infinitos.

3. Autogeneración de Dimensiones Emergentes (Auto-Clustering)

  • Label Propagation Algorithm (LPA): El motor analiza el grafo de sinapsis durante el ciclo de sueño y agrupa de manera autónoma los conceptos en comunidades densas (cliques de tamaño $\ge 5$ y densidad interna $\ge 0.3$).
  • Dimensiones Temáticas Dinámicas: Cada comunidad detectada genera una dimensión emergente (auto_TOKEN1_TOKEN2_TOKEN3) nombrada mediante los tokens más frecuentes de sus contenidos (excluyendo stopwords). Los nodos correspondientes se asocian de forma automática a este nuevo eje dimensional, permitiendo búsquedas dimensionales ponderadas por confianza.

Motor Cognitivo Biomimético Integrado — v19.0

Para la versión v19.0 de BioRAG, revolucionamos el paradigma de recuperación conceptual sin embeddings mediante una Arquitectura Cognitiva Biomimética Integrada de 5 fases. Esta versión resuelve definitivamente el dilema de la similitud asociativa y la inferencia transitiva ruidosa, logrando un ordenamiento híbrido guiado por 8 señales cognitivas ortogonales y la implementación de memoria dispersa distribuida (SDM - Sparse Distributed Memory).

graph TD
    A[Consulta del Usuario] --> B[Tokenización y Stemming Bilingüe ES/EN]
    B --> C[Ventana de Atención / Context Window]
    B --> D[Pipeline Híbrido de 8 Señales Cognitivas]
    
    subgraph Engine_v19 [BioRAG v19.0 Core Engine]
        D --> D1[1. BM25 / FTS5 Match]
        D --> D2[2. Similitud Topológica Jaccard]
        D --> D3[3. PMI / NPMI Semántico Automático]
        D --> D4[4. SLS: Inferencia Transitiva Filtrada]
        D --> D5[5. Overlap de Dimensiones Semánticas]
        D --> D6[6. SDM: Distancia Hamming 1024-bit]
        D --> D7[7. Fuerza LTP/LTD de Sinapsis]
        D --> D8[8. Bonus de Atención por Contexto]
    end
    
    D1 & D2 & D3 & D4 & D5 & D6 & D7 & D8 --> E[Score Híbrido Ponderado]
    C -->|Boost +0.05| E
    E --> F[Ranking de Nodos Final]

Arquitectura de las 5 Fases de v19.0

Fase 1: PMI / NPMI Semántico Automático (Pointwise Mutual Information)

  • Objetivo y Aporte: Medir la verdadera fuerza asociativa entre pares de palabras en el corpus real del usuario, diferenciando co-ocurrencias estadísticas reales de meras coincidencias léxicas casuales.
  • Fundamento Matemático: Basado en Church & Hanks (1990), calcula la probabilidad conjunta $P(x,y)$ frente a las probabilidades independientes $P(x)$ y $P(y)$: $$\text{PMI}(x, y) = \log_2 \frac{P(x, y)}{P(x) P(y)}$$ $$\text{NPMI}(x, y) = \frac{\text{PMI}(x, y)}{-\log_2 P(x, y)} \quad \in [-1, +1]$$
  • Implementación: core/pmi_semantico.py construye una matriz de co-ocurrencia sobre los nodos activos. Mantiene un caché dinámico en RAM que se recalcula automáticamente cuando el corpus crece $>10%$. En las pruebas de producción con 534 nodos, procesó y evaluó 8,832 pares semánticos en solo 1,007ms.

Fase 2: Stemmer Bilingüe Español/Inglés Integrado

  • Objetivo y Aporte: Proporcionar una pasarela morfológica discreta y ultraligera que unifique variantes gramaticales y términos técnicos en inglés y español sin requerir librerías pesadas como Spacy o NLTK completas.
  • Implementación: core/stemmer_es.py aplica sufijos morfológicos adaptativos para español e inglés, reduciendo variantes léxicas a su raíz común ("configuración" $\rightarrow$ configur, "configuration" $\rightarrow$ configur). Esto permite que consultas formuladas en inglés o con variaciones verbales/nominales conecten de manera exacta con nodos almacenados.

Fase 3: SLS (Sinapsis Latentes Semánticas con Filtro Involutivo)

  • Objetivo y Aporte: Eliminar el ~50% de "ruido de grafo" o falsos enlaces transitivos presentes en las versiones anteriores (v16-v18) al calcular sinapsis indirectas ($A \rightarrow B \rightarrow C$).
  • Filtro Involutivo Doble: Antes de persistir una sinapsis latente en la tabla sinapsis_latentes, la relación debe satisfacer al menos uno de dos criterios estrictos:
    1. Coincidencia Dimensional: El nodo origen y destino comparten al menos un eje en largo_plazo_dimensiones.
    2. Asociación PMI Relevante: El score $\text{NPMI}(A, C) \ge 0.02$.
  • Ponderación Dinámica: Las latentes que superan el filtro reciben una bonificación proporcional a su afinidad semántica: $$\text{peso_final} = \min\left(1.0, \text{peso_max} \times (1.0 + \text{pmi_boost} + \text{dim_boost})\right)$$
  • Impacto: Redujo de 18,988 latentes ruidosas a 17,062 sinapsis latentes puras y validadas semánticamente, eliminando alucinaciones en el razonamiento asociativo.

Fase 4: SDM (Sparse Distributed Memory — Kanerva 1988)

  • Objetivo y Aporte: Permitir la búsqueda asociativa por contenido sin embeddings vectoriales ni modelos neuronales.
  • Implementación: core/sdm.py codifica cada nodo de la memoria a un vector disperso binario de 1024 bits, proyectando mediante funciones de hash deterministas:
    • 500 bits: Tokens de concepto y contenido.
    • 300 bits: Sinónimos y roles semánticos.
    • 100 bits: Categoría del nodo.
    • 124 bits: Vecinos y dimensiones semánticas.
  • Almacenamiento y Recuperación: Los vectores se persisten en SQLite en la tabla nodos_sdm. La búsqueda por similitud asociativa evalúa la distancia Hamming entre el vector de la consulta y los nodos almacenados utilizando la instrucción int.bit_count(). En las pruebas en vivo, indexó los 534 nodos en milisegundos y recuperó nodos por coincidencia estructural con una distancia de tan solo 14 bits de diferencia (98.63% de similitud).

Fase 5: Context Window de Atención Cognitiva (Short-Term Working Memory)

  • Objetivo y Aporte: Implementar un búfer de memoria de trabajo a corto plazo que simula el foco de atención humana, dando prioridad a conceptos accedidos o discutidos recientemente en la sesión.
  • Implementación: En core/memory_store.py, un deque(maxlen=10) registra los últimos conceptos evocados (registrar_acceso_contexto). Si un candidato devuelto por la búsqueda se encuentra en la memoria de trabajo activa, recibe un bonus de atención directa de +0.05 (obtener_bonus_contexto), garantizando continuidad conversacional y coherencia contextual.

Fase 6: Engine de Scoring Híbrido de 8 Señales Cognitivas

  • Fórmula de Evaluación: core/similitud_conceptual.py integra 8 señales independientes para calcular la similitud conceptual latente de cada candidato:
    1. BM25 / FTS5 (0.20): Coincidencia textual ponderada.
    2. Jaccard Red (0.15): Overlap de vecinos en el grafo de sinapsis.
    3. PMI / NPMI Semántico (0.15): Fuerza de asociación estadística entre tokens.
    4. SLS Inferencia Transitiva (0.15): Peso atenuado de caminos latentes validados.
    5. Overlap Dimensional (0.10): Coincidencia en ejes temáticos declarativos.
    6. SDM Hamming (0.10): Similitud en espacio vectorial disperso de 1024 bits.
    7. Fuerza LTP/LTD (0.10): Peso acumulado por consolidación y uso histórico.
    8. Bonus de Atención de Contexto (+0.05): Impulso por presencia en la ventana de trabajo activa.

Fase 7: Auto-Expansión Semántica Autónoma (Pre-Búsqueda en MCP)

  • Objetivo y Aporte: Eliminar la dependencia del "agente disciplinado". En las versiones previas, la calidad del recall dependía de que el agente formulara explícitamente paráfrasis y dimensiones. Si el agente ejecutaba una búsqueda simple o vaga (ej: "arquitectura frontend"), el recall decaía. Un cerebro biológico no exige que la consciencia formule sinónimos antes de recordar; el neocortex expande la señal asociativa espontáneamente.
  • Mecanismo de Inferencia: Cuando biorag_recordar recibe una consulta sin paráfrasis ni dimensiones:
    1. Consulta la matriz de co-ocurrencia PMI ($\text{NPMI} \ge 0.35$) y deduce auto-paráfrasis asociativas (ej: "arquitectura frontend" $\rightarrow$ ['angul', 'formulario', 'decodificada']).
    2. Realiza traversal en largo_plazo_dimensiones para auto-detectar las dimensiones ontológicas activas del dominio.
    3. Inyecta estas señales en el motor de 8 señales, aumentando el score de relevancia (ej: de 0.6500 a 0.7376) automáticamente sin requerir intervención del usuario o del agente.
  • Estado actual: APAGADA por defecto (experimento 07, docs/Mi neurona en el sistema/experimento_07_la_neurona_escucha/). Subir el score no es encontrar mejor: medida por el camino real del agente (recordar), la auto-paráfrasis baja el recall (QA: R@5 no-literal 85.05 % → 95.10 % al quitarla, 39 casos entran al top-5 y 0 salen; corpus no visto python-docs-es: R@1 31.48 % → 45.68 %). Las auto-dimensiones eligen 10 ids arbitrarios y apagan el pseudo-relevance feedback del motor (las dimensiones de los 5 mejores FTS), que es mejor. Además eran no deterministas (list(set)[:10]). Reactivar: BIORAG_MCP_AUTO_PARAFRASIS=1, BIORAG_MCP_AUTO_DIMS=1 (ahora deterministas). Las paráfrasis y dimensiones que manda el agente se usan siempre.

Fase 8: Pasada 4 — Resonancia PMI Hebbiana en Auto-Vinculación (core/sinapsis.py)

  • Objetivo y Aporte: Cerrar la brecha entre Memoria Episódica (hipocampo) y Memoria Semántica (neocorteza). El sistema recordaba episodios específicos (ej. "Ese día implementé formularios anidados en Angular"), pero no clasificaba automáticamente los conceptos nuevos en sus categorías implícitas (no sabía que Angular $\in$ Frontend).
  • Implementación: En el momento de guardar o consolidar un nodo (auto_vincular()), el sistema calcula la resonancia PMI Hebbiana entre los tokens del nodo y la matriz global de co-ocurrencia. Clasifica y vincula automáticamente el nuevo concepto a sus categorías y dominios semánticos correspondientes en el instante de su creación.

Fase 9: Commit Atómico Unificado, Homeostasis Energética y Visibilidad Completa

  • Objetivo y Aporte: Garantizar la integridad transaccional del ciclo de sueño y eliminar puntos ciegos o recortes en la interfaz forense del Neuro-Visor.
  • Implementación:
    1. Commit Atómico Unificado: ciclo_sueno_consolidacion() ejecuta todo el proceso (transferencia LTP, inhibición lateral LTD, cálculo PMI, optimización FTS5 y registro de métricas forenses metricas_cognitivas_nodos) en una sola transacción atómica de SQLite con un único commit() final al cierre del ciclo.
    2. Homeostasis Energética Cortical: Se eliminó la dependencia de parámetros de energía externos (limite_energia), dejando la Inhibición Lateral Activa 100% autorregulada en función de la carga cortical real ($\max(10.0, \text{n_activos} \times 0.8)$).
    3. Visibilidad Completa en Neuro-Visor: Se actualizó el endpoint de actividad (/api/corteza/actividad) ampliando el límite de conceptos devueltos de LIMIT 3 a LIMIT 50 y ordenando por ID descendente, permitiendo inspeccionar la totalidad de los nodos consolidados en cada ciclo.

Fase 10: BioRAG v20.0 — Circuito Sintético Cognitivamente Cerrado (GABA en Vivo, Dopamina RPE, Valencia Somática y Escalado Homeostático)

  • Objetivo y Aporte: Transformar el almacenamiento dinámico de BioRAG en un circuito neurobiológico cerrado autónomo y auto-homeostático, sustituyendo la similitud estática por dinámicas cognitivas inspiradas en Hebb, Schultz (1997), Damasio (1994) y Turrigiano (2008).
  • Componentes Implementados en v20.0:
    1. Inhibición Lateral GABA en Tiempo Real en Evocación (Edelman 1987): En core/memory_store.py (buscar_por_frase), cuando un candidato Top-1 es un atractor fuerte ($\text{Score} \ge 0.80$), atenúa activamente ($\times 0.60$) a los competidores secundarios del mismo nicho semántico, enfocando la atención y eliminando el ruido sin depender de vectores.
    2. Error de Predicción de Recompensa (Dopamina RPE - Schultz 1997) + Factor de Inercia Sináptica: Implementación de la tool MCP biorag_feedback(concepto, util=True/False). Éxito incrementa peso ($\Delta W = +0.15 \times (1.0 - W \times 0.3)$) e incrementa contador de éxitos. Fallo aplica depresión modulada por inercia sináptica: $\Delta W_{\text{fracaso}} = \frac{-0.10}{1.0 + \ln(1 + \text{éxitos})}$, protegiendo nodos antiguos consolidados contra fallos aislados y permitiendo corrección instantánea de nodos nuevos.
    3. Marcadores Somáticos y Valencia Cortical (Damasio 1994): Schema actualizado con columna valencia_somatica (0.0 a 1.0) en largo_plazo y corto_plazo. Nodos con valencia $\ge 0.80$ o categorías axiomáticas (Principle, Protocol) adquieren Inmunidad Cortical Total: son omitidos del decaimiento pasivo LTD (-0.05), la poda y la inhibición lateral.
    4. Escalado Sináptico Homeostático (Synaptic Scaling - Turrigiano 2008): Durante la consolidación nocturna, si el peso promedio de la corteza activa supera $0.70$, se aplica una normalización multiplicativa ($\times 0.98$) a los nodos no inmunes, asegurando capacidad de aprendizaje ilimitada sin saturación a $1.0$.

Fase 11: BioRAG v21.0 — Red por Defecto (Default Mode Network - DMN) y Curiosidad Espontánea Autónoma

  • Objetivo y Aporte: Convertir a BioRAG de un sistema puramente reactivo (que solo recupera información ante solicitudes) a una corteza sintética con ideación espontánea en reposo, emulando la Red por Defecto (DMN) humana (mind-wandering, consolidación asociativa NREM/REM y producción autónoma de hipótesis/insights).
  • Componentes Implementados en v21.0:
    1. Motor DMN en Segundo Plano (core/dmn_engine.py): Hilo autónomo daemon (DMNEngine) que monitorea la inactividad del usuario (BIORAG_DMN_IDLE_SECONDS, por defecto 300s). 100% independiente de librerías externas nativas (Python puro threading y sqlite3).
    2. Interrupción Instantánea de Latencia Cero (threading.Event()): La recepción de cualquier prompt o consulta de usuario activa notificar_actividad_usuario(), el cual notifica al evento de sincronización de inmediato, congelando la ideación autónoma para garantizar 0% de latencia en la atención al usuario.
    3. Muestreo Resonante Cortical (Spindles Replay): Algoritmo que selecciona un Nodo Ancla de alta valencia ($V_s \ge 0.3$) o peso ($W \ge 0.5$) y explora nodos resonantes distantes (a 2-3 saltos asociativos o dimensionales) no conectados fuertemente previo, creando un "Insight" sintético latente.
    4. Concurrencia Aislada Thread-Local: Conexión SQLite dedicada por hilo en modo WAL con PRAGMA busy_timeout = 5000 y transacciones seguras sin bloqueos.
    5. Selección Natural de Hipótesis (Decaimiento LTD Pasivo): Los Insights nacen con peso moderado ($W=0.50$) y valencia somática protegida ($V_s=0.85$). Si el usuario no los refuerza mediante evocación o feedback, sufrirán decaimiento LTD pasivo pasadas varias etapas de consolidación.
    6. Presupuesto de Energía & Período Refractario: Limita la ideación a un máximo de 3 hipótesis por ciclo de reposo (BIORAG_DMN_MAX_IDEAS=3) con un período de enfriamiento refractario de 60 segundos.
    7. Visualización y Monitoreo MCP: Exposición de la herramienta MCP biorag_estado_dmn y el endpoint REST /api/corteza/dmn en el backend del Neuro-Visor para inspección en tiempo real.

Fase 12: BioRAG v22.0 — SDM Query-by-Example: Base Vectorial Ligera

  • Objetivo y Aporte: Convertir al Sparse Distributed Memory (SDM) de 1024 bits en una base vectorial ligera que encuentra nodos conceptualmente similares usando únicamente distancia Hamming, sin GPU ni dependencias externas. Esto cierra el gap entre búsqueda por texto (FTS5) y búsqueda semántica pura.
  • Componentes Implementados en v22.0:
    1. buscar_sdm() con vector_fijo (core/sdm.py): La función de búsqueda SDM ahora acepta un parámetro vector_fijo (bytes). Cuando se proporciona, usa ese vector directamente en vez de generar uno desde texto. Esto habilita "buscar nodos similares a ESTE nodo" — búsqueda semántica pura por Hamming distance.
    2. buscar_similares_a(cerebro, concepto_semilla): Función de conveniencia que toma el vector SDM de un nodo conocido y retorna los nodos más cercanos. El SDM funciona como base vectorial ligera: 128 bytes/nodo (1024 bits), 0 GPU, SQLite puro.
    3. Validación Empírica: Tests con sinónimos técnicos (bug↔error: 5 bits), abreviaturas (DB↔base de datos: 7 bits), cross-domain (base_de_datos↔cache: 9 bits), y query-by-example real sobre 570 nodos (5/5 semillas con hits).
    4. Pipeline de Búsqueda Enriquecido: Capa SDM query-by-example como fallback cuando FTS5 y dimensiones no encuentran suficientes candidatos. Scoring híbrido incorpora similitud SDM como señal adicional.

Por qué el SDM NO reemplaza a WordNet ni a las Dimensiones

El SDM query-by-example no reemplaza WordNet ni las dimensiones semánticas — las completa. Cada técnica resuelve un problema distinto que las otras no pueden cubrir:

CapaProblema que resuelveQué no puede hacer sola
FTS5Texto exacto: "error_http_500" → nodo exactoNo tolera sinónimos ni variaciones
WordNetSinónimos léxicos: "hipertensión" → "presión arterial"No sabe qué dimensiones tiene un nodo
DimensionesPropiedades ontológicas: "todo lo de dominio_tecnico"No encuentra sinónimos léxicos
SDM Query-by-ExampleEstructura compartida: dos nodos con vecinos similares pero sin palabras en comúnNo puede buscar por propiedad ontológica

Ejemplo concreto de por qué cada una es insustituible:

  1. WordNet es insustituible para sinónimos que el SDM no puede adivinar: "hipertensión" ↔ "presión arterial" no comparten dimensiones ni vecinos — solo WordNet sabe que son lo mismo por relación léxico-semántica.

  2. Las dimensiones son insustituibles para búsquedas por propiedad: recordar(dimensiones='{"dominio":["dominio_tecnico"]}') trae TODO lo técnico sin importar el texto del nodo. El SDM no puede hacer esto porque no busca por eje semántico.

  3. El SDM brilla cuando FTS5 y WordNet fallan porque no hay match textual ni sinónimo conocido: dos nodos que comparten vecinos sinápticos pero no palabras. Ejemplo: "repaircard" ↔ "dashboard" (8 bits Hamming) — no comparten texto, pero sí estructura.

El pipeline real en producción:

Usuario busca "hipertensión"
  ↓ Capa 3 (FTS5): encuentra "hipertensión" si existe como nodo
  ↓ Capa 13 (WordNet): expande a "presión arterial", "HTA", "high blood pressure"
  ↓ Capa 14 (SDM): si WordNet no cubre alguna variante, busca por estructura

En resumen: WordNet y dimensiones siguen siendo obligatorios. El SDM es la capa que cubre los casos donde el texto no matchea pero la estructura sí — el fallback que cierra el gap semántico sin embeddings.


1. Pipeline de Búsqueda — 14 Capas en Cascada

Cada capa se ejecuta SOLO si la anterior devolvió pocos resultados (< 3 o < limite*2). Es un pipeline de degradación graceful — cada capa es más permisiva que la anterior.

CapaNombreTécnicaQué haceEquivalente en el campo
1NEAR queryNEAR(palabras, 15)Busca palabras dentro de ventana de 15 tokensProximity search (Elasticsearch match_phrase)
2LIKE en conceptoLIKE '%palabra%' + PALABRA_COMPLETASubstring match en nombre de nodo con word boundaryFuzzy entity matching
3FTS5 AND exactoMATCH con paráfrasis ORFull-text search con BM25 ponderadoBM25 ranking (Google, Elasticsearch)
4Términos protegidosunicode61 + PALABRA_COMPLETABypass de trigram para términos entre comillas ("CV")Exact match (Solr exact)
5OR fallbackpalabra1 OR palabra2Amplía recall cuando AND da pocos resultadosBoolean OR expansion
6
↑↓ navigate openesc close