AI-модель

Узел, который вызывает модель, — он резервирует деньги вызова, отправляет вызов через пул провайдеров и после ответа отдаёт холд на расчёт.

7 мин чтения

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

Узел
AI-модель
Тип
ai_model
Категория
Модель
Порты
  • Успех success подключение обязательно
  • Ошибка error подключение необязательно
  • Пул исчерпан rate_limit подключение необязательно
  • Отказ deny подключение необязательно
Завершает путь
Нет

Что делает узел

Когда выполнение доходит до узла, вызов проходит три шага.

  1. Холд. Slen проверяет политики, оценивает вызов — модель, сообщения, потолок выхода — и резервирует оценку, умноженную на множитель запаса, в бюджетах, под которые попадает вызов. Вызов, сделанный для одного из ваших клиентов, резервирует ещё и свою цену в кредитах на счёте клиента того типа кредитов, который запрос называет в context.credit_type. Холд объясняет статья Как работает резервирование бюджета.

  2. Вызов. Вызов делает подключение пула провайдеров, попытка за попыткой, как говорит следующий раздел.

  3. Расчёт. Когда провайдер ответил, выполнение выходит через Успех, а холд в фоне списывается на сумму, во что обошёлся вызов. cost.actual выполнения становится известен, когда это сделано. Вызов, который не удался или был отклонён, возвращает свой холд.

Промпт — это messages из входа запроса, отправленные такими, какими пришли. Вход без непустого messages завершает выполнение как failed с invalid_flow_input. Узел добавляет модель, потолок выхода и температуру из своих настроек, а также список инструментов и формат ответа, когда они заданы.

Какое подключение делает вызов

  • Узел с выбранным пулом провайдеров вызывает через этот пул.

  • Узел без него вызывает через пул по умолчанию провайдера модели, а когда такого нет, — через одно подключение с одной попыткой; какое именно, говорит статья Пулы провайдеров.

  • Узел может задать своё число попыток и то, что следует за лимитом запросов. И то и другое главнее настроек пула и действует, только пока вызов идёт через пул.

  • Пул, который узел называет и который удалён или выключен, или провайдер без подключения, способного обслужить вызов, завершают вызов с provider_not_configured.

Когда выполнение ждёт на узле

Узел может заставить выполнение ждать. Тогда его статус — waiting, а запрос, который его начал, получил ответ 202.

  • Ожидание подключения. Когда узел или его пул отвечает на лимит запросов значением queue, а ни у одного подключения нет места для вызова, выполнение ждёт столько, сколько попросил провайдер, или минуту, и узел пробует снова с новым холдом. Пока выполнение ждёт, ничего не зарезервировано. После трёх ожиданий по умолчанию вызов завершается с pool_exhausted.

  • Вызов, который провайдер выполняет в фоне. Когда сервис для этого настроен, вызов выполнения, отправленного в асинхронном режиме, может быть передан провайдеру, который умеет выполнять его в фоне. Выполнение ждёт, пока Slen спрашивает провайдера, как идёт вызов, и продолжается с ответом. Холд такого вызова по умолчанию стоит 30 минут от начала вызова; этот срок ограничивает холд, а не вызов. О конце вызова сообщают operation.completed, operation.failed или operation.uncertain.

    • Когда провайдера больше не удаётся спросить, выполнение заканчивается как uncertain, а холд стоит, пока не истечёт.

    • Когда холд закрыло другое списание, пока вызов ждал, вызов заканчивается, не спросив у провайдера ответа, с background_hold_expired. Ничего не возвращается, и провайдер может всё равно выставить счёт за вызов.

    • Когда провайдер всё ещё называет вызов выполняющимся после того, как выполнение прождало 72 часа (по умолчанию), выполнение закрывается как failed с parked_expired. Никаких событий о вызове не отправляется, и его операция остаётся pending.

Политика перерасхода

У нового узла политики перерасхода нет. Политика, выбранная в поле При превышении, заставляет Slen оценить вызов второй раз прямо перед обращением к провайдеру и сравнить это число с холдом. Обе оценки получены из одного и того же запроса с разницей в мгновение, поэтому политика практически никогда не срабатывает — и при этом добавляет вторую оценку к каждому вызову. Когда она всё же срабатывает, вызов идёт дальше, останавливается с overrun_stopped, ждёт одобрения человека или переходит на модель подешевле со вторым холдом — как сказано в политике. Заявку, по которой решает человек, описывает статья Согласования.

Когда использовать

  • Он есть в каждом флоу, который вызывает модель: этот узел и есть вызов.

  • Поставьте перед ним Проверка бюджета, чтобы отказывать до того, как зарезервированы деньги, и Поиск в кеше, чтобы отвечать на повторный вопрос без вызова.

  • Подключите Отказ, Ошибка и Пул исчерпан, чтобы выбрать, что услышит вызывающий: модель подешевле через Запасной путь, заданный ответ, отказ со своим кодом.

  • Флоу может вызывать несколько моделей. Каждый вызов резервирует и рассчитывается сам по себе и является отдельной операцией, а cost.estimated выполнения — это сумма оценок сделанных вызовов.

Настройки

НастройкаДля чего она
modelМодель, которую вызывает узел, по её коду в каталоге моделей. Обязательна. Вызов оценивается по каталогу в момент, когда берётся его холд.
pool_idПул провайдеров, через который идёт вызов, по его идентификатору, записанному текстом. Без него вызов идёт через пул по умолчанию провайдера модели.
max_output_tokensНаибольшее число выходных токенов в ответе. Целое число не меньше 1. Без него ответ ограничен 1024 токенами, если сервис не настроен иначе. По этому потолку считается размер холда.
temperatureНасколько провайдер может варьировать ответ, от 0 до 2. Без неё провайдер берёт своё значение по умолчанию.
max_attemptsСколько подключений пула можно попробовать для вызова, от 1 до 5. Без него действует число самого пула.
on_rate_limitЧто следует за лимитом запросов провайдера — switch_connection, reject, queue или fallback_model. Без него действует выбор самого пула. Конструктор предлагает первые два; queue заставляет выполнение ждать подключения.
on_provider_errorЧто следует за ошибкой провайдера — switch_connection или reject. Без него действует выбор самого пула. Задаётся через API.
toolsИнструменты, которые может вызвать модель, — непустой список в том виде, который принимает провайдер. Задаётся через API.
response_formatФормат, который должен принять ответ, — объект с типом в том виде, который принимает провайдер. Задаётся через API.
on_overrunЧто делает узел, когда вторая оценка, сделанная прямо перед обращением к провайдеру, оказывается больше холда, — continue, stop, require_approval или degrade. У нового узла её нет. Обе оценки получены из одного запроса с разницей в мгновение, поэтому политика практически никогда не срабатывает.
overrun_toleranceНасколько вторая оценка может превысить холд, прежде чем сработает политика перерасхода, от 1 до 10. 1.25 значит — не больше чем на четверть сверх холда. Без него — 1.25.
degrade_to_modelМодель подешевле, на которую переходит вызов, когда политика перерасхода — degrade. Обязательна для этой политики и не может быть моделью самого узла.

В конструкторе на вкладке Настройки — поля Модель, Температура, Максимум выходных токенов и При превышении. На вкладке Подключения — Пул провайдеров, Максимум попыток и При лимите запросов (429). Вкладка Дополнительно показывает весь конфиг узла таким, каким он сохранён, вместе с ключами, для которых на вкладках нет полей: их задают через API.

У нового узла модели нет, и флоу не публикуется, пока она не выбрана. Пустое поле Максимум выходных токенов ограничивает ответ 1024 токенами, если сервис не настроен иначе, и по этому потолку считается размер холда.

Порты

ПортВыполнение выходит через него, когда
УспехПровайдер ответил. Обязательный
ОтказВызов отклонён до обращения к провайдеру: бюджетом (budget_exceeded, operation_limit_exceeded, concurrency_limit_exceeded), политикой (policy_denied), кредитами вашего клиента (insufficient_credits), блокировкой вашего клиента (customer_blocked) или политикой перерасхода (overrun_stopped)
Пул исчерпанПопытки или подключения пула закончились без ответа (pool_exhausted)
ОшибкаПровайдер ответил ошибкой, которая завершает вызов; вызов, который провайдер выполнял в фоне, не удался или закончился без ответа (background_hold_expired); или ни одно подключение не может обслужить провайдера модели (provider_not_configured)
  • Три последних порта необязательные. Когда у Пул исчерпан нет связи, а у Ошибка есть, выполнение уходит на ветку Ошибка. Что делает неподключённый порт, сказано в статье Порты и ветвление.

  • Когда провайдера вызвали, а его ответ потерялся, узел не выходит ни через один порт: выполнение заканчивается как uncertain с operation_uncertain, а холд стоит, пока не истечёт. Не запускайте такой запрос снова, как если бы он не удался.

  • Выполнение, которое закончилось как rejected после того, как вызов отклонили, хранит в cost.estimated оценку отклонённого вызова: деньги, которые отказ сберёг, а не потраченные. Отказ по кредитам вашего клиента оставляет его пустым. Ветка Отказ, которая отвечает без вызова модели, заканчивается как completed с той же оценкой и без фактической стоимости.

Выход

Когда провайдер ответил, узел оставляет ответ следующим узлам.

JSON
{
  "model": "gpt-4o-mini",
  "content": "Thank you for your order. It ships on Monday.",
  "finish_reason": "stop",
  "tool_calls": null,
  "usage": { "input_tokens": 1180, "output_tokens": 212, "cached_input_tokens": 0 }
}

Следующий узел читает его по пути nodes.<key>.output.content, где <key> — ключ этого узла во флоу. Вернуть ответ по умолчанию отвечает выходом последней модели.

Когда выполнение выходит через Отказ, Пул исчерпан или Ошибка, узел оставляет вместо этого то, чем закончился вызов:

JSON
{ "error_code": "budget_exceeded", "http_status": 402, "message": "Budget 74438200973595008 (monthly) exceeded" }

Ошибки

Настройки узла проверяются при проверке флоу и при его публикации.

В API запись issues называет такую проверку в params.detail; её code — invalid_node_config.

ПроверкаСообщение в конструкторе
ai_model_needs_modelУзлу «{node}» нужна модель.
ai_model_invalid_pool_idПул узла «{node}» должен быть задан своим идентификатором — текстом.
ai_model_invalid_max_output_tokensЛимит выходных токенов «{node}» должен быть целым числом, не меньше 1.
ai_model_invalid_max_attemptsЛимит попыток «{node}» должен быть целым числом от 1 до {max}.
ai_model_invalid_temperatureТемпература «{node}» должна быть числом от {min} до {max}.
ai_model_unsupported_on_rate_limit«{node}» использует несуществующее поведение при лимите запросов.
ai_model_unsupported_on_provider_error«{node}» использует несуществующее поведение при ошибке провайдера.
ai_model_tools_not_listИнструменты «{node}» должны быть непустым списком.
ai_model_unusable_toolУ «{node}» есть инструмент, который не является ни именованной функцией, ни типизированным инструментом провайдера.
ai_model_invalid_response_formatФормат ответа «{node}» должен быть объектом с полем type.
ai_model_unsupported_on_overrun«{node}» использует несуществующую политику перерасхода.
ai_model_invalid_overrun_toleranceДопуск перерасхода «{node}» должен быть между {min} и {max}.
ai_model_needs_degrade_model«{node}» понижает модель при перерасходе, но не указывает, на какую.
ai_model_degrades_to_same_model«{node}» понижает до модели, которую уже использует.

Проверка читает и то, что называет узел. Модель, которой нет в каталоге (unknown_model), пул, которого не существует (unknown_pool), и пул другого провайдера, не принимающий других провайдеров (pool_provider_mismatch), останавливают публикацию. Пул, который выключен, не имеет включённых подключений или не имеет ни одного, способного обслужить модель, — это предупреждение (pool_disabled, pool_without_connections, pool_cannot_serve_model), как и узел без ветки Ошибка (error_port_not_connected).

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

Пример

  • Запрос — По умолчанию → AI-модель
  • AI-модель — Успех → Вернуть ответ
  • AI-модель — Пул исчерпан → Запасной путь
  • AI-модель — Ошибка → Запасной путь
  • Запасной путь — По умолчанию → AI-модель
  • AI-модель — Успех → Вернуть ответ
  • AI-модель — Отказ → Отклонить запрос

AI-модель резервирует деньги и вызывает модель, а его ответ идёт в Вернуть ответ. Когда пул исчерпан или провайдер дал сбой, выполнение проходит Запасной путь ко второму AI-модель с моделью подешевле и своим холдом. Когда вызов отклонён, Отклонить запрос завершает запрос со своим кодом.

Собрано из openapi b070e1f, sdk contract 5cc7055, php ae4a53b, node 84bc62d