n8n + LLM-агент: автоматизация обработки счетов для 1С — АйТи Фреш
· 15 мин чтения

n8n + LLM-агент: как я убрал ручной ввод входящих счетов из 1С

n8n + LLM-агент: как я убрал ручной ввод входящих счетов из 1С

Каждый второй клиент с парком до 50 рабочих мест рассказывает нам одну и ту же историю: счета от поставщиков падают на почту, бухгалтер вручную забивает их в 1С, и часть просто тонет в потоке входящих. Знакомо? Мы собрали конвейер на n8n с LLM-агентом на Claude — он читает вложение, сам создаёт черновик поступления в 1С и напоминает об оплате. Разбираю схему узел за узлом: конфиги, пороги, грабли — всё как есть.

Зачем мы вообще взялись за это

Компания на 20–40 рабочих мест. Бухгалтер получает 15–30 счетов в месяц — PDF-вложения, сканы, иногда фото прямо со смартфона поставщика. Каждый нужно открыть, вычитать реквизиты, найти или создать контрагента в 1С, внести строки табличной части, проверить НДС и не забыть про срок оплаты. А теперь представьте это в период закрытия месяца или когда кто-то в отпуске. Часть счетов просто оседает в папке «Входящие» и всплывает только тогда, когда поставщик звонит с претензией по просрочке.

Мы не стали предлагать клиентам ЭДО-интеграцию как единственный выход — она решает вопрос только с теми контрагентами, кто на неё перешёл, а это меньшинство. Вместо этого мы построили конвейер, который работает с обычной почтой: письмо приходит на выделенный ящик invoices@клиент.ru, автоматика читает вложение, извлекает данные через LLM и кладёт в 1С черновик документа «Поступление товаров и услуг» — бухгалтеру остаётся проверить и провести. Плюс отдельный контур следит за сроками оплаты и сам шлёт напоминания.

Дальше — не пересказ чужого туториала. Это наша рабочая схема: разворачиваем её клиентам на выделенном контейнере с самостоятельным n8n и Claude API в роли LLM-агента.

Архитектура: пять узлов между почтовым ящиком и проводкой в 1С

Конвейер мы делим на короткие изолированные шаги — намеренно. Один гигантский workflow с AI-нодой в центре выглядит монолитно, но отлаживать его — боль, и переиспользовать куски под разных клиентов почти невозможно. В n8n у нас пять логических блоков, каждый живёт в отдельном workflow. Общаются они через Execute Sub-workflow или через Webhook.

БлокКлючевая нода n8nРоль
1. Приём письмаEmail Trigger (IMAP), тип n8n-nodes-base.emailReadImapСлушает ящик invoices@, скачивает вложения, фильтрует мусор
2. Подготовка документаCode (JavaScript) + SwitchОпределяет тип файла, кодирует в base64, готовит content-блок для LLM
3. Извлечение данныхAI Agent (n8n-nodes-langchain.agent) + Anthropic Chat Model + Structured Output ParserВозвращает строгий JSON с реквизитами счёта
4. Валидация и мэтчингCode + HTTP Request (OData/HTTP-сервис 1С)Проверяет ИНН, ищет контрагента, отсекает дубли
5. Запись в 1С + напоминанияHTTP Request (создание документа) + Schedule Trigger (напоминания)Создаёт черновик поступления, следит за сроком оплаты

Каждый блок пишет свой результат в отдельную таблицу Postgres — поднимаем её тем же docker-compose, что и сам n8n. Получается полный аудиторский след: какое письмо пришло, какой JSON вернула модель, что и с каким статусом легло в 1С. Когда что-то идёт не так, сразу видно на каком шаге.

Приём письма: Email Trigger (IMAP) и фильтрация шума

Мы заводим клиенту отдельный почтовый ящик под счета — не общий бухгалтерский, чтобы триггер не реагировал на переписку и рекламные рассылки. В ноде Email Trigger (IMAP) настройки такие: Mailbox: INBOX, доступ по IMAP через TLS на порту 993, аутентификация — пароль приложения (не основной пароль ящика). В секции Options критично включить Download Attachments: true и выставить Format: Resolved — только в этом режиме вложения приходят как готовые бинарные данные, а не как base64-строка внутри RAW-сообщения, которую пришлось бы парсить вручную.

Отдельная головная боль — дубли и мусор. Мы вешаем на ноду custom email rule по критериям IMAP-поиска: UNSEEN плюс проверку темы/отправителя через дополнительный Filter сразу после триггера (тема содержит «счёт», «invoice», «акт», либо вложение с расширением pdf/jpg/png). Post-processing action ставим в «пометить прочитанным» только после успешного считывания — иначе при перезапуске workflow n8n возьмёт то же письмо повторно и создаст дубль поступления.

Polling-интервал — 60 секунд. При потоке в 20–40 писем в месяц гонять опрос чаще просто незачем, а лишняя нагрузка на IMAP-сервер клиента нам не нужна.

Из PDF и скана — в данные, понятные модели

Отдельный OCR-слой — Tesseract, Yandex Vision и подобные — мы сюда намеренно не тащим. Современные модели Claude принимают PDF и изображения напрямую как content-блок сообщения: текст, таблицы, рукописные пометки — всё разбирается внутри одного запроса. Это убирает целый класс ошибок распознавания, которые возникают на стыке двух систем, и заметно упрощает конвейер.

Code-нода перед вызовом агента делает три вещи. Проверяет MIME-тип вложения: PDF, JPEG, PNG проходят дальше, остальное уходит в очередь на ручную обработку. Конвертирует бинарные данные в base64. Собирает JSON-блок нужного формата — для PDF это document-блок, для фото-скана image-блок.

{ "role": "user", "content": [ { "type": "document", "source": { "type": "base64", "media_type": "application/pdf", "data": "{{ $binary.attachment_0.data }}" } }, { "type": "text", "text": "Извлеки реквизиты счёта по схеме invoice_schema." } ] }

Есть практическое ограничение по объёму вложения на один запрос — по документации Anthropic счёт идёт на десятки страниц и порядка 30 МБ на файл. Нам этого с запасом хватает: многостраничных счетов от 50 листов у наших клиентов не встречалось. Если письмо приходит вообще без вложения, а реквизиты и сумма просто в теле письма — прогоняем через ту же модель текст письма вместо документа. Агент один и тот же, меняется только content-блок.

LLM-агент: извлечение структурированных данных

Это сердце конвейера. Нода AI Agent (Tools Agent) со связанным Anthropic Chat Model и Structured Output Parser на выходе. Вольный текстовый ответ мы агенту не разрешаем — Structured Output Parser принудительно приводит результат к JSON-схеме. Без этого на стороне 1С пришлось бы выдирать поля регуляркой из свободного текста. А это прямой путь к тихим ошибкам, которые всплывают в самый неудобный момент.

Базовая JSON-схема, которую мы используем как стартовую точку. Под особенности учёта конкретного клиента расширяем — мультивалюта, несколько юрлиц в одной базе и так далее.

{ "type": "object", "properties": { "supplier_name": {"type": "string"}, "supplier_inn": {"type": "string"}, "supplier_kpp": {"type": "string"}, "invoice_number": {"type": "string"}, "invoice_date": {"type": "string", "format": "date"}, "due_date": {"type": ["string", "null"]}, "currency": {"type": "string"}, "total_with_vat": {"type": "number"}, "vat_amount": {"type": "number"}, "vat_rate": {"type": "string", "enum": ["20", "10", "0", "без НДС"]}, "line_items": { "type": "array", "items": { "type": "object", "properties": { "name": {"type": "string"}, "qty": {"type": "number"}, "unit_price": {"type": "number"}, "amount": {"type": "number"} } } }, "confidence": {"type": "number"} }, "required": ["supplier_inn", "invoice_number", "total_with_vat", "confidence"] }

Поле confidence модель заполняет сама по инструкции в системном промпте: «оцени от 0 до 1, насколько уверенно ты прочитал реквизиты; если качество скана низкое или часть полей рукописная — снижай оценку». Порог мы ставим на уровне 0.85: всё, что ниже — не идёт в 1С автоматически, а падает в отдельную очередь на ручную проверку бухгалтером (у нас это лист Google Sheets с ссылкой на письмо и распознанный JSON рядом).

Одна модель на всё — не наш подход. Базовую экстракцию гоняем на более лёгкой и дешёвой модели. Если уверенность низкая или сумма счёта выше заданного порога — переключаемся на модель помощнее.

СценарийМодельПочему
Чистый PDF-счёт, стандартный шаблонClaude Haiku 4.5Дешевле и быстрее, точности достаточно на структурированных PDF (оценка по нашей практике)
Скан низкого качества / рукописные пометкиClaude Sonnet 5Выше точность распознавания на «грязных» изображениях
Confidence < 0.85 при первом проходеПовторный запрос на Sonnet 5Второй проход другой моделью снижает риск систематической ошибки одной модели
Счета выше согласованного с клиентом лимита суммыSonnet 5 + обязательная ручная проверкаФинансовый риск важнее экономии на токенах

Переключение моделей в n8n технически — это просто параметр Model в ноде Anthropic Chat Model. Передаём его через выражение в зависимости от результата первой Code-ноды, которая проверяет тип файла и считает эвристику качества.

Валидация, мэтчинг контрагента и защита от дублей

JSON от модели — это гипотеза, а не факт, поэтому дальше идёт слой чистой валидации на Code-ноде без единого обращения к LLM: проверка контрольной суммы ИНН (10 знаков для юрлица, 12 — для ИП, с проверкой контрольных разрядов по стандартному алгоритму ФНС), проверка что total_with_vat = сумма строк + vat_amount с точностью до рубля, проверка что invoice_date не в будущем и не старше разумного срока давности.

Дальше — поиск контрагента. HTTP Request-нода обращается к OData-интерфейсу базы 1С с фильтром по ИНН: GET /base/odata/standard.odata/Catalog_Контрагенты?$filter=ИНН eq '{{ $json.supplier_inn }}'. Если запись найдена — берём её Ref для документа поступления. Если нет — не создаём контрагента автоматически «на лету»: помечаем документ флагом «новый контрагент, требуется проверка» и подставляем реквизиты из JSON как заготовку, финальное решение — за бухгалтером. Это осознанное ограничение: справочник контрагентов — не то место, где хочется автоматических вставок без контроля.

От дублей защищаемся хэшем по связке ИНН + номер счёта + сумма. При каждой успешной обработке пишем хэш в отдельную таблицу Postgres. Перед созданием документа в 1С проверяем: не встречался ли уже такой хэш за последние 90 дней. Это ловит и повторно пересланные письма, и ситуацию, когда поставщик присылает один и тот же счёт с почты и через WhatsApp-пересылку на тот же ящик.

Хотите такой же конвейер для своей 1С

Мы разворачиваем этот конвейер под ключ: свой n8n на выделенном контейнере, HTTP-сервис на стороне вашей 1С, настройка порогов и напоминаний под ваш учёт. Если у вас входящие счета до сих пор набиваются вручную — напишите нам, посмотрим на ваш поток писем и оценим, сколько процентов можно снять с бухгалтера уже в первый месяц.

Запись черновика поступления в 1С

Здесь у нас принципиальный выбор — отдельный HTTP-сервис 1С вместо голого OData для создания документа. OData хорошо работает для чтения и простых справочников. Но документ «Поступление товаров и услуг» с табличной частью «Товары» через стандартный OData-интерфейс — это отдельный POST на каждую строку табличной части после создания шапки. Лишние round-trip'ы плюс реальный риск получить документ с частично заполненной табличной частью, если сеть упадёт посреди пачки запросов. Поэтому мы пишем клиенту простой HTTP-сервис прямо на встроенном языке 1С — модуль HTTP-сервиса, метод POST. Он принимает один JSON целиком и создаёт документ одной транзакцией.

СпособПлюсыМинусыКогда используем
Стандартный ODataНичего писать в 1С не нужно, работает из коробкиТабличная часть — отдельные запросы, нет бизнес-валидации на стороне 1СЧтение справочников, простые документы без табличных частей
Свой HTTP-сервисОдин запрос — весь документ, можно встроить бизнес-логику и статус «черновик»Требует разработки и поддержки на стороне 1СДокументы с табличными частями: поступления, реализации

Вот пример тела запроса, который отправляет HTTP Request-нода на наш эндпоинт:

POST /base/hs/invoice_import/create HTTP/1.1 Content-Type: application/json { "Контрагент": "00000012-3456-7890-abcd-000000000001", "НомерВходящегоСчета": "АА-1042", "ДатаСчета": "2026-07-01", "Организация": "ООО Клиент", "ВалютаДокумента": "RUB", "СуммаСНДС": 184320.00, "СтавкаНДС": "20", "Товары": [ {"Номенклатура": "Бумага офисная А4", "Количество": 50, "Цена": 350.00, "Сумма": 17500.00}, {"Номенклатура": "Картриджи HP 05A", "Количество": 8, "Цена": 4200.00, "Сумма": 33600.00} ], "Проведён": false, "Комментарий": "Создано автоматически из письма, требует проверки бухгалтера" }

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

Напоминания об оплате и эскалация

Отдельный, независимый от приёма писем workflow с нодой Schedule Trigger по расписанию (у нас — по будням в 9:00 по Москве, cron-выражение 0 9 * * 1-5) опрашивает 1С через OData на предмет непроведённых и проведённых, но неоплаченных поступлений с приближающимся сроком оплаты. Срок оплаты (due_date) мы либо берём напрямую из счёта, если модель его распознала, либо вычисляем по правилу «дата счёта + отсрочка по договору с этим контрагентом» — отсрочку храним в отдельном регистре сведений в 1С, который заполняется один раз при заведении контрагента.

Пороги эскалации мы настраиваем под каждого клиента отдельно. Обычно схема выглядит так: за 3 дня до срока — напоминание ответственному бухгалтеру в Telegram. В день срока — снова напоминание, плюс копия уходит руководителю. А если просрочка перевалила за 2 дня — отдельное сообщение с пометкой «критично», и сразу вся сумма по всем счетам этого контрагента: чтобы не проморгать риск блокировки поставки.

Технически это HTTP Request к Telegram Bot API или к обычному email-каналу — зависит от того, чем клиент уже пользуется. Сообщение компактное, без вложений. Внутри — ссылка на карточку документа в веб-клиенте 1С, чтобы провести оплату буквально в одно касание.

Что это даёт на практике и где граница автоматизации

На наших текущих внедрениях около 70-80% счетов проходят весь путь без единой ручной правки реквизитов — только финальное подтверждение проведения документа. Это не строгий бенчмарк, а практическая оценка. И она сильно плавает в зависимости от того, насколько разношёрстные шаблоны счетов у поставщиков конкретного клиента. Оставшиеся 20-30%? Низкое качество сканов, нестандартные структуры табличной части, счета на иностранных языках без перевода. Плюс редкие случаи, когда модель уверенно — но неверно — читает рукописные правки прямо на счёте.

Мы намеренно не гонимся за автоматизацией на 100%. Последние проценты стоят непропорционально много в разработке — и не стоят риска пропустить ошибку в проводке. Порог confidence 0.85 и обязательная проверка новых контрагентов — это не технические ограничения. Это осознанная граница: где заканчивается ответственность машины и начинается ответственность бухгалтера.

Что реально измеримо: время от получения письма до появления черновика в 1С сокращается с дней до секунд-минут. Без автоматизации счёт запросто пролежит в почте до конца недели. Для компании с 20-30 счетами в месяц это, честно говоря, не про экономию рабочего времени бухгалтера — счета и так не занимают у него весь день. Это про другое: счета перестают теряться, а просрочки по оплате больше не становятся неприятным сюрпризом.

Частые вопросы

Нужен ли отдельный сервер под n8n или можно обойтись облаком?
Мы разворачиваем n8n self-hosted в Docker на отдельном небольшом VPS клиента или на своей инфраструктуре — так вложения счетов и переписка с LLM не проходят через сторонний облачный тариф n8n Cloud, а ключи от 1С и почты остаются под нашим и клиента контролем. Для потока в 20-40 счетов в месяц хватает минимальной конфигурации: 2 vCPU, 4 ГБ RAM, отдельный контейнер Postgres под очереди и логи выполнения.
Что если скан плохого качества и модель ошибается в цифрах?
Для этого в схеме есть поле confidence и порог 0.85: всё, что ниже, не создаёт документ автоматически, а падает в очередь на ручную проверку с приложенным письмом и распознанным JSON рядом. Дополнительно мы всегда проверяем контрольные разряды ИНН и сверяем сумму строк с итоговой суммой счёта — это ловит ошибки распознавания ещё до похода в 1С, даже если сама модель была излишне уверена.
А если в одной базе 1С несколько юрлиц или разные ставки НДС?
Схема извлечения данных уже включает поле ставки НДС и валюту, а выбор организации-получателя в документе поступления мы завязываем на почтовый ящик, на который пришло письмо — под каждое юрлицо клиента заводим отдельный адрес вида invoices-ооо1@ и invoices-ооо2@, это проще и надёжнее, чем пытаться определить получателя из текста счёта.
Безопасно ли отправлять счета во внешний LLM с точки зрения защиты персональных данных
В счетах поставщиков персональных данных физлиц, как правило, нет — только реквизиты юрлиц (ИНН, КПП, наименование, суммы), что не подпадает под 152-ФЗ. Если в конкретном потоке всё же попадаются данные физлиц (например, счета от ИП с указанием паспортных данных), мы либо исключаем такие вложения из автоматической обработки, либо предварительно согласовываем с клиентом использование внешнего API и фиксируем это в договоре на обработку.
Сколько стоит внедрение и когда оно окупается
Стоимость зависит от готовности инфраструктуры клиента (есть ли уже сервер под n8n, опубликован ли веб-сервис 1С) и от количества особых случаев в потоке счетов — для типового клиента до 50 РМ мы укладываемся в разработку и настройку конвейера за одну-две недели. Окупаемость считаем не в часах бухгалтера, а в снятом риске просрочек оплаты и потерянных счетов — этот риск обычно ощутимее прямой экономии времени.
📄
Скачайте подробный разбор в PDF Кейсы, статистика, типовые ошибки и чек-лист самопроверки — 12 страниц
Скачать PDF

Подпишитесь на разборы ITfresh

Раз в неделю — практичные материалы по ИТ для бизнеса. Без спама, только польза.