Skip to content

NuclearAPK/ite2026

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 

Repository files navigation

От 1С до AI-ассистента: Kafka + n8n + Ollama

Пошаговая инструкция по созданию кадрового AI-ассистента, получающего данные из 1С ЗУП через Apache Kafka и предоставляющего информацию через чат-интерфейс n8n.


1. Разворачиваем инфраструктуру в Docker

Создайте файл docker-compose.yml:

version: '3.8'

services:
  postgres:
    image: postgres:16
    container_name: n8n_postgres
    environment:
      POSTGRES_DB: n8n
      POSTGRES_USER: n8n
      POSTGRES_PASSWORD: n8n_secure_password
    ports:
      - "5432:5432"
    volumes:
      - postgres_data:/var/lib/postgresql/data
    restart: unless-stopped
    networks:
      - app_network

  kafka:
    image: confluentinc/cp-kafka:7.7.0
    container_name: n8n_kafka
    environment:
      KAFKA_NODE_ID: 1
      KAFKA_PROCESS_ROLES: broker,controller
      KAFKA_CONTROLLER_QUORUM_VOTERS: 1@kafka:29093
      KAFKA_LISTENERS: PLAINTEXT://kafka:29092,CONTROLLER://kafka:29093,EXTERNAL://0.0.0.0:9092
      KAFKA_ADVERTISED_LISTENERS: PLAINTEXT://kafka:29092,EXTERNAL://localhost:9092
      KAFKA_LISTENER_SECURITY_PROTOCOL_MAP: PLAINTEXT:PLAINTEXT,CONTROLLER:PLAINTEXT,EXTERNAL:PLAINTEXT
      KAFKA_CONTROLLER_LISTENER_NAMES: CONTROLLER
      KAFKA_INTER_BROKER_LISTENER_NAME: PLAINTEXT
      KAFKA_OFFSETS_TOPIC_REPLICATION_FACTOR: 1
      KAFKA_LOG_DIRS: /tmp/kraft-combined-logs
      CLUSTER_ID: MkQkQm1sQWVFN2VkOGp5bGwzbQ
      KAFKA_AUTO_CREATE_TOPICS_ENABLE: "true"
    ports:
      - "9092:9092"
    volumes:
      - kafka_data:/tmp/kraft-combined-logs
    restart: unless-stopped
    networks:
      - app_network

  ollama:
    image: ollama/ollama:latest
    container_name: n8n_ollama
    ports:
      - "11434:11434"
    volumes:
      - ollama_data:/root/.ollama
    restart: unless-stopped
    networks:
      - app_network

  n8n:
    image: n8nio/n8n:latest
    container_name: n8n_app
    environment:
      DB_TYPE: postgresdb
      DB_POSTGRESDB_HOST: postgres
      DB_POSTGRESDB_PORT: 5432
      DB_POSTGRESDB_DATABASE: n8n
      DB_POSTGRESDB_USER: n8n
      DB_POSTGRESDB_PASSWORD: n8n_secure_password
      N8N_HOST: localhost
      N8N_PORT: 5678
      N8N_PROTOCOL: http
      WEBHOOK_URL: http://localhost:5678/
    ports:
      - "5678:5678"
    volumes:
      - n8n_data:/home/node/.n8n
    depends_on:
      - postgres
      - kafka
      - ollama
    restart: unless-stopped
    networks:
      - app_network

volumes:
  postgres_data:
  kafka_data:
  ollama_data:
  n8n_data:

networks:
  app_network:
    driver: bridge

Запуск

docker compose up -d
docker compose ps   # проверяем что все сервисы запущены

После запуска:

  • n8n доступен по адресу: http://localhost:5678
  • Kafka слушает на порту: 9092
  • PostgreSQL слушает на порту: 5432
  • Ollama API доступен по адресу: http://localhost:11434

2. Установка моделей Ollama

После запуска контейнеров загружаем необходимые модели:

# Модель для создания эмбеддингов (векторная БД)
docker exec -it n8n_ollama ollama pull qwen3-embedding:8b

# Модель для генерации ответов агента
docker exec -it n8n_ollama ollama pull gpt-oss:120b-cloud

# Проверяем список загруженных моделей
docker exec -it n8n_ollama ollama list

3. Подключение компоненты Simple Kafka в 1С

3.1. Скачивание компоненты Simple Kafka

  1. Перейдите в репозиторий: https://github.com/NuclearAPK/Simple-Kafka_Adapter
  2. Откройте раздел Releases на странице репозитория
  3. Скачайте готовую сборку для вашей платформы (Windows x64 / Linux x64)
  4. Файл компоненты (.dll / .so) необходимо поместить в общий макет конфигурации 1С

3.2. Подключение компоненты в 1С

На сервере (рекомендуется для продуктивной работы):

// Настоятельно рекомендуется подключать компоненту в изолированном режиме,
// чтобы падение компоненты не приводило к падению процесса rphost
ПодключитьВнешнююКомпоненту("ОбщийМакет.SimpleKafka1C", "Integration",
    ТипВнешнейКомпоненты.Native,
    ТипПодключенияВнешнейКомпоненты.Изолированно);

Компонента = Новый("AddIn.Integration.simpleKafka1C");

На клиенте (асинхронный вызов):

Ожидать ПодключитьВнешнююКомпонентуАсинх("ОбщийМакет.SimpleKafka1C", "Integration",,
    ТипПодключенияВнешнейКомпоненты.Изолированно);

Компонента = Новый("AddIn.Integration.simpleKafka1C");

3.3. Подключение расширения Kafka1CExtension

  1. Перейдите в репозиторий: https://github.com/NuclearAPK/Kafka1CExtension
  2. Скачайте расширение (файл .cfe) из раздела Releases, либо соберите из исходников (папка src)
  3. В 1С откройте: Администрирование → Печатные формы, отчеты и обработки → Расширения
  4. Нажмите Добавить из файла и выберите скачанный файл .cfe
  5. Установите флаг Активно для подключенного расширения
  6. Перезапустите 1С

Расширение содержит внешнюю компоненту, примеры работы с ней, а также базовые объекты для встраивания в конфигурации.


4. Включение механизма ИсторияВерсийДанных в 1С ЗУП

Механизм ИсторияВерсийДанных позволяет отслеживать изменения объектов и реагировать на них (например, отправлять событие в Kafka при изменении кадровых данных).

4.1. Добавление объектов в расширение

В подключенном расширении Kafka1CExtension необходимо добавить объекты, для которых требуется отслеживание изменений (например, документ КадровыйПеревод, справочник Сотрудники и т.д.).

4.2. Настройка обработчика ПередЗаписью

В модуле объекта (в расширении) добавьте обработчик ПередЗаписью:

Процедура ПередЗаписью(Отказ)

    ЭтотОбъект.ЗаписьИсторииДанных.ВыполнятьОбработкуПослеЗаписиВерсии = Истина;
    ЭтотОбъект.ЗаписьИсторииДанных.ОбновлятьИсториюСразуПослеЗаписи = Истина;

КонецПроцедуры
  • ВыполнятьОбработкуПослеЗаписиВерсии — включает вызов обработчика ОбработкаПослеЗаписиВерсийИсторииДанных после записи версии
  • ОбновлятьИсториюСразуПослеЗаписи — записывает историю синхронно, а не в фоновом задании

4.3. Удаление истории (если хранение не предполагается)

Если долгосрочное хранение истории версий не требуется (данные нужны только для триггера отправки в Kafka), рекомендуется удалять историю после обработки.

Важно: Если хранение истории версий не предполагается в принципе, следует периодически очищать накопленные записи, чтобы не допустить разрастания базы данных.


5. Отправка событий в Kafka из 1С

5.1. Структура сообщения обмена

В модуле менеджера объекта добавьте функцию, описывающую формат сообщения:

Функция СтруктураСообщенияОбмена()

    Результат = Новый Структура;
    Результат.Вставить("uid", "");
    Результат.Вставить("fio", "");
    Результат.Вставить("func", "");
    Результат.Вставить("unit", "");
    Результат.Вставить("status", "");
    Результат.Вставить("llc", "");
    Результат.Вставить("description", "");

    Возврат Результат;

КонецФункции

5.2. Обработчик ОбработкаПослеЗаписиВерсийИсторииДанных

В модуле объекта (в расширении) добавьте процедуру, которая вызывается после записи версии истории данных. Эта процедура собирает кадровые данные и отправляет их в Kafka:

Процедура ОбработкаПослеЗаписиВерсийИсторииДанных(ИнформацияОЗаписиВерсий)

    Если ИнформацияОЗаписиВерсий.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;

    Запрос = Новый Запрос;
    Запрос.Текст = "ВЫБРАТЬ первые 1
    |    КИС.Сотрудник,
    |    ПРЕДСТАВЛЕНИЕ(КИС.Сотрудник) КАК employee,
    |    ПРЕДСТАВЛЕНИЕ(КИС.Сотрудник.ФизическоеЛицо) КАК fio,
    |    ПРЕДСТАВЛЕНИЕ(КИС.Должность) КАК func,
    |    ПРЕДСТАВЛЕНИЕ(КИС.Подразделение) КАК unit,
    |    ПРЕДСТАВЛЕНИЕ(ЕСТЬNULL(ДанныеСостоянийСотрудников.Состояние, """")) КАК status,
    |    ПРЕДСТАВЛЕНИЕ(КИС.Организация) КАК llc,
    |    ПРЕДСТАВЛЕНИЕ(КИС.Сотрудник.кОписаниеОбязаностей) КАК description
    |ИЗ
    |    РегистрСведений.КадроваяИсторияСотрудников.СрезПоследних(&ДатаСреза,
    |        Сотрудник = &Сотрудник) КАК КИС
    |        ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ДанныеСостоянийСотрудников
    |            КАК ДанныеСостоянийСотрудников
    |        ПО (КИС.Сотрудник = ДанныеСостоянийСотрудников.Сотрудник)";

    // Установка значений параметров
    Запрос.УстановитьПараметр("Сотрудник",
        ИнформацияОЗаписиВерсий[0].Данные.Сотрудник);
    Запрос.УстановитьПараметр("ДатаСреза", Неопределено);
    РезультатЗапроса = Запрос.Выполнить();

    СообщениеОбмена = СтруктураСообщенияОбмена();

    Выборка = РезультатЗапроса.Выбрать();
    Пока Выборка.Следующий() Цикл
        ЗаполнитьЗначенияСвойств(СообщениеОбмена, Выборка);
        СообщениеОбмена.uid = XMLСтрока(Выборка.Сотрудник);
    КонецЦикла;

    ОбъектJSON = Новый ЗаписьJSON;
    ОбъектJSON.УстановитьСтроку();
    ЗаписатьJSON(ОбъектJSON, СообщениеОбмена);
    СтрокаJSON = ОбъектJSON.Закрыть();

    Ключ = Строка(Новый УникальныйИдентификатор);
    Продюсер = Константы.KFK_ОсновнойПродюсер.Получить();

    ТаблицаТопики = Продюсер.Топики;
    Если ТаблицаТопики.Количество() = 0 Тогда
        Возврат;
    КонецЕсли;

    Топик = ТаблицаТопики[0].Топик;
    АдресБрокера = ТаблицаТопики[0].Брокер.АдресБрокера;

    ИдентификаторВК = KFK_Интеграция.ИдентификаторВнешнейКомпоненты();
    Компонента = KFK_Интеграция.ПодключитьКомпонентуКафка(ИдентификаторВК);

    // Рекомендуемые параметры для синхронной отправки
    Компонента.УстановитьПараметр("queue.buffering.max.ms", "1");
    Компонента.УстановитьПараметр("message.timeout.ms", "5000");

    Для каждого СтрокаПараметров Из ТаблицаТопики[0].Брокер.ПараметрыПодключения Цикл
        Компонента.УстановитьПараметр(
            СокрЛП(СтрокаПараметров.Ключ),
            СокрЛП(СтрокаПараметров.Значение));
    КонецЦикла;

    РезультатИнициализации = Компонента.ИнициализироватьПродюсера(АдресБрокера);

    Если РезультатИнициализации Тогда
        // Синхронная отправка с ожиданием подтверждения от брокера
        РезультатОтправки = Компонента.ОтправитьСообщениеСОжиданиемРезультата(
            СтрокаJSON, Топик,, Ключ);

        Если РезультатОтправки = 2 Тогда  // RD_KAFKA_MSG_STATUS_PERSISTED
            // Сообщение успешно доставлено и подтверждено брокером
        ИначеЕсли РезультатОтправки = 1 Тогда  // RD_KAFKA_MSG_STATUS_POSSIBLY_PERSISTED
            KFK_ОбщегоНазначенияКлиентСервер.СообщитьПользователю(
                "Сообщение возможно доставлено: "
                + Компонента.ПолучитьСообщениеОбОшибке());
        Иначе  // 0 или -1
            ВызватьИсключение "Ошибка доставки: "
                + Компонента.ПолучитьСообщениеОбОшибке();
        КонецЕсли;

        Компонента.ОстановитьПродюсера();
    Иначе
        ВызватьИсключение Компонента.ПолучитьСообщениеОбОшибке();
    КонецЕсли;

КонецПроцедуры

Примечание: Если вы записываете историю версии справочника Сотрудники (а не документа), замените ИнформацияОЗаписиВерсий[0].Данные.Сотрудник на ИнформацияОЗаписиВерсий[0].Данные — так как сам объект и является сотрудником.


6. Создание топика Kafka из 1С

Перед отправкой сообщений убедитесь, что целевой топик существует. Если топика нет, создайте его через метод компоненты Simple Kafka:

ИдентификаторВК = KFK_Интеграция.ИдентификаторВнешнейКомпоненты();
Компонента = KFK_Интеграция.ПодключитьКомпонентуКафка(ИдентификаторВК);

// СоздатьТопик(АдресБрокера, ИмяТопика, КоличествоПартиций, ФакторРепликации)
Результат = Компонента.СоздатьТопик("localhost:9092",
    "zup.employees.updates.ok", 1, 1);

Если Результат Тогда
    Сообщить("Топик успешно создан");
Иначе
    Сообщить("Ошибка: " + Компонента.ПолучитьСообщениеОбОшибке());
КонецЕсли;

Параметры метода СоздатьТопик:

Параметр Тип Описание
Брокер Строка Адрес брокера Kafka (например, localhost:9092)
ИмяТопика Строка Имя создаваемого топика
КоличествоПартиций Число Количество партиций
ФакторРепликации Число Фактор репликации (для одного брокера — 1)

7. Чтение сообщений из Kafka

Для проверки отправленных сообщений можно использовать следующие инструменты:

7.1. kcat (рекомендуется)

Легковесный CLI-инструмент для работы с Kafka.

# Установка
# macOS:  brew install kcat
# Ubuntu: sudo apt install kcat
# Docker: см. ниже

# Чтение всех сообщений из топика с начала
kcat -b localhost:9092 -t zup.employees.updates.ok -C -o beginning

# Чтение последних 5 сообщений
kcat -b localhost:9092 -t zup.employees.updates.ok -C -o end -c 5

# Форматированный вывод с ключом и временем
kcat -b localhost:9092 -t zup.employees.updates.ok -C \
  -f 'Key: %k\nValue: %s\nTimestamp: %T\n---\n'

# Список всех топиков
kcat -b localhost:9092 -L

# Через Docker (без локальной установки)
docker run --network=host edenhill/kcat:1.7.1 \
  -b localhost:9092 -t zup.employees.updates.ok -C -o beginning

7.2. kafka-console-consumer (встроенный в Kafka)

# Через docker exec в контейнер Kafka
docker exec -it n8n_kafka kafka-console-consumer \
  --bootstrap-server localhost:29092 \
  --topic zup.employees.updates.ok \
  --from-beginning

# С выводом ключей
docker exec -it n8n_kafka kafka-console-consumer \
  --bootstrap-server localhost:29092 \
  --topic zup.employees.updates.ok \
  --from-beginning \
  --property print.key=true \
  --property key.separator=" | "

7.3. Offset Explorer (GUI)

Графическое приложение для работы с Kafka:

  1. Скачайте с offsetexplorer.com
  2. Установите и запустите
  3. Создайте подключение: localhost:9092
  4. В дереве найдите топик zup.employees.updates.ok → вкладка Data → просмотр сообщений

8. Настройка n8n: создание API-ключа

  1. Откройте n8n в браузере: http://localhost:5678
  2. Перейдите в Settings (иконка шестеренки в левом нижнем углу)
  3. Выберите раздел API
  4. Нажмите Create an API key (Создать API Ключ)
  5. Скопируйте сгенерированный ключ — он понадобится для подключения MCP-сервера

Путь в интерфейсе: Settings → API → Create an API key


9. Подключение Claude Code в VS Code

9.1. Установка расширения

  1. Откройте VS Code
  2. Перейдите в Extensions (Ctrl+Shift+X)
  3. В поиске введите: Claude Code
  4. Найдите расширение Claude Code от Anthropic
  5. Нажмите Install

Также можно установить через терминал:

code --install-extension anthropic.claude-code

9.2. Включение Bypass-режима

Bypass-режим позволяет Claude Code автоматически выполнять операции без подтверждения каждого действия.

  1. Откройте Settings VS Code (Ctrl+,)
  2. В поиске настроек введите: claude code
  3. Найдите параметр Claude Code: Auto Approve
  4. Либо в терминале Claude Code используйте команду:
# Включить режим автоматического одобрения всех действий
claude config set autoApprove true

# Или для конкретных категорий
claude config set autoApprove.read true
claude config set autoApprove.edit true
claude config set autoApprove.bash true

Также можно переключать режим прямо в чате Claude Code:

  • Нажмите на индикатор режима в нижней панели
  • Или используйте команду /permissions в чате

10. Создание нового проекта в VS Code

  1. Откройте VS Code
  2. File → Open Folder (Ctrl+K, Ctrl+O)
  3. Создайте новую папку для проекта (например, n8n-hr-assistant)
  4. Выберите созданную папку
  5. Откройте терминал (Ctrl+`)
  6. Инициализируйте проект:
git init

11. Настройка CLAUDE.md

Для чего нужен CLAUDE.md?

CLAUDE.md — это файл конфигурации проекта для Claude Code. Он задает контекст, правила и инструменты, которые Claude будет использовать при работе с проектом. Это аналог системного промта, но привязанный к конкретному проекту. При каждом запуске сессии Claude Code автоматически считывает этот файл и следует указанным в нем инструкциям.

Команда для Claude Code

В терминале Claude Code введите следующий промт:

Помоги мне заполнить Claude.md для данного проекта. Этот проект создан для того
чтобы с твоей помощью автоматизировать процессы n8n. Для этого я предоставлю
доступ к инструментам:
n8n skills: https://github.com/czlonkowski/n8n-skills
n8n mcp: https://github.com/czlonkowski/n8n-mcp
Используй данные инструменты в сочетании с моими запросами для создания
качественных workflow n8n.
Все описание должно быть на русском языке и фокус workflow на AI-агентах.

Claude Code проанализирует указанные репозитории и создаст CLAUDE.md с описанием проекта, доступных инструментов и правил работы.


12. Установка MCP-сервера и Skills

Команда для Claude Code

После успешного составления CLAUDE.md введите:

Установи mcp сервер n8n: https://github.com/czlonkowski/n8n-mcp
Установи skills: https://github.com/czlonkowski/n8n-skills

Что такое MCP (Model Context Protocol)?

MCP-сервер — это локальный сервер, который предоставляет Claude Code набор инструментов (tools) для прямого взаимодействия с внешними системами. В данном случае MCP-сервер n8n позволяет Claude:

  • Создавать, читать, обновлять и удалять workflow в n8n через API
  • Управлять нодами и соединениями
  • Активировать/деактивировать рабочие процессы
  • Получать информацию о существующих workflow

Что такое Skills?

Skills — это набор промтов и шаблонов, которые обучают Claude Code правильно работать с n8n. Они содержат:

  • Шаблоны для типовых workflow (вебхуки, AI-агенты, обработка данных)
  • Правила валидации конфигурации нод
  • Паттерны построения рабочих процессов
  • Знания о синтаксисе выражений n8n

Skills работают как «память» Claude о best practices n8n, а MCP — как «руки» для непосредственного управления инстансом.


13. Создание workflow кадрового ассистента

Промт для Claude Code

После настройки MCP и Skills введите следующий промт:

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

Необходимо создать 2 рабочих процесса в инстансе n8n.

Первый workflow: будет считывать из Kafka топика zup.employees.updates.ok
сообщения, в которых содержится кадровая информация о сотруднике - формат json
с полями:
- llc - организация в которой числится сотрудник
- unit - подразделение в котором числится сотрудник
- description - описание чем занимается сотрудник, особенности
- status - состояние (работает, уволен)
- func - должность сотрудника
- fio - фамилия имя отчество
- uid - уникальный идентификатор сотрудника.
Информацию из сообщения необходимо сохранять в векторную базу данных.
В качестве векторной базы используй Postgres. Модель для embedding -
qwen3-embedding:8b через Ollama. Ключом будет выступать uid. При записи данных,
которые содержат uid, который уже есть в базе - должно происходить обновление
записи. В ноде, которая получает сообщения из kafka должны быть заданы опции
JSON Parse Message = true и Only message.

Второй рабочий процесс - это интерфейс агента через чат (который должен быть
публичным, опубликованным). Агент должен выступать в роли специалиста, который
владеет кадровой информацией по сотрудникам и предоставляет запрашиваемую
информацию из кадровой базы знаний, которая реализована в первом рабочем
процессе. Отрази это в системном промте агента. Если в информации по сотруднику
указано что сотрудник не работает, например - уволен - обязательно укажи это
в ответе. Ответы должны быть лаконичными. В качестве модели используй gpt-oss:20b
в ollama chat model.

Ожидаемый результат

Claude Code создаст два workflow в n8n:

Workflow 1: Kafka → Векторная БД

[Kafka Trigger] → [JSON Parse] → [Upsert в PGVector по uid]
                                        ↓
                              [Ollama Embeddings: qwen3-embedding:8b]
  • Триггер Kafka подписан на топик zup.employees.updates.ok
  • Опции: JSON Parse Message = true, Only message = true
  • Данные сохраняются в PostgreSQL с pgvector
  • При совпадении uid — обновление существующей записи

Workflow 2: Чат-агент

[Chat Trigger (публичный)] → [AI Agent] → [Ответ в чат]
                                  ↓
                        [PGVector Tool: поиск по базе]
                        [Ollama Chat: gpt-oss:20b]
  • Публичный чат-интерфейс (опубликованный webhook)
  • AI-агент с системным промтом кадрового специалиста
  • Поиск по векторной базе знаний сотрудников
  • Обязательное указание статуса сотрудника (уволен/работает)
  • Лаконичные ответы

Архитектура решения

┌─────────────┐     Kafka      ┌─────────────┐    PGVector    ┌──────────┐
│   1С ЗУП    │───────────────→│  n8n WF #1  │───────────────→│ Postgres │
│  (Simple    │  zup.employees │  (Kafka →   │   Embeddings   │ (pgvector│
│   Kafka)    │  .updates.ok   │   Vector)   │←──────────────→│   DB)    │
└─────────────┘                └─────────────┘    Ollama       └────┬─────┘
                                                qwen3-embedding    │
                                                    :8b            │
                                                                   │ Поиск
┌─────────────┐                ┌─────────────┐                     │
│ Пользователь│←──────────────→│  n8n WF #2  │─────────────────────┘
│  (Браузер)  │   Публичный    │  (AI Agent  │
│             │     чат        │   + Chat)   │←── Ollama gpt-oss:20b
└─────────────┘                └─────────────┘

About

Репозиторий мастер класса по n8n

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors