Загрузка...

Извлечение полей

Модель, которая не пишет текст, а заполняет поля: номер, сумму, дату, список, оценку — и для каждого говорит, насколько уверена.

Extractions — соседний с решениями класс моделей. Decisions отвечают на вопросы с заранее известными вариантами, extractions достают из текста значения: номер счёта, сумму, дату, список контактов. Вы описываете поля и их типы, модель возвращает готовые значения. Парсить JSON из текста не нужно, и выдуманного формата не будет: число приходит числом, дата датой.

В RouterAI такие модели доступны через эндпоинт /api/v1/extractions (для клиентов, которые строят путь как OpenRouter, работает и /api/alpha/extractions). Сейчас это cloudflare/clairic. Работает обычный ключ RouterAI.

Decisions (/api/v1/decisions) Extractions (/api/v1/extractions)
questions: да/нет, выбор варианта, оценка fields: текст, число, дата, список, оценка, прогноз
Ответ — вероятности по вашим вариантам Ответ — значение, confidence и p_null
Jev, liquid/d1, cloudflare/clef* и другие cloudflare/clairic

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

import requests

response = requests.post(
    "https://routerai.ru/api/v1/extractions",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={
        "model": "cloudflare/clairic",
        "state": "Счёт № СЧ-2291 от 02.10.2026. Поставщик: ООО «Ромашка», ИНН 7701234567. "
                 "Оплата в течение 30 календарных дней. Итого к оплате: 108 000,00 руб.",
        "reference_date": "2026-11-09",
        "fields": {
            "invoice_number": {"type": "text", "instructions": "Номер счёта"},
            "supplier_inn": {"type": "text", "instructions": "ИНН поставщика"},
            "total": {"type": "number", "unit": "RUB", "decimals": 2, "instructions": "Итоговая сумма к оплате"},
            "payment_term": {"type": "duration", "unit": "days", "instructions": "Срок оплаты"},
            "contract_number": {"type": "text", "instructions": "Номер договора"}
        }
    },
)
answers = response.json()["answers"]
print(answers["total"]["value"])            # 108000
print(answers["contract_number"]["value"])  # None — договора в тексте нет

Ответ — объект answers с теми же именами полей:

{
  "invoice_number": {"type": "text", "value": "СЧ-2291", "span": [7, 14], "confidence": 0.9998, "p_null": 0.00008},
  "total": {"type": "number", "value": 108000, "confidence": 0.9995, "p_null": 0.00003},
  "payment_term": {"type": "duration", "value": 30, "unit": "days", "confidence": 0.9997},
  "contract_number": {"type": "text", "value": null, "guess": "СЧ-2291", "p_null": 0.87}
}
  • value — значение поля. null, если поля в тексте, скорее всего, нет.
  • p_null — вероятность, что поля в тексте нет. Если она выше порога (по умолчанию 0.5, меняется параметром null_threshold у поля), value становится null.
  • guess — лучшая догадка, даже когда value = null. В примере выше модель предлагает номер счёта как номер договора, но сама считает это маловероятным.
  • confidence — уверенность в найденном значении.
  • span — у текстовых полей: позиция [начало, конец) в state, в символах Unicode.

Типы полей

Тип Что вернёт Параметры
text Фрагмент текста и его span —
number Число unit, decimals, integer
date Дата YYYY-MM-DD —
time Время суток —
datetime Дата и время —
duration Длительность unit: seconds, minutes, hours, days, weeks, months, years
list Список значений items: text, number или date (обязателен)
estimate Оценка величины: value, mean, median, p10, p90 min, max (обязательны), step, scale, unit
forecast Прогноз ряда на несколько шагов min, max, horizon, interval (обязательны)

У любого поля есть instructions — что в нём должно быть — и null_threshold.

estimate и forecast отвечают, даже когда прямого ответа в тексте нет: модель оценивает величину по контексту и возвращает распределение. Например, поле «через сколько дней клиент фактически оплатит счёт» с min: 0, max: 120 для счёта выше дало value: 32, p10: 25, p90: 38.

Как не ошибиться

  • Проверяйте confidence. Явные значения (номер, ИНН, сумма) приходят с уверенностью 0.999+. Вычисленные — заметно ниже. «Дата счёта плюс 30 дней» в наших прогонах давала то 2026-11-01, то 2026-11-02 с confidence 0.5–0.65. Такие поля сверяйте в коде или отдавайте человеку.
  • Списки чистите по порогу. В списке контактов модель однажды вернула лишний элемент «Р» рядом с двумя ФИО, и confidence всего списка упал до 0.69. Низкая уверенность — повод перепроверить.
  • Передавайте reference_date. Без неё модель не знает, к какому году отнести «2 октября» и от чего отсчитывать «через неделю».
  • Не просите вычислять в модели то, что можно посчитать в коде. Извлеките дату счёта и срок оплаты отдельными полями и сложите их сами: результат будет точным.

Картинки и PDF

Файлы не кладутся в state. Они передаются один раз в assets под ключом, а ключ упоминается в state или в instructions поля там, где файл нужен:

{
  "model": "cloudflare/clairic",
  "state": "Чек покупки: receipt_1",
  "assets": {
    "receipt_1": {"type": "image", "format": "jpeg", "data_base64": "/9j/4AAQSkZJRgABAQ..."}
  },
  "fields": {
    "total": {"type": "number", "unit": "RUB", "instructions": "Сумма чека"}
  }
}
  • data_base64 — файл в base64 без префикса data:. Форматы — png, jpg, jpeg, pdf.
  • Каждый файл из assets должен быть упомянут хотя бы раз.
  • PDF читают только document-модели. Модель без изображений на входе на картинку ответит 400.
  • У значения, прочитанного с картинки, может прийти source: "image" и spell_confidence — уверенность в написании.

Стоимость

Тарифицируются только входные токены: текст state, описание полей и картинки. Выход не тарифицируется. Счёт выше с девятью полями — около 1 200 входных токенов, это примерно одна сотая рубля. Цена конкретной модели — на её странице в каталоге.

Частые вопросы

Можно ли вызвать clairic через /api/v1/decisions? Нет. cloudflare/clairic обслуживается только на /api/v1/extractions с fields. На /decisions RouterAI ответит 400 с подсказкой правильного пути.

Работают ли temperature, response_format, стриминг? Нет. Тело запроса — model, state, fields и, по необходимости, assets, reference_date, provider, session_id, user. Ответ приходит целиком.

Что значит truncated: true? Модель прочитала только начало state: текст длиннее её контекста. Разбейте документ на части или передайте только нужный фрагмент.

Что дальше