La fuente son las páginas 21–28 del PDF, que en realidad son un segundo documento pegado detrás del primero: tiene su propio índice y está titulado también «1.».
| Pieza | Fase 1 | Fase 2 |
|---|---|---|
| Memoria corta | Checkpointer sobre SQLite | Checkpointer sobre PostgreSQL |
| Memoria larga | Almacén vectorial embebido | PGVector, en la misma base |
| Caché | No hay | Tabla de respuestas cacheadas |
| Trazas | Solo logs por consola | LangFuse, un decorador por nodo |
| Entrada | Chainlit | Chainlit + cuatro endpoints HTTP |
| Dependencias | requirements.txt | pyproject.toml, lockfile, .python-version |
El grafo no cambia. Cambia lo que hay debajo y lo que hay delante. Si te encuentras tocando nodos o aristas, es que algo se ha desviado del enunciado.
vector habilitada en esa base..env — con el .gitignore de la fase 1 ya
funcionando.| # | Criterio | Cómo se comprueba |
|---|---|---|
| 1 | Ninguna escritura va ya a SQLite | Borrar el fichero .db y que todo siga funcionando |
| 2 | Un hilo sobrevive al reinicio del proceso | Conversar, matar el proceso, reanudar el mismo hilo |
| 3 | Las memorias largas están en PGVector | Consultarlas con psql, no solo por la app |
| 4 | La caché acierta y se puede vaciar | Repetir una consulta y ver el ahorro; luego invalidarla |
| 5 | Cada nodo aparece en LangFuse | Una conversación completa trazada de principio a fin |
| 6 | Los cuatro endpoints responden | Un curl por endpoint, con su fichero |
| 7 | El entorno se reconstruye desde el lockfile | Entorno limpio, instalar desde el lock, arrancar |
| 8 | El README describe la estructura real | Comparar su árbol con git ls-files |
El script de setup puede «terminar bien» sin crear nada. El código de inicialización de
las tablas prueba un método, luego otro, y si ninguno existe imprime que «puede que las tablas se
creen solas en el primer uso» y que «puede que haya que crearlas a mano». El except
exterior imprime algo parecido. En ningún camino devuelve un código de salida distinto de cero.
¿Cómo sabes si ese script ha hecho algo? ¿Y por qué se entrega como código cerrado, cuando todo lo
demás del proyecto se entrega como prompt?
El cambio de checkpointer aparece en un sitio y hace falta en dos. La guía da una línea
de reemplazo para pasar de SQLite a Postgres, pero en la fase 1 el checkpointer se abre en
dos manejadores distintos: el de mensajes y el de fin de audio. Si migras solo el que
enseña la guía, la conversación por voz sigue escribiendo en SQLite y ninguna prueba obvia lo
delata. ¿Cuántos sitios hay realmente en tu app.py?
Tres gestores de entorno en un proyecto. Empieza con conda, instala con pip durante unos
treinta prompts —cada uno con licencia para añadir lo que le falte— y en el último paso
pide generar el lockfile y el pyproject.toml «a partir del proyecto entero». El
lockfile no previene el desorden: lo fotografía. ¿Qué versión de cada librería estás fijando, y
por qué esa?
La caché indexa por la cadena literal de la consulta. En un agente cuya respuesta depende del historial, de la memoria larga y de la modalidad que eligió el router. Dos usuarios distintos con la misma pregunta reciben la misma respuesta cacheada. Después de un máster entero sobre embeddings y similitud, ¿por qué una caché de coincidencia exacta? ¿Y cuándo se invalida?
La instalación solo vale en un ordenador. brew, una versión mayor de
PostgreSQL que ya no es reciente y una ruta de pg_config específica de Apple Silicon.
Ni Linux, ni Windows, ni contenedor. En un módulo que se titula «producción», ¿qué dice que la
única forma documentada de levantar la base de datos dependa del portátil que tengas?
Credenciales de ejemplo que invitan al desastre. La URI de muestra se conecta como
root con contraseña password y se copia en .env, con la
palabra gitignore todavía sin aparecer en el documento. ¿Cuánto de ese ejemplo
acabaría tal cual en un repositorio si nadie lo cuestiona?
Antes de tocar nada, en tu propio proyecto:
grep -rni "sqlite" --include="*.py" --include="*.txt" .
Ese número —no el de la guía— es el número de sitios que tienes que cambiar. Apúntalo, migra, y
vuelve a correr el mismo grep: si no sale vacío, la migración no ha terminado.