Una memoria que sabe cuándo callar.
Un RAG sobre un corpus personal que responde citando el fragmento real y su página — y que dice «no guardo ese recuerdo» en vez de inventar cuando la pregunta cae fuera. Desplegado en producción con FastAPI, Docker y Cloud Run. Segundo artefacto de la ruta Data Science → AI Engineering.
Recuperar el momento, no resumir un libro
No es un buscador ni una enciclopedia: es recuperación episódica. Ante una pregunta, encuentra los momentos reales del corpus que más se le parecen por significado, y solo entonces redacta una respuesta anclada a esos momentos, citando de qué pasaje y página sale cada cosa.
La sonda mide antes de navegar
Antes de llamar al modelo, el sistema mide cuánto se parece la mejor coincidencia. Si no alcanza, no llama al LLM: ni inventa una cercanía que no existe, ni gasta una petición. Elige una pregunta y mira dónde cae la aguja.
{ "consulta": "¿qué ropa me pongo para una boda?" }
{ "banda": "lejano", # ○ 0,262 < 0,43
"respuesta": null, # «no guardo ese recuerdo»
"fuentes": [],
"cercanos": [ # lo más próximo, no concluyente ] }
0 llamadas al LLM El umbral cortó antes del modelo: ni invención ni gasto. La honestidad es una característica del diseño, no un accidente — y además sale gratis.
{ "banda": "posible", # ◐ 0,43 ≤ 0,44 < 0,45
"respuesta": "…redactada, marcando la incertidumbre…",
"fuentes": [ # solo los momentos ≥ 0,43 ] }
responde con aviso El vecindario entero mide dos centésimas. El mejor momento roza el recuerdo: se responde, pero la incertidumbre viaja con la respuesta en vez de esconderse.
{ "banda": "claro", # ● 0,58 ≥ 0,45
"respuesta": "…con [#momento · página] en cada afirmación…",
"fuentes": [ # los 4 momentos citados ] }
responde y cita Cada afirmación lleva su cita [#momento · página]. Si no puedes ver de qué pasaje real sale, no cuenta.
El umbral tiene historia, y no la escribí yo a ojo. Las fronteras vivían en 0,40 hasta que el harness del Artefacto 3 cazó un falso positivo: contenido ausente del corpus colándose en «posible» con similitud 0,421. Subir el listón a 0,43 llevó la métrica de decisión del 86 % al 100 %, con cero regresiones en el golden set. El instrumento calibró al instrumento — con su caveat honesto anotado en el código: n pequeño, vigilar.
Cuatro capas y una caja en la nube
El sistema está desacoplado en capas que solo se hablan por un contrato (un JSON). Cambiar la cara no toca el motor; cambiar el modelo no toca la web.
/preguntar protegido por token, /salud para el orquestador. Motor cargado en el lifespan.
fetch y pinta el JSON: banda, respuesta y fuentes.
Un corpus personal, protegido por capas
El corpus es material personal, así que la privacidad no se deja al azar: el repositorio público
no contiene ni el corpus ni los vectores (un .gitignore los blinda),
la imagen vive en un registro privado, las claves se inyectan desde
Secret Manager —nunca en el código— y la consulta exige token.
Demo real, acceso por token. La URL está viva y abierta para cargar la web, pero preguntar al corpus requiere un token que se comparte de forma selectiva. Así se puede enseñar el sistema funcionando sin abrir el contenido personal a cualquiera.
Los tres criterios, cumplidos
Un RAG fácil contesta siempre; uno bueno sabe cuándo callar. Poner el umbral antes del modelo convierte «no alucinar» en una decisión de ingeniería — y eso, además, no cuesta dinero.