Oferta de lanzamiento +1000 créditos de IA/mes para los primeros 10 registros. Empieza gratis
← Volver al blog
La arquitectura de operaciones autónomas de KubeBolt en seis capas

Un motor de operaciones autónomas para Kubernetes: la arquitectura de 6 capas

La mayoría de las herramientas de AI Ops son cajas negras que devuelven respuestas mágicas. Así construimos lo contrario: un motor de seis capas donde una Capa 1 determinística resuelve la mayoría de los incidentes sin una sola llamada al LLM, y el LLM nunca toca tu cluster directamente.

Pregúntale a la mayoría de los productos de “AI Ops” cómo llegaron a una conclusión y vas a recibir un encogimiento de hombros disfrazado de feature. Un modelo miró tu incidente, lo pensó, y devolvió una respuesta. Quizás acertó. Quizás alucinó un Deployment que no existe. No hay forma de saberlo, porque el razonamiento vive dentro de una única llamada opaca: un prompt entra, un veredicto sale. Está bien para un chatbot. Es una idea genuinamente mala darle a esa forma la capacidad de hacer kubectl delete en producción.

Construimos KubeBolt Autopilot sobre la premisa opuesta: un motor de operaciones autónomas debería ser tan auditable como las personas a las que sustituye. No “confía en el modelo”, sino “muestra tu trabajo en cada paso, y deja que una capa aburrida y determinística tenga las llaves”. Ese principio se convirtió en una arquitectura concreta: seis capas, cada una con un solo trabajo, cada una observable por separado. Este post es el recorrido honesto de por qué tiene esa forma, qué te da, y dónde cuesta más que el enfoque de caja negra que reemplaza.

El problema del LLM como caja negra

La versión seductora de AI Ops es un único agente con una ventana de contexto enorme y credenciales del cluster. Le das la alerta, lo dejas razonar, lo dejas actuar. Luce impecable. También falla de tres maneras que importan más que la demo.

No rinde cuentas. Cuando una sola llamada hace detección, diagnóstico, planificación y ejecución al mismo tiempo, no hay costura que inspeccionar. No puedes responder “¿por qué escaló ese deployment?” con nada mejor que “el modelo lo decidió”. La revisión post incidente se vuelve arqueología.

Es caro por defecto. Cada incidente (incluyendo el 60-70% que son de manual, el pod que murió por OOMKill después de un deploy, el image pull que falló por un tag mal escrito) paga por una pasada de razonamiento con un modelo de frontera. Estás alquilando el cerebro de un ingeniero senior para responder preguntas que un case podría responder.

Es peligroso cuando actúa. Un LLM que decide y ejecuta no tiene ningún freno natural sobre sus propios errores. Si alucina el nombre de un recurso o malinterpreta un nivel de riesgo, el mismo razonamiento defectuoso que produjo el plan también lo lleva a cabo. No hay segunda opinión, porque no hay segundo componente.

La solución no es un mejor prompt. Es separación de responsabilidades: la idea más vieja del diseño de sistemas, aplicada al tipo de componente más nuevo. Divide el trabajo en capas, da a cada una una responsabilidad estrecha, y obtienes las dos cosas que las cajas negras no pueden ofrecer: un registro de auditoría y un lugar donde poner los guardarraíles.

La arquitectura: seis capas, un incidente

Cada incidente fluye por el mismo pipeline. Entra por arriba y desciende solo hasta donde necesita: la mayoría se detiene temprano. Cada capa es una interface de Go con una entrada y una salida definidas, así que podemos testearlas en aislamiento y cambiar un modelo en una sin tocar las demás.

L1  Detector       determinística    "¿Ya conozco este patrón?"
L2  Router         Claude Haiku      "¿Esto es señal o ruido?"
L3  Investigador   Claude Sonnet     "¿Qué está mal en realidad?"
L4  Planner        Sonnet / Opus     "¿Qué hacemos al respecto?"
L5  Executor       determinística    "Hacelo: seguro, bajo guardarraíles."
L6  Postmortem     Claude Opus       "Anota lo que pasó."

Todo corre sobre el Claude Agent SDK, con las llamadas a los modelos enrutadas por un gateway interno que hace failover entre proveedores (Anthropic API, luego Google Vertex, luego AWS Bedrock) con un circuit breaker, así un pestañeo de un proveedor no frena una investigación. Pero la parte interesante no es a qué modelos llamamos. Es cuándo nos negamos a llamarlos.

L1 · Detector (determinística)

La primera capa nunca habla con un modelo. Es el mismo motor de reglas que hoy ya se distribuye como nuestro Insights Engine open source: un conjunto de chequeos determinísticos que reconocen los incidentes que Kubernetes produce de a miles. ¿BackOff con un contador de reinicios por encima de cinco y una firma de OOMKill? Eso es un problema de límite de memoria, y conocemos la forma del arreglo sin preguntarle a nadie. ¿Image pull fallando por un tag que falta? Patrón conocido, respuesta conocida.

func (r *CrashLoopRule) Match(incident *Incident) (bool, float64) {
    return incident.Reason == "BackOff" && incident.RestartCount > 5, 0.95
}

La latencia objetivo aquí es menos de 50 milisegundos, porque no hay ningún viaje de red a un modelo. Si una regla matchea con alta confianza, saltamos todas las capas LLM de abajo y vamos directo a un plan. Si matchea con confianza intermedia, pasamos la pista al Investigador como ventaja inicial en vez de veredicto. Si nada matchea, escalamos.

Esta es la capa que hace que la economía funcione, y vuelvo a ella más adelante: es toda la tesis.

L2 · Router (Claude Haiku)

Si L1 no reconoce el incidente, la pregunta todavía no es “¿cuál es la causa raíz?”. Es la pregunta más barata y más gruesa: ¿esto vale siquiera una investigación? Los clusters son ruidosos. Mucho de lo que parece un incidente es un reinicio normal, un scale down programado, o el cuarto duplicado de un evento que ya tenemos abierto.

Así que la Capa 2 es una pasada de triage rápida y barata con Claude Haiku: un par de cientos de tokens de salida, bastante por debajo de una fracción de centavo, con un techo de alrededor de un segundo. Devuelve uno de tres veredictos:

  • noise: transitorio, esperado, o duplicado. Frena aquí. No despiertes a nadie, no gastes una llamada a Sonnet.
  • investigate: real, pero no en llamas. Escala.
  • critical: impacto en producción, escala con urgencia.

El punto de L2 es protector. Se para entre el mundo determinístico barato de arriba y el mundo caro de razonamiento de abajo, y su trabajo entero es evitar que el ruido llegue alguna vez a los modelos que cuestan dinero de verdad.

L3 · Investigador (Claude Sonnet)

Ahora el trabajo se pone genuinamente difícil, y ahora (solo ahora) sacamos un modelo de razonamiento. El Investigador corre Claude Sonnet en un loop de tool use multi turno. No recibe un volcado de datos: pide lo que necesita, usando las mismas herramientas que nuestro Copilot expone a los operadores humanos (get_pod_logs, describe_deployment, get_recent_events, query_metric) solo que corriendo bajo la service account propia de Autopilot.

Itera: forma una hipótesis, junta evidencia, refina, repite, hasta llegar a una causa raíz en la que confía (nuestra vara es un score de confianza por encima de 0.7) o hasta quedarse sin turnos. Si no llega, no improvisa: marca requires_human y escala a una persona con todo lo que juntó adjunto. La salida es estructurada: un resumen de causa raíz, un score de confianza, y el rastro de evidencia real, así quien revise después ve qué vio el modelo, no solo su conclusión.

Ese rastro de evidencia es el antídoto contra la caja negra. El razonamiento del Investigador es un registro, no una intuición.

L4 · Planner (Sonnet u Opus)

Diagnosticar y remediar son habilidades distintas, así que son capas distintas. El Planner toma los hallazgos del Investigador y produce un RemediationPlan concreto: una lista ordenada de acciones, un nivel de riesgo, una duración esperada, y (esto es clave) una estrategia de rollback para cuando las cosas se tuerzan.

La elección de modelo aquí es deliberada. Un arreglo simple, de un solo paso, va con Sonnet. Un plan complejo, de varios pasos y con radio de impacto real, va con Claude Opus, donde la calidad extra de razonamiento se gana su costo. Gastamos el modelo caro solo en las decisiones que de verdad son caras de equivocar.

Después viene la costura que más importa. El plan que produce el LLM no se confía. Antes de que se acerque siquiera a tu cluster, un ActionRegistry determinístico valida cada acción contra una whitelist cerrada. Si el modelo propone un Kind de acción que no está en el registro, el plan se rechaza de plano y entra un humano. El LLM puede sugerir; no puede inventar capacidades.

L5 · Executor (determinística)

Aquí está la capa que nos deja dormir. El Executor no usa LLM. Es Go puro. Toma el plan validado y lo recorre acción por acción, y es el único componente del sistema con la capacidad de mutar tu cluster.

Todo lo que el Executor puede hacer vive en un catálogo cerrado de unas 25 acciones (scale_deployment, rollout_undo, patch_deployment_resources, restart_pod, drain_node, etcétera) cada una etiquetada con un nivel de riesgo, si es reversible, y si siempre requiere aprobación humana. Las acciones destructivas (delete_deployment, patch_secret, drain_node) requieren visto bueno sin importar en qué modo estés. Para cada acción, el Executor:

  1. Chequea que el modo del cluster permita este nivel de riesgo; si no, frena y pide aprobación.
  2. Envía el comando al agente dentro del cluster por un WebSocket persistente.
  3. Espera el resultado con un timeout.
  4. Persiste el desenlace de inmediato: auditoría en tiempo real, no después.
  5. Ante una falla, dispara la estrategia de rollback.
func (e *Executor) Execute(ctx context.Context, plan *RemediationPlan, mode AutopilotMode) (*Execution, error) {
    execution := e.createExecution(plan)
    for i, action := range plan.Actions {
        if !e.canExecute(action, mode) {
            return e.requestApproval(execution, plan, i) // guardarraíl, no sugerencia
        }
        result := e.executeAction(ctx, action)
        execution.ActionResults = append(execution.ActionResults, result)
        e.saveExecution(execution)
        if result.Status == "failed" {
            return e.rollback(ctx, execution, plan, i, result.Error)
        }
    }
    return e.verify(ctx, execution, plan)
}

Esta es L5 tal como se distribuye hoy como nuestra superficie determinística de operaciones de escritura: el mismo camino de ejecución protegido, atado a RBAC y completamente auditado, ya sea que un humano haga clic en “aprobar” en Copilot o que Autopilot lo corra de forma autónoma. Los disparadores de rollback son ellos mismos determinísticos: una acción falla, o la verificación falla (los pods no se estabilizan dentro de 180 segundos), o una métrica clave se degrada de golpe tras el cambio (la latencia se duplica, la tasa de error se multiplica por cinco). Cualquiera de esas, y el Executor revierte solo.

L6 · Postmortem (Claude Opus)

Una vez que un incidente llega a resolved o failed, corre una última capa de forma asíncrona: fuera del camino crítico, así nunca frena un arreglo. Claude Opus escribe el postmortem: una línea de tiempo, la narrativa de causa raíz, la evaluación de impacto, y action items estructurados, renderizados a un PDF. Este es el único lugar donde con gusto gastamos el modelo grande y nos tomamos el tiempo, porque el valor entero de un postmortem es la calidad, y es el artefacto que los humanos de verdad leen cuando se asienta el polvo.

Por qué el esquema en capas se gana su lugar

Dos ejes justifican todo el diseño. Colapsa las capas y pierdes los dos.

Separación de costo. Las capas se mapean sobre un gradiente de costo deliberado: gratis (L1), casi gratis (Haiku), moderado (Sonnet), caro cuando hace falta (Opus). Un incidente solo paga por la inteligencia que de verdad requiere. La mayoría rutinaria se resuelve por prácticamente nada. Los casos genuinamente difíciles reciben razonamiento de modelo de frontera, pero son la minoría, así que el costo promedio se mantiene bajo. En nuestro MVP esto mantiene la resolución de punta a punta cómodamente por debajo de $1 por incidente, la mayoría en menos de 90 segundos. Un único agente monolítico cobraría precios de modelo de frontera por cada tropezón, ruido incluido.

Separación de riesgo. El LLM propone; un componente determinístico dispone. El diagnóstico y la planificación son trabajo creativo, y ahí es donde los modelos brillan. Pero actuar sobre infraestructura de producción es justo el tipo de tarea que quieres rígida, predecible y acotada: lo opuesto a lo que es un modelo de lenguaje. Al poner un registro que valida contra whitelist (L4) y un executor sin LLM (L5) entre las ideas del modelo y tu cluster, obtenemos diagnóstico creativo sin destrucción creativa. El radio de impacto de una alucinación es un plan rechazado, no un namespace borrado.

Encima de eso van los guardarraíles de cara al operador: modos que van desde suggest_only (investiga, nunca toca) pasando por approve_and_execute hasta autonomous; namespaces bloqueados (kube-system y compañía quedan fuera de límites por defecto); cooldowns; ventanas de congelamiento; límites de concurrencia por organización; y un TTL de plan de cuatro horas para que nadie apruebe un arreglo hecho para un estado del cluster que ya no existe. Hay incluso detección de outage masivo: pasados los 50 eventos por minuto de un mismo cluster, Autopilot deja de investigar individualmente y llama a un humano, porque 300 fallas simultáneas no son 300 incidentes: son uno, y una persona debería verlo.

La idea que lo hace barato: la Capa 1 hace el trabajo pesado

Si te llevas una sola cosa de este post, que sea esta: la llamada al LLM más barata es la que nunca haces.

El núcleo contraintuitivo del diseño es que la primera capa, la más tonta, resuelve la mayoría de los incidentes. Alrededor del 60-70% de lo que un cluster de Kubernetes te tira cae en patrones muy trillados: CrashLoopBackOff por una config mala, OOMKills que quieren un límite de memoria más alto, schedules fallidos, errores de image pull, replicas que nunca llegan a Ready. Esto no necesita razonamiento. Necesita reconocimiento. Y el reconocimiento es la cancha propia de un motor de reglas determinístico: menos de 50ms, cero tokens, y (esto importa) más confiable que un LLM, porque una regla que matchea Reason == "BackOff" la matchea de la misma forma todas y cada una de las veces.

Así que las capas caras existen para manejar la cola larga, no el caso común. La mayoría de los incidentes se reconocen y resuelven en L1 antes de que se consulte siquiera a Haiku. Eso no es un camino de respaldo; es el camino principal. La IA es el manejador de excepciones.

Esto invierte el pitch de venta habitual de AI Ops, que arranca con el modelo de frontera. Nosotros arrancamos con determinismo y tratamos al LLM como un bisturí para los casos que genuinamente necesitan uno. Es menos vistoso. Es mucho más barato de correr, y mucho más fácil de confiar en él.

Los tradeoffs honestos

Esta arquitectura no es gratis, y fingir lo contrario sería justo el tipo de deshonestidad de respuesta mágica contra la que estamos argumentando. Esto es lo que cuesta.

Es más compleja de construir y operar. Seis capas coordinadas, una máquina de estados por incidente, un orquestador manejando dedup y backpressure, failover entre proveedores, un WebSocket persistente con el agente: son bastante más piezas móviles que “llama al modelo, corre la salida”. Un agente monolítico es genuinamente más simple de levantar. Asumimos la complejidad porque la auditabilidad y la seguridad no son opcionales en infraestructura de producción, pero es complejidad real, y es nuestra para cargar.

Gastamos más en ingeniería para gastar menos en inferencia. La apuesta de determinismo primero significa que mucho de nuestro esfuerzo va a la capa poco glamorosa: escribir y mantener reglas determinísticas, curar la whitelist de acciones, endurecer el executor. Ese es trabajo humano que un enfoque de puro LLM se saltea empujando todo al modelo. Creemos que es el trade correcto (las reglas son más baratas, más rápidas y más confiables que los tokens en runtime) pero el costo se mueve de tu factura de inferencia a nuestro código.

Las fronteras entre capas suman latencia y traspasos. Pasar un incidente por etapas discretas, persistiendo estado en cada una, es más lento por paso que un único flujo de razonamiento sin interrupciones. Lo recuperamos haciendo que la mayoría de los incidentes salgan temprano en L1, pero para los casos difíciles que atraviesan las seis capas, la estructura tiene overhead. Creemos que unos segundos extra en un incidente genuinamente complejo son un precio justo por saber exactamente qué pasó y poder revertirlo.

El determinismo tiene un techo. Un motor de reglas solo atrapa lo que alguien pensó en codificar. Los modos de falla novedosos caen a las capas LLM por diseño (esa es la red de seguridad funcionando) pero sí significa que la tasa de acierto de L1 es función de qué tan buenas son nuestras reglas, y eso es una inversión continua, no un problema resuelto.

Números reales, presentados con honestidad

Aquí es donde estamos, dicho sin rodeos. Estas son cifras de MVP y de testing, no un SLA, y preferimos que nos midas por la arquitectura antes que por un benchmark.

En testing, la primera capa determinística maneja la mayoría de los incidentes comunes (el 60-70% que diseñamos para atrapar) sin una sola llamada al modelo. De punta a punta, los incidentes que Autopilot resuelve entran en menos de 90 segundos y por debajo de $1 cada uno, porque el gradiente de costo hace su trabajo: los casos baratos se quedan baratos y el modelo caro solo aparece cuando se está ganando su lugar. Las capas que hacen esto real se están distribuyendo como parte del preview de Autopilot, con L1 ya open source en el Insights Engine y L5 ya en vivo como la superficie protegida de operaciones de escritura detrás de Copilot.

No vamos a maquillar eso como garantías. Lo que vamos a defender es la forma: un sistema donde cada incidente tiene un rastro en papel, donde una capa determinística tiene las llaves, y donde el LLM es un componente sobre el que puedes razonar en vez de una caja negra en la que tienes que confiar.

Si quieres la arquitectura completa (los contratos entre capas, la whitelist de acciones, el modelo de guardarraíles) está toda en la documentación técnica, y el motor es open source, Apache 2.0 si prefieres simplemente leer el código. Ese es exactamente el punto. La forma más confiable de correr autonomía en infraestructura es hacerla algo que puedas inspeccionar: así que lo hicimos.