OrgGraph AI: Graf wiedzy oparty na agentach bez konieczności ręcznego kodowania, przeznaczony do danych HR.
Jak LLM odkrywa schemat grafu z dowolnego pliku Excel lub CSV, ładowa go do Neo4j za pomocą dynamicznego Cyphera oraz odpowiada na pytania dotyczące zasobów ludzkich za pośrednictwem agenta rozmówczego LangGraph.
Źródła: Building a Fully Agentic Employee Knowledge Graph: **OrgGraph AI — using LangGraph & Neo4j**
Wielkie firmy przechowują o swoich pracownikach więcej danych niż kiedykolwiek wcześniej, a decyzje dotyczące zatrudniania wciąż opierają się na domysłach. Hierarchie działu HR znajdują się w Workday, a przydziały projektów – w Jira. Umiejętności, poziomy biegłości i certyfikaty są zamknięte w starych portalach szkoleniowych. Nagle pojawia się projekt o wysokim priorytecie z wykorzystaniem sztucznej inteligencji, a kierownik realizacji pyta, kto w biurze w Mumbaju lub Pune posiada zaawansowaną wiedzę z Pythona, ma certyfikat AWS, zna się na sztucznej inteligencji/machine learningu, pracował nad projektami bankowymi i ma jeszcze wolną zdolność przerobową.
Odpowiedź na to pytanie wymaga około tygodnia, o ile w ogóle jest możliwa. Fakty istnieją, ale są pogrzebane w oddzielnych systemach, które nie potrafią analizować wzajemnych powiązań między nimi.
OrgGraph AI to system stworzony po to, by zamknąć tę lukę. Przyjmuje surowe dane organizacyjne w dowolnej formie Excel lub CSV, za pomocą LLM samodzielnie wyznacza schemat grafu, zapisuje wszystko do Neo4j, a następnie odpowiada na pytania w prostym języku. Żadna logika domeny nie jest żadnym miejscu zakodowana sztywno.
Związki są ważniejsze niż rekordy
Standardowe narzędzia HR opierają się na płaskich tabelach SQL. Znalezienie wszystkich pracowników w Bangalore lub tych, którzy znają Python, jest dla nich łatwe. Mają trudności z pytaniami intersekcjonalnymi, tymi, które wymagają jednoczesnego analizowania kilku wymiarów związków. Graf wiedzy umożliwia cztery rodzaje działań:
- Dokładne planowanie zasobów ludzkich. Znalezienie jednej osoby, która posiada umiejętność A, certyfikat B, pracuje w lokalizacji C i ma wolną przepustowość, przy użyciu jednej trasy zamiast czterech oddzielnych połączeń.
Co oznacza brak hardcodingu
Większość projektów grafów wiedzy ma jeden niezręczny sekret: schemat jest zapisany w sposób sztywny. Inżynier czyta arkusz kalkulacyjny, decyduje, że pracownicy to węzły, umiejętności też są węzłami, a łącze HAS_SKILL łączy je ze sobą, pisze specjalny kod Cypher dla każdej jednostki i go wdraża. Następnie dział HR dodaje arkusz z danymi o Certifications lub zmienia nazwę pola PrimarySkill na TechStack, w wyniku czego cały proces przestaje działać.
OrgGraph AI odwraca tę sytuację. Sztuczna inteligencja decyduje o tym, jaki powinien być schemat. Dla dowolnego pliku tabelarycznego system:
- profiluje dane, w tym typy kolumn, kardynalność oraz możliwe klucze obce
- wynika schemat grafu na podstawie strukturyzowanych wyników sztucznej inteligencji, zweryfikowanych za pomocą Pydantic
- dynamicznie generuje i uruchamia zapytania Cypher typu
MERGE - analizuje gotowy graf, aby agent czatowy mógł go przeszukiwać
Nikt nie rysuje map ręcznie, a żaden kod nie jest pisany z góry. Jutro wystarczy zastąpić dane HR danymi z logistyki łańcucha dostaw, a ta sama baza kodu stworzy zupełnie inny graf. Zbiór danych do testów był syntetyczny, składał się mniej więcej z tuzina arkuszy, a proces przetwarzania przyjmuje wszystko, co mu zostanie podane.
Cztery fazy
System działa w czterech fazach, koordynowanych za pomocą Pythona, LangChain, LangGraph, Pydantic i Neo4j.
Faza 1: profilowanie metadanych
Zanim zostanie użyty jakikolwiek model językowy, MetadataProfiler analizuje surowe dane lokalnie i tworzy zwięzły obraz ich struktury. To świadoma decyzja dotycząca ochrony prywatności – rzeczywiste dane pracowników nigdy nie trafiają do modelu. Model otrzymuje nazwy kolumn, typy danych, liczbę różnych wartości w każdej kolumnie oraz kilka przykładowych wartości.
Najcenniejszą umiejętnością profilera jest automatyczne wykrywanie kluczy obcych. Oznacza on kolumnę jako potencjalny klucz obcy, gdy jej wartości występują głównie w kolumnie klucza pierwszego w innym miejscu:
# Simplified FK detection logic from profiler.py
overlap = col_values & ref_values
if len(overlap) / len(col_values) >= 0.8:
fk_candidates.append({
"source_table": tname,
"source_column": col,
"target_table": ref_table,
"target_column": ref_col,
"match_pct": round(len(overlap) / len(col_values) * 100, 1),
})
W zestawie danych HR widać, że Manager_Employee_ID z tabeli Employees pokrywa się z Employee_ID w stopniu przekraczającym 80%, co wskazuje na relację typu self-referencing REPORTS_TO. Wskazówka jest kierowana do LLM, które nie mogło wywnioskować hierarchii na podstawie samych nazw kolumn.
Faza 2: odkrywanie schematu
Profil jest przekazywany LLM, które można skonfigurować spośród OpenAI GPT-4o, Google Gemini i Groq, przy czym prompt określa je jako głównego architekta bazy danych grafowych.
Głównym problemem inżynieryjnym jest to, że LLM generują tekst w formie swobodnej, podczas gdy bazy danych grafowych wymagają ścisłej struktury. Funkcja with_structured_output() z LangChain łączy te dwa podejścia, zmuszając model do zwracania zweryfikowanego obiektu Pydantic:
# The LLM is coerced to return this exact structure
class GraphMappingModel(BaseModel):
nodes: List[NodeMapping] # What becomes a Node?
relationships: List[RelationshipMapping] # What becomes an Edge?
notes: str # LLM's reasoning notes
class NodeMapping(BaseModel):
label: str # e.g., "Employee"
source_table: str # e.g., "Employees"
primary_key_column: str # e.g., "Employee_ID"
properties: List[PropertyMapping] # All columns to map
class RelationshipMapping(BaseModel):
type: str # e.g., "HAS_SKILL"
from_node_label: str # e.g., "Employee"
to_node_label: str # e.g., "Skill"
from_key_column: str # FK column in source table
to_key_column: str # PK column of target node
properties: List[PropertyMapping] # Edge properties
GraphMappingModel pełni rolę umowy dla całego systemu. Tworzy go agent schematu, a konsumuje go silnik integracji danych. Jeśli walidacja się nie powiedzie, pytanie skierowuje się ponownie do LLM, dzięki czemu żaden błędnie sformatowany schemat nie trafia do Neo4j.
Faza 3: dynamiczna integracja Cypher
Z walidowanym schematem silnik generuje w czasie rzeczywistym parametryzowane zapytania Cypher. Nie ma tu szablonów ani instrukcji switch dla poszczególnych typów entytetów. Silnik odczytuje mapowanie i tworzy instrukcje MERGE oraz SET dla każdego typu węzła i relacji:
# Dynamically generated Cypher from the mapping — zero hardcoding
UNWIND $rows AS row
MERGE (n:Employee {employee_id: row.employee_id})
SET n.full_name = row.full_name,
n.designation = row.designation,
n.date_of_joining = row.date_of_joining,
n.annual_ctc_lpa = toFloat(row.annual_ctc_lpa)
Ponieważ wywnioskowane nazwy schematów to klucze pierwszorzędne, silnik używa MERGE, a nie CREATE, co sprawia, że proces jest idempotentny. Uruchomienie go trzy razy na tych samych danych daje ten sam graf bez duplikatów. Silnik także przekształca typy (toInteger(), toFloat()), zamienia NaN na None i pomija wiersze, których klucz pierwszorzędny jest null.
Zbiór danych demonstracyjnych nie jest prostym przykładem: 151 pracowników w 13 powiązanych ze sobą tabelach, w tym 935 mapowania umiejętności, 285 przydziałów do projektów, 107 certyfikatów, 313 recenzji oraz 453 wpisów szkoleniowych, rozproszonych między 10 działami i 10 oddziałami globalnymi.
Faza 4: czat GraphRAG oparty na agentach
Szczegół czatu to coś więcej niż tylko translator tekstu na Cypher. Jest to maszyna stanowa LangGraph składająca się z czterech węzłów, wyposażona w wbudowaną funkcję przywracania po błędach:
User Question
↓
┌─────────────┐
│ Planner │ → Analyzes intent, extracts entities, maps to schema
└──────┬──────┘
↓
┌─────────────┐
│ CypherGen │ → Generates Cypher query using schema + few-shot examples
└──────┬──────┘
↓
┌─────────────┐ ┌─── Error? ───→ Retry CypherGen (up to 2x)
│ Executor │ ────┤
└──────┬──────┘ └─── Success ──→
↓
┌──────────────┐
│ Synthesizer │ → Formats raw graph data into natural language
└──────────────┘
Trzy cechy sprawiają, że jest on elastyczny.
Introspekcja schematu w czasie wykonywania. Podczas uruchamiania agent pobiera aktualny schemat z Neo4j, pokazujący, jakie typy węzłów i relacji istnieją, ich właściwości oraz sposób połączeń między nimi. Ten schemat jest uwzględniany we wszystkich zapytaniach, dzięki czemu agent nigdy nie zakłada, co zawiera baza danych.
Samo generowane przykłady typu few-shot. Wiele systemów GraphRAG ma w kodzie przykłady zapytań w formacie Cypher. Tutaj LLM tworzy własne przykłady typu few-shot na podstawie aktualnego schematu i wybranych danych, a one są automatycznie regenerowane po zmianie schematu spowodowanej nowym załadunkiem danych.
Ponawianie prób z uwzględnieniem błędów. Jeśli wygenerowane zapytanie zawiedzie, komunikat o błędzie trafia z powrotem do węzła CypherGen, który poprawia zapytanie i próbuje ponownie, maksymalnie dwa razy. Dzięki temu agent jest wyjątkowo odporny na problemy składniowe w trudnych przypadkach.
Kwestie związane z biznesem
Prywatność. LLM widzi strukturę, a nie osoby. Tylko nazwy kolumn, typy i kardynalność opuszczają narzędzie analizy, a dane osobowe pozostają na twoim serwerze.
Elastyczność dostawcy. Wzorzec LLM Factory umożliwia przełączanie się między OpenAI, Gemini i Groq poprzez zmianę jednej zmiennych środowiskowej:
# .env: LLM_PROVIDER=gemini | openai | groq
llm = get_llm() # Returns the configured ChatModel
Brak zmian w kodzie i brak zależności od konkretnego dostawcy.
Zanieczyszczone dane. Korporacyjne arkusze kalkulacyjne nigdy nie są czyste. Silnik integracji radzi sobie z dodatkowymi przestrzeniami pustymi, mieszanymi formatami dat, nieoczekiwanymi wartościami NaN oraz pustymi kluczami głównymi, pomijając lub konwertując problematyczne wiersze zamiast się zawiesić.
Od przesyłania do odpowiedzi
Interfejs użytkownika to panel sterowania Streamlit. Użytkownik przesyła plik Excel lub CSV w pasku bocznym i obserwuje działanie całego procesu na żywo: analizę profilową, wykrywanie schematu, integrację danych oraz inicjalizację agenta. Po tym mogą po prostu rozmawiać.
Odrębna demonstracja pokazuje użycie Vis.js do renderowania grafów opartych na zasadach fizyki oraz GSAP do animacji uruchamianych przy przewijaniu. Węzły ładują się pod wpływem sił grawitacji i odpychania w stopniowym ujawnianiu się. Kliknięcie dowolnego węzła otwiera panel z jego właściwościami oraz powiązanymi relacjami. Symulowany czat pokazuje zarówno odpowiedź w języku naturalnym, jak i zapytanie Cypher wygenerowane w tle.
Poza HR
Taka architektura nie jest powiązana wyłącznie z działem HR. Ten sam kod mógłby służyć do tworzenia grafu wiedzy do zarządzania zasobami IT, mapując serwery, aplikacje, zespoły i powiązania między nimi. Mógłby również śledzić dostawców, materiały, magazyny i trasy logistyczne w łańcuchu dostaw lub łączyć badaczy, artykuły naukowe, instytucje i źródła finansowania w sieci badawczej.
Kanale przepływu danych, które dostosowują się do danych zamiast gdy inżynierowie próbują wpasować je w sztywne schematy, to kierunek, w którym zmierzają architektury agentowe, a ten projekt jest jednym z przykładów takiego rozwiązania.