· 15 мин чтения

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

Схема, которую мы используем как базовую (расширяем под особенности учёта конкретного клиента — мультивалюта, несколько юрлиц в одной базе):

{ "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

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