rag-service/docs/OPERATIVA.md

10 KiB

Operativa del servicio RAG

Modulo: RAG Ultima actualizacion: 2026-09-17 Version: 1.2


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-17)

  • 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 privado ocr-service de 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 responderia 404 antes 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 /health del RAG confirma PostgreSQL, Qdrant y reconciliador sanos. OCR responde internamente live=ok y ready=true, con cola vacia y version 0.1.0.
  • La migracion 003_ocr_recovery_audit.sql esta 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_FOUND y accion verify_version_id.
  • Las imagenes en ejecucion tienen digest, pero ambas etiquetas OCI org.opencontainers.image.revision valen unknown: EasyPanel no esta pasando BUILD_REVISION durante el build. La identidad de revision verificable sigue pendiente.

Lista rapida en EasyPanel

  1. Rotar las credenciales expuestas (ver seccion siguiente); la rotacion sigue pendiente.
  2. Comprobar que las variables coinciden con la tabla de configuracion actual.
  3. Mantener OCR_INGEST_ENABLED=true para el flujo OCR ya habilitado.
  4. Pulsar Deploy en EasyPanel despues de cada cambio principal.
  5. Verificar GET /health del RAG y las rutas internas de salud del OCR tras cada deploy.
  6. Registrar el digest de cada imagen como identidad exacta de la version desplegada. Configurar RAG_VERSION, OCR_VERSION y BUILD_REVISION en un ciclo posterior si se necesita una revision legible desde health o etiquetas OCI.

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; y ANSWER_API_KEY si 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 Deploy de 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 /health del RAG.

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_KEY no se define, el codigo reutiliza EMBEDDING_API_KEY.
  • Si POSTGRES_URL no se define, el codigo prueba DATABASE_URL.
  • Si OCR_INGEST_ENABLED no existe, el codigo tambien la toma como false; por eso debe existir explicitamente con valor true en el entorno persistido de EasyPanel.
  • Un cambio en KNOWLEDGE_LIFECYCLE_ENFORCED, INGEST_WRITES_ENABLED o OCR_INGEST_ENABLED se 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 PaddleOCR 3.4.0 y PaddlePaddle 3.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_URL apunta al servicio OCR interno por el puerto 8000; el valor por defecto del codigo es http://ocr-service:8000, valido para un servicio llamado ocr-service en 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.
  • La readiness es falsa hasta que los modelos estan cargados; 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, la limpieza automatica expira los trabajos a las 24 horas.
  • La limpieza transitoria nunca toca los artefactos duraderos del RAG ni el corpus activo.

Verificacion posterior al despliegue (cuando cambian ambos servicios)

  1. Publicar el codigo en Git main y desplegar OCR y RAG desde EasyPanel.
  2. Verificar el OCR internamente: GET /health/live y GET /health/ready deben responder con el servicio preparado.
  3. Verificar GET /health del RAG: PostgreSQL, Qdrant y reconciliador deben estar correctos.
  4. Comprobar una ruta OCR protegida sin token. Un 401 Lifecycle admin token is required confirma que OCR esta habilitado y que la autenticacion administrativa permanece protegida; no es un error que requiera correccion.
  5. Contrastar OCR_INGEST_ENABLED=true en el entorno persistido de EasyPanel y en el proceso del contenedor si la UI no coincide con el comportamiento efectivo.
  6. Consultar con token administrativo una version inexistente en revision y recuperacion: ambas deben devolver un error estructurado 404 OCR_CANDIDATE_NOT_FOUND sin modificar datos.
  7. Confirmar que rag_schema_migrations contiene 003_ocr_recovery_audit.sql y que existe rag_ocr_recovery_audit.
  8. Revisar los digests y etiquetas OCI de ambas imagenes. El digest es la identidad exacta actual; una revision OCI legible es una mejora operativa posterior si sigue en unknown.
  9. No crear, recuperar, aprobar, indexar ni activar candidatas hasta la fase aprobada para v4 y FacturaTech.

Rollback de emergencia

  • Ante cualquier fallo: poner OCR_INGEST_ENABLED=false, pulsar Deploy en el RAG y conservar la version activa actual del corpus.
  • 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; requieren revision humana obligatoria (estado review_required).
  • Desactivar el OCR no borra el corpus activo ni exige reingesta.

Limites opcionales del RAG (valores por defecto del codigo)

Variable Valor por defecto
OCR_MAX_UPLOAD_BYTES 52428800 (50 MiB)
OCR_MAX_PAGES 100
OCR_PAGE_TIMEOUT_MS 60000
OCR_TOTAL_TIMEOUT_MS 900000 (15 min)
LIFECYCLE_RECONCILE_INTERVAL_MS 300000
LIFECYCLE_INDEXING_STALE_TIMEOUT_MS 1800000
QDRANT_LOGS_COLLECTION rag_eval_logs

Verificaciones habituales

  • GET /health del RAG: estado general con PostgreSQL, Qdrant y reconciliador.
  • GET /health/live y GET /health/ready del servicio OCR: solo accesibles desde la red interna del proyecto.
  • Tras cambiar cualquier variable: pulsar Deploy y 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.