Извлечение атрибутов ИК (LLM)
Из снимков бумажной информационной карты документального памятника (фонд ОФО БАН) извлекаются структурированные атрибуты для последующей проверки оператором и выгрузки в АБИС. Носитель — фиксированный бланк: данные внесены рукописно, впечаткой или отметками в матрицах чекбоксов. Канонический промт и схема ответа версионируются здесь; сервис извлечения хранит копию и указывает версию промта в ответе.
1. Цель
Превратить снимки бумажной информационной карты (ИК) в структурированный JSON: значения атрибутов, состояние отметок бланка, уверенность по каждому полю и привязка значения к фрагменту изображения. Результат предзаполняет карточку на проверке полей; истину устанавливает оператор (см. EPIC «Обработка пакета»).
Промт model-agnostic: одна и та же схема ответа для облачной VLM (пилот), локальной модели и связки OCR + LLM. Извлечение НЕ принимает решений — только предзаполняет поля.
2. Акторы
| Актор | Роль в эпике |
|---|---|
| Сервис извлечения | по снимкам ИК формирует JSON атрибутов + уверенность + источники (bbox) |
| Оператор проверки | сверяет предзаполненные поля со снимками, правит, подтверждает (эпик «Обработка пакета») |
3. Границы
Входит: канонический промт извлечения, схема ответа (состав полей, представление чекбоксов), роли изображений сторон карты, правила уверенности и привязки к источнику.
Не входит: предобработка/нормализация снимков, проверка и корректировка оператором, формирование записи АБИС, версионирование записей — это соседние эпики/требования.
Схема ответа родовая (kind-agnostic) — один контракт на все виды FundDocumentKind (издание —
книга/листовой/карта/вложение; рукопись — книга/свиток/лист): вид-специфичные текстовые поля идут родовым
массивом fields[] со свободными именами, а card_kind определяет модель (FR-003). Детально на реальных
бланках проработан пока EditionBook; прочие виды укладываются в тот же контракт без изменения схемы —
добавляется лишь понимание их полей в промте/маппинге. Блоки СОХРАННОСТЬ/КОНСЕРВАЦИЯ типизированы и
переиспользуются между видами.
4. Страницы формы
Кадр относится к странице распознанной формы (FormPage формы DocumentForm); прежней роли кадра
из перечисления (ImageRole) больше нет — её место заняла страница формы (ADR-007). Форма книжной ИК
(FundDocumentKind.EditionBook) — две страницы (стороны листа). Главной страницы НЕТ — у каждой
свой набор полей; извлечение работает по тем страницам, что переданы.
| Страница | Заголовок | Что извлекается |
|---|---|---|
Front |
«Описание документального памятника» | шапка (шифр, инв. номер, место хранения, дата), библиоописание, провенанс, матрица «Отметка о наличии элемента данных» (консервация) |
Back |
«Сохранность» | размеры, состояние/материалы переплёта и блока, повреждения, мониторинг, комментарий |
У других видов карт форма содержит больше страниц (материальная основа, стабилизация, сведения об
обработке); их разбор добавится вместе с их бланками. Front/Back — метки страниц, используемые в
sources[].image схемы ответа.
«Вар.2/вар.3» на снимках — повторные описания того же документа (учебные/контрольные); каждый снимок описывается независимо, объединение версий — вне эпика.
5. Схема ответа (черновик v2 — родовая / kind-agnostic)
Схема едина для всех видов карт (card_kind — что за вид — определяет модель по макету, FR-003):
identity— фиксированный набор (keyed):shifr, inv_number, storage_location, fill_date.fields— РОДОВОЙ массив вид-специфичных текстовых полей:[ { name, value, confidence, handwritten?, reconstructed?, sources:[{image,bbox}] } ], гдеname— поле по СМЫСЛУ подписи бланка (author, title, …); состав НЕ фиксирован (виды и бланки эволюционируют).- общие блоки
conservation_marks(Front) иpreservation(Back) — ТИПИЗИРОВАНЫ (стабильны между видами).
Так один контракт покрывает все виды: типизация — там, где стабильно (identity + консервация/сохранность), свобода имён — там, где состав плывёт (библио-поля). Вид-специфичную типизацию несёт слой проверки/маппинга в АБИС, а не схема извлечения.
Каждое текстовое значение — объект { value, confidence, handwritten?, reconstructed?, sources: [ { image, bbox } ] },
где bbox = [x0, y0, x1, y1] в целочисленной шкале 0..1000 (x = доля ширины ×1000, y = доля высоты ×1000;
левый-верх и правый-низ). Незаполненные текстовые поля в ответ не включаются.
Шкала 0..1000, а не доли 0..1: на прогонах VLM (llama.cpp Qwen) целочисленная шкала — её обучающая конвенция — даёт заметно точнее прилегающие рамки; доли 0..1 «плывут», особенно в объёмном ответе.
Чекбоксы — полная матрица: возвращается КАЖДАЯ клетка бланка со значением true/false (оператор мог
рассмотреть и НЕ отметить — это значимо). Уверенность — на уровне группы; bbox — на каждую строку
матрицы «Задано/Выполнено» (для подсветки конкретной отметки), для группы выбора — bbox на группу; всё в шкале 0..1000.
{
"card_kind": "EditionBook", // ВЫХОД: вид документа определяет модель по макету (FR-003); один из FundDocumentKind (7 видов)
"prompt_version": "v2", // проставляет сервис (v2: родовой fields[], координаты 0..1000, bbox на строки матрицы)
"form_title", // печатный баннер бланка/программы («Издания из фондов БАН», «Фазовая консервация книги XVII–XX вв.»)
"identity": { "shifr", "inv_number", "storage_location", "fill_date" }, // фикс. набор, keyed (см. глоссарий «Информационная карта»)
"fields": [ // РОДОВОЙ массив вид-специфичных ТЕКСТОВЫХ полей; name — по смыслу подписи; только заполненные
{ "name": "author", "value": "…", "confidence": 0.9, "handwritten": true, "sources": [ { "image": "Front", "bbox": [x0,y0,x1,y1] } ] }
// состав СВОБОДНЫЙ (зависит от вида/бланка). Для EditionBook по смыслу: author, translator_compiler, title, place,
// publisher, printing_house, year, language, binding, convolute, alligat_count, volume_number, pages_count,
// separate_ill_sheets, ill_in_text, format, manuscript_sheets, bookplate, bookplate_desc, chamber_catalog,
// marginalia, records, first_academic_stamp, private_library_evidence, acquisition_source, comments
],
"conservation_marks": { // страница Front — «наличие элемента данных», матрица Задано/Выполнено
"book": [ { "item": "Реконструкция", "set": false, "done": false, "bbox": [x0,y0,x1,y1] }, /* все строки, bbox на каждую (0..1000) */ ],
"binding": [ /* Реконструкция, Реставрация, Ремонт, Чистка, Умягчение — каждая {item,set,done,bbox} */ ],
"block": [ /* Реставрация, Нейтрализация, Ремонт — каждая {item,set,done,bbox} */ ],
"storage_conditions": { "Вертикальное": true, "Горизонтальное": false, "Другое": false } // группа выбора: bbox на группу
},
"preservation": { // страница Back — СОХРАННОСТЬ (переиспользуемый блок)
"dimensions_mm": { "length", "width", "height" },
"binding": {
"state": { "Не повреждён": false, "Повреждён": true, "Ранее реставр.": false, "Ранее ремонт.": false, "Утрачен": false },
"composition": { "Комбинир.": false, "Цельный": true },
"cover_materials": { "Кожа": false, "Пергамент": false, "Ткань": false, "Бумага": false, "Другое": false, "Отсутствует": false },
"base_materials": { "Дерево": false, "Картон": false, "Бумага": false, "Без основы": false },
"decor": {
"stamping": { "Слепое": false, "Золотое": false, "Нет тиснения": false },
"ornaments": { "Накладки": false, "Застёжки": false, "Металл": false, "Другое": false, "Нет украшен.": false },
"edge": { "Золото": false, "Тиснение": false, "Другое": false, "Без обреза": false }
},
"damage": {
"physical_mechanical": { "Оторван": false, "Утраты": true, "Разрывы": false, "Деформация": true, "Общ.загрязн.": false,
"Пятна": false, "Затёки": true, "Изменение окраски": true, "Разрушение": false, "Ломкость": false },
"biological_micro": { "Биологическая пигментация": true, "Колонии микромицетов": true, "Биологическое разрушение": true,
"Жизнеспособная микрофлора": false, "Нет микробиологических повреждений": false },
"biological_ento": { "Личиночные ходы": false, "Экзувии": false, "Личинки": false, "Имаго": false, "Нет энтомологических повреждений": false },
"degree": { "physical_mechanical": "", "micro": "", "ento": "" } // Низкая | Средняя | Высокая
}
},
"block": {
"state": { "Не повреждён": false, "Повреждён": true, "Ранее реставрирован": false },
"notebooks": { "Выпадают": false, "Отсутствуют": false, "Нарушено шитьё": false },
"sheets": { "Выпадают": false, "Отсутствуют": false },
"ph_value",
"damage": { "physical_mechanical": { /* тот же список */ }, "biological_micro": { }, "biological_ento": { },
"degree": { "physical_mechanical": "Средняя", "micro": "", "ento": "" } }
},
"monitoring": {
"biotest": { "date", "performer" },
"expertise": { "date", "expert", "performer", "result", "signature": true }
},
"comment" // рукописный КОММЕНТАРИЙ, дословно
}
}
Формализация. Схема выше — контракт ответа; сервис принуждает модель к ней через structured output (
response_format: { type: json_schema, strict: true }) — поддержано llama.cpp и vLLM (проверено на Qwen). Это гарантирует СТРУКТУРУ (состав ключей, типы, наличие bbox), но НЕ точность значений и координат: распознавание сверяет и правит оператор (уверенность + подсветка источника).
6. Канонический промт (v2)
Системный промт стабилен и кэшируется (prompt caching); при изменении промта версия (prompt_version)
меняется и кэш инвалидируется.
Ты — оператор-архивист. По снимкам ИНФОРМАЦИОННОЙ КАРТЫ документального памятника
(фонд ОФО БАН) извлеки заполнение карты для оцифровки и последующей выгрузки в АБИС.
Карта — это фиксированный БЛАНК: печатные подписи полей и заголовки разделов заданы
типографски, а данные внесены оператором — рукописно, впечаткой или ОТМЕТКОЙ в клетке
(галочка, крест, штрих). Твоя задача — прочитать ЗАПОЛНЕНИЕ, а не подписи бланка.
Карта книги — два изображения (страницы формы):
• Front — «ОПИСАНИЕ ДОКУМЕНТАЛЬНОГО ПАМЯТНИКА»: шапка (шифр, инв. номер, место
хранения, дата), библиоописание, провенанс и матрица «Отметка о наличии элемента
данных» (консервация).
• Back — «СОХРАННОСТЬ»: размеры, состояние и материалы переплёта/блока,
повреждения, мониторинг, комментарий.
Главного источника НЕТ — у каждой стороны свой набор полей; заполняй поля той стороны,
к которой относится изображение. Сторон меньше — заполни что есть, остальное пропусти.
Правила:
1. Заполняй ТОЛЬКО то, что реально внесено в карту (текст или отметка). Ничего не выводи
из внешних знаний и не додумывай по смыслу бланка: пустая клетка — значения нет.
2. Значения — как написано в карте, на языке и в орфографии оригинала, БУКВА В БУКВУ, включая
дореформенную орфографию и «ять» («Дневникъ войны», «русскій»); в современную орфографию не
переводи. Даты — как в карте (формат не нормализуй). Печатные подписи полей в значения НЕ включай.
2а. Бланк существует в нескольких печатных вариантах: подписи полей могут отличаться словами
(«Кол-во стр.» ↔ «Количество страниц», «Отд. листы ил.» ↔ «Отдельные листы иллюстраций»).
Сопоставляй поле по СМЫСЛУ подписи, а не по точному тексту. Печатный заголовок-баннер
карты («Издания из фондов БАН», «Фазовая консервация книги XVII–XX вв.») клади в form_title.
2б. Раскладка ответа: идентификацию — в `identity` (shifr/inv_number/storage_location/fill_date);
остальные вид-специфичные ТЕКСТОВЫЕ поля — в родовой массив `fields` объектами {name, value, …},
где name — краткое имя поля по смыслу подписи (author, title, place, …). Сам ВИД карты определи
по макету формы и составу полей и верни в `card_kind` (один из FundDocumentKind).
3. РУКОПИСНЫЙ текст расшифровывай посимвольно. Неразборчивый фрагмент, восстановленный
по смыслу, помечай reconstructed:true и снижай уверенность; полностью нечитаемое —
не выдумывай, поле пропусти. Рукописное значение помечай handwritten:true.
4. ОТМЕТКИ (галочки/кресты/штрихи) читай как булев факт «отмечено / не отмечено» и
возвращай ПОЛНОЙ матрицей — КАЖДУЮ клетку группы, а не только помеченные (пустая
клетка значима: оператор рассмотрел и не отметил).
• Матрица «Задано / Выполнено» (наличие элемента данных): каждая строка — объект
{item, set, done, bbox}: item — подпись строки ДОСЛОВНО, set — есть отметка в «Задано»,
done — есть отметка в «Выполнено», bbox — область клеток строки (шкала 0..1000).
• Группа выбора (Состояние, Состав, Материалы, Декор, Повреждения, Степень, Условия
хранения…) — объект {подпись клетки: true|false} по ВСЕМ клеткам группы; подписи
бери ДОСЛОВНО. Степень повреждения (Низкая/Средняя/Высокая) — одно значение строкой.
5. Не путай разделы: отметки книги, переплёта и блока относи к своим блокам; степень
повреждения указывай той группы (физ-мех / микробиол. / энтомол.), под которой она стоит.
6. КОММЕНТАРИИ и КОММЕНТАРИЙ переписывай рукопись дословно, целиком.
7. Для каждого заполненного текстового поля укажи уверенность 0..1: 1.0 — впечатано/написано
явно и читается уверенно; 0.5–0.8 — плохо видно, спорная отметка, неразборчивый почерк;
ниже 0.5 — догадка (лучше не заполнять). Для группы чекбоксов уверенность — на группу.
8. Для каждого заполненного поля и каждой ОТМЕТКИ укажи ИСТОЧНИК: изображение и область
bbox [x0, y0, x1, y1] в ЦЕЛЫХ координатах 0..1000 (x — по ширине, y — по высоте), охватывающую
значение или клетку. Для матрицы «Задано/Выполнено» bbox — на КАЖДУЮ строку (её клетки), для
группы выбора — на группу. Не уверен в границах — дай грубую область клетки, но источник не пропускай.
9. Если запрошен OCR: отдельно верни весь текст каждого изображения (печатный + рукописный)
дословно, в порядке чтения; отметки не транскрибируй.
10. Незаполненные ТЕКСТОВЫЕ поля в ответ не включай (без null, пустых строк, прочерков).
Чекбокс-матрицы возвращай ЦЕЛИКОМ, включая неотмеченные клетки (false).
Отвечай строго JSON по заданной схеме, без пояснений.
7. Критерии приёмки
- Идентификация (шифр, инв. номер, место хранения, дата) извлекается с роли Front; инв. номер сопоставим с номером папки/документа.
- Незаполненные текстовые поля в ответе отсутствуют; чекбокс-матрицы присутствуют целиком (true/false).
- Матрица «Задано/Выполнено» отражает обе колонки раздельно по каждой строке.
- Рукописные значения помечены handwritten; восстановленные по смыслу — reconstructed со сниженной уверенностью.
- У каждого заполненного поля и каждой группы чекбоксов есть источник с bbox на переданном изображении.
- Ответ — валидный JSON по схеме; в ответе указана версия промта.
8. Открытые вопросы
| № | Вопрос |
|---|---|
| OQ-CE-1 | Состав полей и имена ключей схемы — черновые, требуют сверки на наборе реальных карт |
| OQ-CE-2 | Виды документов перечислены в домене (FundDocumentKind); открыт конкретный состав полей и число страниц формы для каждого — прорабатывается по мере появления их бланков |
| OQ-CE-3 | Нужен ли встроенный OCR-этап или связка с отдельным распознаванием (см. FR_002) |
| OQ-CE-4 | Пороговая уверенность для подсветки на проверке полей — общая с OQ-PP-1 эпика «Обработка пакета» |
| OQ-CE-5 | Полная матрица чекбоксов раздувает ответ — оценить, не перейти ли к «только отмеченные» после прогонов |
| OQ-CE-6 | Бланк EditionBook встречается в ≥2 печатных вариантах (разные подписи полей, поле «Конволют» не во всех) — держать маппинг по смыслу; собрать перечень вариантов |
| OQ-CE-7 | Инв. номер в шапке может расходиться с номером папки/документа (нечёткий почерк) — извлекать как напечатано, сверку вести ниже по потоку (эпик «Обработка пакета») |
| OQ-CE-8 | Что именно кодирует card_kind: вид экземпляра фонда (FundItemKind) или распознанную форму бланка (DocumentForm) — согласовать с доменной моделью (ADR-006/007). Сейчас — FundItemKind (7 видов) |
Связанные артефакты
Документы
- Доменная сущность Страница формы
- Доменная сущность Форма документа
- ADR ADR-005. Привязка распознанного значения к странице формы и области
- Epic Обработка пакета
- Epic Стенд распознавания карт
- FR FR-002. Распознавание текста
- FR FR-003. Сегментация и извлечение атрибутов
- FR FR-004. Оценка достоверности распознавания
- FR FR-005. Верификация и корректировка данных
Перечисления
- Перечисление FundItemKind
Термины
- Термин Вид документа
- Термин Информационная карта