Visión general de la arquitectura
- Server: Servicio HTTP en Rust; recibe lotes de eventos, los escribe en ClickHouse y mantiene el estado relacional en PostgreSQL.
- Dashboard: Aplicación web Next.js; lee y escribe exclusivamente a través de la API del servidor.
- agenteye-collector: se despliega en las máquinas de los agentes, no en el host del servidor.
- Postgres 15+: OBLIGATORIO. (Actualizado desde la versión 14 en la versión multi-tenant; el esquema de pertenencia a organizaciones usa una clave foránea
ON DELETE SET NULLcon lista de columnas, disponible desde Postgres 15+. Actualiza Postgres antes de desplegar esta versión.) Almacena el estado OLTP:api_keys,users,sessions,evaluation_jobs(cola),dashboards,saved_queries,otp_codes, además de las tablas multi-tenantorgs,org_memberships,org_settings. - ClickHouse 24+: OBLIGATORIO. El almacén de analítica para cada evento ingerido. Motor:
ReplacingMergeTree, particionado por mes, ordenado por(session_id, ts, dedup_key). El servidor se conecta a través deCLICKHOUSE_URL; eldeploy/base/clickhouse/incluido incorpora una configuración de nodo único optimizada para rendimiento. Requisito multi-tenant: la configuración incluida habilita la gestión de acceso SQL +users_without_row_policies_can_read_rows=falsepara que el servidor pueda crear un usuario de ClickHouse de solo lectura + política de fila por organización (el límite de aislamiento impuesto por el motor para el editor SQL y el agente de IA). Si usas tu propia configuración de ClickHouse, incorpora estos ajustes (verdeploy/base/clickhouse/configmap.yaml). - Redis 7+: caché compartida opcional + backend de limitación de tasa. El servidor y el panel se conectan a través de
REDIS_URL. Si no está disponible, ambos degradan de forma controlada a rutas que solo usan Postgres. Consulta Redis (caché opcional) a continuación.
Servidor
Descargar la imagen
Las compilaciones actuales se publican conbeta-latest;latestsolo se asigna a versiones estables. Para producción, fija una etiqueta específica:v<versión>; consulta Etiquetas de imagen disponibles.
Variables de entorno
| Variable | Obligatoria | Valor por defecto | Descripción |
|---|---|---|---|
DATABASE_URL | Sí | ninguno | DSN de Postgres. Formato de cadena de conexión libpq estándar con esquema postgres://. Admite ?sslmode=require y otros parámetros libpq. La contraseña no debe contener /, + ni =; usa openssl rand -hex para generar contraseñas seguras para URL. |
ADMIN_KEY | No | ninguno | Clave de API de administrador de arranque. Se inserta o actualiza con todos los permisos en cada inicio. Rótala cambiando el valor y reiniciando. |
LISTEN_ADDR | No | 0.0.0.0:8080 | Dirección TCP a la que vincularse |
MAX_BODY_BYTES | No | 134217728 (128 MB) | Tamaño máximo del cuerpo de la solicitud |
ADMIN_EMAIL | No | ninguno | Correo electrónico del usuario administrador de arranque. Se inserta o actualiza con todos los permisos en cada inicio y se marca como protegido: no puede deshabilitarse ni modificarse sus permisos desde el panel/API. Para rotar el administrador de arranque, cambia ADMIN_EMAIL y reinicia; el nuevo correo se inserta como protegido, y el anterior conserva su protección hasta que se limpie manualmente en la base de datos. |
ALLOWED_EMAILS | No | ninguno (todos bloqueados) | Lista separada por comas de correos permitidos para la creación de usuarios e inicio de sesión. Admite direcciones exactas (user@example.com) y comodines de dominio (*@example.com). Si no se establece, no se puede crear ningún usuario ni iniciar sesión. Solo semilla en el primer arranque: llena la lista de permitidos de la organización predeterminada en el primer arranque; a partir de entonces, la página /<org>/settings de cada organización es la fuente de verdad y cambiar esta variable de entorno no tiene efecto. |
SMTP_HOST | No | ninguno | Nombre de host del servidor SMTP para enviar correos OTP. Si no se establece, los códigos OTP se registran en stdout. |
SMTP_PORT | No | 587 | Puerto del servidor SMTP |
SMTP_USERNAME | No | ninguno | Nombre de usuario de autenticación SMTP |
SMTP_PASSWORD | No | ninguno | Contraseña de autenticación SMTP |
SMTP_FROM | No | ninguno | Dirección de correo del remitente para los correos OTP |
SMTP_TLS | No | STARTTLS | Se usa STARTTLS a menos que lo desactives explícitamente: false o 0 envía texto plano (sin TLS); cualquier otro valor — incluido no establecerlo — habilita STARTTLS. |
DASHBOARD_URL | No | valor predeterminado integrado | Origen del panel usado para construir el enlace mágico del correo OTP y los enlaces mágicos de incidentes en las notificaciones de alertas. Si no se establece, recurre a un valor predeterminado integrado (y, solo para OTP, al origen de la solicitud derivado del panel primero). Establécelo para configuraciones con dominios separados de modo que tanto los correos como los enlaces de Slack/incidentes apunten a tu panel. Consulta URL del enlace mágico por correo a continuación; la mayoría de los operadores no necesitan configurar esto. |
SESSION_TTL_SECS | No | 86400 (24 h) | Duración de la sesión del panel en segundos. Solo semilla en el primer arranque: edítalo por organización en /<org>/settings después del primer despliegue. |
OTP_TTL_SECS | No | 600 (10 min) | Período de validez del código OTP en segundos. Solo semilla en el primer arranque: edítalo por organización en /<org>/settings después del primer despliegue. |
REDIS_URL | No | ninguno | Backend opcional de caché compartida + limitación de tasa, p. ej. redis://redis:6379/0. Cuando se establece, el servidor almacena en caché las búsquedas de claves API autenticadas, el agregado /models del panel, la lista de sesiones y la faceta de lista de entornos; también mueve la limitación de tasa de solicitudes OTP de Postgres COUNT a Redis INCR. Si no se establece o es inaccesible, el servidor funciona sin caché (el límite OTP vuelve a Postgres; el resto de llamadas de caché recurren a la fuente de verdad). Consulta Redis (caché opcional) a continuación. |
CLICKHOUSE_URL | Sí | ninguno | URL base de la instancia de ClickHouse, p. ej. http://clickhouse:8123. El servidor aplica su esquema de eventos a esta base de datos en cada inicio y se niega a arrancar si no puede alcanzar ClickHouse. Consulta ClickHouse (almacén de analítica obligatorio) a continuación. |
CLICKHOUSE_DATABASE | No | agenteye | Nombre de la base de datos (esquema) de ClickHouse. El servidor la crea al inicio si no existe. |
ORG_CH_SECRET | No (un solo tenant) / Sí (multi-org) | valor predeterminado de desarrollo | Clave HMAC a partir de la cual se deriva la contraseña de ClickHouse por tenant de cada organización. El editor SQL y el run_query del agente de IA se ejecutan como el usuario de ClickHouse de solo lectura propio de la organización, cuya política de fila impone el aislamiento de tenant en el motor. Los despliegues de un único tenant arrancan bien con el valor predeterminado de desarrollo integrado; antes de provisionar una segunda organización DEBES establecer un valor sólido y estable, porque la CLI agenteye-orgctl org create se niega a ejecutarse con el valor predeterminado de desarrollo integrado. Rotarlo huérfana el usuario de ClickHouse de cada organización hasta el próximo inicio, que los vuelve a provisionar automáticamente. Mantenlo en secreto e igual en todas las réplicas. El provisionamiento de organizaciones es solo para operadores; consulta Organizaciones (multi-tenancy) a continuación. |
DEFAULT_ORG_NAME | No | Default | Nombre de visualización sembrado para la organización predeterminada integrada. Solo semilla en el primer arranque, y solo mientras la organización conserve su identidad genérica recién migrada; se aplica al inicio y luego se ignora. Una vez que renombras la organización (agenteye-orgctl org rename), el nuevo nombre es autoritativo y esta variable de entorno no tiene más efecto. |
DEFAULT_ORG_SLUG | No | default | Slug de URL para la organización predeterminada integrada, la ruta del panel donde reside (/<slug>/…). Misma semántica de solo primer arranque / solo estado inicial que DEFAULT_ORG_NAME. Debe tener entre 1 y 40 caracteres alfanuméricos en minúsculas con guiones internos simples y no ser una palabra reservada; un valor inválido se ignora (la organización conserva default). Permite que una instalación de un único tenant se presente como p. ej. /acme en lugar de /default sin ningún paso adicional de CLI post-despliegue. |
RUST_LOG | No | info | Nivel de detalle del registro (debug, warn, error, agenteye_server=trace) |
EVALUATOR_ENDPOINT | No | ninguno | URL base de tu servicio evaluador (p. ej. http://evaluator:9000). Si no se establece, toda la canalización de evaluación es una operación vacía; no se escriben filas en la cola ni se ejecutan workers. Consulta Suite de evaluación. |
EVALUATOR_TOKEN | No | ninguno | Enviado como Authorization: Bearer <token> al evaluador. Debe ser igual al valor con el que está configurado el servicio evaluador. Opcional solo si tu evaluador está configurado sin token. |
EVALUATOR_WORKERS | No | 2 | Concurrencia: número de tareas worker por instancia de servidor que despachan evaluaciones. Es seguro ejecutarlo en varios servidores escalados horizontalmente. |
EVALUATOR_CLAIM_BATCH | No | 4 | Número máximo de evaluaciones que un solo worker reclama por ciclo. Los lotes se despachan concurrentemente, por lo que la concurrencia total en tu endpoint evaluador es EVALUATOR_WORKERS × EVALUATOR_CLAIM_BATCH. |
EVALUATOR_POLL_IDLE_SECS | No | 2 | Tiempo que un worker duerme entre intentos de despacho cuando no hay nada pendiente. |
EVALUATOR_POLLING_INTERVAL_SECS | No | 10 | Cadencia de reserva final (segundos) para los sondeos GET /evaluate/{id} cuando el evaluador no devuelve un next_poll_secs por respuesta ni anuncia un default_poll_interval_secs desde GET /config. |
EVALUATOR_REQUEST_TIMEOUT_MS | No | 30000 | Tiempo de espera por solicitud HTTP al evaluador (milisegundos). |
EVALUATOR_MAX_ATTEMPTS | No | 5 | Tras este número de intentos fallidos, una evaluación se registra como error terminal (o timeout si los fallos fueron tiempos de espera de solicitud). |
EVALUATOR_CONFIG_REFRESH_SECS | No | 300 (5 min) | Con qué frecuencia el servidor vuelve a obtener GET /config del evaluador. |
EVALUATOR_MAX_POLL_DURATION_SECS | No | 3600 (1 h) | Tiempo máximo de reloj de pared que una sesión puede permanecer en la cola de sondeo antes de que AgentEye la termine como timeout. Protege contra un evaluador que devuelve pending indefinidamente. |
ALERT_WORKERS | No | 1 | Concurrencia: número de tareas worker por instancia de servidor que evalúan reglas de alerta. Consulta Alertas. |
ALERT_CLAIM_BATCH | No | 16 | Número máximo de alertas que un solo worker reclama por ciclo. |
ALERT_POLL_IDLE_SECS | No | 5 | Tiempo que un worker de alertas duerme cuando la cola está vacía. |
ALERT_REQUEST_TIMEOUT_MS | No | 15000 | Tiempo de espera por evaluación de disparo (consultas ClickHouse + HTTP de canal saliente). |
ALERT_MAX_ATTEMPTS | No | 5 | Fallos transitorios consecutivos antes de que una alerta se reprograme en su cadencia normal en lugar de con retroceso exponencial. |
AUDIT_WORKERS | No | 1 | Concurrencia: número de tareas worker por instancia de servidor que ejecutan auditorías. Consulta Auditorías. |
AUDIT_CLAIM_BATCH | No | 1 | Número máximo de auditorías pendientes que un solo worker reclama por ciclo. Una investigación agéntica es un bucle largo, por lo que el valor predeterminado es 1. |
AUDIT_POLL_IDLE_SECS | No | 30 | Tiempo que un worker de auditorías duerme cuando no hay ninguna pendiente. |
AUDIT_REQUEST_TIMEOUT_MS | No | 30000 | Tiempo de espera por consulta de política en ClickHouse (milisegundos). |
AUDIT_LLM_TIMEOUT_MS | No | 1440000 | Tiempo de espera para la llamada de investigación agéntica al servicio de asistente de IA. Un bucle de agente completo se ejecuta durante minutos; mantenlo POR ENCIMA del propio AGENTEYE_AUDIT_TIMEOUT_MS del agente para que este devuelva sus hallazgos parciales antes de que el servidor se rinda. |
AUDIT_MAX_ATTEMPTS | No | 5 | Fallos transitorios consecutivos antes de que una auditoría se reprograme en su cadencia normal en lugar de con retroceso exponencial. |
AGENTEYE_AGENT_URL / AGENTEYE_AGENT_TOKEN | No | — | La investigación agéntica de la auditoría llama al servicio agent de asistente de IA, reutilizando la misma conexión que el asistente — así que establece estos dos también en el servidor (los manifiestos/compose incluidos lo hacen). Ambos establecidos ⇒ las auditorías ejecutan la investigación de IA; cualquiera sin establecer ⇒ las auditorías se ejecutan solo con políticas (el paso determinista de políticas SQL sigue ejecutándose), independientemente del indicador llm_enabled por auditoría. El agente también debe tener un LLM configurado — consulta assistant.md. |
AGENTEYE_AUDIT_* y todos opcionales:
| Variable | Valor por defecto | Significado |
|---|---|---|
AGENTEYE_AUDIT_MAX_STEPS | 200 | Turnos máximos del agente por investigación. |
AGENTEYE_AUDIT_TIMEOUT_MS | 1200000 | Tiempo de reloj de pared para una investigación (20 min). Debe mantenerse por debajo del AUDIT_LLM_TIMEOUT_MS del servidor. |
AGENTEYE_AUDIT_MAX_CONCURRENCY | 1 | Investigaciones concurrentes por pod de agente (independiente del presupuesto del asistente de chat). |
AGENTEYE_AUDIT_SANDBOX_TIMEOUT_MS / _MEM_MB / _CPU_SECS / _OUTPUT_MAX_BYTES / _SCRIPT_MAX_BYTES | 20000 / 768 / 10 / 64000 / 64000 | Límites por script para el sandbox bubblewrap. |
clone() — establece seccompProfile: Unconfined (k8s) o security_opt: [seccomp:unconfined] (compose) en el agente. Donde el kernel del nodo deshabilita los espacios de nombres de usuario sin privilegios (p. ej. algunas imágenes GKE COS), el sandbox falla en la verificación previa y el auditor degrada automáticamente a solo SQL — sin error, simplemente un sandbox_available: false en el /health del agente.
Ejecutar
EstableceDATABASE_URL en tu entorno y pásalo al contenedor:
Verificación de estado
/health para sondeos de liveness y /ready para sondeos de readiness / balanceador de carga. /ready verifica las dependencias estrictas sin las que el servidor no puede funcionar (Postgres + ClickHouse), por lo que un servidor en ejecución que no puede alcanzar su base de datos se saca de rotación y aparece como NotReady; Redis se informa pero nunca falla la disponibilidad. En los manifiestos de Kubernetes incluidos, el sondeo de readiness ya apunta a /ready y el de liveness permanece en /health. Consulta enterprise-docs/health-monitoring.md para la imagen completa, incluidas las alertas de fallo de pod nativas de Kubernetes con opt-in a Slack.
URL del enlace mágico por correo
Los correos de inicio de sesión OTP contienen un botón abrir el panel con un solo toque. Al hacer clic, el usuario llega a/login?token=<code>&email=<address>; el panel intercambia ese par por una sesión y redirige a la aplicación, sin necesidad de volver a introducir el código manualmente. El servidor resuelve el origen del panel utilizado para construir el enlace en tres niveles:
- Encabezado
X-AgentEye-Dashboard-Url: lo establece automáticamente el proxy/api/auth/otp/requestdel panel desde su propio origen público. En un despliegue del mismo origen (el servidor y el panel comparten un host detrás de un ingress que reenvía encabezados proxy), no se requiere ninguna configuración. - Variable de entorno
DASHBOARD_URL: establécela si tu panel es accesible en un origen diferente al que ve el endpoint de solicitud OTP del servidor (dominios separadosapi.example.com/app.example.com), o si tu ingress no propaga el host público al pod del panel (de modo querequest.nextUrl.originde otro modo resolvería a una dirección de vinculación comodín como0.0.0.0:3000). Ejemplo:DASHBOARD_URL=https://app.example.com. - Valor predeterminado:
https://app.befailproof.ai, usado solo si ninguno de los anteriores está presente.
https://* y de loopback (http://localhost*, http://127.0.0.1*), y las direcciones de vinculación comodín (0.0.0.0, [::]) se rechazan incluso con el esquema https://. Cualquier otra cosa cae al nivel 2.
Establécelo en un clúster en ejecución con una sola línea; sin archivos, sin reconstrucción de kustomize:
kustomize build | kubectl apply posterior contra el overlay lo eliminará a menos que añadas la misma variable de entorno al parche server-env.yaml de tu overlay.
Panel de control
Descargar la imagen
Variables de entorno
| Variable | Obligatoria | Valor por defecto | Descripción |
|---|---|---|---|
AGENTEYE_SERVER_URL | Sí | ninguno | URL base del servidor, p. ej. http://localhost:8080 |
AGENTEYE_API_KEY | Sí | ninguno | Clave de API que usa el panel para autenticarse en el servidor. Necesita todos los permisos (se recomienda la clave de administrador). |
AE_LOG_LEVEL | No | info | Nivel de detalle del registro del lado del servidor: debug, info, warn, error. Establécelo en debug para ver líneas de solicitud/respuesta ascendente y trazas de validación de sesión al diagnosticar problemas. |
AE_LOG_JSON | No | automático | 1 fuerza la salida JSON por línea; 0 fuerza la salida legible por humanos. Si no se establece, JSON se habilita automáticamente si NODE_ENV=production. Se recomienda JSON en producción para que los registros se analicen limpiamente con jq o un agregador de registros. |
AE_ANALYTICS_DISABLED | No | ninguno | Establécelo en 1/true para deshabilitar la telemetría anónima de uso del producto del panel. Consulta Telemetría y privacidad a continuación. |
REDIS_URL | No | ninguno | Backend opcional de caché compartida, p. ej. redis://redis:6379/0. Cuando se establece, el panel almacena en caché los resultados de validateSession() entre réplicas y comparte la caché de fetch de Next.js para las rutas proxy de agregado de latencia y lista de entornos. Los límites de tasa de solicitud y verificación OTP del lado del edge también usan Redis cuando está presente (fallando abiertos si Redis es inaccesible; el límite del lado del servidor es la salvaguarda de seguridad). Consulta Redis (caché opcional) a continuación. |
AGENTEYE_AGENT_URL | No | ninguno | URL base del servicio agent de asistente de IA opcional, p. ej. http://agent:9100. Déjalo sin establecer para ocultar el asistente por completo: no aparece ninguna burbuja de asistente en el panel. Consulta enterprise-docs/assistant.md. |
AGENTEYE_AGENT_TOKEN | No | ninguno | Secreto compartido que el panel presenta al servicio agent. Debe coincidir con el AGENTEYE_AGENT_TOKEN configurado en el agente. Consulta enterprise-docs/assistant.md. |
Ejecutar
Telemetría y privacidad
El panel envía analítica anónima de uso del producto al servicio de analítica de Exosphere (PostHog): qué páginas del panel se visitan y algunas acciones de la interfaz de usuario, como crear una clave de API o volver a evaluar una sesión. Esta señal de uso informa qué funciones se priorizan.- Ningún dato de agente, sesión o evento sale nunca de tu infraestructura. Solo se informa el uso de la interfaz de usuario del panel. Las URL de las páginas se eliminan de identificadores antes de enviarlas, y los operadores se identifican solo por un ID interno opaco, nunca por correo electrónico.
- La telemetría está habilitada de forma predeterminada. Para desactivarla completamente, establece
AE_ANALYTICS_DISABLED=1en el contenedor del panel y reinícialo. - La analítica se envía a la propia ruta
/ingestdel panel, que el panel envía en proxy inverso a PostHog (https://us.i.posthog.com). Mantener las solicitudes como propias significa que los bloqueadores de anuncios del navegador no las descartan. El contenedor del panel necesita acceso saliente a PostHog; si está bloqueado, la telemetría no hace nada silenciosamente y el panel no se ve afectado.
Asistente de IA (opcional)
Un asistente de IA integrado en el panel permite a tu equipo hacer preguntas sobre sus datos de agentes en lenguaje natural (resumir sesiones, redactar SQL para el editor/queries y convertir consultas guardadas en tiles del panel) sin salir del panel. Se ejecuta como un contenedor agent interno separado (sobre el Agents SDK de Claude) al que solo el panel puede acceder, y permanece deshabilitado hasta que configures un endpoint LLM.
Para habilitarlo, estableces en el servicio agent una conexión LLM (Portkey a través de PORTKEY_API_KEY + un slug de catálogo de modelos AGENTEYE_AGENT_MODEL=@<slug>/<model>, Anthropic directo a través de ANTHROPIC_API_KEY, otra puerta de enlace a través de ANTHROPIC_BASE_URL, o Bedrock/Vertex), una clave de datos dedicada y un AGENTEYE_AGENT_TOKEN compartido que coincida con el panel. Los usuarios del panel además necesitan el permiso agent:use.
Para la clave de datos del asistente no necesitas generar nada manualmente: elige un secreto aleatorio, establécelo como AGENTEYE_API_KEY en el agent y como AGENT_API_KEY en el server, y el servidor lo inicia con un conjunto fijo de permisos. Su acceso a datos es de solo lectura (events:read, evaluations:read, dashboards:read, queries:read), y además tiene alcances de creación con aprobación requerida (dashboards:write, queries:write, queries:run) para que pueda redactar y validar consultas guardadas y construir tiles del panel en nombre del usuario; todo el SQL sigue ejecutándose a través del rol de ClickHouse de solo lectura de la organización, por lo que esto amplía lo que el asistente puede crear, no los datos a los que puede acceder. Los alcances están fijos en el código y no pueden ampliarse mediante configuración. Esa clave está protegida; no se puede deshabilitar ni regenerar a través de la API, solo rotarla cambiando el valor y reiniciando. Nunca reutilices la clave de administrador/panel para esto.
La configuración completa, la referencia completa de variables de entorno, las opciones de telemetría y el modelo de seguridad están en enterprise-docs/assistant.md.
ClickHouse (almacén de analítica obligatorio)
ClickHouse mantiene tus paneles responsivos a altos volúmenes de eventos y permite que el editor SQL/queries una eventos, evaluaciones y sesiones en un único almacén. Es el almacén canónico obligatorio para cada evento ingerido, cada resultado de evaluación terminal y los agregados por sesión derivados. PostgreSQL almacena las tablas relacionales / de estado mutable (api_keys, users, otp_codes, evaluation_jobs, dashboards, saved_queries); la superficie analítica vive en ClickHouse para que los resúmenes del panel y tus propias consultas SQL puedan escanearlos y unirlos de forma nativa, sin viajes de ida y vuelta entre bases de datos. El servidor se niega a arrancar sin CLICKHOUSE_URL.
Esquema
Se crean tres objetos de ClickHouse al inicio del servidor, todos idempotentes (CREATE IF NOT EXISTS):
agenteye.events:ReplacingMergeTree(ingested_at), particionado portoYYYYMM(ts), ordenado por(session_id, ts, dedup_key). Las inserciones duplicadas (reintentos del collector) colapsan a una sola fila en el momento de la fusión; el servidor calcula undedup_keySHA-256 determinista para cada evento de modo que los reintentos son seguros.agenteye.evaluations:ReplacingMergeTree(ingested_at), particionado portoYYYYMM(finished_at), ordenado por(session_id, finished_at, dedup_key). Escrito una vez por resultado de evaluación terminal por la canalización del evaluador. Mismo modelo de clave de deduplicación queevents.agenteye.agent_sessions: una VISTA sobreagenteye.events, no una tabla física. Cada columna es derivada (started_at = min(ts),last_event_at = max(ts),ended_at = max(if event_type='agent_end', ts, NULL),event_count = count(), etc.). Sin upsert por evento y sin relleno retroactivo separado; la vista refleja automáticamente lo que hay enevents.
analytics.evaluations / analytics.sessions, el servidor también crea una base de datos analytics de ClickHouse con vistas sobre las tablas agenteye.*; analytics.events, analytics.evaluations, analytics.agent_sessions, analytics.sessions se resuelven correctamente.
Configuración
El docker-compose incluido ydeploy/base/clickhouse/ incorporan un servicio de ClickHouse ajustado para la carga de trabajo de AgentEye:
- 2 GiB solicitados / 4 GiB límite de memoria en el overlay base incluido (dimensionado para nodos pequeños de POC/staging); los clientes de producción deberían aumentarlo — el mínimo recomendado es 2c / 4Gi de solicitud, 6c / 8Gi de límite.
max_server_memory_usage_to_ram_ratio=0.9 - 5 GiB de caché de marcas + 8 GiB de caché sin comprimir
background_pool_size=16,background_merges_mutations_concurrency_ratio=2- MergeTree:
parts_to_throw_insert=3000,parts_to_delay_insert=1500,non_replicated_deduplication_window=1000 local_io_method=auto(io_uring en kernels compatibles)fsync_metadata=0: aceptable por la ingestión at-least-once + deduplicación ReplacingMergeTreequery_loghabilitado con TTL de 30 días;query_thread_logeliminado (costoso con QPS alto)max_execution_time=30para consultas del lado del usuario- 100 GiB PVC en la plantilla StatefulSet (los overlays de los clientes DEBEN sobreescribir a una clase de almacenamiento SSD rápida para producción)
Copias de seguridad
Tu conjunto de datos completo se captura diariamente en un archivo restaurable único, por lo que una pérdida de clúster o almacenamiento es recuperable. ClickHouse se respalda automáticamente mediante el CronJob diarioagenteye-backup, que vuelca tanto PostgreSQL como ClickHouse en un solo paso. ClickHouse se lee a través de su API HTTP: agenteye.events y agenteye.evaluations se vuelcan en formato nativo de ClickHouse (las vistas y las políticas de fila se recrean por el servidor al inicio, por lo que los datos de la tabla son el cuadro completo) y se agrupan con el volcado de Postgres en un único archivo comprimido subido a tu almacenamiento de objetos.
El bucket de destino y las credenciales en la nube se configuran por overlay. Consulta la sección Copias de seguridad de enterprise-docs/kubernetes-deployment.md para la configuración de subida y los pasos de restauración.
Redis (caché opcional)
Redis es un backend opcional de caché compartida + limitación de tasa usado por el servidor y el panel. Con Redis desplegado yREDIS_URL establecido en ambos servicios:
- El servidor almacena en caché las búsquedas de claves API autenticadas, las listas
/events/environments+/evaluations/environments, el rollup/events/latency_aggregate(la consulta más pesada que sondea el panel), la lista/sessions, y cambia la limitación de tasa de solicitudes OTP de unCOUNT(*)de Postgres a unINCR + EXPIREde Redis. - El panel almacena en caché los resultados de
validateSession()para que las 10-20 llamadas API autenticadas que emite una carga de página típica compartan una sola verificación de sesión ascendente. También limita la tasa de solicitudes OTP y verificación OTP en el edge del panel.
Err dentro de un tiempo de espera acotado y el llamador recurre a la fuente de verdad (Postgres en el servidor, el servidor Rust ascendente en el panel). La limitación de tasa OTP recurre a la ruta COUNT(*) de Postgres en el servidor (la propiedad de seguridad se preserva); el límite OTP del edge del panel falla abierto mientras el límite del lado del servidor sigue vigente. Que Redis esté caído degrada la latencia, no la corrección.
Configuración
El paquete docker-compose ya incluye un servicio Redis y conectaREDIS_URL=redis://redis:6379/0 al servidor y al panel. Para usar un Redis externo, establece REDIS_URL en tu endpoint y elimina el servicio redis del archivo compose.
Memoria + persistencia
La imagen de Redis incluida se ejecuta con--appendonly yes --appendfsync everysec --maxmemory 256mb --maxmemory-policy allkeys-lru. La persistencia AOF significa que la caché sobrevive a los reinicios del contenedor; everysec es el equilibrio adecuado de durabilidad/rendimiento porque perder el último segundo de escrituras de caché es inofensivo. La expulsión LRU limita el crecimiento de la memoria.
Cuándo NO desplegar Redis
- Desarrollo/QA de instancia única. Las cachés en proceso del servidor por sí solas ofrecen la mayor parte del beneficio por réplica; Redis añade el uso compartido entre réplicas que las configuraciones de instancia única no necesitan.
- Instalaciones aisladas de la red donde el coste operativo de ejecutar un servicio más supera la mejora de latencia.
Docker Compose (recomendado)
Hay undocker-compose.yml disponible en el repositorio agenteye-enterprise/releases. Levanta Postgres, el servidor y el panel con un solo comando.
.env:
Ajustes operativos
Un pequeño conjunto de configuraciones operativas que antes estaban fijadas por variables de entorno ahora son editables por organización desde la página/<org>/settings del panel; cada organización configura las suyas. Los cambios surten efecto en segundos, sin reinicio ni redespliegue.
| Ajuste | Variable de entorno de arranque | Qué controla |
|---|---|---|
| Inicios de sesión permitidos | ALLOWED_EMAILS | Correos electrónicos (o comodines *@domain.com) autorizados a recibir un OTP y añadirse como usuarios |
| Permisos predeterminados de usuario | DEFAULT_USER_PERMISSIONS | Tokens de permiso separados por comas preseleccionados cuando un administrador abre + nuevo usuario. Cada token debe ser una de las cadenas listadas en Permisos de clave de API. Tiene como predeterminado el preset standard: acceso de solo lectura más las acciones cotidianas de guardia (activar reevaluaciones, ejecutar consultas, reconocer incidentes, usar el asistente). |
| Duración de la sesión | SESSION_TTL_SECS | Cuánto tiempo permanece válido un inicio de sesión en el panel antes de requerir autenticación. El panel vuelve a verificar la sesión ascendente cada 5 segundos, por lo que una actualización de permisos en /<org>/users surte efecto en la próxima solicitud del usuario afectado, sin necesidad de volver a iniciar sesión. |
| Duración del código de un solo uso | OTP_TTL_SECS | Cuánto tiempo permanece utilizable un OTP / enlace mágico |
| Canales de notificación de alertas | ALERTS_ENABLED_CHANNELS | Lista separada por comas de tipos de canales que el despachador de alertas puede usar: email, slack, webhook. La configuración por alerta sigue creándose en /<org>/alerts/<id>, pero el despachador filtra cada entrega saliente a través de este conjunto; un canal deshabilitado aquí se cortocircuita con una fila de auditoría skipped_disabled. El canal dashboard (la inserción de auditoría local) siempre está permitido. Por defecto los tres están activados. |
Cómo funciona el arranque
Los ajustes se almacenan por organización enorg_settings. En el primer arranque, el servidor llena las filas faltantes de la organización predeterminada a partir de la variable de entorno correspondiente (o un valor predeterminado razonable si la variable no está establecida). A partir de ahí, el valor almacenado es la fuente de verdad y la variable de entorno se ignora; cambiar la variable de entorno en un reinicio posterior no afectará al valor de una organización activa, y las organizaciones adicionales parten de los valores predeterminados y configuran los suyos propios.
Esto significa:
- Para un despliegue nuevo, establece las variables de entorno como se muestra arriba y la organización predeterminada las leerá en el primer arranque.
-
Para cambiar un valor más adelante, inicia sesión en el panel y edítalo en
/<org>/settings. El cambio se aplica en segundos en todas las réplicas del servidor; no se necesita reinicio. -
Una línea de registro al inicio registra qué se sembró frente a qué ya estaba presente, para que puedas confirmar que el arranque surtió efecto:
Semántica de inicio de sesión entre organizaciones
Una sesión y un OTP son globales al usuario, no a una sola organización, por lo que dos reglas reconcilian los ajustes por organización en el momento del inicio de sesión:- Duración de sesión / OTP: gana la duración más estricta (más corta) entre las organizaciones a las que pertenece el usuario.
- Inicios de sesión permitidos: la puerta hace un OR de la lista de permitidos de cada organización junto con la pertenencia a la organización: un usuario puede solicitar un OTP si la lista de permitidos de cualquier organización admite su correo electrónico o ya es miembro de cualquier organización.
Permisos
El acceso a una página/<org>/settings está controlado por dos permisos:
settings:read: ver la página y los valores actuales.settings:write: guardar cambios.
ADMIN_EMAIL) obtiene ambos automáticamente junto con todos los demás permisos. Otórgalos a otros usuarios desde /<org>/users según sea necesario.
Organizaciones (multi-tenancy)
Un único despliegue puede servir a múltiples organizaciones (tenants) aisladas; cada fila de datos pertenece exactamente a una organización y el aislamiento se impone en el motor de base de datos. Una instalación de un único tenant no necesita nada aquí; todos los datos viven en una organizacióndefault integrada. (Puedes darle a esa organización un nombre y slug de URL más amigables, para que viva en p. ej. /acme en lugar de /default, estableciendo DEFAULT_ORG_NAME / DEFAULT_ORG_SLUG antes del primer arranque, o renombrándola en cualquier momento con agenteye-orgctl org rename.)
El provisionamiento de tenants es solo para operadores. Las organizaciones y sus pertenencias se crean y gestionan con la CLI agenteye-orgctl, que se incluye dentro de la imagen del servidor (junto a agenteye-server) y se ejecuta dentro del pod del servidor existente; no hay pod/Job separado, ni API HTTP, ni botón en el panel. Reutiliza el DATABASE_URL, CLICKHOUSE_URL y ORG_CH_SECRET del servidor.
org create | list | rename | delete | purge y member add | list | update | remove, con conjuntos de permisos integrados admin, standard y read-only. Los miembros añadidos reciben un OTP en el primer inicio de sesión en el panel.
Antes de crear una segunda organización: establece un ORG_CH_SECRET sólido y estable (el comando org create se niega a ejecutarse con el valor predeterminado de desarrollo integrado) y asegúrate de que Postgres sea 15+. Sin cambios: las claves de API por organización siguen siendo acuñadas en el panel/API por los miembros de la organización; solo el ciclo de vida de organizaciones + miembros se movió a la CLI. Referencia completa de comandos y un ejemplo práctico: enterprise-docs/tenant-management.md.
Relleno de la ventana de contexto
Cada eventomodel_response muestra una píldora de relleno de contexto — tokens de entrada más salida como porcentaje de la ventana de contexto de ese modelo. Las bandas son healthy (0–24%), watch (25–49%), compacting (50–74%) y reset context (75–100%). AgentEye resuelve los IDs de modelos comunes automáticamente, por lo que no se requiere ninguna configuración inicial.
Cada modelo que envía una organización aparece en Configuración → ventanas de contexto de modelos. Los usuarios con settings:write pueden sobreescribir su ventana o añadir un modelo privado/proxy (0–1.000.000 tokens); 0 significa “desconocido” y suprime la píldora. Los cambios se aplican a los eventos recién ingeridos. Los usuarios con settings:read pueden ver la lista.
Los nuevos eventos obtienen el relleno desde el momento en que actualizas. Para también rellenar los eventos históricos (y la lista por modelo) de un despliegue existente, ejecuta el relleno retroactivo único — se incluye dentro de la imagen del servidor (como agenteye-orgctl) y se ejecuta en el pod del servidor existente:
DATABASE_URL / CLICKHOUSE_URL / REDIS_URL del pod. Vuélvelo a ejecutar después de editar ventanas de modelos si quieres que los eventos existentes se recalculen.
Consideraciones de producción
- Postgres: Usa un servicio de Postgres gestionado o una instancia dedicada con copias de seguridad regulares. El
DATABASE_URLadmite todos los parámetros libpq estándar, incluidosslmode=requirepara conexiones cifradas. - TLS: Coloca el servidor y el panel detrás de un proxy inverso (nginx, Caddy, Traefik) que termine TLS.
- Firewall: El puerto del servidor (por defecto 8080) solo debe ser accesible desde las máquinas del collector y el host del panel, no desde internet público.
- Clave de administrador: Establece
ADMIN_KEYen un secreto aleatorio robusto. Después del arranque inicial, crea claves con alcance dedicado para los collectors y el panel en lugar de usar la clave de administrador en todas partes. - Etiquetas de imagen: Fija la versión en los manifiestos de tu versión (por ejemplo,
server:v0.0.1-beta.48) en producción en lugar de una etiqueta flotante para evitar actualizaciones no intencionadas. Las compilaciones beta actuales se publican conbeta-latest;latestsolo se asigna a versiones estables. - Monitoreo de salud: En Kubernetes, el sondeo de readiness usa
/ready(accesibilidad de Postgres + ClickHouse) mientras que el de liveness permanece en/health. Para alertas de “¿está AgentEye en sí mismo activo?” a toda la flota en Slack, habilita el complemento opcional de Robusta; consulta enterprise-docs/health-monitoring.md.
Etiquetas de imagen disponibles
| Etiqueta | Descripción |
|---|---|
latest | Última versión estable |
beta-latest | Última versión previa al lanzamiento (beta) |
v<versión> | Versión fijada, p. ej. v0.0.1-beta.48 (recomendada para producción) |

