Скармливаем казахскую первичку в Document AI: Как мы автоматизировали ад бухгалтера
Конец месяца в любой казахстанской компании — это время, когда в офисе витает запах кофе, корвалола и ненависти к бумаге. Бухгалтеры, как операторы матричных станций, без остановки вбивают в 1С бесконечный поток первички: акты выполненных работ (АВР), накладные (З-2), счета-фактуры и квитанции. Каждый документ — это минное поле. Поставщик распечатал АВР из кривой ERP-системы, курьер помял его в рюкзаке, а сверху шлепнули жирную синюю печать прямо на БИН компании. Знакомая картина?
Автоматизировать ввод первички пытались многие. На рынке существуют десятки решений, обещающих "мгновенное распознавание". Но реальность сурова. В этой статье мы, инженеры OZAT, расскажем, почему классический шаблонный OCR мертв для казахстанских реалий, и покажем, как мы решили эту проблему раз и навсегда с помощью нейросетей, компьютерного зрения и Google Cloud Document AI.
Почему классический OCR — это боль и страдания?
Исторически автоматизация ввода документов строилась на базе оптического распознавания символов (OCR) — таких движков, как Tesseract или коммерческий Abbyy FineReader. Подход выглядит просто: сканируем документ, получаем полотно текста, а затем натравливаем на него регулярные выражения (RegEx). Ищем слово "БИН", берем 12 цифр после него. Ищем слово "Итого", берем сумму. Что может пойти не так?
Всё. Казахстанская первичка — это хаос, который невозможно загнать в шаблоны.
- Проблема смещения: Шаблонные OCR-системы привязываются к координатам. Стоит бухгалтеру отсканировать лист чуть криво (под углом 5 градусов) — и координаты "едут". Поле "Сумма" внезапно распознается как "Количество".
- Адская синяя печать: Это классика. В Казахстане обожают ставить круглую синюю печать ровно на табличную часть или реквизиты. Для Tesseract синие буквы поверх черных цифр превращаются в месиво из пикселей. БИН "123456789012" превращается в "1234S6?89G12". Регулярное выражение падает.
- Разнообразие форм: Даже стандартная форма АВР (Приложение 50) умудряется выглядеть по-разному в разных учетных системах. Разная ширина колонок, разные шрифты, кто-то добавляет свои поля. Написать универсальный RegEx для табличной части, которая может переноситься на вторую страницу — это задача, от которой седеют бэкенд-разработчики.
В результате, классические OCR-системы в проде дают в лучшем случае 60% точности. Бухгалтеру приходится перепроверять каждый отсканированный документ, исправлять ошибки и ругаться на "тупых программистов". Смысл автоматизации теряется.
Смена парадигмы: Google Cloud Document AI
Поняв, что регулярки и шаблоны ведут в тупик, мы обратили внимание на Document AI от Google Cloud Platform. В отличие от тупого OCR, Document AI — это не просто извлекатель текста. Это мультимодальная нейросеть, которая понимает пространственный и визуальный контекст документа.
Что это значит на практике? Нейросеть смотрит на PDF-файл так же, как человек. Если она видит 12-значный номер в верхнем правом углу, рядом с названием юридического лица, она понимает, что это БИН, даже если само слово "БИН" залито кофем или перекрыто печатью. Ей не нужны строгие координаты. Она анализирует топологию, структуру таблиц, шрифты и взаимосвязь элементов.
Архитектура решения: Custom Extractor под наши реалии
В Document AI есть готовые парсеры (Invoice Parser, Receipt Parser), но они обучены на американских и европейских стандартах. Они отлично понимают Invoice, но пасуют перед нашей Накладной З-2. Поэтому мы использовали Custom Extractor — инструмент, позволяющий обучить собственную Foundation Model от Google на ваших специфичных документах.
Процесс состоял из нескольких инженерных шагов:
1. Разметка данных (Data Labeling) прямо в облаке
Для начала нам понадобился датасет. Мы взяли 200 реальных казахстанских АВР и Накладных (с печатями, подписями, кривыми сканами и артефактами). Загрузили их в Cloud Storage. Затем в консоли Document AI открыли встроенный инструмент разметки.
Задача разметчика — выделять bounding boxes (прямоугольники) вокруг нужных данных и присваивать им классы (сущности). Мы определили следующие сущности:
supplier_name(Название поставщика)supplier_bin(БИН поставщика)invoice_date(Дата документа)total_amount(Итоговая сумма)line_items(Родительская сущность для табличной части)item_name(Наименование работы/услуги)item_quantity(Количество)item_price(Цена)item_amount(Сумма)
2. Обучение модели (Fine-Tuning)
Разметив 150 документов для обучения (Training set) и 50 для тестирования (Test set), мы запустили процесс тренировки. Google Cloud берет свою предобученную мощную LLM-модель (Foundation Model), которая уже понимает, что такое "документ", "таблица" и "текст", и дообучает её веса под наши конкретные классы.
Обучение заняло несколько часов. Когда мы посмотрели на Evaluation Metrics, результаты нас поразили. F1 Score (гармоническое среднее между точностью и полнотой) для БИН составил 0.98, а для табличных строк — 0.95. Модель научилась безошибочно вытаскивать товары из многостраничных накладных, игнорируя синие печати и подписи!
От стартапа в Astana Hub до Enterprise: почему архитектуру нужно закладывать правильно с первого дня
3. Интеграция с бэкендом и 1С
Обученная модель (Processor) была задеплоена и получила свой уникальный Endpoint в GCP. Теперь нам нужно было связать её с учетной системой клиента — 1С:Предприятие.
Архитектура продакшена выглядит так:
- Секретарь кладет пачку первички в сканер. Сканер по FTP отправляет PDF-файлы на наш микросервис (написанный на Node.js).
- Микросервис, крутящийся в бессерверной среде Cloud Run, получает PDF и по gRPC отправляет его в API Document AI.
- Document AI возвращает гигантский JSON (содержащий текст, сущности, геометрию, уверенность распознавания).
- Наш микросервис парсит этот JSON (код приведен ниже), собирает аккуратный объект данных и отправляет его по HTTP/REST в опубликованный веб-сервис 1С.
- В 1С автоматически создается документ "Поступление ТМЗ и Услуг", прикрепляется PDF-файл, и бухгалтеру остается только нажать кнопку "Провести".
Магия в коде: Парсим ответ от Document AI
Самое сложное при работе с Document AI — это парсинг его ответа. API возвращает не просто текст, а сложную графовую структуру. Вот как мы написали обработчик на Node.js для вытаскивания таблиц и шапки документа:
const { DocumentProcessorServiceClient } = require('@google-cloud/documentai').v1;
const client = new DocumentProcessorServiceClient();
async function parseKazakhInvoice(projectId, location, processorId, filePath) {
// Указываем путь к нашему Custom Extractor процессору в Google Cloud
const name = `projects/${projectId}/locations/${location}/processors/${processorId}`;
const fs = require('fs').promises;
const imageFile = await fs.readFile(filePath);
const request = {
name,
rawDocument: {
content: Buffer.from(imageFile).toString('base64'),
mimeType: 'application/pdf',
},
};
// Отправляем скан на обработку в Document AI
console.log('Отправка документа в Document AI...');
const [result] = await client.processDocument(request);
const document = result.document;
const extractedData = { items: [] };
// Функция для безопасного извлечения текста по якорям (Text Anchors)
const getText = (textAnchor) => {
if (!textAnchor || !textAnchor.textSegments || textAnchor.textSegments.length === 0) return '';
let text = '';
for (const segment of textAnchor.textSegments) {
const startIndex = segment.startIndex || 0;
const endIndex = segment.endIndex;
text += document.text.substring(startIndex, endIndex);
}
return text.trim();
};
// Парсинг извлеченных сущностей
for (const entity of document.entities) {
const entityType = entity.type;
const entityValue = entity.mentionText || getText(entity.textAnchor);
// Собираем шапку документа
if (entityType === 'supplier_bin') extractedData.bin = entityValue;
if (entityType === 'total_amount') extractedData.totalAmount = entityValue;
if (entityType === 'invoice_date') extractedData.date = entityValue;
// Парсим табличную часть (Вложенные сущности / Line Items)
if (entityType === 'line_items' && entity.properties) {
for (const item of entity.properties) {
let row = {};
for (const prop of item.properties) {
// Вытаскиваем наименование, количество, цену и сумму
row[prop.type] = prop.mentionText || getText(prop.textAnchor);
}
extractedData.items.push(row);
}
}
}
console.log('Успешно распознано:', JSON.stringify(extractedData, null, 2));
return extractedData;
}
// Пример вызова:
// parseKazakhInvoice('my-gcp-project', 'eu', 'a1b2c3d4e5f6', './nakladnaya.pdf');Смотреть код на GitHub (OZAT-kz)
Обратите внимание на функцию getText(textAnchor). Это важнейший паттерн при работе с Document AI. Нейросеть возвращает не всегда готовый текст сущности (mentionText), а часто указывает "индексы" (start/end) в глобальном массиве текста документа. Мы должны сами "вырезать" нужный кусок текста по этим координатам. Это позволяет избежать потери данных при сложных форматированиях.
Результаты и ROI: Цифры говорят за себя
До внедрения системы, отдел бухгалтерии из 4 человек тратил суммарно около 40 человеко-часов в неделю только на ручной ввод первичных документов от сотен поставщиков. Это была монотонная, изнуряющая работа, приводящая к неизбежным опечаткам (перепутали цифру в сумме, указали не тот БИН).
Время обработки 1000 накладных (в часах)
Попытка внедрить коробочный OCR на базе регулярных выражений сократила время до 15 часов, но добавила новую боль: бухгалтеры тратили нервы на ручное исправление неверно распознанных копеек и "съехавших" таблиц.
Переход на Google Cloud Document AI (Custom Extractor) изменил всё. Время обработки 1000 документов сократилось до 30 минут машинного времени. Бухгалтеру больше не нужно ничего вбивать. Документ появляется в 1С сам. Человек выступает лишь в роли контролера, который глазами пробегается по цифрам и нажимает "ОК".
Резюме
Эра ручного ввода данных и хрупких регулярных выражений официально завершена. Использование Foundation Models и компьютерного зрения в облаке — это уже не "инновации для гиков", а насущная необходимость для бизнеса, который хочет расти.
Google Cloud Document AI доказал, что способен "переварить" даже самую суровую казахстанскую первичку: с синими печатями, подписями поверх текста, кривым сканированием и нестандартными шаблонами. Да, обучение Custom Extractor требует времени и понимания ML-процессов, но ROI (окупаемость инвестиций) этой архитектуры исчисляется месяцами, а сэкономленные нервы бухгалтеров — бесценны.
Если ваша компания всё ещё тонет в бумагах, а отдел ввода данных разрастается — приходите в OZAT. Мы покажем, как заставить нейросети работать на вашу бухгалтерию.
💡 Совет OZAT: Готовы к внедрению? Рассчитайте архитектуру и бюджет через Scope Builder или пройдите бесплатный ИИ-аудит.

Рустам Шарафутдинов
Эксперт в области архитектуры Google Cloud и Senior Full-Stack разработчик с более чем 15-летним опытом. Специализируется на отказоустойчивых архитектурах, оптимизации высоконагруженных проектов и интеграции AI (Vertex AI).