rag-service/docs/API_RAG.md

14 KiB

API del RAG

Proyecto: Workspace de tools IA para empresas
Modulo: RAG
Ultima actualizacion: 2026-09-11 Ultima modificacion por: Subagente Implementacion ciclo de vida del conocimiento Estado: Punto 2 implementado localmente; pendiente de migracion y validacion en produccion

Esta guia explica como descubrir y consumir la API. El contrato tecnico completo y canonico se publica en OpenAPI 3.1.1; este documento prioriza el camino rapido, las decisiones de uso y los ejemplos habituales.

Acceso rapido

Base URL de produccion:

https://rag.por-correo.com
Recurso URL Uso
Ayuda resumida GET /help Descubrimiento rapido para personas y agentes
Contrato OpenAPI GET /openapi.json Esquemas, parametros, respuestas y errores
Playground GET /playground Pruebas manuales desde navegador

GET /help indica expresamente que debe consultarse /openapi.json para obtener los parametros, cuerpos, respuestas, errores y ejemplos completos de cada endpoint.

La API general sigue sin autenticacion completa. Las operaciones administrativas del ciclo de vida usan una proteccion acotada con Authorization: Bearer <LIFECYCLE_ADMIN_TOKEN>; esto no sustituye la autenticacion general pendiente.

Elegir la operacion correcta

Necesidad Endpoint recomendado
Comprobar servicio y capacidades GET /health
Ver scopes ingeridos GET /sources
Ver versiones de una fuente GET /sources/{sourceId}/versions
Activar, rollback o purgar versiones /sources/* con token administrativo
Recuperar contexto para otro agente POST /retrieve
Obtener una respuesta final con citas POST /answer
Comparar una respuesta sin RAG POST /answer/direct
Conversar con bootstrap e historial POST /chat
Ingerir una ruta accesible por el servidor POST /ingest
Subir un archivo o carpeta ZIP POST /ingest/upload
Eliminar una fuente antes de reingestar POST /cleanup legacy, o purga de version no activa
Consultar o actualizar evaluaciones /logs/*

Catalogo completo

La API queda formada por las operaciones de descubrimiento, ingesta, retrieval, evaluacion y ciclo de vida:

Metodo Ruta Descripcion
GET /help Catalogo resumido derivado de OpenAPI
GET /openapi.json Contrato OpenAPI 3.1.1
GET /playground Interfaz web de prueba
GET /health Estado, proveedores, parsers y chunking
GET /sources Scopes disponibles en Qdrant
GET /sources/{sourceId} Fuente registrada en el catalogo
GET /sources/{sourceId}/versions Versiones de una fuente
GET /sources/{sourceId}/versions/{versionId} Detalle de una version
POST /sources/{sourceId}/versions/{versionId}/activate Activacion administrativa con precondicion
POST /sources/{sourceId}/rollback Rollback administrativo sin recalcular embeddings
POST /sources/{sourceId}/versions/{versionId}/retry Reintento explicito de version fallida o huerfana con fuente durable
DELETE /sources/{sourceId}/versions/{versionId} Purga administrativa de una version no activa
GET /models/answer Modelo por defecto y modelos seleccionables
POST /ingest Ingesta desde una ruta del servidor
POST /ingest/upload Upload multipart/form-data
POST /cleanup Borrado controlado por scope
POST /retrieve Recuperacion de contexto
POST /answer Respuesta apoyada en retrieval
POST /answer/direct Respuesta del modelo sin retrieval
POST /chat Conversacion con contexto opcional
GET /logs/recent Logs recientes de evaluacion
POST /logs/manual Registro manual de una evaluacion
PATCH /logs/{id} Seguimiento y resolucion de un log

Contratos comunes

Scope

Permite limitar una consulta o una operacion a fuentes concretas:

{
  "sourceId": "customer-a:manual:v1",
  "sourceRef": "customer-a-errors.md",
  "tags": ["customer-a", "support"]
}

Todos los campos son opcionales en consultas. Para POST /cleanup es obligatorio enviar al menos sourceId o sourceRef; las etiquetas solas no autorizan un borrado.

Modos e intents

Campo Valores Default
mode en retrieval y answer documental, codigo, auto auto
mode en chat documental, codigo, auto documental
intent specific, bootstrap specific
mode en ingesta mechanical, interactive mechanical

Errores

Los errores JSON siguen esta forma:

{
  "ok": false,
  "error": "Description of the error"
}

Actualmente la mayoria de fallos de validacion o de proveedores se devuelven como 500. POST /cleanup y POST /ingest/upload tambien pueden devolver 400, y PATCH /logs/{id} devuelve 404 si no encuentra el log. Mejorar la validacion queda fuera de este bloque para no cambiar silenciosamente el comportamiento existente.

Con KNOWLEDGE_LIFECYCLE_ENFORCED=true, la API devuelve errores mas especificos para el catalogo:

Codigo HTTP Caso
400 Falta expectedActiveVersionId cuando activate=true
409 Cambio concurrente de version activa, version en curso o intento de purgar una activa
422 Fuente vacia, sin documentos soportados o sin contenido util
503 PostgreSQL, Qdrant, embeddings o version activa inconsistente

Recuperar contexto

POST /retrieve es la operacion recomendada cuando otro agente o flujo generara la respuesta final.

curl -sS -X POST "https://rag.por-correo.com/retrieve" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "documental",
    "intent": "specific",
    "query": "What does error FAT07 mean?",
    "scope": {
      "sourceId": "customer-a:manual:v1"
    },
    "useModelInRetrieve": false
  }'

Campos principales:

Campo Requerido Funcion
query Si Consulta de recuperacion
mode No Tipo de conocimiento
intent No Consulta concreta o mapa bootstrap
scope No Limita las fuentes
useModelInRetrieve No Añade modelSummary generado por un modelo
model No Override usado solo para modelSummary
bootstrapMeta No Trazabilidad del bootstrap en logs

Respuesta resumida:

{
  "mode": "documental",
  "intent": "specific",
  "summary": "Retrieved 5 relevant chunks.",
  "topics": ["support-errors.md"],
  "criticalPoints": [],
  "items": [
    {
      "chunkId": "chk:example",
      "documentId": "doc:example",
      "sourceId": "customer-a:manual:v1",
      "title": "support-errors.md",
      "content": "...",
      "score": 0.87
    }
  ],
  "followUpRefs": ["doc:example"],
  "scope": {
    "sourceId": "customer-a:manual:v1"
  }
}

Obtener una respuesta

POST /answer ejecuta retrieval y genera una respuesta final con citas.

{
  "mode": "documental",
  "intent": "specific",
  "query": "Explain the documented resolution for FAT07",
  "scope": {
    "sourceId": "customer-a:manual:v1"
  },
  "model": "openai/gpt-4.1-mini"
}

Tambien acepta preloadedContext y bootstrapMeta. La respuesta incluye model, answer, resumen del retrieval, temas, puntos criticos, citas y scope.

POST /answer/direct no consulta el vector store:

{
  "query": "Explain what a RAG service is",
  "model": "openai/gpt-4.1-mini",
  "preloadedContext": "Optional context supplied by the caller"
}

Su respuesta real solo contiene:

{
  "model": "openai/gpt-4.1-mini",
  "answer": "..."
}

Chat con bootstrap

POST /chat reutiliza contexto precargado, historial reciente y, opcionalmente, una nueva consulta al RAG:

{
  "message": "What should I check next?",
  "history": [
    {
      "role": "user",
      "content": "Give me an initial map of this project"
    },
    {
      "role": "assistant",
      "content": "The project contains..."
    }
  ],
  "mode": "documental",
  "preloadedContext": "Previously loaded bootstrap",
  "allowAdditionalRetrieve": true,
  "scope": {
    "sourceId": "project-docs"
  }
}

Respuesta:

{
  "model": "openai/gpt-4.1-mini",
  "answer": "...",
  "usedBootstrapContext": true,
  "usedAdditionalRetrieve": true,
  "retrieved": {
    "summary": "...",
    "items": []
  }
}

Ingesta

Ruta del servidor

POST /ingest requiere sourceType y sourceRef:

{
  "sourceId": "project-docs",
  "sourceType": "folder",
  "sourceRef": "/data/project-docs",
  "mode": "mechanical",
  "tags": ["project", "documentation"],
  "activate": true,
  "expectedActiveVersionId": null
}

readPath es un campo interno para separar la ruta fisica de lectura de la referencia logica. Los consumidores normales no deben enviarlo.

Con ciclo de vida activo:

  • activate por defecto es true.
  • si activate=true, expectedActiveVersionId es obligatorio: null para primera activacion y UUID para reemplazar una version existente.
  • una ingesta identica a la version activa responde noOp: true y no escribe nuevos puntos.
  • activate=false deja la version en ready para activarla despues con una operacion administrativa.
  • la respuesta exitosa cambia a 201 Created e incluye sourceId, versionId, versionNumber, state, previousVersionId, activated y noOp.

Upload

POST /ingest/upload usa multipart/form-data:

Campo Requerido Formato
file Si Archivo binario o ZIP
sourceId No Identificador logico
mode No mechanical o interactive
tags No Lista separada por comas
isZipFolder No Texto true o false
activate No Texto true o false
expectedActiveVersionId Si activa UUID o texto null
curl -sS -X POST "https://rag.por-correo.com/ingest/upload" \
  -F "file=@./support-errors.md" \
  -F "sourceId=customer-a:manual:v1" \
  -F "mode=mechanical" \
  -F "tags=customer-a,support"

Con enforcement desactivado, ambas variantes conservan 202. Con enforcement activado, responden 201 y usan el catalogo PostgreSQL como autoridad de version activa. El upload añade uploadedResource.

Ciclo de vida de fuentes

El catalogo PostgreSQL es la autoridad para saber que fuentes existen, que versiones tienen y cual es la version activa. Qdrant conserva los puntos fisicos versionados, pero retrieval solo consulta versiones activas resueltas desde PostgreSQL.

Listado y detalle

GET /sources
GET /sources/{sourceId}
GET /sources/{sourceId}/versions
GET /sources/{sourceId}/versions/{versionId}

GET /sources mantiene los campos usados por el playground (sourceId, sourceRef, chunkModes, tags) y añade activeVersionId, activeVersionNumber, state, needsReingest y updatedAt.

Activacion y rollback

curl -sS -X POST "https://rag.por-correo.com/sources/src:default:folder:docs/versions/<version-id>/activate" \
  -H "Authorization: Bearer $LIFECYCLE_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"expectedActiveVersionId":"<active-version-id>"}'

Rollback usa la misma activacion atomica del puntero PostgreSQL:

{
  "targetVersionId": "uuid-version-anterior",
  "expectedActiveVersionId": "uuid-version-activa-actual"
}

Purga

DELETE /sources/{sourceId}/versions/{versionId} exige token administrativo y solo acepta versiones no activas. La purga marca la version como purging, borra puntos Qdrant con wait=true, verifica que no quedan puntos y finalmente deja la version como purged.

Reintento explicito

POST /sources/{sourceId}/versions/{versionId}/retry acepta versiones failed, pending o indexing. Si recibe una fuente durable (sourceType, sourceRef y opcionalmente readPath) cierra versiones huerfanas como fallidas y crea una version nueva mediante /ingest. Si no recibe fuente durable, devuelve 202 con instrucciones: los uploads temporales no se reintentan en sitio porque el original ya no esta garantizado.

Limpieza controlada

POST /cleanup elimina los chunks que coinciden con un scope solo en modo legacy y con INGEST_WRITES_ENABLED=true:

{
  "scope": {
    "sourceId": "customer-a:manual:v1"
  }
}

Respuesta:

{
  "ok": true,
  "deleted": 36
}

Esta operacion es destructiva. Verifica primero el scope con GET /sources.

Evaluacion

GET /logs/recent?limit=20 devuelve los logs recientes. Si no se indica limit, usa 20.

POST /logs/manual registra una observacion humana:

{
  "operation": "retrieve",
  "reason": "manual_review_requested",
  "query": "What does error FAT07 mean?",
  "mode": "documental",
  "intent": "specific",
  "scope": {
    "sourceId": "customer-a:manual:v1"
  },
  "note": "The first result is too generic"
}

PATCH /logs/{id} actualiza su seguimiento:

{
  "reviewStatus": "resolved",
  "severity": "high",
  "reviewedBy": "maintainer",
  "resolutionNote": "Retrieval ranking adjusted and validated.",
  "fixReference": "commit-or-ticket-reference"
}

Valores admitidos:

Campo Valores
reviewStatus pending, in_progress, resolved, ignored
severity low, medium, high

Integracion recomendada con n8n

Para una HTTP Request Tool conectada a un AI Agent:

  1. Usa POST /retrieve.
  2. Fija mode, intent y scope en el nodo.
  3. Permite que el agente complete solo query.
  4. Mantiene useModelInRetrieve=false para evitar procesar la consulta con dos modelos.
  5. Entrega items[].content y sus metadatos al agente final.

Usa POST /answer solamente cuando el propio RAG deba generar la respuesta final.

Fuente de verdad y mantenimiento

  • GET /openapi.json es el contrato publico para integraciones y herramientas.
  • GET /help es el indice rapido derivado del mismo contrato.
  • Este documento explica flujos y decisiones de uso.
  • src/app.ts contiene la implementacion efectiva.
  • Cualquier cambio de endpoint debe actualizar OpenAPI y esta guia en el mismo bloque de trabajo.