Загрузка...

Jev: решения вместо текста

Модель, которая не пишет ответы, а принимает решения — да или нет, выбор из вариантов, оценка по шкале — и возвращает вероятности.

Jev (TypeSafe) — модель другого класса, чем чат-модели. Она не генерирует текст. Вы отправляете ей данные и вопросы с заранее известными вариантами ответа, а она возвращает готовые значения: вероятность «да», выбранный вариант, оценку по шкале. Парсить JSON из текста не нужно — ответ сразу ложится в if, сортировку или порог в вашем коде.

В RouterAI Jev доступна через выделенный эндпоинт /api/v1/decisions. В примерах используется алиас ~typesafe/jev-latest — он всегда указывает на актуальную версию; конкретную версию можно закрепить именем вроде typesafe/jev-1.13. Отдельный аккаунт TypeSafe не нужен — работает обычный ключ RouterAI.

Чем хороша Почему
Быстро Ответ приходит меньше чем за секунду, сколько бы вопросов вы ни задали: они обрабатываются параллельно
Дёшево Тарифицируются только входные токены. Классифицировать одно обращение стоит доли копейки
Предсказуемо Ответ всегда из ваших вариантов — модель не придумает значение, которого вы не предлагали
Честно про сомнения Вместе с ответом приходят вероятности: видно, когда модель уверена, а когда решение лучше отдать человеку

Когда брать Jev, а когда чат-модель

Задача Что подойдёт
Определить тему, отдел, намерение, язык, тип документа Jev
Проверить, есть ли в тексте признак: срочность, жалоба, персональные данные, попытка взлома промпта Jev
Оценить по шкале: критичность бага, раздражение клиента, релевантность документа запросу Jev
Промодерировать список: ники, отзывы, объявления — одним запросом Jev
Выбрать, какой модели или обработчику отдать запрос Jev
Написать ответ клиенту, пересказать, перевести, сгенерировать код Чат-модель (Chat Completions)
Посчитать, сравнить даты, решить многошаговую задачу Обычный код или модель с рассуждениями

Хорошее правило: Jev отвечает на вопросы, на которые знающий человек ответил бы за пару секунд, взглянув на текст. Если нужен анализ из нескольких шагов — разбейте его на простые вопросы и соберите результат в коде.

Три типа вопросов

Тип Вопрос Что возвращает
noul Да или нет? noul — вероятность «да» от 0 до 1
choice Какой вариант из списка? choice — победивший вариант, probabilities — вероятность каждого, confidence — уверенность
score Где на шкале? score — положение на вашей шкале, probabilities по уровням, confidence

В одном запросе типы можно смешивать. Подробно — в гайде «Как задавать вопросы».

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

1. Получите ключ

Ключ создаётся в личном кабинете. Это тот же ключ, что и для остальных эндпоинтов RouterAI.

2. Отправьте данные и вопросы

В state — текст, который нужно оценить. В questions — ваши вопросы: имя вопроса придумываете сами, под ним же придёт ответ. Вопросы и критерии можно писать по-русски.

curl -X POST "https://routerai.ru/api/v1/decisions" \
  -H "Authorization: Bearer $ROUTERAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "~typesafe/jev-latest",
    "state": "Здравствуйте! Третий день не могу подключить оплату на сайте — платежи клиентов не проходят, мы теряем заказы. Помогите, пожалуйста, срочно.",
    "questions": {
      "is_urgent": {
        "type": "noul",
        "instructions": "Клиент сообщает о срочной проблеме?"
      },
      "department": {
        "type": "choice",
        "instructions": "Какая команда должна заняться обращением?",
        "criteria": {
          "billing": "Платежи, счета, возвраты, подписки",
          "technical": "Ошибки, сбои, интеграции, настройка",
          "sales": "Тарифы, покупка, вопросы до оплаты"
        }
      },
      "frustration": {
        "type": "score",
        "instructions": "Насколько раздражён клиент?",
        "criteria": [
          "Спокоен, просто описывает ситуацию",
          "Раздражён, но вежлив",
          "Очень зол, резкие выражения"
        ]
      }
    }
  }'

3. Прочитайте ответ

Ответ на запрос выше, полученный от живой модели (вероятности от прогона к прогону могут немного отличаться):

{
  "id": "rai-dec-1790130957-6mleoJ8dF5ZpJfN2MAkK",
  "model": "typesafe/jev-1.13-20260917",
  "provider": "TypeSafe",
  "answers": {
    "is_urgent": { "type": "noul", "noul": 0.98 },
    "department": {
      "type": "choice",
      "choice": "billing",
      "confidence": 0.61,
      "probabilities": { "billing": 0.74, "technical": 0.26, "sales": 0 }
    },
    "frustration": {
      "type": "score",
      "score": 0.88,
      "confidence": 0.82,
      "probabilities": { "0": 0.12, "1": 0.88, "2": 0 },
      "legend": {
        "0": "Спокоен, просто описывает ситуацию",
        "1": "Раздражён, но вежлив",
        "2": "Очень зол, резкие выражения"
      }
    }
  },
  "usage": { "input_tokens": 633, "output_tokens": 73 }
}
  • is_urgent = 0,98 — почти наверняка срочно. В коде это if noul > 0.8.
  • department = billing, но technical получил 0,26: в обращении есть и оплата, и «не могу подключить». Поэтому confidence всего 0,61 — модель честно показывает, что вариантов два. Такое обращение разумно отдать в биллинг с копией техподдержке.
  • frustration = 0,88 — между «спокоен» (0) и «раздражён, но вежлив» (1), ближе ко второму. Индекс 0 соответствует первому уровню в вашем списке criteria; список повторяется в ответе в поле legend.

Поле model в ответе содержит датированный снимок версии, который обслужил запрос (typesafe/jev-1.13-20260917), даже если в запросе стоял алиас.

Официальный SDK TypeSafe

Если у вас уже есть код на SDK TypeSafe (@typesafe-ai/sdk для JavaScript и TypeScript, typesafe-sdk для Python), его не нужно переписывать: смените адрес и ключ. Запрос и ответ те же, что у /api/v1/decisions.

# pip install typesafe-sdk
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

client = TypeSafeClient(
    base_url="https://routerai.ru/api",
    api_key="YOUR_API_KEY",
    model="jev-latest",
)

response = client.system_one(
    state="Здравствуйте! Третий день не могу подключить оплату на сайте — платежи клиентов не проходят, мы теряем заказы. Помогите, пожалуйста, срочно.",
    questions={
        "is_urgent": Noul(instructions="Клиент сообщает о срочной проблеме?"),
        "department": Choice(
            instructions="Какая команда должна заняться обращением?",
            criteria={
                "billing": "Платежи, счета, возвраты, подписки",
                "technical": "Ошибки, сбои, интеграции, настройка",
                "sales": "Тарифы, покупка, вопросы до оплаты",
            },
        ),
        "frustration": Score(
            instructions="Насколько раздражён клиент?",
            criteria=[
                "Спокоен, просто описывает ситуацию",
                "Раздражён, но вежлив",
                "Очень зол, резкие выражения",
            ],
        ),
    },
)

print(response.answers["is_urgent"].noul)      # 0.98
print(response.answers["department"].choice)   # "billing"
print(response.answers["frustration"].score)   # 0.88

Что нужно знать:

  • Оба SDK читают адрес и ключ и из переменных окружения: TYPESAFE_BASE_URL=https://routerai.ru/api и TYPESAFE_API_KEY=<ключ RouterAI> — тогда конструктор можно не менять.
  • Имена моделей принимаются в записи TypeSafe: jev-latest (значение SDK по умолчанию, если модель не указана) обслуживается как алиас ~typesafe/jev-latest, jev-1.13 — как typesafe/jev-1.13. Имя с автором используется как есть. В ответе поле model содержит идентификатор модели RouterAI.
  • Список моделей через SDK (client.models.list()) не работает: SDK ждёт формат TypeSafe, а GET /api/v1/models отдаёт каталог RouterAI. Смотрите модели в каталоге.
  • Стоимость запроса SDK не показывает, см. раздел о стоимости.

Уверенность: когда действовать автоматически

Вероятности — главное отличие Jev от чат-модели, которая отвечает одинаково уверенным тоном и когда знает, и когда гадает. confidence у choice и score показывает, насколько ответ однозначен: вся вероятность на одном варианте — близко к 1, размазана по нескольким — близко к 0. У noul отдельного confidence нет: сама вероятность и есть сигнал, значение около 0,5 означает «не знаю».

Удобно делить на три зоны и ставить порог по цене ошибки:

Уверенность Что делать
Высокая Действовать автоматически
Средняя Действовать осторожно: попросить подтверждение, пометить для проверки
Низкая Не действовать: передать человеку или более сильной модели
intent = answers["intent"]

if intent["confidence"] < 0.5:
    route_to_human(message)              # модель сомневается — не угадываем
elif intent["choice"] == "check_balance":
    show_balance(account_id)             # ошибка дешёвая — хватит умеренной уверенности
elif intent["choice"] == "approve_transfer":
    if intent["confidence"] > 0.9:
        confirm_then_execute(account_id)
    else:
        ask_user_to_confirm(account_id)  # ошибка дорогая — переспрашиваем

Конкретные пороги зависят от ваших данных. Начните с осторожных значений, прогоните на своих примерах с известными ответами и подстройте. Подбирали пороги под конкретную версию модели — логируйте поле model из ответа и перепроверяйте пороги после её обновления.

Сколько это стоит

  • Тарифицируются только входные токены: ваш state и вопросы. Выходные токены бесплатны. Актуальная цена в рублях — на странице модели.
  • К каждому запросу провайдер добавляет около 280 служебных токенов: запрос с коротким state и одним вопросом занимает примерно 300 входных токенов. Поэтому десять вопросов одним запросом заметно дешевле десяти запросов по одному вопросу — текст и служебная часть оплачиваются один раз.
  • Русский текст занимает больше токенов, чем английский той же длины.
  • В ответе поле usage содержит только токены. Стоимость запроса в рублях доступна по идентификатору из заголовка ответа X-Generation-Id (он же поле id ответа) через GET /api/v1/generation?id=<id> — поле total_cost, а также в истории запросов в личном кабинете.

Отличия от документации TypeSafe

Формат запроса и ответа тот же, что в документации TypeSafe, поэтому её материалы по формулировке вопросов и порогам применимы без изменений. Отличия только в подключении:

  • Эндпоинт — POST https://routerai.ru/api/v1/decisions, ключ — обычный ключ RouterAI.
  • Модель указывается через алиас ~typesafe/jev-latest (с ведущей тильдой — так в RouterAI выглядят все алиасы) или конкретной версией, например typesafe/jev-1.13.
  • Официальные SDK TypeSafe работают: укажите base_url https://routerai.ru/api и ключ RouterAI, см. раздел про SDK.
  • Стоимость не приходит в usage, см. раздел выше.

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

Это языковая модель? Нет. Jev — модель принятия решений: она возвращает типизированные ответы с вероятностями, а не текст, рассуждения или объяснения. Когда нужен текст — берите чат-модель. Когда нужно решение, на которое код может опереться, — Jev.

Может ли Jev объяснить ответ? Нет, объяснений и рассуждений в ответе нет — только вероятности. Если нужна письменная причина, пусть решение принимает Jev, а формулирует чат-модель. Если уверенность низкая — отдайте случай человеку. Часто причину можно получить и без текста: вместо noul «одобрить?» задайте choice с вариантами «ок / бессмыслица / мат / ненависть» — выбранный вариант и будет причиной.

Можно ли задать несколько вопросов в одном запросе? Да, и нужно: все независимые вопросы к одному state отправляйте вместе. Они обрабатываются параллельно и не видят ответов друг друга. Каждый вопрос даёт ровно один ответ, поэтому для списка элементов нужен свой вопрос на каждый — см. рецепт пакетной проверки.

Можно ли использовать ~typesafe/jev-latest? Да. Алиас указывает на текущую версию Jev и переводится на новую, когда она выходит; в ответе, логах и тратах при этом фигурирует реальная модель. Если вы подбирали пороги уверенности под конкретную версию, закрепите typesafe/jev-1.13 — иначе после обновления пороги придётся перепроверять.

Какой размер контекста? 32 000 токенов на state и самый длинный вопрос, 64 000 — на state и все вопросы вместе. Подробнее — в лимитах.

Нужен ли аккаунт TypeSafe или их ключ? Нет. И прямые запросы к /api/v1/decisions, и SDK TypeSafe работают с обычным ключом RouterAI, запросы оплачиваются с баланса RouterAI.

Работают ли параметры temperature, response_format, reasoning? Нет, у decisions-модели их нет. Тело запроса — только model, state и questions. Обращение с этими полями к /api/v1/chat/completions или другим эндпоинтам вернёт ошибку: Jev обслуживается только на /api/v1/decisions.

Что дальше