Playbook operativo · Hermes Agent

Cómo convertir un agente Hermes en una API privada lista para clientes

Documento genérico para reutilizar en implementaciones comerciales: arquitectura, seguridad, configuración, sesiones, healthchecks y patrones de integración con landings, CRM, webhooks y n8n.

OpenAI-compatible Sesiones persistentes Proxy seguro Multi-agente por perfil Docker / VPS / Cloudflare

Objetivo

Exponer Hermes Agent como un servicio HTTP privado para que aplicaciones externas puedan conversar con un agente, mantener continuidad por sesión y ejecutar herramientas server-side sin revelar claves ni abrir el gateway directamente a Internet.

La idea no es vender “un chatbot suelto”, sino una capa reutilizable de agente IA conectable a procesos reales: ventas, soporte, calificación, contenido, operaciones y automatizaciones internas.

Regla central

Nunca publicar el puerto del API Server directo al navegador o a Internet.

El frontend habla con tu backend, Worker o middleware. Ese backend agrega el Bearer token y reenvía a Hermes por red privada.

Arquitectura recomendada

Usuario / Webhook / n8n
        │
        ▼
HTTPS público
Cloudflare / App / Middleware propio
        │  agrega auth, rate-limit, logs
        ▼
Red privada / Docker network / localhost
Hermes API Server
        │
        ▼
Agente + tools + sesiones persistentes

Hermes queda como motor interno. La capa pública controla autenticación, validación, límites de uso y formato de respuesta.

Qué habilita

  • Chat estilo OpenAI en /v1/chat/completions.
  • Responses API en /v1/responses para flujos stateful.
  • Sesiones nativas en /api/sessions.
  • Runs largos en /v1/runs con eventos SSE.
  • Tools ejecutadas en el servidor, no en el cliente.
  • Monitoreo por /health, /v1/capabilities y /v1/toolsets.

Configuración base del gateway

Usa placeholders genéricos. Cada cliente debe tener su propio puerto, token, perfil y ruta de persistencia.

config.yaml

platforms:
  api_server:
    enabled: true
    host: "127.0.0.1"   # o 0.0.0.0 SOLO dentro de Docker privado
    port: 8642

platform_toolsets:
  api_server:
    - clarify
    - crm-tools
    - knowledge-search

tools:
  api_server:
    disabled:
      - terminal
      - process
      - execute_code
      - write_file
      - patch
      - cronjob
      - delegate_task
      - web_search
      - browser_navigate

.env

API_SERVER_KEY="generar-con-openssl-rand-hex-32"
API_SERVER_HOST="127.0.0.1"
API_SERVER_PORT="8642"
API_SERVER_CORS_ORIGINS="https://app.cliente.com"
API_SERVER_MODEL_NAME="agente-ventas"

# Provider LLM
NAN_API_KEY="..."
HERMES_MODEL="qwen3.6"

# Tools internas
CRM_TOOL_BASE_URL="http://app-interna:3000"
AGENT_TOOLS_SECRET="otro-secreto-fuerte"

Si corres en Docker, el bind 0.0.0.0 es aceptable solo si el puerto no se publica al host y la comunicación ocurre por red interna.

Sesiones persistentes

La continuidad puede manejarse de dos formas complementarias:

  • X-Hermes-Session-Id: conserva el hilo técnico de conversación.
  • X-Hermes-Session-Key: identificador estable por usuario, canal o proceso.
  • /api/sessions: crear, listar, leer, actualizar, bifurcar y borrar sesiones.
curl -X POST http://localhost:8642/v1/chat/completions \
  -H "Authorization: Bearer $API_SERVER_KEY" \
  -H "Content-Type: application/json" \
  -H "X-Hermes-Session-Id: lead-123" \
  -H "X-Hermes-Session-Key: cliente:whatsapp:573001112233" \
  -d '{
    "model": "agente-ventas",
    "messages": [{"role":"user","content":"Quiero cotizar"}]
  }'

Persistencia recomendada

En producción, monta el directorio de perfiles en un volumen persistente:

/data/hermes/profiles
├── ventas/state.db
├── ventas/response_store.db
├── ventas/sessions/
├── soporte/state.db
└── soporte/sessions/

Checklist mínimo: crear sesión, enviar mensaje, leer mensajes, reiniciar contenedor y volver a leer la sesión. Si sobrevive, está listo para clientes.

Patrones de integración reutilizables

Landing page

El widget web llama a /api/chat en tu backend. El backend agrega el Bearer token y reenvía a Hermes.

CRM / Inbox

El CRM genera session keys por contacto y guarda resumen, etapa, tags, intención y próximos pasos.

n8n / Webhooks

El workflow llama al middleware, no al API Server directo. Ideal para clasificación, enriquecimiento y tareas internas.

Middleware mínimo en Node/Next.js

export async function POST(request) {
  const { message, userId } = await request.json();

  const response = await fetch(`${process.env.HERMES_URL}/v1/chat/completions`, {
    method: "POST",
    headers: {
      "Authorization": `Bearer ${process.env.HERMES_API_KEY}`,
      "Content-Type": "application/json",
      "X-Hermes-Session-Key": `web:${userId}`,
    },
    body: JSON.stringify({
      model: process.env.HERMES_MODEL,
      messages: [{ role: "user", content: message }],
      stream: false,
    }),
  });

  if (!response.ok) return Response.json({ error: "agent_unavailable" }, { status: 502 });
  const data = await response.json();
  return Response.json({ answer: data.choices?.[0]?.message?.content ?? "" });
}

Reglas no negociables

  • No poner API_SERVER_KEY en frontend, HTML, JavaScript público ni n8n compartido.
  • No publicar el puerto del gateway directo a Internet.
  • No activar tools peligrosas si el agente atiende usuarios externos.
  • No reutilizar la misma API key entre clientes.
  • No guardar secretos en repositorios ni documentación comercial.

Checklist de hardening

  • Clave fuerte con openssl rand -hex 32.
  • Proxy HTTPS con rate limiting.
  • CORS restringido al dominio del cliente.
  • Logs saneados sin tokens ni payloads sensibles.
  • Healthcheck interno y alerta si cae el gateway.
  • Volumen persistente para state.db y sesiones.
  • Backups del directorio de perfiles.

Validación antes de entregar

PruebaComando / criterioResultado esperado
Health simpleGET /health200 OK
Auth obligatoriaGET /v1/models sin token401
ModeloGET /v1/models con token200 + modelo esperado
CapabilitiesGET /v1/capabilitiesLista endpoints y features activos
ToolsGET /v1/toolsetsSolo toolsets permitidos activos
ChatPOST /v1/chat/completionsRespuesta útil, streaming opcional
SesionesCrear → chatear → leer mensajes → reiniciar → leerPersistencia confirmada
Exposiciónss -lntp / firewall / Docker portsPuerto no abierto públicamente

Referencia completa del API Server

¿Qué es el API Server? Es el adaptador HTTP de Hermes Agent. Mantiene compatibilidad OpenAI-compatible, sesiones nativas, ejecución de herramientas en servidor y runs estructurados para procesos largos.

Esta sección conserva los puntos operativos importantes de la guía base, adaptados a un documento genérico para clientes y equipos técnicos.

Reglas duras del servidor

  • El gateway se niega a arrancar si API_SERVER_KEY no está configurada.
  • Si el bind es accesible por red, rechaza claves placeholder o débiles.
  • Límite de body: 10 MB.
  • Los headers de sesión deben tener longitud acotada para evitar abuso.
  • Los logs no deben imprimir tokens, claves, teléfonos ni payloads sensibles.

Endpoints disponibles

GrupoEndpointUso
HealthGET /healthHealth check simple del gateway.
HealthGET /health/detailedEstado enriquecido; en algunas versiones requiere Bearer auth.
MetadataGET /v1/modelsModelo o perfil disponible para ese gateway.
MetadataGET /v1/capabilitiesFeatures, endpoints, auth y runtime activos.
MetadataGET /v1/skillsSkills cargadas por el agente.
MetadataGET /v1/toolsetsToolsets disponibles y cuáles están habilitados.
ChatPOST /v1/chat/completionsChat compatible con OpenAI, con o sin streaming.
ResponsesPOST /v1/responsesResponses API stateful para flujos más estructurados.
ResponsesGET /v1/responses/{id}Recuperar respuesta almacenada.
ResponsesDELETE /v1/responses/{id}Borrar respuesta almacenada.
SesionesGET /api/sessionsListar sesiones persistidas.
SesionesPOST /api/sessionsCrear sesión vacía.
SesionesGET /api/sessions/{id}Leer metadata de una sesión.
SesionesPATCH /api/sessions/{id}Actualizar título o cierre de una sesión.
SesionesDELETE /api/sessions/{id}Borrar una sesión.
SesionesGET /api/sessions/{id}/messagesLeer historial de mensajes.
SesionesPOST /api/sessions/{id}/forkBifurcar una sesión.
SesionesPOST /api/sessions/{id}/chatChatear dentro de sesión existente.
SesionesPOST /api/sessions/{id}/chat/streamChatear con streaming dentro de sesión.
RunsPOST /v1/runsCrear run largo; devuelve run_id.
RunsGET /v1/runs/{id}Consultar estado del run.
RunsGET /v1/runs/{id}/eventsEventos SSE de progreso.
RunsPOST /v1/runs/{id}/approvalResolver aprobación pendiente.
RunsPOST /v1/runs/{id}/stopDetener run en curso.

Autenticación y headers especiales

Todas las rutas operativas deben usar Authorization: Bearer <API_SERVER_KEY>. El servidor compara el token con una comparación segura tipo hmac.compare_digest(); un fallo debe devolver un 401 con error tipo Invalid API key.

HeaderUso
AuthorizationBearer token obligatorio para rutas protegidas.
X-Hermes-Session-IdContinuar una sesión técnica específica.
X-Hermes-Session-KeyIdentificador estable por usuario, canal, formulario o proceso.
Idempotency-KeyEvitar repetir respuestas no-streaming si el cliente reintenta.
OriginValidación CORS cuando aplique.

Ejemplo con Python requests

import requests

BASE = "http://localhost:8642"
API_KEY = "usar-variable-de-entorno"

response = requests.post(
    f"{BASE}/v1/chat/completions",
    headers={
        "Authorization": f"Bearer {API_KEY}",
        "Content-Type": "application/json",
        "X-Hermes-Session-Key": "lead:web:123",
    },
    json={
        "model": "agente-ventas",
        "messages": [
            {"role": "user", "content": "Resume este lead y clasifica urgencia."}
        ],
    },
    timeout=60,
)
print(response.json()["choices"][0]["message"]["content"])

Ejemplo con SDK oficial de OpenAI

from openai import OpenAI

client = OpenAI(
    base_url="http://localhost:8642/v1",
    api_key="usar-variable-de-entorno",
    default_headers={
        "X-Hermes-Session-Key": "cliente:crm:123"
    },
)

response = client.chat.completions.create(
    model="agente-ventas",
    messages=[
        {"role": "system", "content": "Eres un asistente comercial claro y breve."},
        {"role": "user", "content": "¿Qué información falta para cotizar?"},
    ],
)
print(response.choices[0].message.content)

Casos de uso reusable

Chatbot embebido

Un widget en una landing llama a un proxy propio que reenvía a Hermes con sesión por visitante.

Clasificación automática de leads

Un formulario dispara un análisis de intención, urgencia, presupuesto y próximo paso.

Asistente de contenido

Genera titulares, estructura de posts, CTAs o respuestas para canales comerciales.

GitHub / CI

Un webhook puede iniciar un run para revisar cambios, resumir diffs o proponer checklist.

Panel de salud

Un monitor consulta health y capabilities para alertar si el agente no está disponible.

Operación interna

n8n o un backend dispara tareas controladas sin exponer herramientas peligrosas al usuario final.

Systemd y operación

En VPS tradicional, evita procesos sueltos tipo nohup. Usa unidades systemd o contenedores supervisados por Docker/Coolify.

systemctl --user start hermes-gateway-default.service
systemctl --user restart hermes-gateway-default.service
systemctl --user stop hermes-gateway-default.service

Si el gateway habilita jobs o cron internos, audita rutas como /api/jobs y evita que cualquier cliente con API key pueda crear tareas no deseadas.

Diagnóstico rápido

SíntomaCausa probableSolución
Connection refusedGateway detenido o puerto incorrecto.Reiniciar servicio y validar puerto/bind.
Invalid API keyToken mal copiado o env no recargado.Validar API_SERVER_KEY y redeploy/restart.
No respeta sesiónFalta API key o header de sesión inconsistente.Enviar X-Hermes-Session-Id y/o X-Hermes-Session-Key.
CORS blockedOrigen no permitido o llamada directa desde navegador.Usar proxy backend y restringir CORS.
Respuesta vacíaMensaje vacío o solo system prompt.Enviar al menos un mensaje user con contenido.
Tool call no ejecutaToolset no habilitado para api_server.Revisar platform_toolsets.api_server.

Handoff para clientes

Cuando se entrega una implementación, documenta solo lo operativo y no expongas detalles sensibles.

  • URL pública del middleware, no del gateway privado.
  • Casos de uso habilitados: chat, lead scoring, soporte, contenido, etc.
  • Qué datos guarda la sesión y por cuánto tiempo.
  • Cómo apagar/encender automatizaciones.
  • Qué evento escala a humano.
  • Plan de monitoreo y soporte.

Plantilla de decisión rápida

Usar API Server si necesitas integrar un agente con apps, webhooks o workflows manteniendo el agente en tu infraestructura.

Usar proxy siempre que haya un navegador, un cliente externo o una integración de terceros.

No usar directo si no puedes proteger secretos, rate limits, logs y persistencia.