Три часа на один расчёт - это норма?
HR-отдел нашей компании (около 300 человек) каждую неделю тратил до трёх часов только на расчёт отпускных. Формулы в Excel, ручная сверка с табелем, больничные, премии, северные коэффициенты — каждый случай уникален. Ошибки случались регулярно: то не тот средний заработок, то забыли про коэффициент индексации. Недовольство сотрудников росло, а HR валились с ног.
Мы решили, что пора автоматизировать. Но не через дорогую HRM-систему с кучей лишнего функционала, а через AI-агента, который живёт прямо в нашем корпоративном мессенджере Mattermost. Так родился ZeroClaw — локальный AI-агент, который понимает запросы на естественном языке, расчитывает отпускные и обрабатывает исключения. В этой статье я расскажу, как мы это сделали, на какие грабли наступили и почему такой подход выгоднее готовых решений.
Выбираем стек: ZeroClaw, Mattermost и локальная модель
Первым делом определились с требованиями: безопасность (зарплатные данные нельзя отправлять в облачные LLM), гибкость (нужна доработка под российское трудовое законодательство), интеграция с текущими системами (у нас Siberian.pro для учёта рабочего времени и 1С для зарплаты).
Mattermost мы уже активно использовали — open-source, сам себе хозяин. Для агента выбрали ZeroClaw (форк OpenClaw, но с дополнительными модулями). ZeroClaw позволяет описывать инструменты на Python, подключать любые LLM (мы взяли Llama 3 70B, развёрнутую локально на трёх A100), и легко интегрируется с Mattermost через WebSocket.
Для безопасности развернули всё на собственном железе — подробнее об этом подходе мы писали в статье Корпоративная тайна в безопасности: собираем локальный AI-стек для анализа документов без облаков. Концепция ZeroClaw основана на OpenClaw — если вы работаете с Битрикс24, советую глянуть OpenClaw в Битрикс24: как заставить AI-агентов работать с вашей CRM без боли.
Как это работает: архитектура, которая не развалится под нагрузкой
Вот ключевые компоненты:
- Mattermost Bot — слушает каналы, ловит сообщения с упоминанием бота.
- ZeroClaw Orchestrator — получает текст запроса, передаёт его LLM, извлекает намерение, вызывает нужный инструмент.
- Tool: Расчёт отпускных — Python-функция, которая обращается к PostgreSQL (зеркало данных из 1С), парсит запрос (ФИО, даты, период), валидирует остаток дней, вычисляет сумму по ст.139 ТК РФ.
- База данных — содержит сведения о сотрудниках, начислениях, больничных, премиях и графиках.
💡 Важно: LLM отвечает только за понимание запроса и формирование ответа. Все расчёты — в коде. Так мы избегаем галлюцинаций в цифрах.
Агент умеет уточнять данные: если в запросе нет даты начала отпуска или есть неоднозначность (например, два сотрудника с одинаковой фамилией), он задаёт уточняющий вопрос. Для этого используем функцию request_clarification.
1Настройка Mattermost и бота
Создаём бота в Mattermost (System Console > Bot Accounts), выдаём права на чтение сообщений и отправку сообщений в каналы. ZeroClaw включает встроенный Mattermost-драйвер — достаточно указать URL, токен бота и WebSocket-порт.
# config.yaml для ZeroClaw
platform:
mattermost:
url: "https://mattermost.company.com"
token: "bot-token-here"
websocket: true
channels:
- "team:hr"2Создание инструмента расчёта отпускных
Инструмент — это Python-функция с декоратором @tool. ZeroClaw автоматически генерирует для неё OpenAPI-спецификацию, чтобы LLM знала, какие параметры передавать.
@tool
def calculate_vacation_pay(
employee_name: str,
start_date: str,
vacation_days: int
) -> str:
"Расчёт отпускных для указанного сотрудника"
# запрос к БД
employee = db.get_employee(employee_name)
if not employee:
return f"Сотрудник с именем {employee_name} не найден"
# проверка остатка дней
if employee.vacation_balance < vacation_days:
return f"Недостаточно дней: доступно {employee.vacation_balance}"
# вычисление среднего за 12 месяцев
avg_earnings = compute_average(employee.id, start_date)
amount = avg_earnings * vacation_days
return f"Предварительный расчёт: {amount:.2f} руб. \n(с учётом премий и исключения больничных)"Самое интересное — функция compute_average. Там мы учитываем все исключения по ТК РФ: не берутся в расчёт больничные, командировки, отпуска за свой счёт, но включаются квартальные и годовые премии пропорционально. Для каждого случая — своя логика. Мы вынесли её в отдельный модуль и покрыли тестами.
3Обработка исключений и запрос дополнительных данных
LLM иногда ошибается: путает даты, неправильно извлекает ФИО. Чтобы снизить риск, мы добавили систему подтверждений. Агент сначала выводит предварительный расчёт и спрашивает: “Подтвердить?”. Если пользователь отвечает “да” или 👍, агент фиксирует результат и отправляет уведомление в HR-канал. Если “нет” — просит исправить данные.
Пример диалога в Mattermost:
Пользователь: @vacation_bot рассчитай отпуск для Петрова П.П. с 10 июня на 10 дней
Бот: Сотрудник: Петров Пётр Петрович (остаток: 15 дней). Предварительный расчёт: 34 567,80 руб. с учётом премии за 1 квартал. Подтвердить?
Если в расчётном периоде есть больничный, бот пишет: “В расчётном периоде обнаружен больничный (12 дней в марте 2026). Хотите его исключить?” — и после согласия пересчитывает. Это обрабатывается отдельной функцией adjust_for_sick_leave.
Разбор типовых ловушек (и как мы их обходили)
На пути было много граблей. Делимся самыми болезненными.
🔴 Ловушка 1. LLM галлюцинирует даты
Модель могла интерпретировать “с 10 июня” как 10 июня, хотя пользователь имел в виду следующий понедельник. Решение: валидировать даты через парсер (dateparser) и, если дата выпадает на выходной, предлагать ближайший рабочий день.
🔴 Ловушка 2. Конфликт остатка дней
Сотрудник просит отпуск, не зная, что уже использовал все дни. Агент извлекает остаток из БД, но если он отрицательный (человек мог взять в долг), мы выдаём предупреждение. Поначалу агент молча считал — потом бухгалтерия ругалась.
🔴 Ловушка 3. Производительность в пиковые дни
Перед летними каникулами нагрузка выросла в 10 раз. LLM на локальных A100 едва справлялась — время ответа достигало 15 секунд. Пришлось добавить кэширование повторяющихся запросов (актуально для однотипных расчётов) и поставить очередь (Celery) для фоновой обработки. Теперь ответ приходит за 2-3 секунды.
⚠️ Совет: Не пытайтесь сделать всё на одной LLM. Часть логики (проверка остатка, простые вычисления) лучше вынести в код — это быстрее и надёжнее.
Цифры говорят: что мы получили
Внедрение заняло 6 недель силами одного DevOps и одного Python-разработчика. Результаты через месяц работы:
| Показатель | До | После |
|---|---|---|
| Время на один расчёт | 15–30 мин | 30 сек |
| Ошибки (за месяц) | ~8 | 0 |
| Довольных сотрудников | 42% | 89% |
HR перестала тратить время на рутину и занялась стратегическими задачами. Сотрудники получили instant-сервис — написал в чат и через минуту знаешь сумму. Кстати, аналогичные кейсы уже есть: Remote увеличил выручку на 50% с помощью Claude и Slack-агентов, а финтех запустил AI-агента за 16 недель.
Важный момент: мы не увольняли людей. Напротив, перераспределили задачи — это ключ к ROI, как написано в статье Уволить нельзя оставить. Если вам интересно управление несколькими агентами — посмотрите на Paperclip, а для продаж уже есть Rox AI.
Почему это победит готовые HRM-системы
Потому что готовые системы требуют внедрения, обучения, дорогих лицензий и часто не учитывают специфику компании. А AI-агент на базе ZeroClaw — это конструктор: вы описываете свои правила, и он работает именно так, как нужно. Причём интерфейс — ваш любимый мессенджер, не надо учить новый софт.
В Китае уже вовсю монетизируют такие решения — Золотая лихорадка OpenClaw. Думаю, через пару лет ни одна компания не будет считать отпуска вручную. Технология доступна уже сегодня — бери ZeroClaw, Mattermost и вперёд. Если у вас нет времени на разработку, можно нанять команду или использовать готовые инструменты вроде Claude Cowork для других задач.
Ещё один неочевидный совет: начните с одного агента, не пытайтесь автоматизировать всё сразу. Мы сначала сделали только отпуска — обкатали архитектуру, набили шишки, а потом уже добавили расчёт больничных и командировок. Сейчас агент закрывает 80% HR-запросов. И да, он всё ещё работает в Mattermost, а мы получаем удовольствие от того, что в понедельник утром не надо перепроверять Excel.