Panoramica dell’architettura
- Server: servizio HTTP in Rust; riceve batch di eventi, li scrive in ClickHouse e mantiene lo stato relazionale in PostgreSQL.
- Dashboard: app web Next.js; legge e scrive esclusivamente tramite l’API del server.
- agenteye-collector: deployato su macchine agenti, non sull’host del server.
- Postgres 15+: OBBLIGATORIO. (Aumentato dalla versione 14 nel rilascio multi-tenant; lo schema delle appartenenze all’organizzazione utilizza una chiave esterna con lista di colonne
ON DELETE SET NULL, che richiede Postgres 15+. Aggiorna Postgres prima di deployare questa versione.) Memorizza lo stato OLTP:api_keys,users,sessions,evaluation_jobs(coda),dashboards,saved_queries,otp_codes, più le tabelle multi-tenantorgs,org_memberships,org_settings. - ClickHouse 24+: OBBLIGATORIO. L’archivio di analytics per ogni evento ingestionato. Engine:
ReplacingMergeTree, partizionato per mese, ordinato per(session_id, ts, dedup_key). Il server si connette tramiteCLICKHOUSE_URL; ildeploy/base/clickhouse/incluso fornisce una configurazione single-node ottimizzata per le prestazioni. Requisito multi-tenant: la configurazione inclusa abilita la gestione dell’accesso SQL +users_without_row_policies_can_read_rows=falseaffinché il server possa creare un utente ClickHouse di sola lettura + politica di riga per organizzazione (il limite di isolamento applicato dal motore per l’editor SQL e l’agente AI). Se fornisci la tua configurazione ClickHouse, riporta queste impostazioni (vedideploy/base/clickhouse/configmap.yaml). - Redis 7+: opzionale cache condivisa + backend per il rate-limiting. Sia il server che il dashboard si connettono tramite
REDIS_URL. Se assente, entrambi si degradano elegantemente a percorsi solo Postgres. Vedi Redis (cache opzionale) di seguito.
Server
Scarica l’immagine
I build attuali sono pubblicati sottobeta-latest;latestè assegnato solo ai rilasci stabili. Per la produzione, usa un tag specifico:v<version>; vedi Tag di immagine disponibili.
Variabili di ambiente
| Variabile | Obbligatoria | Default | Descrizione |
|---|---|---|---|
DATABASE_URL | Sì | nessuno | DSN PostgreSQL. Stringa di connessione libpq standard con schema postgres://. Supporta ?sslmode=require e altri parametri libpq. La password non deve contenere /, + o =; usa openssl rand -hex per generare password sicure per gli URL. |
ADMIN_KEY | No | nessuno | Chiave API admin di bootstrap. Effettuato un upsert con tutti i permessi ad ogni avvio. Ruota modificando il valore e riavviando. |
LISTEN_ADDR | No | 0.0.0.0:8080 | Indirizzo TCP da assegnare |
MAX_BODY_BYTES | No | 134217728 (128 MB) | Dimensione massima del corpo della richiesta |
ADMIN_EMAIL | No | nessuno | Email utente admin di bootstrap. Effettuato un upsert con tutti i permessi ad ogni avvio e contrassegnato come protetto: non può essere disabilitato o avere i permessi modificati tramite dashboard/API. Per ruotare l’admin di bootstrap, modifica ADMIN_EMAIL e riavvia; il nuovo email viene effettuato come upsert protetto, e il precedente mantiene la protezione finché non viene manualmente cancellata nel database. |
ALLOWED_EMAILS | No | nessuno (tutti bloccati) | Lista separata da virgole di email consentite per la creazione e l’accesso degli utenti. Supporta indirizzi esatti (user@example.com) e wildcard di dominio (*@example.com). Se non impostato, nessun utente può essere creato o effettuare l’accesso. Solo seed di primo avvio: popola la lista consentita dell’organizzazione predefinita al primo avvio; in seguito la pagina /<org>/settings di ogni organizzazione è la fonte di verità e modificare questa variabile di ambiente non ha effetto. |
SMTP_HOST | No | nessuno | Hostname del server SMTP per l’invio di email OTP. Se non impostato, i codici OTP vengono registrati a stdout. |
SMTP_PORT | No | 587 | Porta del server SMTP |
SMTP_USERNAME | No | nessuno | Username di autenticazione SMTP |
SMTP_PASSWORD | No | nessuno | Password di autenticazione SMTP |
SMTP_FROM | No | nessuno | Indirizzo email del mittente per le email OTP |
SMTP_TLS | No | STARTTLS | STARTTLS è utilizzato a meno che non lo disabiliti esplicitamente: false o 0 invia in chiaro (senza TLS); qualsiasi altro valore — incluso non impostato — abilita STARTTLS. |
DASHBOARD_URL | No | default integrato | Origine del dashboard utilizzata per costruire sia il link magico dell’email OTP che i link magici negli incidenti nelle notifiche di alert. Se non impostato, torna a un default integrato (e, solo per OTP, all’origine derivata dal dashboard per prima). Imposta questo per configurazioni con domini separati affinché sia le email che i link Slack/incidenti puntino al tuo dashboard. Vedi URL link magico email di seguito; la maggior parte degli operatori non ha bisogno di impostare questo. |
SESSION_TTL_SECS | No | 86400 (24 h) | Durata della sessione dashboard in secondi. Solo seed di primo avvio: modifica per organizzazione tramite /<org>/settings dopo il primo deploy. |
OTP_TTL_SECS | No | 600 (10 min) | Periodo di validità del codice OTP in secondi. Solo seed di primo avvio: modifica per organizzazione tramite /<org>/settings dopo il primo deploy. |
REDIS_URL | No | nessuno | Cache condivisa opzionale + backend per il rate-limiting, ad esempio redis://redis:6379/0. Se impostato, il server memorizza in cache le ricerche di chiavi API autenticate, l’aggregato /models del dashboard, l’elenco delle sessioni e la faccia dell’elenco env; sposta anche il rate-limiting delle richieste OTP da PostgreSQL COUNT a Redis INCR. Se non impostato o irraggiungibile, il server funziona senza cache (il limite OTP torna a PostgreSQL, ogni altra chiamata di cache cade attraverso alla fonte di verità). Vedi Redis (cache opzionale) di seguito. |
CLICKHOUSE_URL | Sì | nessuno | URL di base dell’istanza ClickHouse, ad esempio http://clickhouse:8123. Il server applica il suo schema di eventi a questo database ad ogni avvio e rifiuta di avviarsi se non riesce a raggiungere ClickHouse. Vedi ClickHouse (archivio analytics obbligatorio) di seguito. |
CLICKHOUSE_DATABASE | No | agenteye | Nome del database (schema) ClickHouse. Il server lo crea all’avvio se non esiste. |
ORG_CH_SECRET | No (single-tenant) / Sì (multi-org) | default di sviluppo | Chiave HMAC da cui è derivata la password ClickHouse per tenant di ogni organizzazione. L’editor SQL e la run_query dell’agente AI vengono eseguiti come l’utente ClickHouse di sola lettura dell’organizzazione, la cui politica di riga applica l’isolamento del tenant nel motore. I deployment single-tenant si avviano correttamente con il default di sviluppo integrato; prima di provisioning di una seconda organizzazione DEVI impostare un valore forte e stabile, poiché il CLI agenteye-orgctl org create rifiuta di funzionare con il default di sviluppo integrato. Ruotarlo orfana ogni utente ClickHouse dell’organizzazione fino al prossimo avvio che li re-provisiona (la riconciliazione al momento dell’avvio guarisce questo automaticamente). Mantienilo segreto e invariato attraverso le repliche. Il provisioning dell’organizzazione stesso è solo per operatori; vedi Organizzazioni (multi-tenancy) di seguito. |
DEFAULT_ORG_NAME | No | Default | Nome visualizzato seminato per l’organizzazione predefinita integrata. Solo seed di primo avvio, e solo mentre l’organizzazione mantiene ancora la sua identità generica appena migrata, applicato all’avvio, quindi ignorato. Una volta rinominata l’organizzazione (agenteye-orgctl org rename) il cambio di nome è autorevole e questa variabile di ambiente non ha ulteriori effetti. |
DEFAULT_ORG_SLUG | No | default | Slug URL per l’organizzazione predefinita integrata, il percorso dashboard in cui vive (/<slug>/…). Stessa semantica di solo primo avvio / pristino come DEFAULT_ORG_NAME. Deve essere 1-40 caratteri alfanumerici minuscoli con singoli trattini interni e non una parola riservata; un valore non valido viene ignorato (l’organizzazione mantiene default). Permette a un’installazione single-tenant di presentarsi come ad esempio /acme invece di /default senza alcun passaggio CLI post-deploy. |
RUST_LOG | No | info | Verbosità del log (debug, warn, error, agenteye_server=trace) |
EVALUATOR_ENDPOINT | No | nessuno | URL di base del tuo servizio valutatore (ad esempio http://evaluator:9000). Se non impostato l’intera pipeline di valutazione è un no-op; nessuna riga di coda viene scritta, nessun worker viene eseguito. Vedi Suite di valutazione. |
EVALUATOR_TOKEN | No | nessuno | Inviato come Authorization: Bearer <token> al valutatore. Deve uguagliare lo stesso valore con cui è configurato il servizio valutatore. Opzionale solo se il tuo valutatore è configurato senza token. |
EVALUATOR_WORKERS | No | 2 | Concorrenza: numero di task worker per istanza server che inviano valutazioni. Sicuro da eseguire su più server scalati orizzontalmente. |
EVALUATOR_CLAIM_BATCH | No | 4 | Numero massimo di valutazioni che un singolo worker rivendica per tick. I batch vengono inviati concorrentemente, quindi la concorrenza totale sul tuo endpoint valutatore è EVALUATOR_WORKERS × EVALUATOR_CLAIM_BATCH. |
EVALUATOR_POLL_IDLE_SECS | No | 2 | Quanto tempo un worker dorme tra i tentativi di invio quando nulla è dovuto. |
EVALUATOR_POLLING_INTERVAL_SECS | No | 10 | Cadenza di fallback finale (secondi) per i poll GET /evaluate/{id} quando il valutatore non ritorna un next_poll_secs per risposta e non pubblicizza un default_poll_interval_secs da GET /config. |
EVALUATOR_REQUEST_TIMEOUT_MS | No | 30000 | Timeout per richiesta HTTP verso il valutatore (millisecondi). |
EVALUATOR_MAX_ATTEMPTS | No | 5 | Dopo questo numero di tentativi falliti una valutazione viene registrata come terminale error (o timeout se i fallimenti erano timeout di richieste). |
EVALUATOR_CONFIG_REFRESH_SECS | No | 300 (5 min) | Con quale frequenza il server ri-raccoglie GET /config dal valutatore. |
EVALUATOR_MAX_POLL_DURATION_SECS | No | 3600 (1 h) | Massimo tempo wallclock una sessione può rimanere nella coda di polling prima che AgentEye la termini come timeout. Protegge da un valutatore che ritorna pending per sempre. |
ALERT_WORKERS | No | 1 | Concorrenza: numero di task worker per istanza server che valutano le regole di alert. Vedi Alert. |
ALERT_CLAIM_BATCH | No | 16 | Numero massimo di alert che un singolo worker rivendica per tick. |
ALERT_POLL_IDLE_SECS | No | 5 | Quanto tempo un worker di alert dorme quando la coda è vuota. |
ALERT_REQUEST_TIMEOUT_MS | No | 15000 | Timeout di valutazione per trigger (query ClickHouse + HTTP canale in uscita). |
ALERT_MAX_ATTEMPTS | No | 5 | Fallimenti transienti consecutivi prima che un alert si riprogrammi alla sua cadenza normale invece del backoff esponenziale. |
AUDIT_WORKERS | No | 1 | Concorrenza: numero di task worker per istanza server che eseguono gli audit. Vedi Audit. |
AUDIT_CLAIM_BATCH | No | 1 | Numero massimo di audit dovuti che un singolo worker rivendica per tick. Un’indagine agenticità è un lungo ciclo, quindi il default è 1. |
AUDIT_POLL_IDLE_SECS | No | 30 | Quanto tempo un worker di audit dorme quando nessun audit è dovuto. |
AUDIT_REQUEST_TIMEOUT_MS | No | 30000 | Timeout per query di politica per query contro ClickHouse (millisecondi). |
AUDIT_LLM_TIMEOUT_MS | No | 1440000 | Timeout per la chiamata di indagine agenticità al servizio assistente AI. Un ciclo di agente completo funziona per minuti; tieni questo SOPRA il AGENTEYE_AUDIT_TIMEOUT_MS dell’agente stesso affinché l’agente ritorni i suoi risultati parziali prima che il server rinunci. |
AUDIT_MAX_ATTEMPTS | No | 5 | Fallimenti transienti consecutivi prima che un audit si riprogrammi alla sua cadenza normale invece del backoff esponenziale. |
AGENTEYE_AGENT_URL / AGENTEYE_AGENT_TOKEN | No | — | L’indagine agenticità dell’audit chiama il servizio agent dell’assistente AI, riutilizzando la stessa connessione dell’assistente — quindi imposta anche questi due sul server (i manifesti/compose inclusi lo fanno). Entrambi impostati ⇒ gli audit eseguono l’indagine AI; uno qualsiasi non impostato ⇒ gli audit eseguono solo politica (il pass di politica SQL deterministico ancora funziona), indipendentemente dal flag llm_enabled per audit. L’agente deve anche avere un LLM configurato — vedi assistant.md. |
AGENTEYE_AUDIT_* e tutti opzionali:
| Variabile | Default | Significato |
|---|---|---|
AGENTEYE_AUDIT_MAX_STEPS | 200 | Massimi turni agente per indagine. |
AGENTEYE_AUDIT_TIMEOUT_MS | 1200000 | Wallclock per un’indagine (20 min). Deve stare sotto il AUDIT_LLM_TIMEOUT_MS del server. |
AGENTEYE_AUDIT_MAX_CONCURRENCY | 1 | Indagini concorrenti per pod agente (separate dal budget dell’assistente di chat). |
AGENTEYE_AUDIT_SANDBOX_TIMEOUT_MS / _MEM_MB / _CPU_SECS / _OUTPUT_MAX_BYTES / _SCRIPT_MAX_BYTES | 20000 / 768 / 10 / 64000 / 64000 | Limiti per script per il sandbox bubblewrap. |
clone() — imposta seccompProfile: Unconfined (k8s) o security_opt: [seccomp:unconfined] (compose) sull’agente. Dove il kernel del nodo disabilita i namespace utente senza privilegi (ad esempio alcune immagini GKE COS), il sandbox fallisce il preflight e l’auditor si degrada a solo SQL automaticamente — nessun errore, solo un sandbox_available: false su /health dell’agente.
Esegui
ImpostaDATABASE_URL nel tuo ambiente, quindi passalo al contenitore:
Health check
/health per probe di liveness e /ready per probe di readiness / load-balancer. /ready controlla le dipendenze hard che il server non può servire senza (Postgres + ClickHouse), quindi un server che è in esecuzione ma non può raggiungere il suo database viene tolto dalla rotazione e appare come NotReady; Redis è segnalato ma non fallisce mai la readiness. Nei manifesti Kubernetes inclusi il probe di readiness punta già a /ready e la liveness rimane su /health. Vedi enterprise-docs/health-monitoring.md per il quadro completo, incluso il pod-failure alerting nativo di Kubernetes opt-in a Slack.
URL link magico email
Le email OTP login contengono un pulsante apri il dashboard one-tap. Cliccarlo atterra l’utente su/login?token=<code>&email=<address>; il dashboard scambia quella coppia per una sessione e reindirizza all’app, senza re-entry manuale del codice. Il server risolve l’origine del dashboard utilizzata per costruire il link in tre livelli:
- Header
X-AgentEye-Dashboard-Url: impostato automaticamente dal proxy/api/auth/otp/requestdel dashboard dalla sua stessa origine pubblica. In un deployment same-origin (server e dashboard condividono un host dietro un ingress che inoltra i proxy header), nessuna configurazione è richiesta. - Variabile di ambiente
DASHBOARD_URL: imposta questo se il tuo dashboard è raggiungibile su un’origine diversa da quella che l’endpoint OTP request del server vede (dividiapi.example.com/app.example.com), o se il tuo ingress non propaga l’host pubblico nel pod dashboard (cosìrequest.nextUrl.originaltrimenti si risolverebbe in un bind wildcard come0.0.0.0:3000). Esempio:DASHBOARD_URL=https://app.example.com. - Default:
https://app.befailproof.ai, utilizzato solo se nessuno dei precedenti è presente.
https://* e loopback (http://localhost*, http://127.0.0.1*) sono accettate, e gli indirizzi di bind wildcard (0.0.0.0, [::]) sono rifiutati anche con lo schema https://. Tutto il resto cade attraverso al livello 2.
Impostalo su un cluster in esecuzione con un one-liner; nessun file, nessuna ricostruzione kustomize:
kustomize build | kubectl apply verso l’overlay lo cancellerà a meno che tu non aggiunga la stessa variabile di ambiente alla patch server-env.yaml del tuo overlay.
Dashboard
Scarica l’immagine
Variabili di ambiente
| Variabile | Obbligatoria | Default | Descrizione |
|---|---|---|---|
AGENTEYE_SERVER_URL | Sì | nessuno | URL di base del server, ad esempio http://localhost:8080 |
AGENTEYE_API_KEY | Sì | nessuno | Chiave API che il dashboard utilizza per autenticarsi al server. Ha bisogno di tutti i permessi (chiave admin consigliata). |
AE_LOG_LEVEL | No | info | Verbosità del log lato server: debug, info, warn, error. Imposta a debug per vedere linee di richiesta/risposta upstream e tracce di validazione della sessione quando si diagnosticano i problemi. |
AE_LOG_JSON | No | auto | 1 forza output JSON per linea; 0 forza output leggibile dall’uomo. Se non impostato, JSON è abilitato automaticamente se NODE_ENV=production. JSON è consigliato in produzione affinché i log si analizzino correttamente con jq o un aggregatore di log. |
AE_ANALYTICS_DISABLED | No | nessuno | Imposta a 1/true per disabilitare la telemetria di utilizzo del prodotto anonima del dashboard. Vedi Telemetria & privacy di seguito. |
REDIS_URL | No | nessuno | Backend cache condiviso opzionale, ad esempio redis://redis:6379/0. Se impostato, il dashboard memorizza in cache i risultati di validateSession() attraverso le repliche e condivide la cache fetch di Next.js per le route proxy dei rollup latenza / lista env. I limiti di rate OTP di richiesta e verifica anche lato edge utilizzano Redis quando presente (fallendo aperto se Redis è irraggiungibile; il limite lato server è il backstop di sicurezza). Vedi Redis (cache opzionale) di seguito. |
AGENTEYE_AGENT_URL | No | nessuno | URL di base del servizio agent assistente AI opzionale, ad esempio http://agent:9100. Lascialo non impostato per nascondere completamente l’assistente: nessuna bolla assistente appare nel dashboard. Vedi enterprise-docs/assistant.md. |
AGENTEYE_AGENT_TOKEN | No | nessuno | Segreto condiviso che il dashboard presenta al servizio agent. Deve corrispondere al AGENTEYE_AGENT_TOKEN configurato sull’agente. Vedi enterprise-docs/assistant.md. |
Esegui
Telemetria & privacy
Il dashboard invia telemetria di utilizzo del prodotto anonima al servizio di analytics di Exosphere (PostHog): quali pagine del dashboard sono visualizzate e una manciata di azioni UI come la creazione di una chiave API o la rivalutazione di una sessione. Questo segnale di utilizzo informa quali funzionalità hanno la priorità.- Nessun dato di agente, sessione o evento lascia mai la tua infrastruttura. Solo l’utilizzo dell’interfaccia utente del dashboard è segnalato. Gli URL delle pagine vengono spogliati degli identificatori prima dell’invio, e gli operatori sono identificati solo da un id opaco interno, mai per email.
- La telemetria è abilitata per default. Per disabilitarla completamente, imposta
AE_ANALYTICS_DISABLED=1sul contenitore dashboard e riavvia. - Gli analytics vengono inviati al percorso
/ingestdel dashboard, che il dashboard rimanda tramite proxy a PostHog (https://us.i.posthog.com). Mantenere le richieste first-party significa che gli ad-blocker del browser non le eliminano. Il contenitore dashboard ha bisogno di accesso in uscita a PostHog; se è bloccato, la telemetria silenziosamente non fa nulla e il dashboard non è interessato.
Assistente AI (opzionale)
Un assistente AI in-dashboard consente al tuo team di porre domande sui dati del loro agente in linguaggio naturale (riassumendo sessioni, bozze SQL per l’editor/queries, e trasformando query salvate in tile dashboard) senza lasciare il dashboard. Funziona come un contenitore agent interno separato (su Claude Agent SDK) che solo il dashboard può raggiungere, e rimane disabilitato finché non configuri un endpoint LLM.
Per abilitarlo imposta, sul servizio agent, una connessione LLM (Portkey tramite PORTKEY_API_KEY + uno slug di catalogo modello AGENTEYE_AGENT_MODEL=@<slug>/<model>, Anthropic diretto tramite ANTHROPIC_API_KEY, un altro gateway tramite ANTHROPIC_BASE_URL, o Bedrock/Vertex), una chiave dati dedicata, e un AGENTEYE_AGENT_TOKEN condiviso che corrisponde al dashboard. Gli utenti del dashboard hanno inoltre bisogno del permesso agent:use.
Per la chiave dati dell’assistente non coni nulla a mano: scegli un segreto casuale, impostalo come AGENTEYE_API_KEY sull’agente e come AGENT_API_KEY sul server, e il server lo popola all’avvio con un insieme di permessi fisso. Il suo accesso ai dati è di sola lettura (events:read, evaluations:read, dashboards:read, queries:read), e inoltre contiene ambiti di authoring gestiti da approvazione (dashboards:write, queries:write, queries:run) affinché possa abbozzare e convalidare query salvate e costruire tile dashboard per conto dell’utente; tutto l’SQL ancora viene eseguito tramite il ruolo ClickHouse di sola lettura dell’organizzazione, quindi questo amplia ciò che l’assistente può creare, non che dati può raggiungere. Gli ambiti sono fissi nel codice e non possono essere ampliati dalla configurazione. Quella chiave è protetta; non può essere disabilitata o rigenerata tramite l’API, solo ruotata modificando il valore e riavviando. Non riutilizzare mai la chiave admin/dashboard per questo.
Setup completo, il riferimento completo delle variabili di ambiente, le opzioni di telemetria, e il modello di sicurezza sono in enterprise-docs/assistant.md.
ClickHouse (archivio analytics obbligatorio)
ClickHouse mantiene i tuoi dashboard reattivi a volumi di evento elevati e consente all’editor SQL/queries di unire tra eventi, valutazioni e sessioni in un unico archivio. È l’archivio canonico obbligatorio per ogni evento ingestionato, ogni risultato di valutazione terminale, e gli aggregati derivati per sessione. PostgreSQL contiene le tabelle relazionali / stato mutevole (api_keys, users, otp_codes, evaluation_jobs, dashboards, saved_queries); la superficie analitica vive in ClickHouse affinché i rollup del dashboard e le tue query SQL possano scansionarlo e unirlo nativamente, senza round-trip cross-database. Il server rifiuta di avviarsi senza CLICKHOUSE_URL.
Schema
Tre oggetti ClickHouse vengono creati all’avvio del server, tutto idempotente (CREATE IF NOT EXISTS):
agenteye.events:ReplacingMergeTree(ingested_at), partizionato pertoYYYYMM(ts), ordinato per(session_id, ts, dedup_key). Gli inserti duplicati (tentativi di raccoglitore) collassano a una singola riga al momento del merge; il server calcola undedup_keySHA-256 deterministico per ogni evento affinché i tentativi siano sicuri.agenteye.evaluations:ReplacingMergeTree(ingested_at), partizionato pertoYYYYMM(finished_at), ordinato per(session_id, finished_at, dedup_key). Scritto una volta per risultato di valutazione terminale dalla pipeline di valutatore. Stesso modello di dedup-key comeevents.agenteye.agent_sessions: una VIEW suagenteye.events, non una tabella fisica. Ogni colonna è derivata (started_at = min(ts),last_event_at = max(ts),ended_at = max(if event_type='agent_end', ts, NULL),event_count = count(), ecc.). Nessun upsert per evento e nessun backfill separato; la view si riflette automaticamente in qualunque cosa sia inevents.
analytics.evaluations / analytics.sessions, il server crea anche un database analytics ClickHouse con view sopra le tabelle agenteye.*; analytics.events, analytics.evaluations, analytics.agent_sessions, analytics.sessions si risolvono tutti correttamente.
Configurazione
Il docker-compose incluso e ildeploy/base/clickhouse/ forniscono un servizio ClickHouse sintonizzato per il carico di lavoro di AgentEye:
- 2 GiB richiesto / 4 GiB limite di memoria nell’overlay base fornito (dimensionato per adattarsi a piccoli nodi POC/staging); i clienti di produzione dovrebbero sovrapporre verso l’alto — il minimo consigliato è 2c / 4Gi richiesta, 6c / 8Gi limite.
max_server_memory_usage_to_ram_ratio=0.9 - 5 GiB mark cache + 8 GiB cache non compressa
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 su kernel supportati)fsync_metadata=0: accettabile per l’ingest almeno una volta + dedup ReplacingMergeTreequery_logabilitato con TTL di 30 giorni;query_thread_logrimosso (costoso a QPS elevato)max_execution_time=30per query lato utente- 100 GiB PVC al template StatefulSet (gli overlay dei clienti DOVREBBERO sovraporre a una classe di archiviazione SSD veloce per la produzione)
Backup
Il tuo set di dati completo è catturato ogni notte in un singolo archivio ripristinabile, quindi una perdita di cluster o archiviazione è recuperabile. ClickHouse viene sottoposto automaticamente a backup dal CronJob giornalieroagenteye-backup, che scarica sia PostgreSQL che ClickHouse in un unico passaggio. ClickHouse viene letto tramite la sua API HTTP: agenteye.events e agenteye.evaluations vengono scaricati nel formato nativo ClickHouse (le view e le politiche di riga vengono ricreate dal server all’avvio, quindi i dati della tabella sono l’immagine completa) e raggruppati con lo scarico Postgres in un unico archivio compresso caricato nel tuo object storage.
Il bucket di destinazione e le credenziali cloud sono configurati per overlay. Vedi la sezione Backup di enterprise-docs/kubernetes-deployment.md per la configurazione dell’upload e i passaggi di ripristino.
Redis (cache opzionale)
Redis è un opzionale cache condiviso + backend per il rate-limiting utilizzato dal server e dal dashboard. Con Redis deployato eREDIS_URL impostato su entrambi i servizi:
- Server memorizza in cache le ricerche di chiavi API autenticate, gli elenchi
/events/environments+/evaluations/environments, il rollup/events/latency_aggregate(la query più pesante che il dashboard polling), l’elenco/sessions, e passa il rate-limiting delle richieste OTP da unCOUNT(*)di Postgres a unINCR + EXPIREdi Redis. - Dashboard memorizza in cache i risultati di
validateSession()così le 10-20 chiamate API autenticate che un tipico caricamento di pagina emette condividono tutti una singola verifica di sessione upstream. Limita anche le richieste OTP-request e OTP-verify nel lato edge del dashboard.
Err entro un timeout limitato e il chiamante torna alla fonte di verità (Postgres sul server, il server Rust upstream sul dashboard). Il rate-limiting OTP torna al percorso COUNT(*) di Postgres sul server (la proprietà di sicurezza è preservata); il limite OTP edge del dashboard fallisce aperto mentre il limite lato server ancora regge. Redis essere giù degrada la latenza, non la correttezza.
Configurazione
Il bundle docker-compose include già un servizio Redis e cablaggio diREDIS_URL=redis://redis:6379/0 nel server e dashboard. Per utilizzare un Redis esterno, imposta REDIS_URL al tuo endpoint e rimuovi il servizio redis dal file compose.
Memoria + persistenza
L’immagine Redis inclusa funziona con--appendonly yes --appendfsync everysec --maxmemory 256mb --maxmemory-policy allkeys-lru. La persistenza AOF significa che la cache sopravvive ai riavvii del contenitore; everysec è il bilancio corretto di durabilità/perf perché perdere l’ultimo secondo di scritture della cache è innocuo. L’evizione LRU limita la crescita della memoria.
Quando NON deployare Redis
- Single-instance dev/QA. Le cache in-process sul server solo forniscono la maggior parte del beneficio per replica; Redis aggiunge la condivisione cross-replica che i setup single-instance non hanno bisogno.
- Installazioni air-gapped dove il costo operazionale di eseguire un servizio in più supera il guadagno di latenza.
Docker Compose (consigliato)
Undocker-compose.yml è disponibile nel repo agenteye-enterprise/releases. Porta su Postgres, il server, e il dashboard con un singolo comando.
.env:
Impostazioni operative
Un piccolo set di manopole operative che usavano stare fissate da variabili di ambiente sono ora modificabili per organizzazione dalla pagina/<org>/settings del dashboard; ogni organizzazione configura la propria. Le modifiche hanno effetto entro pochi secondi, senza riavvio e senza redeploy.
| Impostazione | Variabile di ambiente bootstrap | Cosa controlla |
|---|---|---|
| Accessi consentiti | ALLOWED_EMAILS | Email (o wildcard *@domain.com) autorizzate a ricevere un OTP ed essere aggiunte come utenti |
| Permessi utente predefiniti | DEFAULT_USER_PERMISSIONS | Token di autorizzazione separati da virgole preselezionati quando un admin apre + nuovo utente. Ogni token deve essere una delle stringhe elencate sotto Permessi chiave API. Impostazione predefinita al preset standard: accesso di sola lettura più le azioni quotidiane on-call (attivare rivalutazioni, eseguire query, riconoscere incidenti, usare l’assistente). |
| Durata della sessione | SESSION_TTL_SECS | Quanto tempo un accesso al dashboard rimane valido prima della ri-auth. Il dashboard ri-controlla la sessione upstream ogni 5 secondi, quindi un aggiornamento del permesso su /<org>/users ha effetto sulla richiesta successiva dell’utente interessato, senza riaccesso. |
| Durata del codice una tantum | OTP_TTL_SECS | Quanto tempo un OTP / link magico rimane utilizzabile |
| Canali di notifica degli alert | ALERTS_ENABLED_CHANNELS | Lista separata da virgole di tipi di canale che il dispatcher di alert è autorizzato a usare: email, slack, webhook. La configurazione per-alert è ancora creata su /<org>/alerts/<id>, ma il dispatcher filtra ogni consegna in uscita attraverso questo set; un canale disabilitato qui cortocircuita con una riga di audit skipped_disabled. Il canale dashboard (l’inserimento di audit locale) è sempre consentito. Impostazione predefinita a tutti e tre. |
Come funziona il bootstrap
Le impostazioni sono memorizzate per organizzazione inorg_settings. Al primo avvio, il server popola le righe mancanti dell’organizzazione predefinita dalla variabile di ambiente corrispondente (o un sensato default se la variabile di ambiente non è impostata). In seguito, il valore memorizzato è la fonte di verità e la variabile di ambiente viene ignorata; modificare la variabile di ambiente su un riavvio successivo non interesserà il valore di un’organizzazione viva, e le organizzazioni aggiuntive iniziano da default e configurano le loro.
Questo significa:
- Per un deploy fresco, imposta le variabili di ambiente come mostrato sopra e l’organizzazione predefinita le legge al primo avvio.
-
Per modificare un valore successivamente, accedi al dashboard e modificalo sotto
/<org>/settings. La modifica si applica entro pochi secondi su tutte le repliche del server; nessun riavvio necessario. -
Una linea di log all’avvio registra cosa è stato seminato vs. cosa era già presente, così puoi confermare che il bootstrap ha avuto effetto:
Semantica di accesso attraverso le organizzazioni
Una sessione e un OTP sono globali all’utente, non a una singola organizzazione, quindi due regole riconciliano le impostazioni per organizzazione al momento dell’accesso:- Durata sessione / OTP: il più rigoroso (più breve) il tempo di vita tra le organizzazioni di cui l’utente è membro vince.
- Accessi consentiti: il gate ORs ogni lista di consentiti dell’organizzazione insieme all’appartenenza all’organizzazione: un utente può richiedere un OTP se la lista consentiti di qualunque organizzazione ammette la sua email o sono già membri di qualunque organizzazione.
Permessi
L’accesso a una pagina/<org>/settings è gestito da due permessi:
settings:read: vedi la pagina e i valori attuali.settings:write: salva le modifiche.
ADMIN_EMAIL) li ottiene automaticamente insieme a tutti gli altri permessi. Concedili ad altri utenti da /<org>/users secondo necessità.
Organizzazioni (multi-tenancy)
Un singolo deployment può servire molteplici organizzazioni isolate (tenant); ogni riga di dati appartiene esattamente a un’organizzazione e l’isolamento è applicato nel motore del database. Un’installazione single-tenant non ha bisogno di nulla qui; tutti i dati vivono in un’organizzazionedefault integrata. (Puoi dare a quell’organizzazione un nome più amichevole e uno slug URL, così vive a es. /acme invece di /default, impostando DEFAULT_ORG_NAME / DEFAULT_ORG_SLUG prima del primo avvio, o rinominandola in qualsiasi momento con agenteye-orgctl org rename.)
Il provisioning del tenant è solo per operatori. Le organizzazioni e le loro appartenenze sono create e gestite con il CLI agenteye-orgctl, che viene fornito dentro l’immagine del server (insieme a agenteye-server) e viene eseguito dentro il pod del server esistente; non c’è nessun pod/Job separato, nessuna API HTTP, e nessun pulsante dashboard. Riutilizza il DATABASE_URL del server, CLICKHOUSE_URL, e ORG_CH_SECRET.
org create | list | rename | delete | purge e member add | list | update | remove, con set di permessi integrati admin, standard, e read-only. I membri aggiunti ricevono un OTP al primo accesso al dashboard.
Prima di creare una seconda organizzazione: imposta un forte, stabile ORG_CH_SECRET (il comando org create rifiuta di funzionare sul built-in dev default) e assicurati che Postgres sia 15+. Invariato: le chiavi API per organizzazione sono ancora coniate nel dashboard/API dai membri dell’organizzazione; solo il ciclo di vita dell’organizzazione + membro è passato al CLI. Riferimento completo del comando e un esempio lavorato: enterprise-docs/tenant-management.md.
Riempimento della finestra di contesto
Ogni eventomodel_response mostra una pillola di riempimento contesto — token di input più output come percentuale della finestra di contesto di quel modello. Le bande sono healthy (0–24%), watch (25–49%), compacting (50–74%), e reset context (75–100%). AgentEye risolve gli ID modello comuni automaticamente, quindi nessuna configurazione iniziale è richiesta.
Ogni modello che un’organizzazione invia appare sotto Impostazioni → finestre di contesto modello. Gli utenti con settings:write possono sovrastare la sua finestra o aggiungere un modello privato/proxy (0–1.000.000 token); 0 significa sconosciuto e sopprima la pillola. Le modifiche si applicano agli eventi appena ingestionati. Gli utenti con settings:read possono visualizzare l’elenco.
I nuovi eventi ottengono il riempimento dal momento in cui aggiorni. Per popolare anche gli eventi storici (e la lista per modello) per un deployment esistente, esegui il backfill unico — viene fornito dentro l’immagine del server (come agenteye-orgctl) e funziona nel pod server esistente:
DATABASE_URL / CLICKHOUSE_URL / REDIS_URL dal pod. Esegui di nuovo dopo aver modificato le finestre del modello se vuoi che gli eventi esistenti siano ricalcolati.
Considerazioni sulla produzione
- Postgres: Usa un servizio Postgres gestito o un’istanza dedicata con backup regolari. Il
DATABASE_URLsupporta tutti i parametri libpq standard, inclusosslmode=requireper le connessioni criptate. - TLS: Metti il server e il dashboard dietro un reverse proxy (nginx, Caddy, Traefik) che termina TLS.
- Firewall: La porta del server (default 8080) dovrebbe essere raggiungibile solo da macchine di raccoltore e dall’host del dashboard, non da internet pubblico.
- Chiave admin: Imposta
ADMIN_KEYsu un segreto casuale forte. Dopo il bootstrap, crea chiavi scoped dedicate per i raccoglitori e il dashboard piuttosto che usare la chiave admin ovunque. - Tag di immagine: Fissa alla versione nei tuoi manifesti di release (ad esempio,
server:v0.0.1-beta.48) in produzione piuttosto che un tag fluttuante per evitare aggiornamenti non intenzionali. I build beta attuali vengono pubblicati sottobeta-latest;latestè assegnato solo ai rilasci stabili. - Monitoraggio della salute: Su Kubernetes il probe di readiness utilizza
/ready(raggiungibilità Postgres + ClickHouse) mentre la liveness rimane su/health. Per il “AgentEye stesso è su?” alerting a livello di flotta a Slack, abilita il complemento Robusta opt-in; vedi enterprise-docs/health-monitoring.md.
Tag di immagine disponibili
| Tag | Descrizione |
|---|---|
latest | Ultimo rilascio stabile |
beta-latest | Ultimo pre-rilascio (beta) |
v<version> | Versione fissa, es. v0.0.1-beta.48 (consigliato per la produzione) |

