AIOps basado en agencias con un grafo de contexto: Neocarta, Neo4j, LangGraph y Gemini
Un diseño de respuesta a incidentes de bucle cerrado: incorporar ServiceNow, Dynatrace y GitHub en Neo4j, razonar con LangGraph y Gemini detrás de una barrera de seguridad, y registrar cada acción realizada.
Fuentes: Building Agentic AIOps: A Closed-Loop Platform with LangGraph, Gemini, and a Native Graph Database
Durante una interrupción en una plataforma o en un equipo de SRE, el patrón se repite: un ingeniero sigue las trazas de Dynatrace, otro revisa el historial de despliegues en GitHub para averiguar qué cambió, y un tercero edita el ticket de ServiceNow para que la dirección deje de solicitar actualizaciones. Nadie tiene una visión completa porque esa información no se encuentra en ningún lugar específico; está distribuida entre tres o diez herramientas diferentes.
Esa fragmentación, más que el error o el mal despliegue, es lo que suele retrasar la recuperación. La demora se debe a que las personas tienen que reconstruir el contexto que ya existía en algún lugar del sistema, solo que no en un único sitio.
Un plan para solucionar esto combina tres tecnologías seleccionadas en una plataforma AIOps basada en agentes. Neocarta automatiza la ingesta de datos en un grafo Neo4j y expone dicho grafo a las herramientas de IA a través de MCP. LangGraph se encarga de la orquestación determinista del agente, mientras que el SDK de Google Gen AI con Gemini proporciona la capacidad de razonamiento. No hay lakehouse, ni procesamiento ETL por lotes, ni configuraciones manuales de webhook, ni paneles con métricas obsoletas. Lo que queda es un grafo en tiempo real y consultable de la realidad operativa al que un agente puede acceder directamente y actuar sobre él.
Un grafo de contexto en lugar de paneles
Muchas herramientas de AIOps añaden inteligencia a un almacén de datos analíticos diseñado para la inteligencia empresarial y no para el razonamiento en tiempo real, lo cual constituye una base incorrecta. El diseño aquí presenta el estado operativo como un problema de grafos. Cada servicio, despliegue, incidente, equipo y acción de corrección se convierte en un nodo, mientras que las relaciones entre ellos, como DEPLOYED_TO, ALERTS_ON, TRIGGERED_BY y OWNER_OF, son aristas de primera clase.
Una vez que los eventos de infraestructura forman un grafo conectado en lugar de registros aislados, el análisis de causas raíz cambia de naturaleza. Deja de ser una labor arqueológica manual para convertirse en un recorrido por el grafo, una consulta de múltiples pasos que un LLM puede procesar directamente mediante Graph RAG.
Cuatro capas que cierran el ciclo
Cada una de las cuatro capas tiene una responsabilidad específica, y el ciclo se cierra porque las acciones del propio agente se escriben de nuevo en el grafo. Por lo tanto, el siguiente incidente que maneja ya sabe qué se ha intentado anteriormente.
- Recopilación automatizada con la CLI de ingestión de Neocarta. En lugar de crear un receptor de webhook para cada herramienta, los conectores de Neocarta extraen metadatos y registros de ServiceNow, Dynatrace y GitHub y los cargan en el grafo. No es necesario mantener un servicio de ingestión personalizado para cada fuente.
Neocarta sustituye al servicio de ingestión personalizado y a las llamadas directas al controlador de la base de datos. Su CLI automatiza la recopilación en Neo4j, y su servidor MCP es con el que realmente interactúa el agente para obtener contexto del grafo.
Capas 1 y 2: ingestión a través de Neocarta
El esquema viene primero, ya que constituye la ontología sobre la cual se basa toda la plataforma. Las etiquetas de los nodos y los tipos de relaciones son lo que cada conector y cada consulta Cypher leen y escriben en última instancia. Cada entidad es un nodo de tipo definido, y cada dependencia, enlace de propiedad y alerta es un arista dirigida de tipo definido. Esa estructura es lo que convierte una investigación entre herramientas en un recorrido a través del grafo.
Antes, la ingestión significaba ejecutar un receptor de webhook por cada fuente y escribir manualmente consultas Cypher para cada formato de carga. Neocarta reduce eso a una simple configuración: basta con dirigir su CLI hacia ServiceNow, Dynatrace y GitHub para que se encargue del descubrimiento de esquemas, las cargas incrementales y la asignación a los tipos de nodos y relaciones del grafo.
# Register each source once — Neocarta handles auth, schema inference, and scheduling
neocarta connect servicenow --instance your-org.service-now.com --scope incident
neocarta connect dynatrace --tenant your-tenant-id --scope metrics,problems
neocarta connect github --org your-org --scope deployments,repos
# Point the loader at your graph and let it run
neocarta load --target neo4j://your-instance:7687 --database aiops-graph
A continuación, se utilizan los mismos patrones MERGE y CREATE que uno escribiría a mano. Las entidades persistentes como repositorios, servicios y equipos se fusionan, de modo que nunca aparecen nodos duplicados. Los eventos vinculados a un momento específico, como una implementación o un incidente, se insertan como nuevos nodos cada vez, lo que mantiene la línea de tiempo precisa y preserva la historia anterior intacta. La diferencia es que nadie tiene que mantener el código de mapeo entre tres APIs que cambian la estructura de los datos según sus propios horarios.
Más allá de la ingesta, Neocarta añade su servidor MCP. Una vez que el grafo está poblado, se expone como un endpoint MCP, y un cliente que utilice MCP, como LangGraph, puede realizar consultas al grafo en múltiples pasos como si fueran llamadas normales a herramientas. El código del agente no necesita una capa de controlador de base de datos para escribir o mantenerlo.
# LangGraph's context-fetching node talks to Neocarta over MCP,
# not to a Neo4j driver directly
from langchain_mcp_adapters.client import MCPClient
neocarta_client = MCPClient(server_url="http://neocarta-mcp:8080")
tools = await neocarta_client.get_tools() # graph_query, graph_traverse, etc.
El control del esquema permanece en manos de los ingenieros. Las restricciones y los índices se definen, como siempre, directamente en Neo4j.
CREATE CONSTRAINT unique_service_id IF NOT EXISTS
FOR (s:Service) REQUIRE s.id IS UNIQUE;
CREATE INDEX incident_state_index IF NOT EXISTS
FOR (i:Incident) ON (i.state);
Nivel 3: el bucle de LangGraph
Este nivel merece ser llamado “agente”. En lugar de una sola llamada al LLM, el razonamiento se lleva a cabo como una máquina de estados con nodos y aristas explícitos, lo que permite inspeccionar, probar y analizar cada camino de decisión, a diferencia del bucle opaco que presentan muchos agentes.
El estado es un diccionario tipado que fluye a través del grafo.
class AIOpsAgentState(TypedDict):
incident_id: str
failing_service_id: str
graph_context_summary: Optional[str] = None
safety_gate_passed: Optional[bool] = None
chosen_action: Optional[str] = None
target_repository: Optional[str] = None
execution_result: Optional[str] = None
Cuatro nodos impulsan el bucle:
FetchGraphContextllama a la herramienta graph_traverse en el servidor MCP de Neocarta para rastrear un incidente hasta su servicio correspondiente, luego hasta la implementación que modificó dicho servicio, el repositorio involucrado y el equipo responsable de él. El código del agente nunca mantiene una conexión directa a la base de datos.VerifySafetyGateverifica, a través de la misma interfaz de consulta MCP, si ya se aplicó alguna solución para este servicio durante la última hora. Este interruptor de circuito impide que un agente siga intentando interactuar indefinidamente con un servicio problemático.GeminiReasoningse ejecuta únicamente si la verificación tiene éxito. Gemini 2.5 Pro recibe el resumen del contexto del grafo junto con una instrucción de sistema específica, y la única respuesta aceptable es uno de dos tokens fijos.
ExecuteRemediationTool inicia la corrección y escribe un nodo RemediationAction de vuelta en Neo4j a través de Neocarta, lo que cierra el ciclo.Si hay un componente que merece la mayor atención, es la puerta de seguridad. Aquí se describe como una llamada a la herramienta MCP en lugar de una sesión directa del controlador.
async def evaluate_remediation_safety_gate(state: AIOpsAgentState) -> Dict:
result = await neocarta_client.call_tool(
"graph_query",
cypher="""
MATCH (s:Service {id: $service_id})<-[:EXECUTED_AGAINST]-(a:RemediationAction)
WHERE a.timestamp >= datetime() - duration('PT1H')
RETURN count(a) as active_actions
""",
params={"service_id": state["failing_service_id"]},
)
return {"safety_gate_passed": (result["active_actions"] == 0)}
Un bucle de acción autónomo sin una barrera de seguridad nunca debería lanzarse al mercado. La barrera es lo que impide que un agente vuelva a activar una reversión cada treinta segundos, ya que la anomalía subyacente aún no se ha resuelto.
El nodo Gemini está diseñado de forma aburrida a propósito, y esa es su virtud.
system_instruction = (
"You are an automated Agentic AIOps architect. "
"Analyze the provided graph context summary. "
"If a deployment recently modified the service state, "
"output EXACTLY the word TRIGGER_ROLLBACK. "
"If the context is clear but safe guidelines are violated, "
"output HALT_ESCALATE. Do not append any other characters."
)
Al limitar la salida del modelo a dos tokens exactos, la llamada se comporta más como una función programada que como una respuesta de chat, lo cual es la característica adecuada cuando el resultado provoca un retroceso en producción.
Nivel 4: cerrar el bucle
El último nodo ya sea que inicie un retroceso a través de la API de GitHub Actions o no haga nada más que registrar la interrupción. En cualquier caso, el grafo se actualiza mediante el mismo camino de escritura MCP que todo lo demás, por lo que no se necesitan credenciales de base de datos separadas para la escritura posterior.
await neocarta_client.call_tool(
"graph_write",
cypher="""
MATCH (s:Service {id: $service_id}), (i:Incident {id: $incident_id})
CREATE (a:RemediationAction {id: $action_id, timestamp: datetime(), status: 'SUCCESS_ROLLBACK'})
CREATE (a)-[:EXECUTED_AGAINST]->(s)
CREATE (a)-[:ATTEMPTED_TO_FIX]->(i)
""",
params={"service_id": service_id, "incident_id": incident_id, "action_id": action_id},
)
Lo que convierte esto en un sistema de bucle cerrado y no en un script de automatización desechable es un detalle sencillo: el resultado de la acción del propio agente se convierte en contexto para el siguiente incidente que evalúa, de modo que la plataforma adquiere mayor conciencia situacional con el tiempo en lugar de disminuirla.
Un incidente de principio a fin
El plano incluye una simulación de prueba que muestra cómo colaboran las diferentes partes, y un resumen de ella es muy instructivo.
- 14:00:00. El servicio de pasarela de pagos finaliza una implementación, lo que agrega un nodo de Implementación conectado a dicho servicio.
- 14:05:00. Dynatrace detecta una anomalía crítica en el mismo servicio.
- 14:06:00. Aparece un incidente de nivel P1 en ServiceNow y se convierte en un nodo de Incidente, vinculado al servicio mediante un enlace ALERTS_ON.
De la aparición de la anomalía a la solución del problema transcurren minutos, no se necesita una llamada de emergencia. Cada paso del razonamiento permanece auditable en el grafo posteriormente, lo que permite consultar por qué el agente realizó ciertas acciones.
Una vez mapeado, el incidente forma una única estructura conectada que abarca al equipo, el código, el despliegue, el servicio, el incidente en sí y las acciones de solución del propio agente. Ese es exactamente el subgrafo sobre el que se basa Gemini; una sola estructura conectada en lugar de tres paneles separados es lo que permite al agente rastrear un incidente de nivel P1 hasta el commit correspondiente.
La misma historia puede dividirse en tres momentos que dieron forma al grafo: el despliegue, la caída del sistema y la corrección. Cada uno representa una escritura separada en la base de datos, pero juntos forman una línea de tiempo continua que va desde una fusión en Git, pasando por una alerta en producción, hasta una solución que cierra el ciclo, todo en siete minutos.
Brindando a los ingenieros una visión del grafo
Un sistema autónomo que los ingenieros no pueden inspeccionar representa un riesgo. Por lo tanto, el diseño incluye un panel de control Streamlit desarrollado con pyvis que muestra en tiempo real la topología del grafo y un registro continuo de las acciones realizadas.
net = Network(height="600px", width="100%", bgcolor="#1a1c1e", directed=True)
color_map = {
"Team": "#5f3dc4", "Repository": "#24292e", "Deployment": "#007acc",
"Service": "#11a685", "Incident": "#c41c1c", "RemediationAction": "#cc0088"
}
Los ingenieros pueden ver toda la cadena de procesos desde la fusión en Git hasta el incidente en producción y la corrección automática, con una vista que se puede desplazar y ampliar; además, existe un registro lateral con todas las acciones realizadas por el agente, en orden. La visibilidad es lo que hace que un sistema autónomo sea lo suficientemente confiable como para activarse en producción, ya que nada de lo que hace es opaco.
Un despliegue que protege la producción
La ruta recomendada es conservadora, con tres fases en lugar de una activación única.
- Semana 1: ingestión y validación. Dirigir los conectores de Neocarta hacia copias de prueba de cada fuente, crear las restricciones del grafo y verificar que los nodos se mapeen y conecten correctamente antes de involucrar datos reales de producción.
Solo después de que las tres fases funcionen correctamente deben dirigirse las herramientas de corrección a los endpoints de producción.
Por qué este diseño funciona
Varias decisiones separan una demostración de algo fiable en producción.
- Las máquinas de estado son superiores a los bucles de agentes sin estructura. LangGraph hace que cada ruta de decisión sea explícita e inspeccionable, y no existe ninguna cadena de razonamiento oculta que no pueda reproducirse.
- Una puerta de seguridad precede a cada llamada al LLM que podría desencadenar una acción. Si recientemente se ejecutó una medida correctiva, el agente no puede acceder al nodo de razonamiento. Esa verificación se encuentra en código determinista, no en un prompt.
- El contrato de salida está restringido. No se le pide a Gemini que genere prosa; limitarlo a uno de dos tokens hace que su resultado sea tan fiable como el valor devuelto por una función.
- El grafo funciona como memoria y no solo como almacenamiento. Las acciones de corrección se escriben en el mismo grafo que lee el agente, por lo que su conciencia situacional se acumula y no se reinicia con cada incidente.
- MCP es la conexión entre el agente y el grafo. Gracias a que el servidor MCP de Neocarta se encuentra entre LangGraph y Neo4j, el agente nunca maneja un controlador de base de datos ni gestiona grupos de conexiones. Simplemente llama a las herramientas. Esta conexión también permite reemplazar Gemini por otro modelo, o LangGraph por otro orquestador, sin afectar la fase de ingestión ni la capa del grafo.
El contexto que reside de forma nativa en un grafo, un bucle de razonamiento con pasos fijos y un interruptor de circuito integrado en el código hacen que la remediación autónoma sea algo viable para su implementación, en lugar de algo que solo parece bueno en diapositivas. Seguimientos razonables serían entregar la solución con Docker Compose y enviar notificaciones por Slack desde el router de capa 4, de modo que todos se enteren de cada acción autónoma, incluso cuando nadie tuvo que intervenir.
Leer más
- Un agente de QuickBooks Finance que funciona con un LLM local mediante Ollama y LangChain — Un agente ReAct en Qwen 3.5 9B y una RTX 4070 lee datos en tiempo real de QuickBooks sin ningún costo relacionado con la nube. Consulte el código, los resultados y las limitaciones conocidas.
- Notas prácticas: Construcción de un bucle de revisión de código con dos agentes utilizando A2A, LangGraph y — Guía paso a paso de las notas prácticas para crear un bucle de revisión de código con dos agentes mediante A2A, LangGraph, incluyendo contratos, verificaciones y espacios para código listos para su uso por los equipos que implementan este patrón.