Strona główna / Artykuły

AIOps oparte na agentach z grafem kontekstowym: Neocarta, Neo4j, LangGraph i Gemini

Projekt reagowania na incydenty z zamkniętym obiegiem: integruj ServiceNow, Dynatrace i GitHub z Neo4j, przeprowadzaj analizy za pomocą LangGraph i Gemini za zabezpieczoną barierą, a następnie zapisuj każdą podjętą czynność.

Wydawca: REACTAPP.TOP10 min czytania2402 słów

Źródła: Building Agentic AIOps: A Closed-Loop Platform with LangGraph, Gemini, and a Native Graph Database

Podczas awarii na platformie lub w zespole SRE powtarza się ten sam schemat: jeden inżynier śledzi ślady Dynatrace, inny przegląda historię deplojów w GitHubie, aby ustalić, co się zmieniło, a trzeci edytuje ticket w ServiceNow, by kierownictwo przestało żądać aktualizacji. Nikt nie ma pełnego obrazu sytuacji, ponieważ nie znajduje się on nigdzie w konkretnym miejscu – jest rozproszony między trzema lub dziesięcioma narzędziami.

To rozproszenie, bardziej niż błąd czy nieudany deploy, najczęściej powoduje opóźnienia w przywracaniu normalnej pracy. Opóźnienie wynika z faktu, że ludzie muszą na nowo budować kontekst, który już istniał gdzieś w całym systemie, tylko nie w jednym miejscu.

Graf kontekstowy zamiast paneli

Wiele narzędzi AIOps dodaje funkcje analityczne do magazynów danych przeznaczonych do analiz biznesowych, a nie do rozumowania w czasie rzeczywistym, co stanowi błędną podstawę. Taki projekt traktuje stan operacyjny jako problem grafowy – każda usługa, implementacja, incydent, zespół oraz działanie naprawcze staje się węzłem, a relacje między nimi, takie jak DEPLOYED_TO, ALERTS_ON, TRIGGERED_BY i OWNER_OF, są krawędziami pierwszej klasy.

Gdy zdarzenia infrastrukturalne tworzą połączony graf, a nie izolowane logi, analiza przyczyn źródłowych zmienia charakter. Przestaje być manualną procedurą i staje się przeszukiwaniem grafu, zapytaniem wieloetapowym, nad którym model językowy może bezpośrednio rozumować za pomocą Graph RAG.

Cztery warstwy, które zamknięte są w pętli

Cztery warstwy każda pełni jedną funkcję, a pętla się zamyka, ponieważ własne działania agenta są zapisywane z powrotem do grafu. Dlatego kolejny incydent, który obsługuje, wie już, co zostało wcześniej wypróbowane.

  1. Zautomatyzowane zbieranie danych za pomocą CLI Neocarta ingestion. Zamiast tworzyć odbiornik webhook dla każdego narzędzia, konektory Neocarta pobierają metadane i logi z ServiceNow, Dynatrace oraz GitHub i umieszczają je w grafie. Nie trzeba utrzymywać żadnych specjalistycznych usług pobierania danych dla każdego źródła.
  • Kontekst systemowy w Neo4j, obsługiwany przez serwer Neocarta MCP. To jest „mózg” systemu. Repozytoria, usługi, implementacje, incydenty, zespoły oraz działania naprawcze to węzły, a każda relacja to skierowana krawędź o określonym typie. Neocarta umieszcza serwer MCP przed grafem, dzięki czemu każde narzędzie obsługujące standard MCP, w tym agent LangGraph, może go wykorzystywać bez konieczności pisania specjalnego kodu bazodanowego.
  • Rozumowanie za pomocą LangGraph i Gemini. Maszyna stanowa LangGraph uruchamia cykl obserwacji, orientacji, podejmowania decyzji i działania. Pobiera kontekstowy podgraf przez interfejs MCP, konwertuje go na prompt i daje Gemini ograniczony wybór: naprawić problem lub przekazać go człowiekowi.
  • Korekta i zapisywanie zmian. Jeśli agent decyduje się na działanie, uruchamia procedurę naprawczą, na przykład odwrócenie zmian w GitHub Actions, a następnie rejestruje wynik w grafie jako nowy węzeł. Większość demonstracji AIOps pomija właśnie ten krok, a to on sprawia, że pętla jest zamknięta, a nie jednorazowa.
  • Neocarta zastępuje usługę dostarczania danych według własnych specyfikacji oraz bezpośrednie wywołania sterowników bazy danych. Jego interfejs CLI automatyzuje przechowywanie danych w Neo4j, a serwer MCP służy jako narzędzie komunikacji z agentem w celu uzyskania kontekstu grafu.

    Kiły 1 i 2: dostarczanie danych przez Neocartę

    Schemat jest najważniejszy, ponieważ stanowi ontologię, na której opiera się cała platforma. Etykiety węzłów i typy relacji to to, co każdy łącznik oraz każda zapytanie Cypher ostatecznie odczytuje i zapisuje. Każda entytet to węzeł o określonym typie, a każda zależność, powiązanie własnościowe oraz alert to skierowana krawędź o określonym typie. To właśnie ta struktura przekształca badanie przeprowadzane w różnych narzędziach w przejście po grafie.

    Kiedyś konieczne było uruchamianie odbiornika webhook dla każdego źródła oraz ręczne pisanie zapytań Cypher dostosowanych do każdego formatu danych. Neocarta sprowadza to do prostych ustawień – wystarczy skierować jego interfejs wiersza poleceń na ServiceNow, Dynatrace i GitHub, aby samodzielnie zajmował się odkrywaniem schematu, ładowaniem danych stopniowym oraz mapowaniem ich na typy węzłów i relacji w grafie.

    # 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
    

    Poniżej stosuje się te same wzorce MERGE i CREATE, które zwykle pisze się ręcznie. Trwałe elementy takie jak repozytoria, usługi i zespoły są łączone ze sobą, dzięki czemu nigdy nie pojawiają się duplikatowe węzły. Zdarzenia związane z konkretnym momentem, takie jak wdrożenie lub incydent, są za każdym razem dodawane jako nowe węzły, co zapewnia dokładność chronologii i zachowuje wcześniejszą historię. Różnica polega na tym, że nikt nie musi utrzymywać kodu mapowania w trzech API, które samodzielnie zmieniają strukturę przekazywanych danych.

    Oprócz procesu pobierania danych, Neocarta dodaje swój serwer MCP. Gdy graf zostanie wypełniony, jest udostępniany jako punkt końcowy MCP, a klient używający protokołu MCP, np. LangGraph, może wysyłać zapytania do grafu jako zwykłe wywołania narzędzi. Kod agenta nie wymaga warstwy sterowników bazy danych do zapisu ani utrzymywania danych.

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

    Kontrola schematu pozostaje w rękach inżynierów. Ograniczenia i indeksy są zdefiniowane jak zawsze, bezpośrednio w 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);
    

    Warstwa 3: pętla LangGraph

    Warstwa ta nadaje się do określenia jako „agentywna”. Zamiast jednego wywołania modelu językowego, proces rozumowania przebiega jako maszyna stanowa z wyraźnymi węzłami i krawędziami, dzięki czemu każda ścieżka decyzyjna może być sprawdzana, testowana i analizowana, w odróżnieniu od nieprzejrzystej pętli wielu agentów.

    Stanem jest skatalogowany słownik, który przepływa przez graf.

    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
    

    Cztery węzły napędzają ten cykl:

    • FetchGraphContext wywołuje narzędzie graph_traverse w serwerze MCP Neocarty, aby prześledzić incydent aż do związanej z nim usługi, dalej do implementacji, która tę usługę zmieniła, do repozytorium oraz do zespołu, który nią zarządza. Kod agenta nigdy nie utrzymuje bezpośredniego połączenia z bazą danych.
    • VerifySafetyGate sprawdza, za pośrednictwem tej samej interfejsu zapytań MCP, czy w ciągu ostatniej godziny dla tej usługi nie została już zastosowana żadna korekta. Ten mechanizm bezpieczeństwa zapobiega nieskończonemu działaniu agenta w przypadku niestabilnej usługi.
    • GeminiReasoning uruchamia się tylko wtedy, gdy brama bezpieczeństwa pozwala na to. Gemini 2.5 Pro otrzymuje streszczenie kontekstu grafu wraz z precyzyjną instrukcją systemową, a jedyną dopuszczalną odpowiedzią jest jeden z dwóch ustalonych tokenów.
  • ExecuteRemediationTool uruchamia procedurę naprawczą i zapisuje węzeł RemediationAction z powrotem do Neo4j za pośrednictwem Neocarty, co zamyka pętlę.
  • Jeśli jakiś komponent zasługuje na największą uwagę, to jest to brama bezpieczeństwa. Jest ona tutaj przedstawiona jako wywołanie narzędzia MCP, a nie jako surowa sesja sterownika.

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

    Pętla działań autonomicznych bez zabezpieczenia nie powinna kiedykolwiek trafić do użycia. To właśnie to zabezpieczenie zapobiega temu, by agent ponownie uruchamiał procedurę cofania co trzydzieści sekund, ponieważ podstawowa anomalia jeszcze nie zniknęła.

    Węzeł Gemini jest celowo nudny, a to jest jego zaleta.

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

    Ograniczenie wyjścia modelu do dwóch dokładnych tokenów sprawia, że wywołanie zachowuje się bardziej jak funkcja typowana niż odpowiedź w czacie, co jest właściwością pożądaną, gdy wynik powoduje cofnięcie produkcji.

    Szczegół 4: zamknięcie pętli

    Ostatni węzeł albo uruchamia procedurę cofnięcia za pośrednictwem API GitHub Actions, albo nic nie robi, jedynie rejestruje zatrzymanie. W obu przypadkach graf jest aktualizowany tą samą ścieżką zapisu MCP co wszystko inne, więc do zapisu powrotnego nie są potrzebne oddzielne uprawnienia do bazy danych.

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

    To, co czyni to systemem zamkniętym, a nie jednorazowym skryptem automatyzacji, to prosty detal: wynik własnego działania agenta staje się kontekstem dla następnego incydentu, który jest analizowany, dzięki czemu platforma z czasem staje się coraz lepiej świadoma sytuacji, a nie gorzej.

    Incydent od początku do końca

    Plan zawiera symulację próbną, która pokazuje, jak poszczególne elementy współpracują, a jej fragmenty są pouczające.

    1. 14:00:00. Usługa bramy płatności kończy proces wdrażania, co powoduje dodanie węzła Deployment połączonego z tą usługą.
    2. 14:05:00. Dynatrace wykrywa krytyczną anomalię w tej samej usłudze.
    3. 14:06:00. W ServiceNow pojawia się incydent o priorytecie P1, który staje się węzłem Incident i jest powiązany z usługą za pomocą krawędzi ALERTS_ON.
  • Agent LangGraph budzi się przy nowym węźle incydentu. Funkcja FetchGraphContext przemieszcza się od incydentu przez usługę, deployment, repozytorium aż do zespołu i stwierdza, że deployment miał miejsce pięć minut przed anomalią.
  • Funkcja VerifySafetyGate nie znajduje wcześniejszych działań korygujących w ciągu ostatniej godziny, więc droga jest wolna od przeszkód.
  • Gemini otrzymuje streszczenie kontekstu, rozpoznaje, że to deployment spowodował incydent, i zwraca wartość TRIGGER_ROLLBACK.
  • Egzekutor narzędzia uruchamia proces odwracania zmian w GitHub Actions, a następnie przechowuje nowy węzeł RemediationAction w Neo4j.
  • Od wystąpienia anomalii do podjęcia działań korygujących potrzeba zaledwie kilku minut, a nie rozmowy w sali kryzysowej. Każdy krok rozumowania pozostaje dostępny do audytu w grafie, dzięki czemu można sprawdzić, dlaczego agent postąpił w określony sposób.

    Gdy zdarzenie zostanie zmapowane, tworzy ono jedną spójną strukturę obejmującą zespół, kod, proces wdrożenia, usługę, samo zdarzenie oraz działania podejmowane przez agenta w celu jego naprawy. To właśnie ten podgraf jest przedmiotem analizy Gemini – jedna spójna struktura zamiast trzech oddzielnych paneli umożliwia agentowi śledzenie zdarzenia typu P1 aż do odpowiedniego komit w historii kodu.

    Tę samą historię można podzielić na trzy etapy, które doprowadziły do utworzenia tego grafu: wdrożenie, awaria i naprawa. Każdy z tych etapów to odrębna operacja zapisu do bazy danych, ale razem tworzą one ciągłą chronologię trwającą siedem minut – od fuzji w Git, przez alert produkcyjny, aż po finalną naprawę.

    Dostarczanie inżynierom widoku na graf

    System autonomiczny, którego inżynierowie nie mogą sprawdzić, stanowi zagrożenie. Dlatego projekt obejmuje panel Streamlit zbudowany na bazie pyvis, który wyświetla aktualną topologię grafu oraz ciągły zapis dokonanych działań.

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

    Inżynierowie mają możliwość przeglądania całego łańcucha – od fazy łączenia w Git, przez incydenty w produkcji, aż po automatyczne naprawy – z funkcją przewijania i powiększania. Dodatkowo dostępna jest lista z boku z każdą dokonaną czynnością agenta, ułożona w kolejności. Dzięki takiej przejrzystości system autonomiczny jest na tyle godny zaufania, by można go było włączyć do produkcji, ponieważ żadna z jego działań nie jest niejasna.

    Rozwój bez ryzyka dla produkcji

    Zalecana ścieżka jest ostrożna – składa się z trzech faz, a nie z jednego natychmiastowego włączenia.

    • Tydzień 1: pobieranie danych i weryfikacja. Użyj konektorów Neocarta do kopi zapasowych każdego źródła, utwórz ograniczenia grafu i sprawdź, czy węzły są poprawnie mapowane i połączone, zanim zostaną użyte jakiekolwiek dane z produkcji.
  • Tydzień 2, próby w środowisku testowym. Buduje się orkiestratora LangGraph na bazie bazy danych testowej tylko do odczytu i obserwuje się decyzje Gemini przy wyłączonej eksploatacji. W tym etapie ujawniają się problemy z promptami lub kontekstem.
  • Tydzień 3, automatyzacja w zamkniętym obiegu. Łączy się warstwę 4 z rzeczywistymi punktami końcowymi API testowego i sprawdza się, czy transakcje zapisu zamykają cykl, dostarczając bramie bezpieczeństwa rzeczywiste dane historyczne do analizy.
  • Tylko po tym, jak wszystkie trzy fazy się sprawdzą, narzędzia naprawcze mogą być skierowane na punkty końcowe produkcyjne.

    Dlaczego taka architektura jest skuteczna

    Kilka decyzji odróżnia wersję demonstracyjną od rozwiązania godnego zaufania w środowisku produkcyjnym.

    • Maszyny stanowe są lepsze od swobodnych pętli agentów. LangGraph sprawia, że każda ścieżka decyzyjna jest jawna i poddawalna inspekcji, a nie istnieją żadne ukryte łańcuchy rozumowania, których nie dałoby się odtworzyć.
    • Każde wezwanie modelu LLM, które może wywołać jakąś akcję, poprzedzone jest bramką bezpieczeństwa. Jeśli niedawno została uruchomiona procedura korygująca, agent nie może dotrzeć do węzła rozumowania. Ta kontrola znajduje się w kodzie deterministycznym, a nie w instrukcjach do modelu.
    • Umowa dotycząca wyniku jest ograniczona. Od Gemini nie wymaga się tekstu prozą. Ograniczenie jej do jednego z dwóch tokenów sprawia, że wynik jest tak niezawodny jak wartość zwracana przez funkcję.
    • Graf służy jako pamięć, a nie tylko miejsce przechowywania. Działania korygujące są zapisywane w tym samym grafie, który czyta agent, dzięki czemu jego świadomość sytuacyjna się kumuluje i nie jest resetowana przy każdym incydencie.
    • MCP to połączenie pomiędzy agentem a grafem. Dzięki serwerowi MCP firmy Neocarta, który znajduje się pomiędzy LangGraph a Neo4j, agent nie posiada żadnego sterownika bazy danych ani nie zarządza zasobami połączeń. Wykorzystuje jedynie dostępne narzędzia. To połączenie umożliwia również zastąpienie modelu Gemini innym modelem lub systemu LangGraph innym orkiestratorem, bez konieczności modyfikacji procesu pobierania danych czy warstwy grafu.

    Kontekst przechowywany natywnie w grafie, pętla rozumowania z ustalonymi krokami oraz mechanizm ochronny wpleciony w kod sprawiają, że autonomiczne naprawianie problemów staje się rzeczą realizowalną w praktyce, a nie czymś, co wygląda dobrze tylko na slajdach. Rozsądne kroki dalsze to dostarczenie całego zestawu za pomocą Docker Compose oraz wysyłanie powiadomień do Slack z routera warstwy 4, aby wszyscy byli poinformowani o każdej autonomicznej akcji, nawet jeśli nikt nie musiał interweniować.