Коллеги из бухгалтерии пришли с приземленной задачей – научить искусственный интеллект разбирать счета. В проект мы вписались сразу. Во-первых, работать с прикладными сценариями всегда интересно. Во-вторых, бизнес обеспечивает нас крутыми железками для запуска LLM-ок, и помочь бизнесу избавиться от части рутины – достойный ответный жест. Хотя, признаюсь, на этапе «посмотрите, что искусственный интеллект может сделать» отнеслась к идее скептически. Мне казалось, что бухгалтерские документы давно формируют одни и те же программы, примерно в одних и тех же форматах. В статье расскажу, почему цифровая бухгалтерия часто не такая уж цифровая, и как мы из on-prem LLM и OCR собрали решение для обработки платежных документов, которое передает структурированные данные в 1С. Что из этого получилось – под катом.

Всем привет! Меня зовут Александра Царева, я старший специалист машинного обучения в компании «Инфосистемы Джет».
Сначала я хотела рассказать историю о впечатляющей ИИ-архитектуре или тонкостях дообучения больших языковых моделей. Но, пока в нашей дата-сайентистской башне из слоновой кости достраивается очередной этаж, коллеги из бухгалтерии пришли с более приземленной задачей – научить искусственный интеллект разбирать счета.
В проект мы вписались сразу. Во-первых, работать с прикладными сценариями всегда интересно. Во-вторых, бизнес обеспечивает нас крутыми железками для запуска LLM-ок, и помочь бизнесу избавиться от части рутины – достойный ответный жест.
Хотя, признаюсь, на этапе «посмотрите, что искусственный интеллект может сделать» отнеслась к идее скептически. Мне казалось, что бухгалтерские документы давно формируют одни и те же программы, примерно в одних и тех же форматах. Даже если между компаниями не настроен прямой документооборот, проблем передать файл от контрагента заказчику быть не должно, правда?
А они есть.
В статье расскажу, почему цифровая бухгалтерия часто не такая уж цифровая, и как мы из on-prem LLM и OCR собрали решение для обработки платежных документов, которое передает структурированные данные в 1С. Что из этого получилось – под катом.
Цифровая бухгалтерия, которой не случилосьКогда мы получили тестовый набор счетов, иллюзии о победе цифровизации пропали сами собой.
Счета, которые получали наши бухгалтеры, были разными по виду и формату:
сделанные в древних версиях Excel;
содержащие CID-шрифты;
таблицы, но почему-то в Word;
многостраничные документы;
просто перечисление реквизитов без какой-либо структуры;
собранные в pdf с границами таблиц, расположенных вовсе не так, как нарисовано;
сфотографированные и присланные в JPG или PNG.
Кстати, профильный инструмент для получения данных из счетов у бухгалтеров уже был, но со всем разнообразием документов не справлялся. Он был готов к неким универсальным шаблонам, но не к реальному миру, где у контрагента есть только фотография документа, сделанная в плохом освещении.
Поэтому нашей задачей было создать сервис, который учитывает все «потребности на земле», и его легко можно было подкрутить по обратной связи.
Работать предстояло с коммерчески значимой информацией, поэтому публичные ИИ-агенты нам не подходили. Кроме того, модель нужно было интегрировать с 1С и встроить в контролируемый внутренний контур. Поэтому мы выбрали собственную on-prem LLM. Документы не покидают инфраструктуру компании, а результат обработки сразу уходит дальше по пайплайну.
Как мы превратили зоопарк документов в данные для LLMПервой по каталогу примеров прошлась наша внутренняя модель. Она помогла быстро собрать необычные случаи, на которых стандартная обработка наверняка споткнулась бы. Затем мы подготовили предобработку для разных форматов и стали приводить содержимое документов к Markdown.
На вход LLM теперь поступал не исходный Word или PDF, а текст с сохранённой структурой. Таблицы оставались таблицами, абзацы – абзацами, а разрозненные фрагменты реквизитов не превращались в одну длинную строку. Такой промежуточный формат упростил промпт и сделал поведение модели более предсказуемым.
Но навести порядок только в формате оказалось недостаточно. Реквизиты в счетах могут стоять в таблице, идти строкой после названия компании или прятаться в неожиданном месте. Иногда поле уезжает из-за дефекта PDF-формы, а иногда документ просто заполняют, мягко скажем, очень творческие люди.
Мы решили не пытаться заранее нормализовать каждый возможный вариант. Вместо этого «рассказали» модели всё, что ей нужно знать о российских бухгалтерских счетах.
В дело пошла методичка про бухучет и помощь внешнего ИИ-ассистента:
типичные сокращения, которые могут встретиться (например, (к/с = корреспондентский счёт, р/с = расчётный счёт),
какие бывают реквизиты, как их могут сокращать и какие ожидаемые значения по цифрам там могут быть,
отдельные ролевые инструкции, касающиеся входных данных — предупреждения о том, что они «сырые», что могут встречаться таблицы, что это бухгалтерские документы и т.п.,
типовые места, где могут скрываться реквизиты выставившего счет или получателя, но при этом не называться так впрямую,
и подробное описание, какой структурированный JSON должна вернуть модель в результате.
JSON стал контрактом между моделью, нашим API и 1С. Такой контракт не делает ответ LLM автоматически правильным, зато даёт сервису понятную точку контроля. Можно проверить структуру и разобрать поля. Затем сервис решает, что делать с ошибкой, прежде чем она попадёт в учётную систему.
Почему одного ответа модели недостаточноПосле LLM начиналась менее эффектная, но не менее важная часть пайплайна — жёсткие проверки. Ответ модели забирала 1С, поэтому принцип «выглядит правдоподобно» нам не подходил – ошибка в реквизитах превращается в проблему с реальным платежом.
Сначала решение собирало JSON и проверяло его формально. Все поля должны иметь ожидаемый тип, обязательные значения не могут пропадать, а реквизиты нужно хранить строками. Последнее особенно важно: модели попроще любят превращать номер в число и терять нули в начале.
На это мы напоролись, когда меняли языковую модель. Наши первые эксперименты были с qwen3-thinking-30b-a3b, но для продуктива мы в итоге выбрали openai/gpt-oss-120b.
Она чуть хуже по качеству «размышлений», из-за чего и произошел забавный момент с неожиданными багами. Я не сразу сообразила, что бухгалтерские реквизиты не всегда число, а регионы могут начинаться с 0. Qwen считал это само собой разумеющимся и всегда возвращал реквизиты как string.
После переключения модели gpt-oss решила, что это вообще-то не строка, а число. А так как моих бухгалтерских знаний в типизации не хватало, часть реквизитов завалилась. Баг мы быстро нашли и починили. Но ценой бесконечной контекстной рекламы бухгалтерских курсов.
Дальше, если ответ не проходил проверку, сервис выбирал один из трёх сценариев. Безнадёжный результат отклонял, исправимый отправлял на повторное извлечение, а для локальной ошибки запускал вспомогательный вызов LLM. Так мы не гоняли весь документ заново там, где достаточно поправить одно поле.
Затем подключалась предметная проверка. Вместе с коллегами мы перенесли в код правила из той же бухгалтерской методички. Функции проверяли контрольные суммы, длину значений, допустимые коды и связи между разными реквизитами.
В самих проверках нет ничего сложного, но если делаете похожего ассистента, может пригодиться:
# Сначала проверяем, что это только цифры, и вычищаем возможные дефекты от OCR
def _digits(value: Optional[object]) -> Optional[str]:
if value is None:
return None
v = re.sub(r"\D", "", str(value))
return v or None
# Потом поехали формальные проверки на длину и контрольные суммы
def is_bik(value: Optional[object]) -> bool:
v = _digits(value)
return bool(v) and len(v) == 9
def is_ks(value: Optional[object]) -> bool:
v = _digits(value)
return bool(v) and len(v) == 20
def is_kpp(value: Optional[object]) -> bool:
v = _digits(value)
return bool(v) and len(v) == 9
def _inn_checksum_10(inn10: str) -> int:
w = [2, 4, 10, 3, 5, 9, 4, 6, 8]
s = sum(int(d) * w[i] for i, d in enumerate(inn10[:9]))
return (s % 11) % 10
def _inn_checksum_12_c11(inn12: str) -> int:
w = [7, 2, 4, 10, 3, 5, 9, 4, 6, 8, 0]
s = sum(int(inn12[i]) * w[i] for i in range(10))
return (s % 11) % 10
def _inn_checksum_12_c12(inn12: str) -> int:
w = [3, 7, 2, 4, 10, 3, 5, 9, 4, 6, 8]
s = sum(int(inn12[i]) * w[i] for i in range(11))
return (s % 11) % 10
def is_inn(value: Optional[object]) -> bool:
v = _digits(value)
if not v:
return False
if len(v) == 10:
return int(v[-1]) == _inn_checksum_10(v)
if len(v) == 12:
c11 = _inn_checksum_12_c11(v)
c12 = _inn_checksum_12_c12(v)
return int(v[-2]) == c11 and int(v[-1]) == c12
return False
def bik_matches_ks(bik: Optional[object], ks: Optional[object]) -> bool:
b = _digits(bik)
k = _digits(ks)
if not b or not k or len(b) != 9 or len(k) != 20:
return False
return k[-3:] == b[-3:]Сделать эти правила слишком строгими тоже нельзя. В потоке встречались не только российские счета, а зарубежные реквизиты устроены иначе. Проверка должна отсеивать чушь для российских банков, но не браковать иностранный документ из-за непривычного формата. На границе между «подозрительно» и «допустимо» пришлось попотеть. Но в итоге на тестовом наборе весь пайплайн в итоге показал 100% точности.
Сканы всё ещё существуют — подключаем OCRКогда сервис научился разбирать текстовые документы, бизнес предложил следующий логичный шаг: добавить сканы и фото в ту же форму. Отсканированный распечатанный счет без текстового слоя – все еще реальность 2026 года. И неудобств от него больше, чем от кривого PDF: даже скопировать реквизиты не получится.
Проще всего перебить «пару цифр» руками. Но человек, который целый день переносит цифры между системами, рано или поздно ошибается. А ещё устаёт и грустит – не лучший результат ИИ-трансформации.
Мы снова пошли по пути максимальной пользы при минимальных технических вложениях. Для оптического распознавания выбрали open-source PaddleOCR. Русский текст он распознавал не идеально, зато с цифрами справлялся приемлемо и не требовал слишком много ресурсов.
Результат OCR мы не отправляли напрямую в 1С. Распознанный текст проходил ту же предобработку, трансформировался в Markdown, затем попадал в LLM и дальше шёл через формальные и предметные проверки. Для таблиц добавили отдельные инструкции, чтобы модель учитывала возможные сдвиги ячеек и потерянные границы.
Так OCR стал ещё одной входной веткой, а не отдельным сервисом со своей логикой. Текстовый PDF начинал путь с парсинга, изображение — с распознавания. После преобразования в Markdown оба маршрута сходились в одном пайплайне.
Что в итогеДальше начинается польза для бэк-офиса. Учётная система находит по реквизитам записи в справочниках, подтягивает договоры и счета, затем формирует платёжные документы. Ручных операций стало меньше, а вместе с ними снизился риск ошибок.
Заявки на основании счетов теперь быстрее попадают в работу. Путь от входящего документа до обработки в 1С стал заметно короче, очень близко к «режиму реального времени».
На продуктиве идеальные 100% точности, конечно, не сохранились. Сервис работает уже полгода, и за это время мы встречали новые ошибки модели. Пока с каждой удавалось разобраться: где-то уточняли знания о бухгалтерии, где-то добавляли простое правило постобработки.
Из этого проекта у нас получился довольно приземлённый рецепт успеха.
Бизнес должен понимать, какую рутину хочет убрать. Коллеги из бэк-офиса лучше всех знают, где теряется время. Если они уже пробовали публичные модели, важно сразу объяснить границы: какие документы можно загружать наружу, а какие должны оставаться внутри.
Разработчики информационных систем должны участвовать с самого начала. LLM без интеграции остается демо-игрушкой. Польза появляется, когда ответ модели попадает в привычный процесс, а не создаёт сотруднику ещё одно окно для копирования данных.
Даже небольшой сервис требует контроля качества. Нужно следить за дрейфом входных документов, балансом ресурсов и точности, обновлениями модели и изменениями в open source.
Соблазн развернуть всё на слабой виртуалке и забыть особенно велик, когда задача выглядит тривиальной. В некотором смысле «каждая домохозяйка может про KDE2 под FreeBSD, используя ChatGPT». Но между эффектной демонстрацией и сервисом, которым пользуются каждый день, лежат проверки, интеграция и сопровождение.
Проект уже начал расти за пределы исходного сценария. Другие подразделения заинтересовались распознаванием счетов и попросили API для тестов. Бухгалтерия обнаружила, что ассистент умеет извлекать полезную информацию даже из договоров. Под этот формат мы его специально не настраивали, но однозначно радуемся.
Впереди у нас новые типы документов, дополнительные проверки и наблюдение за качеством на продуктиве.
Если вы автоматизировали похожую рутину в бухгалтерии или другом бэк-офисе, расскажите в комментариях.
| # | Наименование новости | Тональность | Информативность | Дата публикации |
|---|---|---|---|---|
| 1 | Библиотека искусственного интеллекта для 1С. Назначение. Примеры использования | 0 | 7.88 | 31-07-2026 |
| 2 | От OCR до ADE: как машины научились не просто читать, а понимать документы | 0 | 8.43 | 12-03-2026 |
| 3 | Попытались поставить программу с ИИ в бухгалтерию. Но искуственный интеллект ... | 0 | 3.4 | 28-07-2026 |
| 4 | Сверхразум и закат человеческого труда: почему бухгалтерам и юристам стоит бояться не роботов-уборщиков, а алгоритмов | 0 | 7.78 | 21-07-2026 |
| 5 | Извлечение и обработка требований из документов с помощью NLP-инструментов | 0 | 7.9 | 15-05-2026 |
| 6 | От заявки до оплаты: Сбербанк трансформирует закупочные процессы с помощью ИИ-агентов | 5 | 7 | 05-06-2026 |
| 7 | Как я ML-ку делал | 0 | 9.12 | 01-02-2026 |
| 8 | Добавляем в бизнес-портал Битрикс24 роботов для автоматизации | 0 | 14.6 | 20-03-2026 |
| 9 | Сдерживаем полет фантазии LLM в киносервисе | 0 | 6.59 | 01-07-2026 |
| 10 | Сколково, ИИ и HR: Мы едем в будущее, глядя в ... | 5 | 7 | 01-07-2026 |