Загрузка...

Работа с PDF

Отправляйте PDF-документы любой модели на RouterAI.

RouterAI поддерживает обработку PDF через API /api/v1/chat/completions. PDF можно отправлять как прямые URL или данные в формате base64 в массиве сообщений через тип контента file. Эта функция работает с любой моделью на RouterAI.

Поддержка URL: Отправляйте публично доступные PDF напрямую без скачивания или кодирования Поддержка Base64: Требуется для локальных файлов или приватных документов, которые недоступны публично

PDF также работают в чате для интерактивного тестирования.

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

Конфигурация плагина

Для настройки обработки PDF используйте параметр plugins в вашем запросе. RouterAI предоставляет несколько движков обработки PDF с различными возможностями и ценами:

{
  "plugins": [
    {
      "id": "file-parser",
      "pdf": {
        "engine": "cloudflare-ai"
      }
    }
  ]
}

Доступные движки:

  • cloudflare-ai — для текстовых PDF (бесплатно)
  • mistral-ocr — для отсканированных документов и PDF с изображениями
  • native — для моделей с нативной поддержкой файлов
Значение `"pdf-text"` устарело и автоматически интерпретируется как `"cloudflare-ai"`. Существующие запросы с `"pdf-text"` продолжат работать.

Цены

RouterAI предоставляет несколько движков обработки PDF:

  1. mistral-ocr: лучше всего подходит для отсканированных документов или PDF с изображениями (~450 ₽ за 1 000 страниц).
  2. cloudflare-ai: конвертирует PDF в markdown через Cloudflare Workers AI (бесплатно, без изображений).
  3. native: доступен только для моделей, которые поддерживают ввод файлов нативно (оплачивается как входные токены).

Если вы явно не указываете движок, RouterAI по умолчанию сначала использует нативные возможности обработки файлов модели, а если они недоступны — cloudflare-ai.

Ограничения OCR на изображения

Когда движок mistral-ocr извлекает изображения из PDF, RouterAI запрашивает у Mistral не более 8 изображений на PDF и передаёт не более 8 изображений в нижестоящую модель. Избыточные изображения отбрасываются, при этом весь распознанный текст сохраняется в полном объёме.

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

Если ваша нижестоящая модель вообще не принимает изображения на вход, OCR-извлечённые изображения полностью отбрасываются, а в модель передаётся только распознанный текст.

Использование URL PDF

Для публично доступных PDF вы можете отправить URL напрямую без необходимости скачивания и кодирования файла:

curl https://routerai.ru/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ROUTERAI_API_KEY" \
  -d '{
    "model": "anthropic/claude-sonnet-4",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Каковы основные моменты в этом документе?"
          },
          {
            "type": "file",
            "file": {
              "filename": "document.pdf",
              "file_data": "https://bitcoin.org/bitcoin.pdf"
            }
          }
        ]
      }
    ],
    "plugins": [
      {
        "id": "file-parser",
        "pdf": {
          "engine": "mistral-ocr"
        }
      }
    ]
  }'
URL PDF работают со всеми движками обработки. Для Mistral OCR URL передается напрямую в сервис. Для других движков RouterAI загружает PDF и обрабатывает его внутренне.

Использование PDF в формате Base64

Для локальных PDF-файлов или когда вам нужно отправить содержимое PDF напрямую, вы можете закодировать файл в base64:

Подготовка base64 в Linux

# Кодирование PDF в base64 и сохранение в переменную
BASE64_PDF=$(base64 -w 0 path/to/your/document.pdf)

# Создание data URL
DATA_URL="data:application/pdf;base64,$BASE64_PDF"

Пример запроса с base64

# Сначала подготовьте base64
BASE64_PDF=$(base64 -w 0 path/to/your/document.pdf)
DATA_URL="data:application/pdf;base64,$BASE64_PDF"

# Затем отправьте запрос
curl https://routerai.ru/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ROUTERAI_API_KEY" \
  -d '{
    "model": "google/gemma-3-27b-it",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Каковы основные моменты в этом документе?"
          },
          {
            "type": "file",
            "file": {
              "filename": "document.pdf",
              "file_data": "'"$DATA_URL"'"
            }
          }
        ]
      }
    ],
    "plugins": [
      {
        "id": "file-parser",
        "pdf": {
          "engine": "cloudflare-ai"
        }
      }
    ]
  }'
Разбор PDF будет работать, даже если плагин не указан явно. По умолчанию используется движок, оптимальный для выбранной модели.

Пропуск затрат на разбор

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

Вот как повторно использовать аннотации файлов:

Первый запрос с PDF

# Подготовка base64
BASE64_PDF=$(base64 -w 0 path/to/your/document.pdf)
DATA_URL="data:application/pdf;base64,$BASE64_PDF"

# Первый запрос
RESPONSE=$(curl -s https://routerai.ru/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ROUTERAI_API_KEY" \
  -d '{
    "model": "google/gemma-3-27b-it",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Каковы основные моменты в этом документе?"
          },
          {
            "type": "file",
            "file": {
              "filename": "document.pdf",
              "file_data": "'"$DATA_URL"'"
            }
          }
        ]
      }
    ]
  }')

# Извлечение аннотаций из ответа
ANNOTATIONS=$(echo $RESPONSE | jq '.choices[0].message.annotations')
ASSISTANT_CONTENT=$(echo $RESPONSE | jq -r '.choices[0].message.content')

Последующий запрос с аннотациями

# Последующий запрос с использованием аннотаций (без повторной отправки PDF)
curl https://routerai.ru/api/v1/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $ROUTERAI_API_KEY" \
  -d '{
    "model": "google/gemma-3-27b-it",
    "messages": [
      {
        "role": "user",
        "content": [
          {
            "type": "text",
            "text": "Каковы основные моменты в этом документе?"
          },
          {
            "type": "file",
            "file": {
              "filename": "document.pdf",
              "file_data": "'"$DATA_URL"'"
            }
          }
        ]
      },
      {
        "role": "assistant",
        "content": "'"$ASSISTANT_CONTENT"'",
        "annotations": '"$ANNOTATIONS"'
      },
      {
        "role": "user",
        "content": "Можете ли вы подробнее рассказать о втором пункте?"
      }
    ]
  }'
Когда вы включаете аннотации файлов из предыдущего ответа в последующие запросы, RouterAI будет использовать эту предварительно разобранную информацию вместо повторного разбора PDF, что экономит время обработки и затраты. Это особенно полезно для больших документов или при использовании движка `mistral-ocr`, который влечет дополнительные расходы.

Схема file-аннотаций

Когда RouterAI разбирает PDF, ответ включает file-аннотации в сообщении ассистента. JSON Schema:

{
  "$schema": "https://json-schema.org/draft-07/schema",
  "$defs": {
    "FileAnnotation": {
      "type": "object",
      "required": ["type", "file"],
      "properties": {
        "type": { "const": "file" },
        "file": {
          "type": "object",
          "required": ["hash", "content"],
          "properties": {
            "hash":    { "type": "string", "description": "Уникальный SHA256 hash разобранного файла" },
            "name":    { "type": "string", "description": "Исходное имя файла (опционально)" },
            "content": {
              "type": "array",
              "items": { "$ref": "#/$defs/ContentPart" }
            }
          }
        }
      }
    },
    "ContentPart": {
      "oneOf": [
        {
          "type": "object",
          "required": ["type", "text"],
          "properties": {
            "type": { "const": "text" },
            "text": { "type": "string" }
          }
        },
        {
          "type": "object",
          "required": ["type", "image_url"],
          "properties": {
            "type": { "const": "image_url" },
            "image_url": {
              "type": "object",
              "required": ["url"],
              "properties": {
                "url": {
                  "type": "string",
                  "description": "Data URL вида data:image/png;base64,..."
                }
              }
            }
          }
        }
      ]
    }
  }
}

Массив content содержит распознанное содержимое PDF — текстовые блоки и изображения (как base64 data URL). Поле hash уникально идентифицирует разобранный файл и используется для пропуска повторного разбора, если вы включаете аннотацию в последующие запросы.

Формат ответа

API вернет ответ в следующем формате:

{
  "id": "gen-1234567890",
  "provider": "DeepInfra",
  "model": "google/gemma-3-27b-it",
  "object": "chat.completion",
  "created": 1234567890,
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "Документ обсуждает...",
        "annotations": [
          {
            "type": "file",
            "file": {
              "hash": "abc123...",
              "name": "document.pdf",
              "content": [
                { "type": "text", "text": "Распознанное содержимое..." },
                { "type": "image_url", "image_url": { "url": "data:image/png;base64,..." } }
              ]
            }
          }
        ]
      }
    }
  ],
  "usage": {
    "prompt_tokens": 1000,
    "completion_tokens": 100,
    "total_tokens": 1100
  }
}

Ошибки с разобранными аннотациями

Если RouterAI успешно разобрал PDF, но провайдер инференса затем вернул ошибку, аннотации всё равно возвращаются в поле error.metadata.file_annotations ответа с ошибкой. Структура совпадает с FileAnnotation из success-ответа, поэтому вы можете передать тот же массив обратно в RouterAI при повторной попытке и пропустить повторный разбор.

Это применимо к движкам mistral-ocr и cloudflare-ai, которые разбирают PDF до отправки в модель. Движок native не выдаёт аннотации, поскольку файл передаётся напрямую в модель.

{
  "error": "Provider returned an error",
  "metadata": {
    "file_annotations": [
      {
        "type": "file",
        "file": {
          "hash": "abc123...",
          "name": "document.pdf",
          "content": [
            { "type": "text", "text": "Распознанное содержимое..." }
          ]
        }
      }
    ]
  }
}