OrgGraph AI: граф знаний с агентным подходом без необходимости ручного кодирования для данных HR.
Как большая языковая модель находит схему графа из любого файла Excel или CSV, загружает её в Neo4j с использованием динамического Cypher и отвечает на вопросы, связанные с персоналом, через чат-агента LangGraph.
Источники: Building a Fully Agentic Employee Knowledge Graph: **OrgGraph AI — using LangGraph & Neo4j**
Крупные компании хранят о своих сотрудниках больше данных, чем когда-либо раньше, но подбор персонала по-прежнему основывается на догадках. Информация о кадровой иерархии находится в Workday, а данные о распределении проектов — в Jira. Навыки, уровни компетентности и сертификаты остаются в старых порталах обучения. Затем появляется проект с высоким приоритетом, и руководитель проекта спрашивает, кто в офисах в Мумбаи или Пуне владеет продвинутым Python, имеет сертификат AWS, знает AI/ML, работал над банковскими проектами и при этом имеет свободные ресурсы.
На ответ на этот вопрос уходит примерно неделя, если он вообще получается найти. Факты существуют, но они захоронены в отдельных системах, которые не могут анализировать взаимосвязи между различными данными.
OrgGraph AI — это система, созданная для преодоления этого разрыва. Она принимает сырые организационные данные в любом формате Excel или CSV, с помощью LLM самостоятельно определяет структуру графа, загружает всё в Neo4j, а затем отвечает на вопросы простым языком. Логика конкретной области нигде не закодирована жестко.
Отношения важнее записей
Стандартные инструменты HR основаны на плоских SQL-таблицах. Для них легко получить информацию обо всех сотрудниках в Бангалоре или о всех, кто использует Python. Однако они сталкиваются с сложными вопросами, требующими одновременного анализа нескольких уровней отношений. Граф знаний позволяет выполнять четыре вида задач:
- Точное планирование штата. Найти одного человека, соответствующего критериям навыка A, сертификата B, местоположения C и имеющего свободные ресурсы, за один проход вместо четырех отдельных объединений данных.
Что означает отсутствие жесткой кодировки
Большинство проектов, связанных с графами знаний, скрывают один неприятный секрет: схема задана жестко. Инженер читает таблицу, решает, что сотрудники — это узлы, навыки тоже являются узлами, а связь между ними обеспечивается ребром HAS_SKILL, пишет специальный код Cypher для каждой сущности и выпускает его в эксплуатацию. Затем отдел кадров добавляет таблицу Certifications или меняет название поля PrimarySkill на TechStack, и вся система перестает работать.
OrgGraph AI меняет эту ситуацию. Язык больших моделей сам определяет, какой должна быть схема. Получив любой таблицевый файл, система:
- анализирует данные, включая типы столбцов, кардинальность и возможные внешние ключи
- выводит схему графа на основе структурированных результатов работы языка больших моделей, проверенных с помощью Pydantic
- динамически генерирует и выполняет запросы Cypher типа
MERGE - анализирует готовый граф, чтобы чат-агент мог выполнять запросы к нему
Никто не создаёт карты вручную, и никакой код не пишется заранее. Если завтра заменить данные о персонале на информацию логистики цепочек поставок, тот же код создаст совершенно другую структуру графа. Набор данных для тестирования был синтетическим — примерно дюжина таблиц, и система обрабатывает всё, что ей передаётся.
Четыре этапа
Система работает в четыре этапа, организованных с использованием Python, LangChain, LangGraph, Pydantic и Neo4j.
Этап 1: анализ метаданных
Прежде чем привлекаться к помощи каких-либо больших языков моделирования, объект MetadataProfiler анализирует сырые данные локально и формирует компактный структурный отпечаток. Это осознанное решение в плане защиты приватности: настоящие записи сотрудников никогда не попадают к модели. Система получает названия столбцов, типы данных, количество уникальных значений в каждом столбце и несколько примеров значений.
Самый ценный инструмент профилировщика — автоматическое обнаружение иностранных ключей. Он отмечает столбец как возможный иностранный ключ, когда его значения в основном содержатся в столбце первичного ключа в другом месте:
# 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),
})
В наборе данных HR это показывает, что Manager_Employee_ID в таблице Employees совпадает с Employee_ID в более чем 80% случаев, что свидетельствует о самореферентной связи REPORTS_TO. Это указание предназначено для LLM, который не смог определить иерархию на основе одних только названий столбцов.
Этап 2: обнаружение схемы
Профиль передается в LLM, который можно настроить среди OpenAI GPT-4o, Google Gemini и Groq; в промпте он описывается как главный архитектор графовых баз данных.
Ключевая инженерная проблема заключается в том, что LLM генерируют текст свободной формы, в то время как графовые базы данных требуют строгой структуры. Функция with_structured_output() от LangChain сглаживает этот разрыв, заставляя модель возвращать проверенный объект 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 служит контрактом для всей системы. Его генерирует агент схемы, а потребляет двигатель ввода данных. Если проверка не пройдена, запрос направляется LLM заново, поэтому в Neo4j не попадает некорректная схема.
Этап 3: динамический ввод данных с использованием Cypher
При наличии проверенной схемы двигатель в реальном времени генерирует параметризованные запросы Cypher. Не используются шаблоны и операторы выбора в зависимости от типа сущности. Система читает информацию о соответствии и формирует запросы MERGE и SET для каждого типа узлов и связей:
# 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)
Поскольку имена схем, определённые автоматически, являются именами первичных ключей, движок использует команду MERGE, а не CREATE, что делает процесс идемпотентным. Его выполнение трижды с одними и теми же данными приводит к получению одинаковой структуры без дубликатов. Кроме того, движок преобразует типы (toInteger(), toFloat()), заменяет NaN на None и пропускает строки с нулевым первичным ключом.
Демонстрационный набор данных — это не простая модель: 151 сотрудник, распределённый по 13 взаимосвязанным таблицам, включая 935 записей о навыках, 285 заданий на проекты, 107 сертификатов, 313 отзывов и 453 записи об обучении, распределённые между 10 отделами и 10 глобальными офисами.
Этап 4: чат на основе GraphRAG с агентами
Слой чата — это не просто переводчик текста в формат Cypher. Это четырёхузловая машина состояний LangGraph с встроенной функцией восстановления от ошибок:
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
└──────────────┘
Три особенности делают его гибким.
Интроспекция схемы во время выполнения. При запуске агент загружает актуальную схему из Neo4j, в которой указаны типы узлов и связей, их свойства и способы взаимосвязи. Эта схема используется во всех запросах, поэтому агент никогда не делает предположений относительно содержимого базы данных.
Самостоятельно генерируемые примеры с небольшим количеством примеров. Во многих системах GraphRAG примеры на языке Cypher задаются жестко. Здесь большая языковая модель создает собственные примеры на основе актуальной схемы и выбранных данных, и они автоматически обновляются после того, как новый загрузочный файл изменяет схему.
Повторные попытки с учетом ошибок. Если сгенерированный запрос не сработал, сообщение об ошибке возвращается в узел CypherGen, который исправляет запрос и пытается его выполнить снова, максимум два раза. Это делает агента особенно устойчивым к редким синтаксическим проблемам.
Проблемы корпоративного уровня
Конфиденциальность. Язык больших моделей воспринимает структуру, а не людей. Из инструмента анализа выводятся только названия столбцов, их типы и кардинальность, а личные данные остаются на вашем сервере.
Гибкость поставщика. Благодаря паттерну LLM Factory можно переключаться между OpenAI, Gemini и Groq, изменяя всего одну переменную среды:
# .env: LLM_PROVIDER=gemini | openai | groq
llm = get_llm() # Returns the configured ChatModel
Никаких изменений в коде и отсутствие привязки к поставщику.
Загромождённые данные. Корпоративные таблицы никогда не бывают чистыми. Механизм загрузки справляется с лишними пробелами, разными форматами дат, неожиданными значениями NaN и нулевыми первичными ключами, пропуская или конвертируя проблемные строки вместо того, чтобы выйти из строя.
От загрузки к результатам
Интерфейс — это панель управления Streamlit. Пользователь загружает файл Excel или CSV в боковой панели и наблюдает за работой всей системы в реальном времени: анализ структуры, обнаружение схемы, загрузка данных, затем инициализация агента. После этого остаётся только общение.
Отдельная демонстрация использует Vis.js для отрисовки графов на основе физических законов и GSAP для анимаций, запускаемых при прокрутке. Узлы загружаются под действием сил гравитации и отталкивания, постепенно становясь видимыми. При нажатии на любой узел открывается панель с его свойствами и связями с другими узлами. Симулированный чат отображает как ответ на естественном языке, так и соответствующий Cypher-запрос, сгенерированный для его получения.
За пределами HR
Эта архитектура не связана исключительно с HR. Тот же код может быть использован для создания графа знаний для управления IT-активами, в котором отображаются серверы, приложения, команды и зависимости между ними. Он может отслеживать поставщиков, материалы, склады и маршруты логистики в цепочке поставок, а также соединять исследователей, статьи, учреждения и источники финансирования в исследовательской сети.
Архитектуры агентов развиваются в направлении трубопроводов обработки данных, которые адаптируются к данным самостоятельно, вместо того чтобы инженеры принуждали данные соответствовать жестким схемам, и этот проект является одним из примеров такого подхода.