Как думаете, сколько времени нужно кластеру серверов 1С, чтобы намертво лечь от безобидной нейросети, вычисляющей скидки? Если вы ответили «часы» — вы оптимист. У нас это заняло ровно четыре минуты.
Интеграция ИИ с 1С и ERP: как встроить модель, не сломав учётную систему — это не абстрактная тема для конференции, а вопрос того, уволят вас в чёрную пятницу или выпишут премию. Я помню тот инцидент до секунд. Крупный ритейл, пиковая нагрузка конца месяца. Модель машинного обучения должна была на лету скорить B2B-контрагентов и отдавать вероятность дефолта. Архитекторы со стороны заказчика настояли на «максимально производительном» решении: прямой коннектор из Python-сервиса в СУБД (PostgreSQL), лежащую под сервером 1С. Чтение таблиц напрямую, инференс, прямая запись результатов обратно с помощью UPDATE. Никаких HTTP-оверхедов, никакого парсинга JSON, чистый SQL.
Это была катастрофа.
Прямой доступ к базе 1С — это гарантированный выстрел себе в ногу. Платформа реализует собственную ORM и свой менеджер управляемых транзакционных блокировок на уровне процессов rphost. СУБД для неё — просто тупое хранилище. Когда наш ML-сервис начал агрессивно делать тяжелые аналитические джойны по таблицам регистров накопления, он повесил на них эксклюзивные блокировки базы данных. 1С об этих блокировках ничего не знала. В итоге транзакции пользователей начали отваливаться по таймауту на уровне СУБД. Менеджеры на складах не смогли провести ни один заказ покупателя. Встало абсолютно всё. Мониторинг покраснел, фуры на погрузке скопились в мёртвую пробку. Бизнес был парализован из-за попытки сэкономить микросекунды на интеграции.
После жёсткого пост-мортема и отката на старую логику мы начали выстраивать архитектуру заново. Реальность такова, что у вас есть только два пути, если вы хотите оставить 1С в живых: REST/HTTP-сервисы внутри самой платформы и слабая связанность через брокеры сообщений.
Мы попробовали REST. Подняли HTTP-сервис в расширении 1С. Логика простая: при обработке проведения документа 1С делает синхронный POST-запрос к нашему API, ждёт ответ модели, подставляет скоринговый балл, завершает транзакцию. Звучит как стандартный микросервисный паттерн. Проблема в том, что 1С — это не Node.js и не Go. Асинхронность под капотом веб-вызовов там специфическая. Каждый исходящий HTTP-запрос к модели — это заблокированный рабочий поток кластера 1С.
Наш latency-бюджет на инференс составлял 200 миллисекунд. Но сеть нестабильна, а видеокарты иногда делают сборку мусора. Как только GPU задумался на 800 миллисекунд, очередь процессов в 1С начала расти по экспоненте. Если 500 менеджеров одновременно нажали кнопку «Провести», а модель отвечает секунду, вы моментально выжигаете пул потоков кластера 1С. Сервер начинает лихорадочно порождать новые процессы rphost, сжирает всю оперативную память, уходит в своп и умирает. Синхронная интеграция убивает ERP так же эффективно, как прямой коннектор. Просто агония длится чуть дольше.
Оставался единственный инженерно правильный, хотя и более дорогой в разработке путь — асинхронные очереди.
Когда мы в Morana Labs катили систему предиктивного пополнения складов для промышленного холдинга, мы уже не играли в рулетку с REST API. Мы поставили RabbitMQ как жесткий буфер между ERP и нейросетями. Архитектура перевернулась. 1С больше не ждёт ответа. При записи документа формируется легковесное событие: «Документ изменён, вот JSON с базовыми реквизитами». Это событие улетает в брокер. Сетевой вызов отрабатывает за 5 миллисекунд, и транзакция в 1С успешно завершается. Учётная система свободна, она может обрабатывать следующего пользователя.
Модель на стороне Python спокойно выгребает эти события. И вот здесь вступает в игру батчинг. Нельзя загружать тензор в GPU на каждый чих — вы получите чудовищный оверхед на передачу данных по шине PCIe. Наш сервис-воркер собирает микробатчи: мы ждём 50 миллисекунд или накопления 256 сообщений. Собранный батч конвертируется в матрицу, пролетает через инференс за те же 10 миллисекунд, и сервис отправляет пачку ответов в топик результатов.
Слабая связанность решает проблему производительности, но порождает логический кошмар — гонку данных. Асинхронность означает, что между отправкой запроса на скоринг и получением результата проходит время. Пусть это даже половина секунды. За эти 500 миллисекунд живой человек мог передумать, открыть тот же документ, изменить сумму контракта и нажать «Записать». Если ML-сервис слепо запишет свой ответ в базу, он перетрёт ручные изменения или зафиксирует скоринг, рассчитанный для неактуальной суммы.
Как встроить результат, не разрушив консистентность?
def apply_ml_scoring(message: RabbitMessage, db_session):
current_state = fetch_1c_document_metadata(message.doc_id)
if current_state.version != message.source_version:
log.warning(f"Race condition for {message.doc_id}. Doc mutated. Dropping ML update.")
metrics.inc("ml_write_rejected_race")
return
payload = {
"doc_id": message.doc_id,
"score": message.score_value,
"inference_id": message.request_id,
"idempotency_key": message.hash_key
}
send_to_1c_ml_register(payload)Правило выживания номер один: никогда не изменяйте сам исходный документ 1С извне. Создайте в 1С отдельный независимый регистр сведений, назовите его условно «РезультатыMLСкоринга». Пусть ML-модель пишет данные только туда. Документ или форма в 1С просто читают этот регистр. Если человек изменил данные, версия объекта (DataVersion) обновляется. Сервис интеграции видит несовпадение хешей и просто отбрасывает вычисленный результат, инициируя новый цикл пересчёта. Влетает дубль сообщения из-за сетевого сбоя? Идемпотентность по ключу на стороне 1С тихо погасит вторую запись. Упал коннект при обновлении? Брокер автоматически сделает ретрай.
Остаётся вопрос: где брать тяжелые признаки? Модели часто нужно знать оборот контрагента за последние три года, средний чек, частоту возвратов. Если вы начнёте собирать этот датасет прямыми запросами к боевой базе 1С прямо во время инференса, вы вернётесь к тому, с чего начали — убьёте дисковую подсистему мастера. Решение — изоляция аналитической нагрузки. Поднимается асинхронная реплика PostgreSQL. Мастер-база 1С обрабатывает только короткие транзакции (OLTP). ML-инфраструктура нарезает фичи исключительно с реплики. Да, реплика может отставать на пару секунд. Но для 99% задач индустриального машинного обучения факт того, что клиент купил гвозди две секунды назад, не влияет на его кредитный скоринг, рассчитываемый по трехлетней истории.
Защитив железо, вы неизбежно столкнётесь с корпоративной безопасностью. Когда нейросеть начнёт отклонять отгрузки на миллионы рублей, к вам придут суровые люди из службы аудита. Учётная система тем и отличается от портала с котиками, что требует железобетонного лога: кто, когда и на каком основании принял решение. Аудит требует строгой архитектуры:
- Каждый сервис, который пишет данные в 1С, обязан проходить аутентификацию по JWT, чтобы отслеживать, какой именно под или контейнер сделал изменение.
- В каждую запись результата в 1С вклеивается уникальный идентификатор инференса.
- В ELK или ClickHouse по этому ID навечно сохраняется полный вектор входных фичей и вероятностное распределение выхода.
Если через год аудит спросит, почему этому ООО дали огромную скидку, вы достанете идентификатор из документа 1С, поднимете логи и покажете точный срез данных, на которые смотрела модель в тот миллисекундный срез времени.
Тесная синхронная интеграция всегда выглядит заманчиво на этапе MVP. Она дешевле, требует меньше серверов и быстрее выкатывается. Но это иллюзия контроля. Вы экономите две недели работы архитекторов, но расплачиваетесь хрупкостью. Разработчики ERP переименовали реквизит — модель упала с ошибкой сериализации. Переделали логику проведения — модель начала питаться мусорными данными. Чтобы отслеживать такие разъезжающиеся контракты данных и деградацию распределения, вам нужна полноценная инфраструктура MLOps, которая заалертит о дрифте входных фичей до того, как неверный прайсинг сожжёт маржу за месяц.
Мы выстроили стену из очередей, изолированных реплик, регистров сведений и жесткого версионирования. Система масштабировалась, держала поток в сотни тысяч документов в сутки и больше ни разу не зацепила продуктивную транзакционную базу. Но тот холодный пот, когда логистический хаб намертво встал из-за одной блокировки в СУБД, останется со мной навсегда. Интегрируйте ИИ в энтерпрайз так, будто ERP-система обязательно попытается вас убить. Потому что она попытается.