16 KiB
Operativa del servicio RAG
Modulo: RAG Ultima actualizacion: 2026-09-24 Version: 1.7
Este documento registra los hechos operativos del servicio RAG: la configuracion vigente en EasyPanel y la salida por etapas del OCR. No contiene secretos: las credenciales reales viven unicamente en EasyPanel.
Estado verificado (2026-09-24)
- Preflight R5 de solo lectura (2026-09-23): el contenedor RAG usa la base
db_ragcon el rolusr_rag.rag_schema_migrationscontiene001_knowledge_lifecycle.sql,002_ocr_review.sqly003_ocr_recovery_audit.sql, todos con checksums coincidentes con el commit publicado; la unica migracion pendiente es004_ocr_quality_diagnostics.sql. - Despliegue R5 verificado (2026-09-23): RAG y OCR exponen
version=0.2.1yrevision=0654ce5; sus etiquetas OCI coinciden. Digests: RAGsha256:9a22730406c09c6b773891d8953f451e6263bf9fb0033188f4479f0b93ec8bbf, OCRsha256:6725991d3893a4f16ae6c75f28e9dd59b051bdbc344b28d79f1292224ddceda1.004_ocr_quality_diagnostics.sqlesta aplicada; OCR estalive/ready, con cola vacia, worker/sweeper operativos y almacenamiento disponible; RAG confirma PostgreSQL, Qdrant y reconciliador sanos. - Despliegue vigente verificado (2026-09-24): RAG y OCR exponen
version=0.2.1yrevision=bfb2d48; sus etiquetas OCI coinciden, las migraciones001-004conservan sus checksums y PostgreSQL, Qdrant, reconciliador, OCR, cola y almacenamiento estan sanos. - Candidata R5 historica: FacturaTech v8
f4fd1502-1d4d-454f-bbfb-4c3b6820ee97completo 25/25 paginas OCR y su revision visual, pero el 2026-09-24 fue rechazada por decision del usuario sin aprobarse, indexarse ni activarse. La version activa3fc78163-9cfb-4979-985c-1520a63327b0sigue intacta. - Limpieza pendiente: la candidata sintetica blank
6011a4eb-3e42-4ea4-a7da-a3e930cc60edpermanecereview_requiredy la sintetica validac4646668-30e4-409e-800d-23a8ee465a42permanecepurging. Los dos defectos que bloqueaban rechazo y purga estan corregidos y validados localmente; no reintentar la limpieza productiva hasta que el usuario despliegue la correccion. - Diagnostico de precision (2026-09-24): los PNG productivos verificados de las paginas 8, 15 y 16 muestran los ceros correctos, mientras
ocr-result.jsonya contiene las tres confusioneso/0con confianza alta y la candidata las conserva sin cambios. Se descartan renderizado, reconstruccion y RAG como origen. El OCR queda aceptado para esta fase como servicio best-effort autonomo; la mejora de precision, la consola humana y un posible revisor visual por IA quedan diferidos. Esta aceptacion no aprueba ni activa v8. KNOWLEDGE_LIFECYCLE_ENFORCED=true: el ciclo de vida del conocimiento esta activo; no queda pendiente ninguna activacion.OCR_INGEST_ENABLED=true: la ingesta OCR esta habilitada en el RAG desplegado.OCR_SERVICE_URL: configurada hacia el servicio privadoocr-servicede la red interna.OCR_INTERNAL_TOKEN: secreto compartido configurado en EasyPanel (RAG y servicio OCR); su valor nunca se documenta.- Volumen duradero del RAG en
/data/ingestions: conserva originales y artefactos de revision. - Volumen transitorio del OCR en
/data/jobs: cola SQLite y trabajos en curso. - La respuesta publica sin token de una ruta OCR protegida es
401, lo que confirma que el proceso desplegado tiene OCR habilitado. Con OCR deshabilitado, la misma ruta responderia404antes de autenticar. - El estado mostrado en EasyPanel debe contrastarse con su entorno persistido y con el entorno del contenedor en ejecucion; anteriormente la UI mostro valores distintos por variables duplicadas y desfasadas.
GET /healthdel RAG confirma PostgreSQL, Qdrant y reconciliador sanos. OCR responde internamentelive=okyready=true, con cola vacia, worker/sweeper operativos y version/revision0.2.1/bfb2d48.- La migracion
003_ocr_recovery_audit.sqlesta aplicada y su tabla de auditoria existe. - Las rutas autenticadas de revision y recuperacion devuelven errores estructurados y seguros para una candidata inexistente:
404,OCR_CANDIDATE_NOT_FOUNDy accionverify_version_id. - La candidata OCR heredada de FacturaTech v4 fue cerrada como
failedel 2026-09-20 mediante recuperacion administrativa auditada tras confirmarOCR_ARTIFACT_UNAVAILABLE. No fue indexada ni activada; la fuente conserva su version activa y no tiene candidatas OCR bloqueantes. - Las imagenes en ejecucion tienen ambas etiquetas OCI
org.opencontainers.image.revision=bfb2d48: EasyPanel recibeBUILD_REVISIONdurante el build. La identidad se verifica mediante las etiquetas y el health; los digests registrados de entregas anteriores son evidencia historica, no la identidad de la revision vigente.
Version de despliegue
- La version correcta de cada despliegue es la declarada en el fichero raiz
VERSIONdel commit que se publica (para la entrega actual,0.2.1). No reutilizar numeros escritos en entradas historicas de este documento. - Ambas imagenes publican
org.opencontainers.image.versionyorg.opencontainers.image.revision; las respuestas de salud muestranversionyrevision. - EasyPanel debe construir ambas imagenes con la version de
VERSIONy conBUILD_REVISION=<commit desplegado>. - Por decision del usuario, RAG y OCR se despliegan juntos con
OCR_INGEST_ENABLED=true; no se desactiva preventivamente ni se introduce una ventana sin ingestas por protocolo. OCR_INGEST_ENABLED=falsey el despliegue por etapas se reservan para responder a un fallo real cuando sus sintomas y la evidencia indiquen que aislar un servicio ayudara al diagnostico o a la recuperacion.
Lista rapida en EasyPanel
- Rotar las credenciales expuestas (ver seccion siguiente); la rotacion sigue pendiente.
- Comprobar que las variables coinciden con la tabla de configuracion actual.
- Mantener
OCR_INGEST_ENABLED=true; cambiarlo afalsesolo ante un fallo real que justifique aislar el flujo OCR. - Pulsar
Deployen EasyPanel despues de cada cambio principal. - Verificar
GET /healthdel RAG y las rutas internas de salud del OCR tras cada deploy. - Registrar el digest de cada imagen y confirmar que
versionyrevisioncoinciden con la entrega desplegada.
Accion de seguridad urgente: rotar credenciales
Credenciales reales quedaron expuestas en una conversacion de chat. Hay que rotarlas:
- La credencial de OpenRouter (variable
EMBEDDING_API_KEY; yANSWER_API_KEYsi tiene valor propio). - La contrasena y la URL de PostgreSQL (variable
POSTGRES_URL). - El token administrativo del ciclo de vida (variable
LIFECYCLE_ADMIN_TOKEN).
Como hacerlo:
- Generar valores nuevos y actualizarlos unicamente en EasyPanel.
- Este documento no afirma que la rotacion ya se haya realizado.
- Nunca pegar valores de credenciales en chat, documentacion, historial ni ficheros versionados.
Como se despliega
- Tras cada cambio principal (variables de entorno o codigo nuevo subido por Git), el usuario pulsa el boton
Deployde EasyPanel. - No existe ninguna accion automatizada documentada sobre EasyPanel: ni scripts, ni comandos de panel, ni webhooks. El deploy siempre lo dispara una persona desde el panel.
- Verificacion minima tras cada deploy:
GET /healthdel RAG.
Acceso remoto a VPS2
- Entorno:
VPS2 PRODUCCION. - Host SSH:
162.19.152.15, puerto22, usuariodebian. - Metodo actual: conexion SSH directa con password mediante
SSH_ASKPASStemporal; nunca reenviar la contrasena por entrada estandar ni mostrarla en la salida. - Fuente canonica del procedimiento y de la credencial vigente:
Empresa/Servidores/VPS2/Vps2_despliegue_apps/instrucciones_montado_y_despliegue_apps_vps2_easypanel.md. - Verificacion de acceso: 2026-09-23, conexion directa correcta como
debianal hostvps-4863ac0d. - Antes de cualquier accion remota, indicar expresamente
VPS2 PRODUCCION; las comprobaciones que no contacten ese host se etiquetanLOCAL. - La contrasena no se copia en este repositorio, historial ni chat. Si cambia, actualizarla solo en la fuente canonica.
Configuracion actual (valores no secretos)
Valores vigentes confirmados en produccion (2026-09-17):
| Variable | Valor actual |
|---|---|
NODE_ENV |
production |
PORT |
80 |
QDRANT_URL |
http://qdrant:6333 |
QDRANT_API_KEY |
vacia (sin valor) |
QDRANT_COLLECTION |
rag_chunks |
EMBEDDING_PROVIDER |
openrouter |
EMBEDDING_MODEL |
qwen/qwen3-embedding-8b |
EMBEDDING_BASE_URL |
https://openrouter.ai/api/v1 |
ANSWER_PROVIDER |
openrouter |
ANSWER_MODEL |
openai/gpt-4.1-mini |
ANSWER_BASE_URL |
https://openrouter.ai/api/v1 |
POSTGRES_SSL |
false |
KNOWLEDGE_LIFECYCLE_ENFORCED |
true |
INGEST_WRITES_ENABLED |
true |
OCR_INGEST_ENABLED |
true |
OCR_SERVICE_URL |
configurada hacia el servicio privado ocr-service |
Notas de comportamiento (derivadas del codigo, sin secretos):
- Si
ANSWER_API_KEYno se define, el codigo reutilizaEMBEDDING_API_KEY. - Si
POSTGRES_URLno se define, el codigo pruebaDATABASE_URL. - Si
OCR_INGEST_ENABLEDno existe, el codigo tambien la toma comofalse; por eso debe existir explicitamente con valortrueen el entorno persistido de EasyPanel. - Un cambio en
KNOWLEDGE_LIFECYCLE_ENFORCED,INGEST_WRITES_ENABLEDoOCR_INGEST_ENABLEDse hace siempre en EasyPanel y se registra en este documento.
Variables con secretos
Estas variables contienen credenciales reales. Aqui solo se registran sus nombres:
| Variable | Estado |
|---|---|
EMBEDDING_API_KEY |
Configurada en EasyPanel; nunca copiarla en documentacion. |
ANSWER_API_KEY |
Configurada en EasyPanel; nunca copiarla en documentacion. |
POSTGRES_URL |
Configurada en EasyPanel; nunca copiarla en documentacion. |
LIFECYCLE_ADMIN_TOKEN |
Configurada en EasyPanel; nunca copiarla en documentacion. |
OCR_INTERNAL_TOKEN |
Configurada en EasyPanel, compartida con el servicio OCR y enviada como Authorization: Bearer; nunca copiarla en documentacion. |
Salida por etapas del OCR
El OCR es un servicio privado e independiente. El RAG solo lo llama si OCR_INGEST_ENABLED esta activo; con el flag apagado, la ingesta sigue el flujo nativo actual, sin cambios. Hoy el flag esta en true en el RAG desplegado.
Servicio OCR privado (referencia de configuracion)
- Contenedor
ocr-service, imagen Python CPU con PaddleOCR3.4.0y PaddlePaddle3.2.2. - Una sola replica y un solo worker; limites del servicio: maximo 3 CPU y 5 GiB de RAM.
- Modelos descargados durante el build, nunca en el arranque.
- Solo red interna del proyecto (
easypanel-ia_servicios), sin dominio publico. OCR_SERVICE_URLapunta al servicio OCR interno por el puerto8000; el valor por defecto del codigo eshttp://ocr-service:8000, valido para un servicio llamadoocr-serviceen la red interna.- Limites fijos (no configurables por variables): cola de 3 trabajos, concurrencia 1, render a 200 DPI, maximo 50 MiB por PDF y 100 paginas por trabajo.
- Cada trabajo dispone de un lease y un limite total de 15 minutos. Solo se recupera una vez; la segunda interrupcion o el timeout son terminales.
- La readiness es falsa hasta que modelo, worker, sweeper y almacenamiento estan operativos; expone conteos por estado, recuperaciones y ultima limpieza sin incluir secretos. El healthcheck de arranque concede 90 segundos.
Volumenes
| Volumen | Ruta | Papel |
|---|---|---|
| Duradero del RAG | /data/ingestions |
Originales y artefactos de revision conservados. |
| Transitorio del OCR | /data/jobs |
Cola SQLite, PDFs y resultados en curso. |
Limpieza transitoria del OCR
- Las filas transitorias, el PDF y los resultados del OCR se eliminan tras la transferencia duradera al RAG, cuando el resultado es aceptado.
- Si esa transferencia no llega, un sweeper ejecutado al arrancar y cada 15 minutos expira los trabajos a las 24 horas, hace checkpoint WAL y vacuum incremental.
- Antes de admitir el PDF y antes de publicar cada PNG, OCR limita su uso al menor entre 10 % del filesystem y 2 GiB, reservando libre el mayor entre 10 % y 2 GiB. La presion falla cerrada como
OCR_STORAGE_PRESSURE. - La limpieza transitoria nunca toca los artefactos duraderos del RAG ni el corpus activo.
- RAG incorpora desde la revision
bfb2d48un scheduler durable basado ennext_attempt_at, con backoff de 2 a 15 segundos y un unico temporizador. El reconciliador de300000ms permanece activo como fallback global.
Verificacion posterior al despliegue (cuando cambian ambos servicios)
- Publicar el codigo en Git
mainy desplegar juntos OCR y RAG con la version indicada enVERSIONyOCR_INGEST_ENABLED=true. - Verificar el OCR internamente:
GET /health/liveyGET /health/readydeben responder con el servicio preparado. - Verificar
GET /healthdel RAG: PostgreSQL, Qdrant y reconciliador deben estar correctos. - Comprobar una ruta OCR protegida sin token. Un
401 Lifecycle admin token is requiredconfirma que OCR esta habilitado y que la autenticacion administrativa permanece protegida; no es un error que requiera correccion. - Contrastar
OCR_INGEST_ENABLED=trueen el entorno persistido de EasyPanel y en el proceso del contenedor si la UI no coincide con el comportamiento efectivo. - Consultar con token administrativo una version inexistente en revision y recuperacion: ambas deben devolver un error estructurado
404 OCR_CANDIDATE_NOT_FOUNDsin modificar datos. - Confirmar que
rag_schema_migrationscontiene003_ocr_recovery_audit.sqly que existerag_ocr_recovery_audit. - Revisar los digests y confirmar que las etiquetas OCI y las respuestas de salud muestran
0.2.1y el commit desplegado, nounknown. - Tras completar estas comprobaciones, crear una candidata FacturaTech no activa. No aprobar, indexar ni activar hasta presentar la evidencia al usuario y recibir autorizacion explicita.
Rollback de emergencia
- Ante un fallo cuyos sintomas indiquen que conviene aislar OCR: poner
OCR_INGEST_ENABLED=false, desplegar el RAG y conservar la version activa actual del corpus. No aplicar este paso automaticamente a fallos no relacionados. - El sistema es fail-closed: un fallo del OCR deja intacta la version activa anterior; no hay activacion parcial.
- Las paginas con OCR no se activan solas; pasan por el contrato de revision en estado
review_required. En la fase autonoma actual esa revision puede ejecutarla el agente; una futura consola humana reutilizara el mismo contrato. - Desactivar el OCR no borra el corpus activo ni exige reingesta.
- Si se revierte a
0.2.0, la migracion aditiva004_ocr_quality_diagnostics.sqlpermanece aplicada. No se eliminan sus columnas ni su fila de historial; antes de reabrir trafico se verifica que RAG y OCR0.2.0arrancan y pasan health con ese esquema extendido.
Limites opcionales del RAG (valores por defecto del codigo)
| Variable | Valor por defecto |
|---|---|
OCR_MAX_UPLOAD_BYTES |
52428800 (50 MiB) |
OCR_MAX_PAGES |
100 |
LIFECYCLE_RECONCILE_INTERVAL_MS |
300000 |
LIFECYCLE_INDEXING_STALE_TIMEOUT_MS |
1800000 |
QDRANT_LOGS_COLLECTION |
rag_eval_logs |
Verificaciones habituales
GET /healthdel RAG: estado general con PostgreSQL, Qdrant y reconciliador.GET /health/liveyGET /health/readydel servicio OCR: solo accesibles desde la red interna del proyecto.- Tras cambiar cualquier variable: pulsar
Deployy verificar/health.
Reglas de uso de este documento
- Consultarlo antes de tareas con servicios externos, credenciales, despliegues o ejecuciones recurrentes.
- Nunca escribir secretos aqui: solo nombres de variables y donde viven (EasyPanel).
- Si un hecho operativo deja de ser valido, actualizarlo o marcarlo como obsoleto en la misma intervencion en que se descubra.