3,583 papers
arXiv:2604.25927 72 1 апр. 2026 г. FREE

Аннотированный few-shot для извлечения данных: как научить модель вытаскивать нужные поля из любого документа

КЛЮЧЕВАЯ СУТЬ
Настройки модели — температура, top-k — это иллюзия контроля: они дают доли процента разницы в точности. Промпт с одним аннотированным примером даёт +19 процентных пунктов. Метод позволяет надёжно вытащить конкретные поля из любого документа — счёт, договор, коммерческое предложение — без риска что модель выберет похожее-но-не-то значение. Схема полей снимает неоднозначность, а разметка показывает соответствие напрямую: #поле текст #поле. Модель не угадывает — она копирует паттерн.
Адаптировать под запрос

TL;DR

Когда нужно извлечь конкретные поля из документа — счёт, договор, коммерческое предложение — стандартный запрос "вытащи данные" работает плохо. Модель угадывает что важно, путает похожие поля, пропускает или галлюцинирует значения. Исследование показывает: достаточно один раз показать модели размеченный пример с явными маркерами — и точность взлетает с уровня "терпимо" до уровня "можно доверять".

Главная находка: разница между нулевым запросом и хорошим few-shot — более 19 процентных пунктов точности. При этом настройки модели (температура, top-k, top-p — параметры, которые влияют на "случайность" ответа) дают лишь доли процента разницы. Промпт важнее настроек в десятки раз. Вторая важная находка: аннотированный пример (где явно помечено, какой текст соответствует какому полю) бьёт неаннотированный — модели не нужно догадываться о соответствии, ей показывают напрямую.

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


🔬

Схема метода

Всё выполняется в одном промпте:

БЛОК 1: Роль → "Ты — ассистент по извлечению данных. Выводи результат в JSON"

БЛОК 2: Схема полей → список полей с описанием каждого
         (чем одно поле отличается от другого — явно)

БЛОК 3: Размеченный пример → фрагмент документа с маркерами
         #поле1 текст из документа #поле1
         #поле2 текст из документа #поле2

БЛОК 4: Сам документ → вставляешь в Markdown-формате
         (с таблицами, заголовками, структурой)

Вывод: JSON со всеми полями

🚀

Пример применения

Задача: Получил коммерческое предложение от подрядчика на разработку сайта. Нужно быстро сравнить 5 разных КП — вытащить из каждого ключевые условия в единую таблицу: цена, сроки, гарантия, состав работ, условия оплаты.

Промпт:

Ты — ассистент по извлечению данных из коммерческих предложений.
Выведи результат строго в формате JSON.

## Поля для извлечения

- "компания": название компании-исполнителя
- "цена_итого": итоговая сумма за весь проект (в рублях)
- "срок_выполнения": срок реализации проекта (в днях или неделях как указано)
- "гарантия": гарантийный период после сдачи (если указан)
- "состав_работ": перечень работ, кратко (список)
- "условия_оплаты": схема оплаты — аванс, поэтапно, постоплата
- "контакт": имя менеджера или email для связи

Важно: "цена_итого" — это финальная цифра всего проекта, не стоимость отдельных модулей.

## Пример разметки

Ниже пример документа, где текст, соответствующий каждому полю, обёрнут в маркеры:

---
Коммерческое предложение от #компания Студия Сайтов «Веб-Мастера» #компания

Стоимость разработки: #цена_итого 320 000 рублей #цена_итого

#состав_работ Дизайн главной, разработка 10 страниц, интеграция с 1С, SEO-оптимизация #состав_работ

Срок реализации: #срок_выполнения 45 рабочих дней #срок_выполнения

Оплата: #условия_оплаты 50% аванс, 50% по сдаче #условия_оплаты

Гарантия: #гарантия 6 месяцев на функциональность #гарантия

Менеджер: #контакт Алексей, aleksey@veb-mastera.ru #контакт
---

## Документ для извлечения

{вставь текст КП сюда — желательно сохранив таблицы и структуру}

Результат: Модель вернёт JSON с заполненными полями. Если поле в документе не найдено — поставит null. Повторяешь для каждого из 5 КП, потом просишь модель свести JSON-объекты в сравнительную таблицу.


🧠

Почему это работает

Проблема "угадывания". Когда пишешь "вытащи данные из документа" — модель сама решает, что важно. Документ может содержать 3 разных суммы: сумма за модуль, сумма без НДС, итоговая сумма. Без явного указания модель выберет случайную из трёх.

Схема полей убирает неоднозначность. Когда ты прямо пишешь "поле A — это сумма за весь проект, НЕ стоимость отдельных модулей" — модель получает инструкцию однозначно. Это не угадывание, а чёткое задание.

Разметка показывает, не объясняет. Вместо словесного описания "текст поля находится после двоеточия в разделе..." — ты просто показываешь: вот текст, вот маркер, вот соответствие. Модель видит паттерн и переносит его на новый документ. Один хороший размеченный пример = десятки страниц объяснений о структуре документа.

Рычаги управления: - Детализация описаний полей — чем точнее описание "чем это поле отличается от похожего", тем меньше ошибок при похожих значениях - Количество примеров — добавь 2-3 документа разной структуры, если одно предприятие делает документы в разных форматах - Структура документа — сохраняй таблицы и заголовки, не вставляй документ сплошным текстом, это снижает точность


📋

Шаблон промпта

Ты — ассистент по извлечению данных из {тип_документа}.
Выводи результат строго в формате JSON.

## Поля для извлечения

{для каждого поля:}
- "{название_поля}": {что это такое, чем отличается от похожих полей}

## Размеченный пример

---
{фрагмент реального документа, где каждое значение обёрнуто в маркеры:}
#название_поля значение из текста #название_поля
---

## Документ для извлечения

{вставь документ здесь — сохрани таблицы, заголовки, форматирование}

Что подставлять: - {тип_документа} — счёт, договор, КП, акт, резюме - {название_поля} — короткое имя: "цена", "срок", "исполнитель" - {что это такое...} — особенно важно, если в документе несколько похожих полей - В примере — лучше взять реальный фрагмент из похожего документа, а не придумывать


🚀 Быстрый старт — вставь в чат:

Вот шаблон для извлечения данных из документов. Адаптируй под мою задачу: {твоя задача}.
Задавай вопросы, чтобы заполнить поля.

[вставить шаблон выше]

LLM спросит какой тип документа, какие поля нужно извлечь и попросит пример документа или фрагмент — потому что без примера маркеры в шаблоне будут пустыми, а именно они делают извлечение точным.


⚠️

Ограничения

⚠️ Сложная структура документа: Если таблицы в документе многоуровневые или данные разбросаны по нескольким страницам в нелогичном порядке — точность падает. Структура документа-источника — главный определитель сложности, не размер или тип.

⚠️ Это не для простых документов: Если документ небольшой и нужно 2-3 поля — достаточно прямого запроса. Метод окупается при 10+ полях или при регулярной обработке однотипных документов.

⚠️ Формат подачи важен: Если вставлять документ сплошным текстом без форматирования — теряются связи между элементами. PDF → скопируй с сохранением структуры, или используй инструменты конвертации в Markdown.

⚠️ Галлюцинации при отсутствующих полях: Если поле в документе не указано, модель иногда придумывает значение вместо null. Проверяй результат по критичным полям.


🔍

Как исследовали

Исследователи взяли 2 400 испанских счетов за электричество — синтетически сгенерированных, но по реальным шаблонам Iberdrola, Endesa, Naturgy. Шесть разных шаблонов с одинаковым содержимым, но совершенно разной структурой: у одних данные в таблицах, у других — в колонках, у третьих — вразброс. Задача — извлечь до 107 полей из каждого документа и сравнить с эталоном.

Ключевое решение: всё сравнение построено на промптах, а не на обучении модели. Шесть стратегий — от "просто попроси" (zero-shot) до "покажи три размеченных примера из разных шаблонов" (cross-validation). Параллельно прогнали 19 конфигураций параметров генерации. Итог оказался однозначным: разница между лучшей и худшей настройкой параметров — меньше 1%. Разница между zero-shot и лучшим few-shot — 19+ процентных пунктов. Это как сравнить влияние шрифта резюме и содержания резюме при найме.

Интересная деталь: аннотированные примеры (с явными маркерами #поле текст #поле) оказались лучше неаннотированных — где модели просто показывали пару "документ → JSON" без пометок. Это значит, что явное указание "вот этот конкретный фрагмент = вот это поле" работает лучше, чем "догадайся из примеров". Ещё одна находка: примеры, взятые из структурно разных шаблонов, дают лучшую обобщаемость — модель не переучивается на один тип форматирования.


💡

Адаптации и экстраполяции

🔧 Техника: Итеративное извлечение по категориям → точность на сложных документах

Вместо выгрузки всех полей сразу — разбей на блоки. Сначала "извлеки только реквизиты сторон", потом "извлеки финансовые условия", потом "извлеки сроки и ответственность". Каждый запрос — меньше полей, меньше шанс перепутать. Исследование называет это Iterative strategy: она даёт лучший контроль за счёт большего числа запросов.

Шаг 1 из 3: извлеки только реквизиты сторон из договора:
- "заказчик_название", "заказчик_инн", "исполнитель_название", "исполнитель_инн"
[размеченный пример для этих полей]
[документ]

🔧 Техника: Шаблон для регулярной обработки → однажды размеченный пример работает многократно

Если ты регулярно работаешь с одним типом документов (акты одного подрядчика, счета одного поставщика) — один раз сделай качественный размеченный пример из реального документа этого поставщика. Сохрани его в заметки. Дальше подставляй только новые документы — схема остаётся. Это и есть то, что исследователи называют "template-specific extraction": если пример взят из того же формата, что и обрабатываемый документ, точность максимальная.


🔗

Ресурсы

Information Extraction from Electricity Invoices with General-Purpose Large Language Models — Javier Gómez, Javier Sánchez, Universidad de Las Palmas de Gran Canaria (ULPGC), Centro de Tecnologías de la Imagen (CTIM)

Датасет IDSEM (Invoices Database of the Spanish Electricity Market): публично доступен, 75 000 счетов, 6 шаблонов

Опирается на: Gemini 1.5 Pro (Google DeepMind), Mistral-small; работы по Markdown-форматированию для LLM [Borchmann et al.], LayoutLM, chain-of-thought prompting


📋 Дайджест исследования

Ключевая суть

Настройки модели — температура, top-k — это иллюзия контроля: они дают доли процента разницы в точности. Промпт с одним аннотированным примером даёт +19 процентных пунктов. Метод позволяет надёжно вытащить конкретные поля из любого документа — счёт, договор, коммерческое предложение — без риска что модель выберет похожее-но-не-то значение. Схема полей снимает неоднозначность, а разметка показывает соответствие напрямую: #поле текст #поле. Модель не угадывает — она копирует паттерн.

Принцип работы

Не объясняй где искать значение — покажи: оберни реальный текст в маркеры. В документе три суммы — за этап, без НДС, итоговая? Напиши в схеме: «цена_итого — это финальная цифра всего проекта, НЕ стоимость отдельных модулей». Потом покажи пример: #цена_итого 320 000 рублей #цена_итого. Модель перестаёт гадать. Она видит прямое соответствие и переносит его на новый документ.

Почему работает

Без схемы и разметки модель сама решает что важно. Документ с тремя суммами — модель выберет случайную из трёх. Это не сбой, это нормальное поведение при размытом запросе. Схема полей работает как однозначная инструкция: вот что искать, вот чем это поле отличается от соседнего. Разметка — это показать пальцем, а не объяснять словами где искать. Разница как между «значение находится после двоеточия в разделе оплаты» и «вот оно — #поле 320 000 рублей #поле». Первое — интерпретация. Второе — прямой паттерн.

Когда применять

Документы с 10+ полями для извлечения — счета, договоры, акты, коммерческие предложения, резюме. Особенно когда в документе несколько похожих значений: суммы, даты, реквизиты — и важно не перепутать. Подходит для регулярной обработки однотипных документов: настроил один раз, гоняешь сотни. НЕ подходит для простых документов с 2-3 полями — там достаточно прямого вопроса. Также снижается точность если документ вставлен сплошным текстом без таблиц и заголовков.

Мини-рецепт

1. Задай схему полей: список с описанием каждого — особенно тех, что похожи друг на друга. Пример: «сумма_итого» — финальная цифра всего проекта, НЕ стоимость отдельных этапов.

2. Возьми реальный фрагмент похожего документа и оберни каждое значение в маркеры: #название_поля значение #название_поля. Не придумывай пример — бери настоящий текст.

3. Вставь документ с сохранённой структурой — таблицы, заголовки, разделы. Из PDF копируй с форматированием или конвертируй в Markdown. Сплошной текст режет точность.

4. Попроси вывести JSON — так результат легко проверить и использовать дальше. Если поле не найдено — модель ставит null; критичные поля всё равно перепроверь вручную.

Примеры

[ПЛОХО] : Вытащи ключевые данные из этого счёта на оплату
[ХОРОШО] : Ты — ассистент по извлечению данных из счетов. Выводи результат строго в формате JSON. ## Поля для извлечения - "поставщик": название компании-продавца - "сумма_с_ндс": итоговая сумма к оплате включая НДС (не сумма без НДС) - "дата_выставления": дата когда выставлен счёт (не дата оплаты) - "номер_счёта": номер документа - "срок_оплаты": до какой даты нужно оплатить (если указан) ## Размеченный пример Счёт №#номер_счёта 47/2025 #номер_счёта от #дата_выставления 15 апреля 2025 #дата_выставления Поставщик: #поставщик ООО «Энергосбыт» #поставщик Итого к оплате: #сумма_с_ндс 18 400 рублей #сумма_с_ндс Оплатить до: #срок_оплаты 30 апреля 2025 #срок_оплаты ## Документ для извлечения {вставь текст счёта сюда — сохрани таблицы и структуру}
Источник: Information Extraction from Electricity Invoices with General-Purpose Large Language Models
ArXiv ID: 2604.25927 | Сгенерировано: 2026-04-30 05:23

Проблемы LLM

ПроблемаСутьКак обойти
Модель выбирает случайное значение когда похожих несколькоПросишь "извлеки сумму". В документе три суммы: за модуль, без НДС, итого. Модель сама решает какую взять. Угадывает. Ошибается. Это происходит в любых документах с повторяющимися типами данныхДобавь в запрос явное описание поля: "цена\_итого — это финальная сумма всего проекта, не стоимость отдельных частей". Одно уточняющее предложение с разграничением устраняет путаницу

Методы

МетодСуть
Размеченный пример — точное извлечение полейДай модели до документа два блока. Блок 1 — список полей с описанием каждого. Блок 2 — фрагмент похожего документа, где каждое значение обёрнуто в маркеры: #поле значение #поле. Потом подаёт сам документ в Markdown (с таблицами и заголовками). Почему работает: маркеры показывают соответствие напрямую. Не нужно объяснять "ищи после двоеточия в разделе X". Модель видит паттерн и переносит его на новый документ. Когда применять: 10+ полей, повторяющаяся обработка однотипных документов, несколько похожих значений в одном документе. Когда не нужен: 2-3 поля, простой документ — достаточно прямого запроса

Тезисы

ТезисКомментарий
Качество запроса важнее настроек модели на порядокПараметры "случайности" модели — температура и подобные — дают доли процента разницы в точности. Хороший запрос даёт 19+ процентных пунктов разницы. Это значит: не трать время на подбор параметров. Трать время на запрос. Применяй: если результат не устраивает — переписывай запрос, а не крути настройки
📖 Простыми словами

Information Extraction from Electricity Invoices with General-PurposeLargeLanguageModels

arXiv: 2604.25927

Когда ты просишь нейронку вытащить данные из сложного документа вроде счета за электричество или договора, она ведет себя как невнимательный стажер. Проблема в том, что LLM не понимает контекст бизнеса «из коробки» — для нее цифра в углу листа и цифра в центре имеют одинаковый вес. Если в счете указаны три разные суммы (с налогами, без и аванс), модель просто ткнет пальцем в небо. Это фундаментальный баг нулевого контекста: без четкого примера нейронка галлюцинирует или выбирает данные, которые ей «кажутся» правильными, превращая автоматизацию в лотерею.

Это как отправить человека в огромный гипермаркет за «каким-нибудь сыром», не уточнив сорт, жирность и бюджет. Он принесет что-то, что формально является сыром, но в твой рецепт это не впишется. Чтобы метод сработал, тебе нужно не просто дать задание, а показать эталонную корзину. Исследование доказывает: один-единственный размеченный пример в промпте превращает модель из гадалки в точного бухгалтера.

Суть метода — Few-Shot Extraction с использованием явных маркеров. Вместо того чтобы надеяться на интеллект модели, ты даешь ей шаблон: «Смотри, вот текст счета, а вот так из него должны выглядеть извлеченные данные». Ты буквально тыкаешь ее носом в то, что Total Amount — это вот эта цифра после слова «Итого», а не номер накладной. Когда модель видит структурную пару «текст — результат», она перестает фантазировать и начинает копировать логику извлечения. Точность при таком подходе взлетает с «ну, вроде похоже» до уровня, когда результатам можно доверять в реальном бизнесе.

Хотя тестировали это на скучных счетах за свет, принцип универсален. Это сработает с любым хаосом: коммерческими предложениями, резюме, выписками из банков или юридическими исками. Если тебе нужно сравнить пять разных КП от подрядчиков и свести их в таблицу, не проси нейронку «сделать красиво». Дай ей одно размеченное КП как образец, где четко выделены цена, сроки и гарантии. SEO для документов больше не нужно — достаточно один раз показать правильный паттерн, и модель вытащит данные даже из самого кривого скана.

Короче: забудь про короткие промпты «извлеки данные», если не хочешь потом перепроверять каждую цифру руками. Один пример в промпте экономит часы ручной правки и убирает 90% ошибок. Либо ты тратишь две минуты на создание качественного шаблона, либо тратишь весь день на разгребание последствий творческого видения нейросети. В мире извлечения данных копирование эталона бьет любой «умный» алгоритм.

Работа с исследованием

Адаптируйте исследование под ваши задачи или создайте готовый промпт на основе техник из исследования.

0 / 2000
~0.5-2 N-токенов ~10-30с
~0.3-1 N-токенов ~5-15с