Извлечение данных из документов: on-demand и batch на Bedrock | AiManual
AiManual Logo Ai / Manual.
11 Июн 2026 Гайд

Динамическое извлечение данных из документов с помощью Amazon Bedrock: on-demand и batch пайплайны

Гайд по Amazon Bedrock для извлечения данных из документов: on-demand и batch пайплайны, динамический выбор модели, оптимизация промптов. Актуально на июнь 2026

Реклама
hor_partv1

Бумажный ад и его цифровой призрак

У вас сотни тысяч PDF, сканов счетов, договоров с кривыми подписями. Каждый документ — уникальный сюрприз: шрифт то мелкий, то цветной, таблицы расползаются, а где-то вообще рукописный текст. И всё это надо распарсить, извлечь поля, загнать в CRM или ERP. Классические OCR-пайплайны тут ломаются на первом же развороте. LLM — спасение, но как их готовить?

Amazon Bedrock к середине 2026 года оброс мускулами: Claude 4 Opus, LLaMA 4, Mistral Large 3 — все они умеют читать документы нативно. Но ключевой вопрос: как собрать пайплайн, который не сожрёт бюджет в real-time и не заставит ждать результатов неделю, если данные нужны вчера?

Ответ — комбинация on-demand и batch режимов с динамическим выбором модели. Звучит как магия, но на деле просто инженерная дисциплина. Давайте разберём на примере, как построить такую систему, не выстрелив себе в ногу.

Когда on-demand душит бюджет, а batch заставляет ждать

Представьте: клиент присылает документ — нужно извлечь данные сейчас и показать в интерфейсе. Вы зовёте Claude 4 Opus, он тратит 5000 токенов на анализ, и через 3 секунды готово. Всё круто, пока таких запросов не становится 10 тысяч в час. Тут бюджет летит в космос, а latency начинает плавать.

С другой стороны — ночной batch. Вы скидываете 50 тысяч документов в S3, запускаете batch inference, и через час получаете результат. Дешевле в 3-5 раз, но как быть с теми, кому ответ нужен сейчас?

Решение — гибридный пайплайн: для критичных документов on-demand с быстрой моделью (например, Claude 4 Haiku), для массовой обработки — batch с более мощной моделью (Claude 4 Opus или LLaMA 4). Но чтобы это работало дешево и предсказуемо, нужно динамически выбирать модель, а не хардкодить.

Архитектура: как не наступить на грабли

Схема простая, но дьявол в деталях. Основные компоненты:

  • S3 Input/Output — сырые документы (PDF, JPG, PNG) и результат извлечения.
  • Lambda + API Gateway — для on-demand запросов. Lambda принимает документ (или ссылку), определяет его сложность и выбирает модель.
  • Bedrock (Converse API / InvokeModel) — on-demand вызов модели.
  • Bedrock Batch Inference — для массовых задач. Конфигурация лежит в S3 (input manifest), результаты тоже в S3.
  • DynamoDB / SQS — для оркестрации и отслеживания статусов.
  • Prompt Registry — хранилище промптов в Parameter Store или отдельный репозиторий.

Критично: для on-demand используйте Converse API (он поддерживает structured output и system prompt), для batch — ModelInvocationJob с конфигурацией в JSON. Не путайте API — будет больно.

Пример конфигурации batch inference на S3:

{
  "jobName": "invoice-extraction-2026-06-11",
  "modelId": "anthropic.claude-4-sonnet-20260501",
  "inputDataConfig": {
    "s3InputDataConfig": {
      "s3Uri": "s3://my-bucket/batch-input/manifest.json"
    }
  },
  "outputDataConfig": {
    "s3OutputDataConfig": {
      "s3Uri": "s3://my-bucket/batch-output/"
    }
  },
  "roleArn": "arn:aws:iam::123456789012:role/BedrockBatchRole"
}

Manifest — это JSONL-файл, где каждая строчка содержит параметры запроса. Например:

{"modelId": "anthropic.claude-4-sonnet-20260501", "prompt": "...", "maxTokens": 4096}

Подробнее про работу с большими документами (когда 128K токенов — это смешно) читайте в статье про AgentCore и Recursive Language Models. Там же рассматривается, как не потерять контекст.

Промпты: заставьте LLM читать документы, а не писать стихи

LLM без хорошего промпта — это генератор галлюцинаций. Для извлечения данных нужно принудить модель отдавать строгий JSON. Тут на помощь приходит structured output, который в Bedrock можно реализовать через tool_use или кастомное response_format. В Structured Outputs в Amazon Bedrock разобрано, как создать валидные JSON-ответы без ручной проверки — обязательно прочтите, иначе половина ответов будет мусором.

Базовый шаблон промпта для извлечения полей из счёта:

Вы — система извлечения данных. Извлеките строго следующие поля из документа в формате JSON.
Поля: invoice_number, date, total_amount, vendor_name, currency, line_items (массив с полями description, quantity, unit_price, amount).
Если поле не найдено, используйте null.
Не добавляйте комментарии и лишний текст. Только JSON.

Документ:
{OCR_TEXT}

Но это только начало. В реальности документы бывают с таблицами, подписями, водяными знаками. Тут помогает контекстная сегментация: разбить документ на страницы, каждую обработать отдельно, а потом смержить. Для мультимодальных документов (картинки, графики) используйте мультимодальный RAG от Bedrock — он умеет индексировать не только текст, но и визуальные элементы.

Динамический выбор модели: дешево и сердито

Зачем гонять Opus на простом счёте, когда Haiku справится за копейки? И наоборот: сложный договор на 50 страниц с кучей исключений — Haiku нагенерирует ошибок. Нужен механизм, который на лету выбирает модель.

Как это работает:

  1. Определяем сложность документа: количество страниц, наличие таблиц, объём текста, язык.
  2. Сопоставляем с порогами: если страниц <5 и нет таблиц — используем Haiku; если от 5 до 20 — Sonnet; если больше 20 или есть сложная вёрстка — Opus.
  3. Для batch: можно в манифесте указывать modelId для каждого документа индивидуально. Bedrock Batch Inference это поддерживает.

Ошибка: многие делают статический выбор модели для всего batch'а. Не делайте так — вы либо переплачиваете за простые документы, либо недобираете качество на сложных. Используйте подход «модель на каждый документ».

Пример кода Lambda, которая определяет модель (Python, boto3):

import boto3
import json

def select_model(document_text: str, num_pages: int) -> str:
    # Простая эвристика
    if num_pages <= 3 and len(document_text) < 5000:
        return "anthropic.claude-4-haiku-20260501"
    elif num_pages <= 15:
        return "anthropic.claude-4-sonnet-20260501"
    else:
        return "anthropic.claude-4-opus-20260501"

def lambda_handler(event, context):
    body = json.loads(event['body'])
    doc_text = body['text']
    pages = body.get('pages', 1)
    model_id = select_model(doc_text, pages)
    
    bedrock = boto3.client('bedrock-runtime')
    response = bedrock.converse(
        modelId=model_id,
        messages=[{"role": "user", "content": [{"text": doc_text}]}]
    )
    return {"statusCode": 200, "body": response['output']['message']['content'][0]['text']}

Для более точного выбора можно использовать классификатор на основе Titan Text — он сам оценит сложность и вернёт рекомендуемую модель. Это даёт дополнительную экономию (см. опыт Ring в статье про масштабирование мультиязычной RAG-поддержки — там похожая оптимизация дала 21% экономии).

Batch пайплайн: когда время терпит, но счетов боишься

Для массовой обработки (например, ежемесячный разбор 100 тысяч счетов) batch — король. Схема:

  • Сырые документы попадают в S3.
  • Lambda-триггер (или Step Functions) генерирует манифест для batch, обогащая каждый документ метаданными (сложность, модель, промпт).
  • Запускается job через Bedrock Batch Inference.
  • Результаты пишутся в S3, затем парсятся и загружаются в базу.

Важный момент: batch-задачи выполняются асинхронно, статус можно отслеживать через CloudWatch Events или подписку на SNS. При падении job — автоматический перезапуск (но с ограничением retry, чтобы не уйти в минус).

Один из наших клиентов (Associa) обрабатывал 26 ТБ документов именно batch-пайплайном. Как они это сделали — читайте в кейсе про 48 миллионов бумаг. Там много идей про предобработку и дедупликацию.

On-demand пайплайн: реальный опыт и грабли

On-demand нужен для интерактивных сценариев: пользователь загружает документ и ждёт результат в UI. Тут главные проблемы — latency и throttling.

  • Latency: даже Claude 4 Haiku может отвечать 2-10 секунд на сложных документах. Нужно асинхронное взаимодействие (WebSocket, Polling).
  • Throttling: Bedrock в on-demand имеет quota на TPM (токенов в минуту). При пиках — 429 ошибки. Решение — очередь (SQS) и пул консьюмеров с exponential backoff.
  • Cost: on-demand дороже batch. Если документ можно подождать минуту — лучше отправлять в mini-batch с задержкой.

Хороший пример асинхронной обработки в реальном времени — система сбора доказательств для аудита. Там каждый документ попадает в пайплайн и обрабатывается с учётом контекста. Читайте пошаговый гайд по автоматизации аудита — принципы те же.

Ошибки и грабли: что я видел на продакшене

За два года внедрения Bedrock для извлечения данных я собрал коллекцию шишек:

  1. Игнорирование системного промпта. Многие передают инструкцию в user message, но system prompt даёт более стабильный результат. Используйте поле system в Converse API.
  2. Забывают про context window. Документ на 100 страниц может не влезть. Используйте чанкование или AgentCore (см. статью про AgentCore).
  3. Не проверяют structured output. Даже с tool_use иногда приходят битые JSON. Добавьте валидацию в конце (и оберните retry с другим промптом).
  4. Экономия на промптах. Один раз написали промпт — и он работает. Нет, нужно A/B тестирование. Промпты должны жить в реестре и версионироваться.
  5. Не чистят PII. Если документы содержат персональные данные, их нужно маскировать до обработки. Подход описан в статье про автоматическую чистку PII.
  6. Batch без мониторинга. Job упал, а вы узнали через день. Настройте CloudWatch Alarms на неудачные завершения.

Что дальше? Прогноз на конец 2026

Amazon уже анонсировал Prompt Management и Prompt Flows в Bedrock — это позволит версионировать промпты и делать A/B тесты прямо в консоли. Ожидается, что cost-оптимизация станет встроенной: модели сами будут переключаться на более дешёвые, если качество обработки совпадает.

Мой совет: не пытайтесь построить универсальный пайплайн на все случаи. Разделите документы на типы (счета, договоры, письма) и для каждого типа сделайте отдельный промпт + правило выбора модели. Это сэкономит вам 30-40% бюджета и нервов. И да, не забудьте про дедупликацию — если один документ попадает и в batch, и в on-demand, вы заплатите дважды.

💡
Начните с пилота на 1000 документов, прогоните через on-demand, посмотрите на ошибки, затем адаптируйте промпты и только потом запускайте batch на всех документах. Иначе рискуете получить тонну мусора и счёт на $10k.

Подписаться на канал