Перейти к содержанию

Распознавание через Claude

Модуль claude_client.py реализует единый запрос к языковой модели Claude для анализа страниц документа. В одном запросе выполняются сразу несколько задач: сегментация (определение границ отдельных документов), классификация (определение типа), извлечение реквизитов из содержимого и разбор данных из имени файла.

Общий принцип

Вместо нескольких последовательных запросов к языковой модели (отдельно для сегментации, отдельно для классификации, отдельно для извлечения данных) используется один объединённый запрос. Это снижает общее количество токенов, уменьшает задержку и упрощает согласованность данных между этапами.

Запрос содержит:

  • изображения страниц в формате base64 (с пометкой номера каждой страницы);
  • имя исходного файла;
  • подробную подсказку с пятью задачами и ожидаемым форматом ответа.

Ответ приходит в формате JSON и содержит массив распознанных документов, данные из имени файла и предупреждения.

Выбор модели

Модель Claude определяется в следующем порядке приоритетов:

  1. Явное указание при создании экземпляра клиента (параметр model).
  2. Значение из настроек программы в базе данных (экран «Настройки» → «Модель распознавания»).
  3. Значение переменной окружения CLAUDE_MODEL.

Это позволяет менять модель через интерфейс программы без перезапуска серверной части.

Режим расширенного размышления

Запросы отправляются с включённым режимом расширенного размышления (extended thinking). Бюджет на размышления --- 2048 токенов. Этот режим улучшает качество распознавания рукописного текста и сложных документов, поскольку модель может «подумать» перед тем, как дать окончательный ответ.

Максимальный размер ответа --- 16 000 токенов.

Структура подсказки

Подсказка состоит из пяти разделов-задач, каждая из которых описывает, что именно нужно извлечь.

Задача 1: сегментация

Определение границ каждого отдельного документа на страницах. Модель получает подробные правила:

  • Признаки начала нового документа: шапка или логотип организации в верхней части страницы, заголовок типа документа («Платёжное поручение», «Счёт-фактура», «Акт» и так далее), стандартная форма бланка, две одинаковые формы с разными номерами.
  • Признаки продолжения того же документа: отсутствие новой шапки, нумерация страниц, продолжение таблицы или текста, итоговые строки («Итого по акту»), подписи и печати.

Многостраничный документ представляется как один объект с массивом номеров страниц.

Задача 2: классификация и заголовок

Для каждого документа определяются:

  • Заголовок (doc_title) --- точный заголовок, как он написан в документе.
  • Тип (type) --- нормализованная категория из фиксированного списка.
  • Поворот (rotation) --- угол поворота содержимого (0, 90, 180 или 270 градусов).
  • Подтип (subtype) --- цвет бумаги (желтая, синяя, белая) и качество скана (хорошее, среднее, плохое).

Список поддерживаемых типов документов:

Группа Типы
Платёжные документы платёжное_поручение, счёт_на_оплату
Счета-фактуры счёт-фактура, упд
Акты акт_выполненных_работ, справка_к_акту, акт_расхода_материалов_подрядчика, акт_использования_давальческих_материалов, акт_использования_покупных_материалов, акт_сверки
Судебные и юридические решение_суда, исковое_заявление, претензия, доверенность
Прочие договор, дополнительное_соглашение, накладная, письмо, приложение, неизвестный

Задача 3: реквизиты из содержимого документа

Из изображения каждого документа извлекаются поля:

Поле Описание
number Номер документа (из заголовка, после знака №)
date Дата документа в формате ДД.ММ.ГГГГ
contract_date Дата договора (если указана)
party_1 Первая сторона (продавец, исполнитель, организация в шапке)
party_2 Вторая сторона (покупатель, заказчик, плательщик)
amount Итоговая сумма без НДС (число)
contract Номер договора
system_numbers Массив рукописных бухгалтерских номеров (см. задачу 5)
handwritten_regions Координаты областей с рукописным текстом (в процентах)
oilfields Массив найденных названий месторождений
project_name Название проекта из шапки документа
spp_element СПП-элемент из текста документа
gtd_number Номер грузовой таможенной декларации (для типа «письмо»)
addition_info Содержимое графы «Дополнение» (для счетов-фактур)
linked_documents Массив ссылок на связанные документы
items Массив позиций из таблицы документа

Подсказка содержит подробные инструкции по определению сторон в зависимости от типа документа (в счёте-фактуре party_1 --- продавец, в акте --- исполнитель и так далее). Для внутренних документов (акты расхода материалов) стороны не извлекаются.

Также выполняется валидация дат: дата договора всегда должна быть раньше даты документа. Если обнаружены две даты --- более ранняя считается датой договора.

Задача 4: реквизиты из имени файла

Из имени исходного файла извлекаются (если присутствуют):

Поле Описание
registry_type Тип реестра (D10, D11, R26, R27 и другие)
buh_number Бухгалтерский номер (10--12 цифр, начинается с 42)
spp_element СПП-элемент (начинается с Ю-016 или U016)
contractor Название контрагента
contract Номер договора
date Дата документа
act_number Номер акта

Данные из имени файла хранятся отдельно от данных из содержимого. Это позволяет обнаруживать расхождения и использовать оба источника для обогащения записи документа.

Задача 5: рукописный бухгалтерский номер

Отдельный раздел подсказки посвящён поиску рукописных числовых отметок на документе. Это 10-значные числа, написанные от руки ручкой (обычно синей или чёрной), которые бухгалтерия проставляет на бумажных документах.

Отличительные признаки:

  • неровный почерк, разный наклон цифр;
  • расположение отдельно от печатного текста --- в углах страницы, на полях, под подписями;
  • начинаются с определённых префиксов (42, 49, 51, 54, 52, 46).

Для каждого найденного номера возвращаются координаты области в процентах от размера страницы, что позволяет локализовать надпись на изображении.

Поиск месторождений

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

Подсказка явно указывает модели: использовать только прямые упоминания в тексте, не угадывать месторождение по названию контрагента или другим косвенным признакам.

Если список месторождений в настройках пуст --- модель возвращает пустой массив.

Работа с кириллицей

Поскольку обрабатываемые документы --- российские бухгалтерские документы на русском языке, подсказка содержит специальный раздел с указаниями по работе с кириллицей:

  • Использовать кириллические буквы, а не похожие латинские (Ю, а не IO; В, а не B).
  • Не путать похожие символы: О и 0 (ноль), З и 3, А и A.
  • Формат номеров договоров: буква V в номере договора (например, 08-V-1414) --- всегда латинская, даже если в документе написана кириллической В.

Разбор ответа

Ответ Claude обрабатывается в следующем порядке:

  1. Из ответа извлекается текстовый блок (при включённом расширенном размышлении ответ содержит блоки thinking и text).
  2. В тексте ищется блок JSON --- сначала внутри тройных обратных кавычек ```json ... ```, затем как первый объект {...} в тексте.
  3. Если JSON успешно разобран --- результат дополняется сведениями об использовании токенов и возвращается.
  4. Если разбор не удался --- возвращается пустой результат с предупреждением.

Обратная совместимость

Модуль сохраняет устаревшие методы для обратной совместимости:

  • segment_pages() --- вызывает analyze_document() и возвращает только массив документов.
  • classify_document() --- анализирует одно изображение и возвращает тип, подтип и уверенность.
  • extract_document_data() --- анализирует одно изображение и возвращает извлечённые поля.

Все эти методы внутренне используют единый analyze_document().

Связь с другими разделами

  • Обработка файлов и распознавание --- преобразование PDF в изображения, передача в Claude
  • Пакетная обработка --- отправка запросов к Claude через пакетный сервис для экономии
  • Конфигурация --- переменные окружения, включая ключ API и модель
  • Настройки --- управление моделью распознавания и списком месторождений через интерфейс