Skip to main content
Glama

7dayrag

Flujo de trabajo RAG + agente de IA orientado a producción expuesto como un servicio FastAPI. Construido como la implementación de referencia para un compromiso de IA SaaS de 7 días: preguntas y respuestas fundamentadas sobre datos empresariales con citas, salvaguardas de rechazo y un agente que usa herramientas y llama a APIs internas.

Consulta ARCHITECTURE.md para conocer la justificación del diseño y el plan de entrega día a día.

Inicio rápido (no se requieren claves API)

La aplicación se ejecuta completamente sin conexión en modo stub (pseudo-embeddings deterministas + LLM con guion). Añade claves reales más tarde para cambiar a OpenAI/Anthropic con conmutación por error automática.

# 1. Postgres + pgvector
docker compose up -d db

# 2. Python deps
pip install -r requirements.txt

# 3. Configure (or skip: defaults match compose)
copy .env.example .env

# 4. Create schema + load the sample knowledge base
python -m scripts.seed_sample_data

# 5. Serve
uvicorn app.main:app --port 8000 --reload

Related MCP server: support-agent-mcp

Pruébalo

# Grounded Q&A with citations
curl -X POST localhost:8000/api/v1/query \
  -H "Content-Type: application/json" \
  -d '{"question": "What is the uptime SLA for Business plans?"}'

# Agent that calls tools (ticket lookup)
curl -X POST localhost:8000/api/v1/agent/run \
  -H "Content-Type: application/json" \
  -d '{"task": "Check ticket TICKET-1001 and summarize its status."}'

# Raw hybrid retrieval (debug/tuning)
curl -X POST localhost:8000/api/v1/documents/search \
  -H "Content-Type: application/json" \
  -d '{"query": "refund window annual plan", "top_n": 3}'

Documentación interactiva: http://localhost:8000/docs

API

Método

Ruta

Propósito

GET

/healthz, /readyz

vitalidad; preparación (BD + proveedores)

POST

/api/v1/documents

insertar o actualizar documento → fragmentar → incrustar → indexar

POST

/api/v1/documents/search

recuperación híbrida con puntuaciones fusionadas

POST

/api/v1/query

preguntas y respuestas fundamentadas {question} → respuesta + citas

POST

/api/v1/agent/run

agente de llamada a herramientas acotado, auditado en agent_runs

POST

/api/v1/admin/seed

recargar la base de conocimiento de muestra

Cada respuesta lleva un x-request-id; los errores están estructurados como {error: {code, message}}.

Configuración

Todo a través de variables de entorno / .env (consulta .env.example). Ajustes clave:

  • LLM_PROVIDER: openai | anthropic | stub | auto (auto recorre PROVIDER_ORDER con reintentos por proveedor + retroceso y conmutación por error; termina en stub si no hay claves configuradas)

  • OPENAI_BASE_URL: apunta a cualquier endpoint compatible con OpenAI (Ollama, vLLM, pasarelas)

  • MIN_VECTOR_SCORE: umbral mínimo de coseno para el mejor resultado, por debajo del cual la API se niega en lugar de adivinar

  • TICKETS_API_BASE_URL / ACCOUNTS_API_BASE_URL: apuntan las herramientas del agente a APIs internas reales; en blanco = datos de sandbox integrados

  • REDIS_URL, CACHE_ENABLED, CACHE_TTL_SECONDS, RATE_LIMIT_PER_MINUTE: caché + limitación de velocidad; la ausencia de Redis solo cuesta rendimiento, nunca disponibilidad

Redis (caché + limitación de velocidad)

Las respuestas fundamentadas se almacenan en caché (clave por pregunta + configuración) y /api/v1/* tiene limitación de velocidad por IP de cliente con una ventana fija de 60 segundos. Las respuestas llevan x-ratelimit-remaining; superar el límite devuelve un 429 estructurado. /readyz informa sobre el estado de Redis; la API falla abierta si Redis está caído. Solo se almacenan en caché las respuestas que no son rechazos (los rechazos pueden cambiar a medida que se actualizan los documentos).

docker compose up -d redis   # or just: docker compose up -d  (brings up db+redis+api+n8n)

Servidor MCP

Expón las mismas capacidades a Claude Desktop o a cualquier cliente MCP:

python mcp_server.py        # stdio transport

Herramientas: search_knowledge_base, answer_question, run_agent, lookup_ticket, lookup_account.

Fragmento de configuración de Claude Desktop:

{
  "mcpServers": {
    "7dayrag": {
      "command": "python",
      "args": ["/absolute/path/to/7dayrag/mcp_server.py"]
    }
  }
}

Automatización de flujos de trabajo con n8n

docker compose up -d n8n → abre http://localhost:5678 → importa desde workflows/:

Flujo de trabajo

Qué hace

ticket_triage.json

Webhook POST /webhook/ticket-triage {ticket_id} → valida la entrada → ejecuta el agente 7dayrag → devuelve un resumen de triaje (con rama de error). Sustituye por un nodo de Slack/correo donde responda el resumen.

kb_sync.json

Programación nocturna → resincroniza la base de conocimiento a través de /api/v1/admin/seed; reemplázala con tu fuente CMS/Git/S3 que alimente /api/v1/documents.

Los flujos de trabajo llaman a http://api:8000 (red de Compose). Si ejecutas n8n fuera de Compose, cambia la URL base a http://localhost:8000.

Prueba el webhook de triaje después de activarlo:

curl -X POST localhost:5678/webhook/ticket-triage \
  -H "Content-Type: application/json" -d '{"ticket_id": "TICKET-1001"}'

Cómo funciona la fundamentación

  1. La pregunta se incrusta (mismo modelo que en la ingesta) y se ejecuta mediante recuperación híbrida: pgvector coseno top-K + Postgres texto completo top-K, fusionados con Reciprocal Rank Fusion.

  2. Si la puntuación vectorial del mejor resultado está por debajo de MIN_VECTOR_SCORE → rechazo (sin llamada al LLM).

  3. De lo contrario, el contexto numerado se envía al modelo con reglas estrictas: citar como [n], responder solo desde el contexto, responder NOT_ENOUGH_CONTEXT en caso contrario.

  4. Las citas en la respuesta se mapean de vuelta a los documentos fuente y se devuelven.

Pruebas

docker compose up -d db      # integration tests need Postgres on :5433
pytest tests -q              # unit + integration; integration skips cleanly without DB
ruff check app tests scripts

21 pruebas: invariantes de fragmentación, fusión RRF, determinismo de embeddings, comportamiento del proveedor stub, análisis del bucle del agente, además de recorridos de extremo a extremo de la API contra Postgres/pgvector reales.

Despliegue (staging)

cp .env.example .env   # add OPENAI_API_KEY
docker compose up -d --build
curl localhost:8000/readyz
curl -X POST localhost:8000/api/v1/admin/seed

Para AWS: mismas imágenes → ECS Fargate + RDS Postgres (habilita la extensión pgvector). Para DigitalOcean: droplet + Postgres gestionado. Secretos solo a través de variables de entorno/gestor de secretos.

Estructura del proyecto

app/
  api/        FastAPI routes (documents, query, agent, health/admin)
  agent/      tool registry (KB search, ticket/account lookup) + bounded agent loop
  llm/        provider abstraction: openai, anthropic, stub + retry/failover router
  rag/        chunking, ingestion, hybrid retrieval (RRF), grounded generation
  cache.py    Redis: response cache + fixed-window rate limiting (fail-open)
  config.py   env-driven settings · db.py engine/session · db_init.py schema bootstrap
data/sample_docs/*.md    demo knowledge base
scripts/seed_sample_data.py
workflows/*.json         importable n8n automations (ticket triage, KB sync)
mcp_server.py            MCP tool server (stdio) for Claude Desktop / MCP clients
tests/

Próximos pasos (backlog posterior al compromiso)

Streaming (SSE), captura de comentarios en un conjunto de evaluación, etapa de reordenamiento, RLS multiinquilino, reindexación programada, versionado de prompts/A-B, paneles de costos.

Related MCP Connectors

Related MCP Servers