1437 строк · в начало
using Ban.Sdaid.Notation.Documents;
using Ban.Sdaid.Icd.Domain.Cards;
namespace Ban.Sdaid.Icd.Backend.Recognition
{
/// <summary>
/// Запрос к модели распознавания: что передаётся вместе с кадром страницы и в каком виде
/// ожидается ответ. Каталог полей приведён для обеих страниц формы «Издания из фондов БАН».
/// </summary>
public class FieldExtractionPrompt : IApplicationServiceDocument, IFolder<BackendFolder>
{
public static string _refName = "запрос к модели распознавания";
public string Name => "Запрос на извлечение полей";
public string Description =>
@"Инструкция модели распознавания, каталог полей страницы и схема ответа. Собирается из конфигурации документа и формы, а не пишется руками.";
public string Version => "0.2";
public string Status => "draft";
public string[] Comments => new[]
{
"2026-08-18. Первая редакция: страница 1 формы «Издания из фондов БАН» по образцам заказчика.",
"2026-08-18. Добавлена страница 2 (оборот) по образцу инв. 74870: 81 отметка, 5 текстовых полей, 3 таблицы; в схему ответа введены таблицы.",
};
public static string S1_Structure = $"""
## Из чего состоит запрос
Запрос к модели складывается из четырёх частей, и только первая написана прозой.
| Часть | Что задаёт | Откуда берётся |
|---|---|---|
| Инструкция | что извлекать, чего не делать, как оценивать уверенность | пишется один раз, общая для всех форм |
| Каталог полей | коды, подписи, типы, ограничения | собирается из конфигурации документа и размещений формы |
| Кадр | изображение страницы | из пакета ввода |
| Схема ответа | строгий формат результата | выводится из каталога полей |
**Каталог не пишется руками.** Он выводится из состава вида ИК и размещений на форме:
код и тип берутся у атрибута, подпись — у размещения на конкретном бланке. Иначе
добавление поля в спеку и в запрос к модели разъедутся при первой же правке.
**Схему ответа передаём параметром, а не текстом.** Современные модели принимают
JSON Schema отдельным полем запроса и физически не могут вернуть что-то другое;
схема, вписанная в текст промта, — только пожелание.
Образцы, по которым составлен каталог, — {nameof(CardSamples)}.
""";
public static string S2_Instruction = """
## Инструкция модели
```
Ты извлекаешь данные из скана бумажной информационной карты Библиотеки Российской
академии наук (форма «Издания из фондов БАН», страница 1).
НА ИЗОБРАЖЕНИИ
Бланк с типографскими подписями полей; значения вписаны от руки чернилами. Два блока:
1. «Описание документального памятника» — таблица с текстовыми полями.
2. «Консервация» — матрица отметок: строка «мероприятие», две колонки «Задано»
и «Выполнено». Значение отметки — факт заполненности клетки любым знаком:
крестик, галочка, косая черта, точка.
ЗАДАЧА
Для каждого поля из каталога верни распознанное значение, уверенность и область
на изображении.
ПРАВИЛА
1. Не додумывай. Не читается — верни value: null, confidence: 0. Пустая клетка бланка —
тоже null: незаполненные поля на этих картах обычны.
2. Транскрибируй как написано, без исправлений орфографии и раскрытия сокращений.
«105 д» остаётся «105 д».
3. Если в клетке помимо значения есть уточнение, верни содержимое целиком:
«5,83 перед форзац», а не «5,83».
4. Отметку возвращай как true либо false. Любой знак в клетке — true, пустая — false.
5. confidence — от 0 до 1, оценка того, что прочитано верно: печатный текст около 0.95,
разборчивый рукописный около 0.7, неуверенное чтение ниже 0.5.
6. bbox — [x, y, ширина, высота] в процентах от размера изображения, с одним знаком
после запятой. Область охватывает значение, а не подпись поля.
7. Часть текста на бланке впечатана типографски — например, описание экслибриса.
Возвращай её как значение и ставь printed: true.
8. Рукописный текст, не помещающийся ни в одно поле каталога, возвращай в notes:
текст, область и подпись ближайшего поля.
9. Если страница не похожа на описанную форму, верни form_match: false и не заполняй поля.
```
""";
public static string S3_TextFields = """
## Каталог: текстовые поля страницы 1
Блок «Описание документального памятника», 29 полей.
| Код | Подпись на бланке | Тип | Ограничения и замечания |
|---|---|---|---|
| `shelf` | Шифр | строка | обязательное; примеры: «105 д», «III 099» |
| `inventory_no` | Инв. номер | строка | обязательное; цифры, иногда с буквой |
| `card_date` | Дата | дата | обязательное; часто в виде «17.10.22» |
| `author` | Автор | строка | |
| `translator_compiler` | Перев., сост. и др. | строка | |
| `title` | Заглавие | строка | до 500 знаков; поле в несколько строк |
| `place` | Место издания | строка | |
| `language` | Язык издания | строка | часто сокращённо: «рус.» |
| `publisher` | Издатель (-ство) | строка | |
| `printing_house` | Типография | строка | |
| `binding_type` | Переплёт | строка | описание переплёта словами |
| `year` | Год издания | число | от 1500 до текущего года |
| `convolute` | Конволют | строка | есть не во всех редакциях бланка |
| `alligate_count` | Количество аллигат | число | |
| `alligate_no` | Номер алл. / тома, вып. | строка | |
| `pages_count` | Кол-во стр. | число | подпись бывает «Количество страниц» |
| `separate_ill_sheets` | Отд. листы ил. | строка | подпись бывает «Отдельные листы иллюстраций» |
| `ill_in_text` | Ил. в тексте | строка | подпись бывает «Иллюстрации в тексте» |
| `format` | Формат | строка | пишут дробью или парой чисел |
| `manuscript_sheets` | Рук. листы | строка | подпись бывает «Рукописные листы» |
| `bookplate` | Экслибрис | строка | |
| `bookplate_description` | Описание экслибриса | строка | в части бланков впечатано типографски |
| `private_library_evidence` | Др. свидетельства принадлежности к частной б-ке | строка | |
| `academy_stamp` | Первонач. Акад. штамп | строка | |
| `chamber_catalog` | Камерный каталог | строка | |
| `marginalia` | Маргиналии | строка | |
| `records` | Записи | строка | |
| `acquisition_source` | Источ. поступ. | строка | есть не во всех редакциях бланка |
| `comments` | Комментарии | строка | поле в несколько строк внизу блока |
""";
public static string S4_MarkFields = """
## Каталог: отметки блока «Консервация»
Каждое мероприятие даёт **два поля** — «задано» и «выполнено», по числу клеток в строке.
Итого 42 отметки.
**Книга** — 10 мероприятий, коды с приставкой `book_`:
| Мероприятие | Код «задано» | Код «выполнено» |
|---|---|---|
| Реконструкция | `book_reconstruction_assigned` | `book_reconstruction_done` |
| Дезинфекция | `book_disinfection_assigned` | `book_disinfection_done` |
| Дезинсекция | `book_disinsection_assigned` | `book_disinsection_done` |
| Реставрация | `book_restoration_assigned` | `book_restoration_done` |
| Ремонт | `book_repair_assigned` | `book_repair_done` |
| Суперобложка | `book_jacket_assigned` | `book_jacket_done` |
| Инкапсулирование | `book_encapsulation_assigned` | `book_encapsulation_done` |
| Конвертирование | `book_enveloping_assigned` | `book_enveloping_done` |
| Гигиеническая обработка | `book_hygienic_assigned` | `book_hygienic_done` |
| Помещение в контейнер | `book_container_assigned` | `book_container_done` |
**Переплёт** — 5 мероприятий, приставка `binding_`: реконструкция
(`binding_reconstruction_*`), реставрация (`binding_restoration_*`), ремонт
(`binding_repair_*`), чистка (`binding_cleaning_*`), умягчение (`binding_softening_*`).
**Блок** — 3 мероприятия, приставка `block_`: реставрация (`block_restoration_*`),
нейтрализация (`block_neutralization_*`), ремонт (`block_repair_*`).
**Условия хранения** — 3 позиции, приставка `storage_`: вертикальное
(`storage_vertical_*`), горизонтальное (`storage_horizontal_*`), другое
(`storage_other_*`).
Все поля этого блока имеют тип «отметка»: значение true либо false, ограничений нет.
""";
public static string S41_Page2Structure = """
## Страница 2: устройство бланка
Оборот целиком посвящён состоянию памятника и его обследованиям. Текстовых полей
почти нет: страница — это матрицы отметок и три журнальные таблицы.
| Блок | Что содержит | Чем описывается |
|---|---|---|
| Сохранность | размеры экземпляра в мм | 3 числа |
| Переплёт | состояние, состав, материалы, декор | 21 отметка |
| Повреждения переплёта | физико-механические, биологические; степень | 17 отметок + 9 отметок степени |
| Блок | состояние, состав тетрадей и листов | 9 отметок |
| Повреждения блока | физико-механические, биологические; степень; величина pH | 16 отметок + 9 отметок степени + 1 текст |
| Мониторинг | биотест и текущая биологическая экспертиза | 2 таблицы |
| Эксперт | кто и когда проводил экспертизу | 1 таблица |
| Комментарий | свободный рукописный текст | 1 текст |
Итого 81 отметка, 5 текстовых полей и 3 таблицы.
**Степень повреждения — тоже отметки.** На бланке это три клетки «Низкая», «Средняя»,
«Высокая», и заполнена бывает любая из них либо ни одной. Модель отмечает заполненность
клеток; то, что значения взаимоисключающие, — правило состава, а не задача распознавания.
Своя тройка степени есть у каждой группы повреждений: физико-механических,
микробиологических, энтомологических — и отдельно для переплёта и для блока.
**Три таблицы — повторяющиеся группы.** Число строк заранее неизвестно, строки
заполняются по мере обследований. Поэтому в ответе они идут не полями, а массивом строк
(см. схему ответа): каждая строка — набор тех же полей.
**Поля за пределами клеток.** На образце справа от строк степени повреждения рукой
приписано «нет» — вне какого-либо поля бланка. Такое возвращается в `notes` с указанием
ближайшего поля, а не приписывается наугад к соседней клетке.
""";
public static string S42_Page2Marks = """
## Каталог: отметки страницы 2
**Переплёт**, приставка `bnd_` — 21 отметка:
| Группа | Позиции и коды |
|---|---|
| Состояние | не повреждён `bnd_state_intact`, повреждён `bnd_state_damaged`, утрачен `bnd_state_lost`, ранее подвергался реставрации `bnd_state_restored_before` |
| Состав | комбинированный `bnd_comp_combined`, цельный `bnd_comp_solid` |
| Материалы покрытия | кожа `bnd_cover_leather`, пергамент `bnd_cover_parchment`, ткань `bnd_cover_fabric`, бумага `bnd_cover_paper` |
| Материалы основы | дерево `bnd_base_wood`, картон `bnd_base_cardboard`, др. материалы `bnd_base_other` |
| Декор · тиснение | слепое `bnd_dec_blind`, золотое `bnd_dec_gold` |
| Декор · украшения | накладки `bnd_dec_overlays`, застёжки `bnd_dec_clasps`, металл `bnd_dec_metal` |
| Декор · обрез | золото `bnd_edge_gold`, др. виды `bnd_edge_other`, тиснение `bnd_edge_tooled` |
**Повреждения переплёта**, приставка `bnd_` — 17 отметок:
| Группа | Позиции и коды |
|---|---|
| Физико-механические | оторван `bnd_dmg_torn_off`, утраты `bnd_dmg_losses`, разрывы `bnd_dmg_tears`, деформация `bnd_dmg_deformation`, пятна `bnd_dmg_stains`, затёки `bnd_dmg_tidelines`, изменения окраски `bnd_dmg_discoloration`, разрушения `bnd_dmg_destruction`, ломкость `bnd_dmg_brittleness` |
| Микробиологические | биологическая пигментация `bnd_bio_pigmentation`, колонии микромицетов `bnd_bio_colonies`, биологическое разрушение `bnd_bio_destruction`, жизнеспособная микрофлора `bnd_bio_viable_microflora` |
| Энтомологические | личиночные ходы `bnd_ent_larval_tunnels`, экзувии `bnd_ent_exuviae`, личинки `bnd_ent_larvae`, имаго `bnd_ent_imago` |
**Блок**, приставка `blk_` — 9 отметок состава и состояния:
| Группа | Позиции и коды |
|---|---|
| Состояние | не повреждён `blk_state_intact`, повреждён `blk_state_damaged`, ранее подвергался реставрации `blk_state_restored_before` |
| Тетради | выпадают `blk_quires_falling`, отсутствуют `blk_quires_missing`, нарушено шитьё `blk_sewing_broken` |
| Листы | выпадают `blk_sheets_falling`, отсутствуют `blk_sheets_missing`, повреждения `blk_sheets_damaged` |
**Повреждения блока**, приставка `blk_` — 16 отметок:
| Группа | Позиции и коды |
|---|---|
| Физико-механические | утраты `blk_dmg_losses`, разрывы `blk_dmg_tears`, деформация `blk_dmg_deformation`, затёки `blk_dmg_tidelines`, изменения окраски `blk_dmg_discoloration`, разрушения `blk_dmg_destruction`, ломкость `blk_dmg_brittleness`, пятна `blk_dmg_stains` |
| Микробиологические | `blk_bio_pigmentation`, `blk_bio_colonies`, `blk_bio_destruction`, `blk_bio_viable_microflora` |
| Энтомологические | `blk_ent_larval_tunnels`, `blk_ent_exuviae`, `blk_ent_larvae`, `blk_ent_imago` |
**Степень повреждения** — 18 отметок: по три клетки (`_low`, `_medium`, `_high`)
на каждую из шести троек:
`bnd_deg_physmech_*`, `bnd_deg_bio_*`, `bnd_deg_ento_*`,
`blk_deg_physmech_*`, `blk_deg_bio_*`, `blk_deg_ento_*`.
""";
public static string S43_Page2Tables = """
## Каталог: текстовые поля и таблицы страницы 2
**Текстовые поля** — 5:
| Код | Подпись на бланке | Тип | Замечания |
|---|---|---|---|
| `dim_length` | Размеры (мм): Длина | число | |
| `dim_width` | Размеры (мм): Ширина | число | |
| `dim_height` | Размеры (мм): Высота | число | |
| `blk_ph` | Величина pH | строка | не число: пишут с уточнением места замера — «5,83 перед форзацем» |
| `page2_comment` | Комментарий | строка | рукописный текст в несколько строк внизу страницы |
**Таблица «Биотест»**, код `biotest`:
| Код колонки | Подпись | Тип |
|---|---|---|
| `seq_no` | № П/П | число |
| `placed_at` | Дата закладки | дата |
| `performer` | Исполнитель | строка |
**Таблица «Текущая биологическая экспертиза»**, код `bio_expertise`:
| Код колонки | Подпись | Тип |
|---|---|---|
| `examined_at` | Дата экспертизы | дата |
| `performer` | Исполнитель | строка |
| `result` | Результат | строка |
**Таблица «Эксперт»**, код `experts`:
| Код колонки | Подпись | Тип |
|---|---|---|
| `role` | должность в левой колонке | строка |
| `examined_at` | Дата экспертизы | дата |
| `person` | Ф И О | строка |
| `signature` | Подпись | строка |
| `result` | Результат | строка |
Про подпись и должность: в левой колонке таблицы «Эксперт» на образце вписано
«Микробиолог» и «Консерватор» — это не подпись бланка, а значение. Колонка `signature`
содержит росчерк, а не текст: разбирать его не нужно, достаточно отметить, что он есть.
""";
public static string S45_Payload = """
## Готовый текст запроса
Ниже — то, что отправляется модели одним сообщением вместе с кадром страницы.
Инструкция и каталог полей идут подряд; схема ответа передаётся отдельным параметром
запроса, а не текстом.
Каталог здесь приведён для страницы 1 формы «Издания из фондов БАН» и должен
собираться Сервисом из состава вида ИК: этот текст — образец того, что получается
на выходе, а не то, что правится руками.
```text
Ты извлекаешь данные из скана бумажной информационной карты Библиотеки Российской
академии наук (форма «Издания из фондов БАН», страница 1).
НА ИЗОБРАЖЕНИИ
Бланк с типографскими подписями полей; значения вписаны от руки чернилами. Два блока:
1. «Описание документального памятника» — таблица с текстовыми полями.
2. «Консервация» — матрица отметок: строка «мероприятие», две колонки «Задано»
и «Выполнено». Значение отметки — факт заполненности клетки любым знаком:
крестик, галочка, косая черта, точка.
ЗАДАЧА
Для каждого поля из каталога верни распознанное значение, уверенность и область
на изображении. Ответ — JSON по заданной схеме, без пояснений вокруг него.
ПРАВИЛА
1. Не додумывай. Не читается — value: null, confidence: 0. Пустая клетка бланка —
тоже null: незаполненные поля на этих картах обычны.
2. Транскрибируй как написано, без исправлений орфографии и раскрытия сокращений.
3. Если в клетке помимо значения есть уточнение, верни содержимое целиком:
«5,83 перед форзац», а не «5,83».
4. Отметку возвращай как true либо false. Любой знак в клетке — true, пустая — false.
5. confidence — от 0 до 1: печатный текст около 0.95, разборчивый рукописный около 0.7,
неуверенное чтение ниже 0.5.
6. bbox — [x, y, ширина, высота] в процентах от размера изображения, с одним знаком
после запятой. Область охватывает значение, а не подпись поля.
7. Текст, впечатанный в бланк типографски, возвращай как значение с printed: true.
8. Рукописный текст, не помещающийся ни в одно поле каталога, возвращай в notes:
текст, область и подпись ближайшего поля.
9. Если страница не похожа на описанную форму, верни form_match: false и не заполняй поля.
КАТАЛОГ ПОЛЕЙ
{
"form": "Издания из фондов БАН, страница 1",
"fields": [
{
"code": "shelf",
"label": "Шифр",
"type": "string",
"required": true,
"hint": "примеры: «105 д», «III 099»"
},
{
"code": "inventory_no",
"label": "Инв. номер",
"type": "string",
"required": true
},
{
"code": "card_date",
"label": "Дата",
"type": "date",
"required": true,
"hint": "часто в виде «17.10.22»"
},
{
"code": "author",
"label": "Автор",
"type": "string"
},
{
"code": "translator_compiler",
"label": "Перев., сост. и др.",
"type": "string"
},
{
"code": "title",
"label": "Заглавие",
"type": "string",
"max": 500
},
{
"code": "place",
"label": "Место издания",
"type": "string"
},
{
"code": "language",
"label": "Язык издания",
"type": "string",
"hint": "часто сокращённо: «рус.»"
},
{
"code": "publisher",
"label": "Издатель (-ство)",
"type": "string"
},
{
"code": "printing_house",
"label": "Типография",
"type": "string"
},
{
"code": "binding_type",
"label": "Переплёт",
"type": "string"
},
{
"code": "year",
"label": "Год издания",
"type": "number",
"min": 1500,
"max": 2026
},
{
"code": "convolute",
"label": "Конволют",
"type": "string",
"hint": "есть не во всех редакциях бланка"
},
{
"code": "alligate_count",
"label": "Количество аллигат",
"type": "number"
},
{
"code": "alligate_no",
"label": "Номер алл. / тома, вып.",
"type": "string"
},
{
"code": "pages_count",
"label": "Кол-во стр.",
"type": "number",
"hint": "подпись бывает «Количество страниц»"
},
{
"code": "separate_ill_sheets",
"label": "Отд. листы ил.",
"type": "string",
"hint": "подпись бывает «Отдельные листы иллюстраций»"
},
{
"code": "ill_in_text",
"label": "Ил. в тексте",
"type": "string",
"hint": "подпись бывает «Иллюстрации в тексте»"
},
{
"code": "format",
"label": "Формат",
"type": "string"
},
{
"code": "manuscript_sheets",
"label": "Рук. листы",
"type": "string"
},
{
"code": "bookplate",
"label": "Экслибрис",
"type": "string"
},
{
"code": "bookplate_description",
"label": "Описание экслибриса",
"type": "string",
"hint": "в части бланков впечатано типографски"
},
{
"code": "private_library_evidence",
"label": "Др. свидетельства принадлежности к частной б-ке",
"type": "string"
},
{
"code": "academy_stamp",
"label": "Первонач. Акад. штамп",
"type": "string"
},
{
"code": "chamber_catalog",
"label": "Камерный каталог",
"type": "string"
},
{
"code": "marginalia",
"label": "Маргиналии",
"type": "string"
},
{
"code": "records",
"label": "Записи",
"type": "string"
},
{
"code": "acquisition_source",
"label": "Источ. поступ.",
"type": "string",
"hint": "есть не во всех редакциях бланка"
},
{
"code": "comments",
"label": "Комментарии",
"type": "string"
},
{
"code": "book_reconstruction_assigned",
"label": "Книга · Реконструкция · Задано",
"type": "bool"
},
{
"code": "book_reconstruction_done",
"label": "Книга · Реконструкция · Выполнено",
"type": "bool"
},
{
"code": "book_disinfection_assigned",
"label": "Книга · Дезинфекция · Задано",
"type": "bool"
},
{
"code": "book_disinfection_done",
"label": "Книга · Дезинфекция · Выполнено",
"type": "bool"
},
{
"code": "book_disinsection_assigned",
"label": "Книга · Дезинсекция · Задано",
"type": "bool"
},
{
"code": "book_disinsection_done",
"label": "Книга · Дезинсекция · Выполнено",
"type": "bool"
},
{
"code": "book_restoration_assigned",
"label": "Книга · Реставрация · Задано",
"type": "bool"
},
{
"code": "book_restoration_done",
"label": "Книга · Реставрация · Выполнено",
"type": "bool"
},
{
"code": "book_repair_assigned",
"label": "Книга · Ремонт · Задано",
"type": "bool"
},
{
"code": "book_repair_done",
"label": "Книга · Ремонт · Выполнено",
"type": "bool"
},
{
"code": "book_jacket_assigned",
"label": "Книга · Суперобложка · Задано",
"type": "bool"
},
{
"code": "book_jacket_done",
"label": "Книга · Суперобложка · Выполнено",
"type": "bool"
},
{
"code": "book_encapsulation_assigned",
"label": "Книга · Инкапсулирование · Задано",
"type": "bool"
},
{
"code": "book_encapsulation_done",
"label": "Книга · Инкапсулирование · Выполнено",
"type": "bool"
},
{
"code": "book_enveloping_assigned",
"label": "Книга · Конвертирование · Задано",
"type": "bool"
},
{
"code": "book_enveloping_done",
"label": "Книга · Конвертирование · Выполнено",
"type": "bool"
},
{
"code": "book_hygienic_assigned",
"label": "Книга · Гигиеническая обработка · Задано",
"type": "bool"
},
{
"code": "book_hygienic_done",
"label": "Книга · Гигиеническая обработка · Выполнено",
"type": "bool"
},
{
"code": "book_container_assigned",
"label": "Книга · Помещение в контейнер · Задано",
"type": "bool"
},
{
"code": "book_container_done",
"label": "Книга · Помещение в контейнер · Выполнено",
"type": "bool"
},
{
"code": "binding_reconstruction_assigned",
"label": "Переплёт · Реконструкция · Задано",
"type": "bool"
},
{
"code": "binding_reconstruction_done",
"label": "Переплёт · Реконструкция · Выполнено",
"type": "bool"
},
{
"code": "binding_restoration_assigned",
"label": "Переплёт · Реставрация · Задано",
"type": "bool"
},
{
"code": "binding_restoration_done",
"label": "Переплёт · Реставрация · Выполнено",
"type": "bool"
},
{
"code": "binding_repair_assigned",
"label": "Переплёт · Ремонт · Задано",
"type": "bool"
},
{
"code": "binding_repair_done",
"label": "Переплёт · Ремонт · Выполнено",
"type": "bool"
},
{
"code": "binding_cleaning_assigned",
"label": "Переплёт · Чистка · Задано",
"type": "bool"
},
{
"code": "binding_cleaning_done",
"label": "Переплёт · Чистка · Выполнено",
"type": "bool"
},
{
"code": "binding_softening_assigned",
"label": "Переплёт · Умягчение · Задано",
"type": "bool"
},
{
"code": "binding_softening_done",
"label": "Переплёт · Умягчение · Выполнено",
"type": "bool"
},
{
"code": "block_restoration_assigned",
"label": "Блок · Реставрация · Задано",
"type": "bool"
},
{
"code": "block_restoration_done",
"label": "Блок · Реставрация · Выполнено",
"type": "bool"
},
{
"code": "block_neutralization_assigned",
"label": "Блок · Нейтрализация · Задано",
"type": "bool"
},
{
"code": "block_neutralization_done",
"label": "Блок · Нейтрализация · Выполнено",
"type": "bool"
},
{
"code": "block_repair_assigned",
"label": "Блок · Ремонт · Задано",
"type": "bool"
},
{
"code": "block_repair_done",
"label": "Блок · Ремонт · Выполнено",
"type": "bool"
},
{
"code": "storage_vertical_assigned",
"label": "Условия хранения · Вертикальное · Задано",
"type": "bool"
},
{
"code": "storage_vertical_done",
"label": "Условия хранения · Вертикальное · Выполнено",
"type": "bool"
},
{
"code": "storage_horizontal_assigned",
"label": "Условия хранения · Горизонтальное · Задано",
"type": "bool"
},
{
"code": "storage_horizontal_done",
"label": "Условия хранения · Горизонтальное · Выполнено",
"type": "bool"
},
{
"code": "storage_other_assigned",
"label": "Условия хранения · Другое · Задано",
"type": "bool"
},
{
"code": "storage_other_done",
"label": "Условия хранения · Другое · Выполнено",
"type": "bool"
}
]
}
```
""";
public static string S46_PayloadPage2 = """
## Готовый текст запроса: страница 2
То же, что для страницы 1, но с каталогом оборота. Отличий в инструкции два: другое
описание изображения и правило про журнальные таблицы.
```text
Ты извлекаешь данные из скана бумажной информационной карты Библиотеки Российской
академии наук (форма «Издания из фондов БАН», страница 2, оборот).
НА ИЗОБРАЖЕНИИ
Бланк описания сохранности; значения проставлены от руки чернилами. Четыре части:
1. «Сохранность» — размеры экземпляра в миллиметрах.
2. «Переплёт» и «Блок» — матрицы отметок: строка «свойство», клетки по столбцам
(«Кожа», «Картон», «Низкая», «Средняя», «Высокая» и прочие). Значение отметки —
факт заполненности клетки любым знаком: крестик, галочка, косая черта, точка.
3. «Мониторинг» и «Эксперт» — журнальные таблицы, заполняются построчно
по мере обследований; число заполненных строк заранее неизвестно.
4. «Комментарий» — свободный рукописный текст внизу страницы.
ЗАДАЧА
Для каждого поля из каталога верни распознанное значение, уверенность и область
на изображении. Ответ — JSON по заданной схеме, без пояснений вокруг него.
ПРАВИЛА
1. Не додумывай. Не читается — value: null, confidence: 0. Пустая клетка бланка —
тоже null: незаполненные поля на этих картах обычны.
2. Транскрибируй как написано, без исправлений орфографии и раскрытия сокращений.
3. Если в клетке помимо значения есть уточнение, верни содержимое целиком:
«5,83 перед форзацем», а не «5,83».
4. Отметку возвращай как true либо false. Любой знак в клетке — true, пустая — false.
5. Степень повреждения — три отдельные клетки. Отмечай заполненные; не выбирай одну
из трёх и не выводи её из других полей.
6. confidence — от 0 до 1: печатный текст около 0.95, разборчивый рукописный около 0.7,
неуверенное чтение ниже 0.5.
7. bbox — [x, y, ширина, высота] в процентах от размера изображения, с одним знаком
после запятой. Область охватывает значение, а не подпись поля.
8. Таблицы каталога возвращай в tables: по одной строке ответа на каждую заполненную
строку бланка, в порядке сверху вниз. Пустые строки таблицы пропускай.
9. Подпись эксперта не разбирай: если росчерк есть — «есть», если нет — null.
10. Рукописный текст, не помещающийся ни в одно поле каталога, возвращай в notes:
текст, область и код ближайшего поля. На этом бланке приписки на полях обычны.
11. Если страница не похожа на описанную форму, верни form_match: false
и не заполняй поля.
КАТАЛОГ ПОЛЕЙ
{
"form": "Издания из фондов БАН, страница 2 (оборот)",
"fields": [
{
"code": "dim_length",
"label": "Размеры (мм) · Длина",
"type": "number"
},
{
"code": "dim_width",
"label": "Размеры (мм) · Ширина",
"type": "number"
},
{
"code": "dim_height",
"label": "Размеры (мм) · Высота",
"type": "number"
},
{
"code": "bnd_state_intact",
"label": "Переплёт · Состояние · Не повреждён",
"type": "bool"
},
{
"code": "bnd_state_damaged",
"label": "Переплёт · Состояние · Повреждён",
"type": "bool"
},
{
"code": "bnd_state_lost",
"label": "Переплёт · Состояние · Утрачен",
"type": "bool"
},
{
"code": "bnd_state_restored_before",
"label": "Переплёт · Состояние · Ранее подвергался реставрации",
"type": "bool"
},
{
"code": "bnd_comp_combined",
"label": "Переплёт · Состав · Комбинированный",
"type": "bool"
},
{
"code": "bnd_comp_solid",
"label": "Переплёт · Состав · Цельный",
"type": "bool"
},
{
"code": "bnd_cover_leather",
"label": "Переплёт · Материалы покрытия · Кожа",
"type": "bool"
},
{
"code": "bnd_cover_parchment",
"label": "Переплёт · Материалы покрытия · Пергамент",
"type": "bool"
},
{
"code": "bnd_cover_fabric",
"label": "Переплёт · Материалы покрытия · Ткань",
"type": "bool"
},
{
"code": "bnd_cover_paper",
"label": "Переплёт · Материалы покрытия · Бумага",
"type": "bool"
},
{
"code": "bnd_base_wood",
"label": "Переплёт · Материалы основы · Дерево",
"type": "bool"
},
{
"code": "bnd_base_cardboard",
"label": "Переплёт · Материалы основы · Картон",
"type": "bool"
},
{
"code": "bnd_base_other",
"label": "Переплёт · Материалы основы · Др. материалы",
"type": "bool"
},
{
"code": "bnd_dec_blind",
"label": "Переплёт · Декор · Тиснение · Слепое",
"type": "bool"
},
{
"code": "bnd_dec_gold",
"label": "Переплёт · Декор · Тиснение · Золотое",
"type": "bool"
},
{
"code": "bnd_dec_overlays",
"label": "Переплёт · Декор · Украшения · Накладки",
"type": "bool"
},
{
"code": "bnd_dec_clasps",
"label": "Переплёт · Декор · Украшения · Застёжки",
"type": "bool"
},
{
"code": "bnd_dec_metal",
"label": "Переплёт · Декор · Украшения · Металл",
"type": "bool"
},
{
"code": "bnd_edge_gold",
"label": "Переплёт · Декор · Обрез · Золото",
"type": "bool"
},
{
"code": "bnd_edge_other",
"label": "Переплёт · Декор · Обрез · Др. виды",
"type": "bool"
},
{
"code": "bnd_edge_tooled",
"label": "Переплёт · Декор · Обрез · Тиснение",
"type": "bool"
},
{
"code": "bnd_dmg_torn_off",
"label": "Повреждения переплёта · Физико-механические · Оторван",
"type": "bool"
},
{
"code": "bnd_dmg_losses",
"label": "Повреждения переплёта · Физико-механические · Утраты",
"type": "bool"
},
{
"code": "bnd_dmg_tears",
"label": "Повреждения переплёта · Физико-механические · Разрывы",
"type": "bool"
},
{
"code": "bnd_dmg_deformation",
"label": "Повреждения переплёта · Физико-механические · Деформация",
"type": "bool"
},
{
"code": "bnd_dmg_stains",
"label": "Повреждения переплёта · Физико-механические · Пятна",
"type": "bool"
},
{
"code": "bnd_dmg_tidelines",
"label": "Повреждения переплёта · Физико-механические · Затёки",
"type": "bool"
},
{
"code": "bnd_dmg_discoloration",
"label": "Повреждения переплёта · Физико-механические · Изменения окраски",
"type": "bool"
},
{
"code": "bnd_dmg_destruction",
"label": "Повреждения переплёта · Физико-механические · Разрушения",
"type": "bool"
},
{
"code": "bnd_dmg_brittleness",
"label": "Повреждения переплёта · Физико-механические · Ломкость",
"type": "bool"
},
{
"code": "bnd_bio_pigmentation",
"label": "Повреждения переплёта · Микробиологические · Биологическая пигментация",
"type": "bool"
},
{
"code": "bnd_bio_colonies",
"label": "Повреждения переплёта · Микробиологические · Колонии микромицетов",
"type": "bool"
},
{
"code": "bnd_bio_destruction",
"label": "Повреждения переплёта · Микробиологические · Биологическое разрушение",
"type": "bool"
},
{
"code": "bnd_bio_viable_microflora",
"label": "Повреждения переплёта · Микробиологические · Жизнеспособная микрофлора",
"type": "bool"
},
{
"code": "bnd_ent_larval_tunnels",
"label": "Повреждения переплёта · Энтомологические · Личиночные ходы",
"type": "bool"
},
{
"code": "bnd_ent_exuviae",
"label": "Повреждения переплёта · Энтомологические · Экзувии",
"type": "bool"
},
{
"code": "bnd_ent_larvae",
"label": "Повреждения переплёта · Энтомологические · Личинки",
"type": "bool"
},
{
"code": "bnd_ent_imago",
"label": "Повреждения переплёта · Энтомологические · Имаго",
"type": "bool"
},
{
"code": "bnd_deg_physmech_low",
"label": "Переплёт · Степень повреждения · Физико-механические · Низкая",
"type": "bool"
},
{
"code": "bnd_deg_physmech_medium",
"label": "Переплёт · Степень повреждения · Физико-механические · Средняя",
"type": "bool"
},
{
"code": "bnd_deg_physmech_high",
"label": "Переплёт · Степень повреждения · Физико-механические · Высокая",
"type": "bool"
},
{
"code": "bnd_deg_bio_low",
"label": "Переплёт · Степень повреждения · Микробиологические · Низкая",
"type": "bool"
},
{
"code": "bnd_deg_bio_medium",
"label": "Переплёт · Степень повреждения · Микробиологические · Средняя",
"type": "bool"
},
{
"code": "bnd_deg_bio_high",
"label": "Переплёт · Степень повреждения · Микробиологические · Высокая",
"type": "bool"
},
{
"code": "bnd_deg_ento_low",
"label": "Переплёт · Степень повреждения · Энтомологические · Низкая",
"type": "bool"
},
{
"code": "bnd_deg_ento_medium",
"label": "Переплёт · Степень повреждения · Энтомологические · Средняя",
"type": "bool"
},
{
"code": "bnd_deg_ento_high",
"label": "Переплёт · Степень повреждения · Энтомологические · Высокая",
"type": "bool"
},
{
"code": "blk_state_intact",
"label": "Блок · Состояние · Не повреждён",
"type": "bool"
},
{
"code": "blk_state_damaged",
"label": "Блок · Состояние · Повреждён",
"type": "bool"
},
{
"code": "blk_state_restored_before",
"label": "Блок · Состояние · Ранее подвергался реставрации",
"type": "bool"
},
{
"code": "blk_quires_falling",
"label": "Блок · Тетради · Выпадают",
"type": "bool"
},
{
"code": "blk_quires_missing",
"label": "Блок · Тетради · Отсутствуют",
"type": "bool"
},
{
"code": "blk_sewing_broken",
"label": "Блок · Тетради · Нарушено шитьё",
"type": "bool"
},
{
"code": "blk_sheets_falling",
"label": "Блок · Листы · Выпадают",
"type": "bool"
},
{
"code": "blk_sheets_missing",
"label": "Блок · Листы · Отсутствуют",
"type": "bool"
},
{
"code": "blk_sheets_damaged",
"label": "Блок · Листы · Повреждения",
"type": "bool"
},
{
"code": "blk_dmg_losses",
"label": "Повреждения блока · Физико-механические · Утраты",
"type": "bool"
},
{
"code": "blk_dmg_tears",
"label": "Повреждения блока · Физико-механические · Разрывы",
"type": "bool"
},
{
"code": "blk_dmg_deformation",
"label": "Повреждения блока · Физико-механические · Деформация",
"type": "bool"
},
{
"code": "blk_dmg_tidelines",
"label": "Повреждения блока · Физико-механические · Затёки",
"type": "bool"
},
{
"code": "blk_dmg_discoloration",
"label": "Повреждения блока · Физико-механические · Изменения окраски",
"type": "bool"
},
{
"code": "blk_dmg_destruction",
"label": "Повреждения блока · Физико-механические · Разрушения",
"type": "bool"
},
{
"code": "blk_dmg_brittleness",
"label": "Повреждения блока · Физико-механические · Ломкость",
"type": "bool"
},
{
"code": "blk_dmg_stains",
"label": "Повреждения блока · Физико-механические · Пятна",
"type": "bool"
},
{
"code": "blk_bio_pigmentation",
"label": "Повреждения блока · Микробиологические · Биологическая пигментация",
"type": "bool"
},
{
"code": "blk_bio_colonies",
"label": "Повреждения блока · Микробиологические · Колонии микромицетов",
"type": "bool"
},
{
"code": "blk_bio_destruction",
"label": "Повреждения блока · Микробиологические · Биологическое разрушение",
"type": "bool"
},
{
"code": "blk_bio_viable_microflora",
"label": "Повреждения блока · Микробиологические · Жизнеспособная микрофлора",
"type": "bool"
},
{
"code": "blk_ent_larval_tunnels",
"label": "Повреждения блока · Энтомологические · Личиночные ходы",
"type": "bool"
},
{
"code": "blk_ent_exuviae",
"label": "Повреждения блока · Энтомологические · Экзувии",
"type": "bool"
},
{
"code": "blk_ent_larvae",
"label": "Повреждения блока · Энтомологические · Личинки",
"type": "bool"
},
{
"code": "blk_ent_imago",
"label": "Повреждения блока · Энтомологические · Имаго",
"type": "bool"
},
{
"code": "blk_deg_physmech_low",
"label": "Блок · Степень повреждения · Физико-механические · Низкая",
"type": "bool"
},
{
"code": "blk_deg_physmech_medium",
"label": "Блок · Степень повреждения · Физико-механические · Средняя",
"type": "bool"
},
{
"code": "blk_deg_physmech_high",
"label": "Блок · Степень повреждения · Физико-механические · Высокая",
"type": "bool"
},
{
"code": "blk_deg_bio_low",
"label": "Блок · Степень повреждения · Микробиологические · Низкая",
"type": "bool"
},
{
"code": "blk_deg_bio_medium",
"label": "Блок · Степень повреждения · Микробиологические · Средняя",
"type": "bool"
},
{
"code": "blk_deg_bio_high",
"label": "Блок · Степень повреждения · Микробиологические · Высокая",
"type": "bool"
},
{
"code": "blk_deg_ento_low",
"label": "Блок · Степень повреждения · Энтомологические · Низкая",
"type": "bool"
},
{
"code": "blk_deg_ento_medium",
"label": "Блок · Степень повреждения · Энтомологические · Средняя",
"type": "bool"
},
{
"code": "blk_deg_ento_high",
"label": "Блок · Степень повреждения · Энтомологические · Высокая",
"type": "bool"
},
{
"code": "blk_ph",
"label": "Величина pH",
"type": "string",
"hint": "пишут с уточнением места замера: «5,83 перед форзацем»"
},
{
"code": "page2_comment",
"label": "Комментарий",
"type": "string"
}
],
"tables": [
{
"code": "biotest",
"label": "Биотест",
"columns": [
{
"code": "seq_no",
"label": "№ П/П",
"type": "number"
},
{
"code": "placed_at",
"label": "Дата закладки",
"type": "date"
},
{
"code": "performer",
"label": "Исполнитель",
"type": "string"
}
]
},
{
"code": "bio_expertise",
"label": "Текущая биологическая экспертиза",
"columns": [
{
"code": "examined_at",
"label": "Дата экспертизы",
"type": "date"
},
{
"code": "performer",
"label": "Исполнитель",
"type": "string"
},
{
"code": "result",
"label": "Результат",
"type": "string"
}
]
},
{
"code": "experts",
"label": "Эксперт",
"columns": [
{
"code": "role",
"label": "Должность",
"type": "string"
},
{
"code": "examined_at",
"label": "Дата экспертизы",
"type": "date"
},
{
"code": "person",
"label": "Ф И О",
"type": "string"
},
{
"code": "signature",
"label": "Подпись",
"type": "string",
"hint": "росчерк не разбирать: «есть» либо null"
},
{
"code": "result",
"label": "Результат",
"type": "string"
}
]
}
]
}
```
""";
public static string S5_ResponseSchema = """
## Схема ответа
```json
{
"type": "object",
"required": ["form_match", "values"],
"properties": {
"form_match": { "type": "boolean" },
"values": {
"type": "array",
"items": {
"type": "object",
"required": ["code", "value", "confidence"],
"properties": {
"code": { "type": "string" },
"value": { "type": ["string", "number", "boolean", "null"] },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"printed": { "type": "boolean" },
"bbox": { "type": "array", "minItems": 4, "maxItems": 4,
"items": { "type": "number" } }
}
}
},
"tables": {
"type": "array",
"items": {
"type": "object",
"required": ["code", "rows"],
"properties": {
"code": { "type": "string" },
"rows": {
"type": "array",
"items": {
"type": "array",
"items": {
"type": "object",
"required": ["code", "value", "confidence"],
"properties": {
"code": { "type": "string" },
"value": { "type": ["string", "number", "null"] },
"confidence": { "type": "number", "minimum": 0, "maximum": 1 },
"bbox": { "type": "array", "minItems": 4, "maxItems": 4,
"items": { "type": "number" } }
}
}
}
}
}
}
},
"notes": {
"type": "array",
"items": {
"type": "object",
"required": ["text", "bbox"],
"properties": {
"text": { "type": "string" },
"bbox": { "type": "array", "minItems": 4, "maxItems": 4,
"items": { "type": "number" } },
"near_field": { "type": "string" }
}
}
}
}
}
```
Пример ответа по образцу инв. 74870, где заполнены только шифр и инвентарный номер:
```json
{
"form_match": true,
"values": [
{ "code": "shelf", "value": "105 д", "confidence": 0.58, "bbox": [25, 14.4, 12, 2.1] },
{ "code": "inventory_no", "value": "74870", "confidence": 0.77, "bbox": [57, 14.3, 15, 2.1] },
{ "code": "card_date", "value": null, "confidence": 0 },
{ "code": "title", "value": null, "confidence": 0 },
{ "code": "bookplate_description",
"value": "Овальный штамп сажевый гербовый: орёл с саблей под графской короной",
"confidence": 0.96, "printed": true, "bbox": [34, 38.4, 32, 3.7] },
{ "code": "book_restoration_assigned", "value": true, "confidence": 0.88, "bbox": [27, 68.2, 8, 2.7] },
{ "code": "book_restoration_done", "value": false, "confidence": 0.9 }
],
"notes": []
}
```
Фрагмент ответа по обороту того же образца — с таблицей и с припиской вне полей:
```json
{
"form_match": true,
"values": [
{ "code": "bnd_state_damaged", "value": true, "confidence": 0.85 },
{ "code": "bnd_comp_combined", "value": true, "confidence": 0.83 },
{ "code": "bnd_cover_paper", "value": true, "confidence": 0.8 },
{ "code": "bnd_base_cardboard", "value": true, "confidence": 0.82 },
{ "code": "bnd_edge_other", "value": true, "confidence": 0.72 },
{ "code": "bnd_deg_physmech_high", "value": true, "confidence": 0.79 },
{ "code": "blk_ph", "value": "5,83 перед форзацем", "confidence": 0.54,
"bbox": [11.8, 59.1, 17.5, 2.4] }
],
"tables": [
{
"code": "bio_expertise",
"rows": [
[
{ "code": "examined_at", "value": "11.01.23", "confidence": 0.74 },
{ "code": "performer", "value": "Тишева З.А.", "confidence": 0.41 },
{ "code": "result", "value": "отр.", "confidence": 0.38 }
]
]
},
{
"code": "experts",
"rows": [
[
{ "code": "role", "value": "микробиолог", "confidence": 0.46 },
{ "code": "examined_at", "value": "20.01.23", "confidence": 0.68 },
{ "code": "person", "value": "Тишева", "confidence": 0.39 },
{ "code": "signature", "value": "есть", "confidence": 0.9 }
],
[
{ "code": "role", "value": "консерватор", "confidence": 0.52 },
{ "code": "examined_at", "value": "23.01.23", "confidence": 0.66 },
{ "code": "person", "value": "Колотилкина Е.В.", "confidence": 0.44 },
{ "code": "signature", "value": "есть", "confidence": 0.9 }
]
]
}
],
"notes": [
{ "text": "нет", "bbox": [88.2, 47.1, 5.4, 2.0],
"near_field": "bnd_deg_ento_low" }
]
}
```
Уверенность в этом примере намеренно низкая на фамилиях и результатах: почерк в журнальных
таблицах беглый, и именно здесь ожидается больше всего правок пользователем.
""";
public static string S6_Risks = """
## Чего ожидать от модели
**Координаты даются хуже значений.** Языковая модель оценивает положение области
приблизительно; ошибка в строку-две обычна. Если подсветка фрагмента важна — а на ней
держится проверка карты, — координаты надёжнее получать от распознавания текста
со словными координатами и сопоставлять с извлечёнными значениями по самому тексту.
**Отметки читаются хуже, чем кажется.** Знаки в клетках разные, часть выходит за границы,
часть проставлена карандашом. Отметки стоит проверять выборочно даже при высокой
уверенности модели.
**Уверенность модели — не вероятность.** Это её собственная оценка, склонная к завышению
на рукописном тексте. Пороги отсечения имеет смысл подбирать по размеченным образцам,
а не назначать умозрительно.
""";
public static string S99_Related = $"""
## Связанные артефакты
- {nameof(Ban.Sdaid.Icd.Requirements.FR_003_AttributeExtraction)} — требование к извлечению атрибутов
- {nameof(Ban.Sdaid.Icd.Arch.Adr.ADR_006_CardDataStructure)} — структура данных карты, откуда берётся каталог полей
- {nameof(CardSamples)} — образцы, по которым составлен каталог
""";
}
}