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

OrgGraph AI: граф знаний с агентным подходом без необходимости ручного кодирования для данных HR.

Как большая языковая модель находит схему графа из любого файла Excel или CSV, загружает её в Neo4j с использованием динамического Cypher и отвечает на вопросы, связанные с персоналом, через чат-агента LangGraph.

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

Источники: 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. Однако они сталкиваются с сложными вопросами, требующими одновременного анализа нескольких уровней отношений. Граф знаний позволяет выполнять четыре вида задач:

  1. Точное планирование штата. Найти одного человека, соответствующего критериям навыка A, сертификата B, местоположения C и имеющего свободные ресурсы, за один проход вместо четырех отдельных объединений данных.
  • Раннее выявление разрыва в навыках. Сравнивайте текущие навыки с требованиями предстоящих проектов. Вы можете узнать, что в отделе данных и ИИ недостаточно экспертизы в Kubernetes для работы над проектами третьего квартала, пока ещё есть время принять меры.
  • Планирование преемственности и сотрудничество. Соединяйте младшего разработчика в Сиднее с старшим архитектором поблизости, использующим тот же набор технологий, или ищите внутренних экспертов для быстрой консультации вместо привлечения сторонних подрядчиков.
  • Анализ организационной сети. Определяйте цепочки отчетности, выявляйте единичные точки сбоев в структуре управления и видите, какие выдающиеся сотрудники перегружены работой до того, как они исчерпают свои ресурсы.
  • Что означает отсутствие жесткой кодировки

    Большинство проектов, связанных с графами знаний, скрывают один неприятный секрет: схема задана жестко. Инженер читает таблицу, решает, что сотрудники — это узлы, навыки тоже являются узлами, а связь между ними обеспечивается ребром HAS_SKILL, пишет специальный код Cypher для каждой сущности и выпускает его в эксплуатацию. Затем отдел кадров добавляет таблицу Certifications или меняет название поля PrimarySkill на TechStack, и вся система перестает работать.

    OrgGraph AI меняет эту ситуацию. Язык больших моделей сам определяет, какой должна быть схема. Получив любой таблицевый файл, система:

    1. анализирует данные, включая типы столбцов, кардинальность и возможные внешние ключи
    2. выводит схему графа на основе структурированных результатов работы языка больших моделей, проверенных с помощью Pydantic
    3. динамически генерирует и выполняет запросы Cypher типа MERGE
    4. анализирует готовый граф, чтобы чат-агент мог выполнять запросы к нему

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

    Четыре этапа

    Система работает в четыре этапа, организованных с использованием 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-активами, в котором отображаются серверы, приложения, команды и зависимости между ними. Он может отслеживать поставщиков, материалы, склады и маршруты логистики в цепочке поставок, а также соединять исследователей, статьи, учреждения и источники финансирования в исследовательской сети.

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