Главная / Статьи

Агентные AIOps с графом контекста: Neocarta, Neo4j, LangGraph и Gemini

Дизайн процесса реагирования на инциденты с замкнутым циклом: встраивание сервисов ServiceNow, Dynatrace и GitHub в Neo4j, анализ с использованием LangGraph и Gemini за защитным барьером, а также запись каждого совершенного действия обратно.

Издатель: REACTAPP.TOP10 мин чтения2402 слов

Источники: Building Agentic AIOps: A Closed-Loop Platform with LangGraph, Gemini, and a Native Graph Database

Во время сбоя на платформе или у команды SRE этот же цикл повторяется: один инженер отслеживает трассы Dynatrace, другой изучает историю развертываний в GitHub в поисках изменений, а третий редактирует заявку в ServiceNow, чтобы руководство перестало требовать обновлений. Никто не имеет полной картины, поскольку она отсутствует в каком-либо конкретном месте — она распределена между тремя или даже десятью инструментами.

Именно такая фрагментация, а не сбой или некорректное развертывание, чаще всего замедляет процесс восстановления. Задержки возникают из-за того, что люди заново собирают информацию, которая уже существовала где-то в системе, просто не в одном месте.

План решения этой проблемы предусматривает объединение трех выбранных технологий в платформу AIOps с агентами. Neocarta автоматизирует загрузку данных в граф Neo4j и обеспечивает доступ к этому графу для инструментов ИИ через MCP. LangGraph отвечает за детерминированную оркестрацию действий агентов, а SDK Google Gen AI с Gemini обеспечивает логические операции. Здесь нет ни lakehouse, ни пакетной обработки ETL, ни ручно настроенных webhook-соединений, ни панелей управления устаревшими метриками. В итоге получается динамический, доступный для запросов граф операционной реальности, к которому агент может напрямую обращаться и принимать меры.

Граф контекста вместо панелей управления

Большинство инструментов AIOps добавляют интеллектный слой поверх аналитического хранилища данных, предназначенного для бизнес-аналитики, а не для реального времени, что является неверной основой. В данном подходе операционное состояние рассматривается как графовая проблема. Каждый сервис, развертывание, инцидент, команда и действие по устранению проблем становятся узлами, а связи между ними, такие как DEPLOYED_TO, ALERTS_ON, TRIGGERED_BY и OWNER_OF, — ребрами первого класса.

Как только события инфраструктуры образуют связанный граф, а не изолированные логи, анализ корневых причин меняет свой характер. Он перестаёт быть ручной археологией и превращается в просмотр графа, многократный запрос, над которым большая языковая модель может работать напрямую с помощью Graph RAG.

Четыре уровня, закрывающие цикл

Каждый из четырех слоев несёт определённую ответственность, и цикл замыкается, поскольку собственные действия агента записываются обратно в граф. Поэтому при обработке следующего инцидента агент знает, что уже пробовалось.

  1. Автоматизированное сбор информации с помощью CLI Neocarta ingestion. Вместо того чтобы писать приёмник webhook для каждого инструмента, коннекторы Neocarta загружают метаданные и логи из ServiceNow, Dynatrace и GitHub в граф. Не требуется поддерживать отдельные сервисы сбора данных для каждого источника.
  • Системный контекст в Neo4j, обеспечиваемый сервером Neocarta MCP. Это операционный «мозг» системы. Хранилища, сервисы, развертывания, инциденты, команды и действия по устранению проблем являются узлами, а каждая связь — типизированной ориентированной рёбром. Neocarta размещает сервер MCP перед графом, так что любой инструмент, поддерживающий MCP, включая агент LangGraph, может выполнять запросы к нему без необходимости писать собственный код базы данных.
  • Расчёты с использованием LangGraph и Gemini. Статическая машина состояний LangGraph выполняет цикл наблюдения, ориентации, принятия решения и действия. Она загружает контекстуальный подграф через MCP, преобразует его в запрос и даёт Gemini ограниченный выбор: исправить проблему или передать её человеку.
  • Устранение проблем и возврат к исходному состоянию. Если агент решает принять меры, он запускает процедуру исправления, например откат изменений через GitHub Actions, а затем фиксирует результат в графе в виде нового узла. Большинство демонстраций AIOps пропускают именно этот шаг, и именно он позволяет создать замкнутый цикл вместо однократной операции.
  • Neocarta заменяет собой пользовательский сервис ввода данных и прямые вызовы драйверов базы данных. Его CLI автоматизирует загрузку данных в Neo4j, а сервер MCP служит инструментом для обмена информацией между агентом и графом.

    Уровни 1 и 2: ввод данных через Neocarta

    Схема находится на первом месте, поскольку именно она является онтологией, на которой основывается вся платформа. Метки узлов и типы связей — это то, что в конечном итоге считывают и записывают все соединители и каждый запрос Cypher. Каждая сущность представляет собой узел с определенным типом, а каждая зависимость, связь владения и уведомление — направленная ребро с определенным типом. Именно эта структура превращает процесс исследования в разных инструментах в последовательное перемещение по графу.

    Раньше для обработки данных требовалось запускать приемник webhook отдельно для каждого источника и вручную писать код Cypher под формат каждого пакета данных. Neocarta сокращает это до простой настройки: достаточно указать его CLI-интерфейс на ServiceNow, Dynatrace и GitHub, чтобы он сам занимался обнаружением схемы, постепенной загрузкой данных и преобразованием их в узлы и связи графа.

    # 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
    

    В основе лежат те же самые шаблоны MERGE и CREATE, которые обычно пишут вручную. Персистентные сущности, такие как хранилища, сервисы и команды, объединяются, поэтому дублирующиеся узлы никогда не появляются. События, связанные с определённым моментом времени, например развертывание или инцидент, каждый раз вставляются как новые узлы, что сохраняет точность временной шкалы и не нарушает предыдущую историю. Разница заключается в том, что никому не нужно поддерживать код маппинга для трёх API, которые самостоятельно меняют структуру данных в соответствии со своими графиками.

    Помимо ввода данных, Neocarta добавляет свой сервер MCP. После заполнения графа он становится доступен как конечная точка MCP, и клиенты, поддерживающие протокол MCP, включая LangGraph, могут выполнять многопромежуточные запросы к графу как обычные вызовы инструментов. Код агента не требует наличия слоя драйверов базы данных для записи или поддержки.

    # 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.
    

    Контроль схемы остается в руках инженеров. Ограничения и индексы всегда определяются непосредственно в 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);
    

    Слой 3: цикл LangGraph

    Этот слой можно назвать агентным. Вместо одного вызова большой языковой модели процесс рассуждений выполняется как машина состояний с явными узлами и рёбрами, что позволяет анализировать, тестировать и обдумывать каждый путь принятия решений, в отличие от непрозрачного цикла множества агентов.

    Состояние представляет собой типизированный словарь, который передаётся по графу.

    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
    

    Четыре узла управляют циклом:

    • FetchGraphContext вызывает инструмент graph_traverse на сервере MCP Neocarta для отслеживания инцидента до соответствующего сервиса, затем до версии приложения, которая изменила этот сервис, до связанного репозитория и до команды, ответственной за него. Код агента никогда не устанавливает прямое соединение с базой данных.
    • VerifySafetyGate с помощью того же интерфейса запросов MCP проверяет, были ли за прошедший час применены какие-либо меры по устранению проблем с этим сервисом. Этот механизм защиты предотвращает бесконечную работу агента с нестабильным сервисом.
    • GeminiReasoning запускается только в случае, если проверка пройдена. Gemini 2.5 Pro получает краткое описание контекста графа вместе с узкоспециализированным системным указанием, причем единственным допустимым ответом является один из двух фиксированных токенов.
  • ExecuteRemediationTool запускает процедуру устранения проблемы и записывает узел RemediationAction обратно в Neo4j через Neocarta, тем самым закрывая цикл.
  • Если какой-то компонент заслуживает наибольшего внимания, это — механизм безопасности. Он реализован здесь как вызов инструмента MCP, а не как прямая сессия драйвера.

    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)}
    

    Автономный цикл действий без защитного механизма никогда не должен поступать в эксплуатацию. Именно этот механизм предотвращает повторное запуск процедуры отката каждые тридцать секунд из-за того, что основная аномалия ещё не устранена.

    Узел Gemini специально сделан скучным, и в этом его преимущество.

    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."
    )
    

    Ограничение вывода модели двумя точными токенами заставляет её поведение больше напоминать вызов функции с вводом данных, чем ответ в чате, что является правильным подходом, когда результат приводит к откату производства.

    Слой 4: закрытие цикла

    Последний узел либо инициирует откат через API GitHub Actions, либо просто фиксирует событие остановки. В любом случае граф обновляется по тому же пути записи MCP, что и всё остальное, поэтому для возврата данных не требуются отдельные учетные данные базы данных.

    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},
    )
    

    То, что делает эту систему замкнутым циклом, а не простым скриптом автоматизации, — это простой факт: результат собственных действий агента становится контекстом для следующего инцидента, который он анализирует, поэтому со временем платформа становится всё более осведомлённой о ситуации, а не менее.

    Инцидент от начала до конца

    В проекте предусмотрена симуляция в режиме отладки, показывающая, как взаимодействуют его компоненты, и информация из неё очень полезна.

    1. 14:00:00. Сервис платежного шлюза завершает развертывание, в результате чего добавляется узел Deployment, связанный с этим сервисом.
    2. 14:05:00. Dynatrace фиксирует критическую аномалию в том же сервисе.
    3. 14:06:00. В ServiceNow появляется инцидент уровня P1, который превращается в узел Incident и связывается с сервисом с помощью ребра ALERTS_ON.
  • Агент LangGraph активируется на узле нового инцидента. Функция FetchGraphContext проходит путь от Инцидента к Службе, затем к Развертыванию, далее к Хранилищу и, наконец, к Команде, и выясняет, что развертывание произошло за пять минут до возникновения аномалии.
  • Функция VerifySafetyGate не находит более ранних мер по устранению проблемы за последний час, поэтому путь для дальнейших действий свободен.
  • Gemini получает краткое описание контекста, понимает, что именно развертывание стало причиной инцидента, и возвращает команду TRIGGER_ROLLBACK.
  • Инструмент-исполнитель запускает процесс отката в GitHub Actions, после чего сохраняет новый узел RemediationAction в Neo4j.
  • От момента возникновения аномалии до её устранения проходят минуты, а не требуется созвон в оперативной комнате. Каждый шаг логического вывода остается доступным для аудита в графе, поэтому можно выяснить, почему агент совершил те или иные действия.

    После создания карты инцидент образует единую связанную структуру, охватывающую команду, код, процесс развертывания, сервис, сам инцидент и действия агента по его устранению. Именно такой подграф является основанием для принятия решений Gemini, и наличие одной связанной структуры вместо трех отдельных панелей управления позволяет агенту проследить инцидент уровня P1 до соответствующего коммита в коде.

    Этот процесс можно разделить на три этапа, из которых складывается граф: развертывание, сбой и устранение проблемы. Каждый из этих этапов представляет собой отдельную запись в базе данных, но вместе они образуют единую непрерывную временную шкалу, охватывающую период от слияния в Git до поступления оповещения в производственной среде и завершения устранения проблемы в течение семи минут.

    Предоставление инженерам возможности просматривать граф

    Автономная система, которую инженеры не могут проверить, представляет собой риск. Поэтому в проект включена панель управления Streamlit, построенная на библиотеке pyvis, которая отображает актуальную топологию графа и постоянный учет записей всех действий.

    net = Network(height="600px", width="100%", bgcolor="#1a1c1e", directed=True)
    color_map = {
        "Team": "#5f3dc4", "Repository": "#24292e", "Deployment": "#007acc",
        "Service": "#11a685", "Incident": "#c41c1c", "RemediationAction": "#cc0088"
    }
    

    Инженеры могут просматривать всю цепочку операций — от слияния в Git до инцидента в производстве и автоматического устранения проблемы — с возможностью панорамирования и увеличения масштаба. В боковой панели отображается пошаговый список всех действий, совершенных агентом. Такая прозрачность делает автономную систему достаточно надежной для использования в производстве, поскольку ничто из её действий не остается непонятным.

    Развертывание, не влияющее на производство

    Рекомендуемый подход щадящий: он включает три этапа, а не одновременное включение системы.

    • 1-я неделя: загрузка данных и проверка. Настройте соединители Neocarta с копиями источников в среде тестирования, определите ограничения графа и убедитесь, что узлы правильно отображаются и связаны между собой, прежде чем начать использовать данные из производства.
  • 2-я неделя: тестовые запуски на стадионге. Создаётся оркестратор LangGraph на основе только для чтения базы данных стадионга, и наблюдается решение Gemini при отключённой реализации. Именно здесь проявляются проблемы с запросами или контекстом.
  • 3-я неделя: автоматизация с замкнутым циклом. Подключается Layer 4 к реальным API-эндпоинтам стадионга, и проверяется, что транзакции с записью завершают цикл, предоставляя системе безопасности реальную историю для анализа.
  • Только после того, как все три этапа окажутся работоспособными, инструменты для устранения ошибок могут быть направлены на эндпоинты производственной среды.

    Почему такая конструкция эффективна

    Несколько ключевых решений отличают демо-версию от надёжного решения в производственных условиях.

    • Машины состояний превосходят циклы агентов с свободной структурой. LangGraph делает каждый путь принятия решений явным и доступным к анализу, при этом отсутствуют скрытые цепочки логики, которые невозможно воспроизвести.
    • Перед каждым вызовом LLM, который может запустить действие, предусмотрены защитные механизмы. Если недавно была выполнена корректирующая операция, агент не может получить доступ к узлу рассуждений. Эта проверка реализована в детерминистическом коде, а не в промпте.
    • Контракт вывода ограничен. От Gemini не требуется написания прозы; ограничение количества символов до одного из двух токенов делает его результат столь же надежным, как значение, возвращаемое функцией.
    • Граф служит не только для хранения, но и в качестве памяти. Действия по коррекции записываются в тот же граф, который читает агент, поэтому его информированность о ситуации накапливается и не сбрасывается при каждом инциденте.
    • MCP представляет собой связующее звено между агентом и графом. Благодаря серверу MCP от Neocarta, находящемуся между LangGraph и Neo4j, агент никогда не использует драйверы баз данных и не управляет пулами подключений. Он просто вызывает необходимые инструменты. Это связующее звено также позволяет заменить модель Gemini на другую или оркестратор LangGraph на другой, не вмешиваясь при этом в процесс получения данных или работу с графом.

    Контекст, хранящийся нативно в графе, цикл рассуждений с фиксированными шагами и механизм защиты от сбоев, встроенный в код, позволяют превратить автономное устранение сбоев в реально работающую функцию, а не просто в красивый элемент презентации. Логичными дальнейшими шагами будут развертывание всего стека с помощью Docker Compose и отправка уведомлений в Slack через маршрутизатор 4-го уровня, чтобы все знали о каждом автономном действии, даже если никому не пришлось вмешиваться.