Skip to content

Оценка вместо генерации (Jev) ​

Обычная модель пишет текст, и дальше вы его разбираете: ищете «да» в ответе, парсите JSON, надеетесь, что формат не поедет. Jev не пишет текста вообще. Вы даёте ей состояние и список типизированных вопросов — она возвращает вероятности, оценки и выбор.

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

Для чего: классификация обращений, маршрутизация заявок, проверка по критериям, модерация, отбор — всё, где нужен не текст, а решение.

Несколько вопросов — один запрос

Модель отвечает на все вопросы за один вызов. Десять вопросов одним запросом стоят примерно как один — это и есть способ экономить.

Быстрый старт ​

bash
curl https://nordrouter.com/v1/evaluate \
  -H "Authorization: Bearer ВАШ-КЛЮЧ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "typesafe-ai/jev",
    "state": "Заказ №1841 не пришёл, клиент пишет третий раз, тон резкий",
    "questions": {
      "urgent": {
        "type": "boolean",
        "question": "Это срочно?",
        "criteria": { "true": "повторное обращение или резкий тон", "false": "первое спокойное" }
      },
      "team": {
        "type": "choice",
        "question": "Кому передать",
        "criteria": { "доставка": "про заказ и сроки", "биллинг": "про деньги", "поддержка": "всё прочее" }
      }
    }
  }'

Ответ:

json
{
  "model": "typesafe-ai/jev",
  "answers": {
    "urgent": { "type": "boolean", "probability": 0.85 },
    "team": {
      "type": "choice",
      "choice": "доставка",
      "probabilities": { "доставка": 1, "биллинг": 0, "поддержка": 0 },
      "confidence": 0.99
    }
  },
  "usage": { "input_tokens": 434, "output_tokens": 82 }
}

Ключи ответов — ваши же имена вопросов. Ничего парсить не нужно.

Три вида вопросов ​

У каждого вида своя форма criteria

Это главная и единственная ловушка формата. Перепутать легко, ошибка приходит сразу и понятная.

boolean — да или нет ​

criteria — объект с двумя ключами:

json
"angry": {
  "type": "boolean",
  "question": "Клиент раздражён?",
  "criteria": { "true": "резкий тон, требования", "false": "спокойный тон" }
}

Возвращает probability от 0 до 1. Порог выбираете вы: 0.5 — обычный, 0.8 — когда ошибка дорога.

score — оценка по шкале ​

criteria — массив, от низшего к высшему:

json
"severity": {
  "type": "score",
  "question": "Насколько серьёзно",
  "criteria": ["мелочь", "обычное", "критично"]
}

Возвращает score, распределение probabilities по делениям и confidence.

choice — выбор одного из вариантов ​

criteria — объект: вариант и его описание.

json
"route": {
  "type": "choice",
  "question": "Кому отдать",
  "criteria": { "поддержка": "общие вопросы", "биллинг": "про деньги", "инженер": "поломка" }
}

Возвращает choice, распределение по всем вариантам и confidence.

Вместо критериев — инструкция ​

Для любого вида можно передать instructions строкой:

json
"ok": { "type": "boolean", "question": "Всё в порядке?", "instructions": "да, если жалоб нет" }

Одно из двух — criteria или instructions — обязательно. Без них модель откажет.

Python ​

python
import httpx

r = httpx.post(
    "https://nordrouter.com/v1/evaluate",
    headers={"Authorization": "Bearer ВАШ-КЛЮЧ"},
    json={
        "model": "typesafe-ai/jev",
        "state": ticket_text,
        "questions": {
            "spam":  {"type": "boolean", "question": "Это спам?",
                      "criteria": {"true": "реклама или бессмыслица", "false": "живое обращение"}},
            "topic": {"type": "choice", "question": "О чём обращение",
                      "criteria": {"оплата": "про деньги", "доступ": "не может войти",
                                   "ошибка": "что-то сломалось"}},
        },
    },
    timeout=40,
)
a = r.json()["answers"]

if a["spam"]["probability"] > 0.8:
    drop(ticket)
else:
    route_to(a["topic"]["choice"])

Цена ​

за 1 млн токенов
вход$0,0504
выходбесплатно

Считается только то, что вы прислали. Ответ не тарифицируется вовсе.

Обращение из примера выше — 434 токена, то есть $0,0000219. Около 46 тысяч таких вызовов на один доллар.

Сколько списано за конкретный вызов, приходит в заголовке X-Charged-USD.

Ограничение частоты ​

Канал держит 15 запросов в секунду. Всё, что сверх, получает 429сразу — мы не держим ваш запрос в ожидании и не решаем за вас, сколько ему висеть. Вместе с отказом приходит заголовок Retry-After с числом секунд.

Повторы — на вашей стороне, и это намеренно: вы лучше знаете, что делать с конкретным вызовом — подождать, отложить или отбросить.

python
import time, httpx

def evaluate(payload, tries=3):
    for _ in range(tries):
        r = httpx.post(URL, headers=HDRS, json=payload, timeout=40)
        if r.status_code != 429:
            return r
        time.sleep(int(r.headers.get("Retry-After", 1)))
    return r

Держите темп ниже потолка

Отказы ничего не стоят, но и пользы не приносят. Пятнадцать запросов в секунду ровным темпом дадут больше сделанной работы, чем сотня разом, из которой восемьдесят вернутся с 429.

Пределы и особенности ​

  • Контекст — 32 000 токенов на state вместе с вопросами.
  • Потока (stream) нет: ответ приходит целиком, обычно за 0,3–0,6 секунды.
  • Модель только эта. Запрос с другим именем вернёт 400.
  • Обычный /v1/chat/completions с ней не работает: это оценочная модель, у неё свой адрес /v1/evaluate.

Ключ и баланс ​

Ваш обычный ключ sk-nr-… и ваш обычный баланс. Ничего заводить не нужно: если вы уже пользуетесь NordRouter, оценочная модель доступна сразу.

Списания видны в кабинете вместе с остальными — отдельной бухгалтерии нет.

Ошибки ​

кодчто значитчто делать
401ключ не принятобычный sk-nr-…, проверьте, что он включён
402на счёте пустопополнить
400не та модель или форма вопросасверьтесь с формой criteria выше
429превышен потолок частотыподождать Retry-After секунд и повторить
502модель временно недоступнаповторить через несколько секунд