Skip to main content
Серверные инструменты работают в режиме beta: состав событий стрима и полей usage может дополняться. Изменения публикуем в истории изменений.
Серверный инструмент — это инструмент, который модель вызывает сама, а выполняет Polza. Вы добавляете в tools элемент вроде {"type": "polza:web_search"}, модель решает, нужен ли поиск, Polza ищет и возвращает результаты модели — и так, пока модель не будет готова ответить. Вы получаете один готовый ответ. Серверные инструменты работают со всеми моделями, которые поддерживают вызов функций, и во всех форматах API: Chat Completions, Responses, Anthropic Messages и Gemini.

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

Ответ — обычный chat.completion: текст модели, источники в annotations и итоговые цифры по всем шагам в usage.

Доступные инструменты

Оплачивается только выполненный вызов: вызов с ошибкой и повтор успешного вызова с теми же аргументами в рамках одного запроса бесплатны. polza:find_party и polza:find_company_by_email списываются, только если компания найдена. Актуальный список инструментов, их параметры в виде JSON Schema и цены отдаёт GET /v1/server-tools (без авторизации):

Параметры инструментов

Параметры задаёте вы в parameters — они ограничивают инструмент. Аргументы вызова (что искать, какую страницу открыть) выбирает модель.
Фильтры доменов применяются к полученной выдаче, поэтому результатов может прийти меньше, чем max_results.Модель может ограничить свежесть выдачи аргументом period: day, week, month или year — только результаты не старше дня, недели, месяца или года. Если поисковик отдал дату публикации, модель видит её рядом с результатом (Дата: 2026-09-22). В ответ клиенту дата не попадает; выбранный моделью period виден в arguments события tool_call.Подробнее о поиске — в гайде Поиск в интернете.
Модель получает итоговый URL, HTTP-статус, заголовок, автора и дату публикации (если есть) и основной текст страницы в Markdown — без меню и футеров.Ограничения: только публичные адреса http/https, только текстовые ответы (HTML, plain text, JSON, XML), не больше 3 редиректов, не больше 1 МБ ответа (дальше обрезается), JavaScript на странице не выполняется. PDF, картинки, приватные адреса, URL с логином и паролем и ответы 4xx/5xx возвращают модели ошибку.
Модель получает время в UTC (datetime), местное время (local), часовой пояс и день недели.
Модель сама задаёт запрос и число картинок (до 50, по умолчанию 10). По каждой картинке она получает image_url, title, source (название сайта), width и height, если они известны. Адреса страницы-источника и превью нет; сами изображения не загружаются.
Модель выбирает фразу и режим:
  • top — сколько раз искали фразу, топ запросов с ней и похожие запросы (до 50 строк каждого списка);
  • history — динамика числа запросов: по месяцам (12 полных месяцев), неделям (12 полных недель) или дням (30 дней по вчерашний).
Дополнительно модель может ограничить статистику регионами Яндекса и типами устройств.
Модель передаёт одну фразу за вызов и выбирает режим:
  • suggest — поисковые подсказки (продолжения фразы из строки поиска) Яндекса или Google;
  • questions — «Вопросы по теме» из выдачи Google, без ответов (до 20, по умолчанию 10).
Данные — из справочников DaData. Модель получает ответ DaData в JSON без пустых полей. Каждый вызов — не дольше 10 секунд.
  • polza:find_party — модель передаёт ИНН (10 или 12 цифр) или ОГРН (13 или 15 цифр). Без КПП возвращается головная организация, число филиалов — в branch_count; с КПП (9 цифр) — конкретный филиал. Ответ — {"found": true, "party": {...}} или {"found": false}.
  • polza:find_company_by_email — модель передаёт адрес электронной почты и получает базовые реквизиты компании или {"found": false}.
  • polza:clean_address — модель передаёт адрес одной строкой, до 250 символов, только Россия. Ответ — стандартизированный адрес с разбором на поля, индексом, кодами ФИАС и КЛАДР, координатами и кодами качества: qc (0 — адрес распознан уверенно, 1 — есть лишние части или мало данных, 2 — пустой или мусор, 3 — есть альтернативы) и qc_geo (точность координат: 0 — дом, 1 — ближайший дом, 2 — улица, 3 — населённый пункт, 4 — город, 5 — координат нет).
«Не найдено» — успешный вызов: он есть в счётчиках usage, но у find_party и find_company_by_email не оплачивается.

Как работает запрос

1

Модель получает описания инструментов

Вместе с вашими сообщениями модель видит инструменты из tools — как обычные функции web_search, web_fetch и т.д.
2

Модель вызывает инструмент

Если для ответа нужны данные, модель вызывает один или несколько инструментов. Если не нужны — сразу отвечает, и запрос обрабатывается как обычный.
3

Polza выполняет вызовы

Вызовы одного шага выполняются параллельно, каждый — не дольше 30 секунд (инструменты DaData — 10 секунд). Результаты добавляются в историю диалога.
4

Модель продолжает

Модель получает результаты и либо вызывает инструменты снова, либо отвечает. Цикл идёт, пока модель не ответит или не закончится лимит вызовов.
Что важно знать:
  • Каждый шаг — отдельный вызов модели. На каждом шаге модель заново получает всю историю вместе с результатами инструментов, поэтому prompt_tokens в итоговом usage — сумма по всем шагам.
  • Ошибка инструмента не прерывает запрос. Модель получает текст ошибки (например, «Ошибка инструмента web_fetch: Страница вернула статус 404») и сама решает, что делать дальше. Вызов с ошибкой не оплачивается.
  • Успешный вызов не повторяется. Если модель снова вызывает тот же инструмент с теми же аргументами, она бесплатно получает результат первого вызова. Вызов, завершившийся ошибкой, при повторе выполняется заново.
  • Не больше 5 одновременных вызовов на организацию для всех инструментов, кроме polza:datetime. Вызов, который не дождался очереди за 15 секунд, завершается ошибкой для модели.
  • tool_choice действует только на первом шаге, дальше модель выбирает сама (auto).
  • Модель должна поддерживать вызов функций. Исключение — polza:web_search: с моделью без вызова функций Polza выполнит поиск до обращения к модели, как плагин web с настройками по умолчанию. Параметры инструмента (max_results, фильтры доменов, engine) при этом не применяются, а поиск стоит так же — 0,50 ₽.

Лимиты вызовов

В max_tool_calls засчитывается каждый вызов инструмента, который запросила модель, — в том числе завершившийся ошибкой и повторный. В max_uses не засчитываются повторы успешного вызова и вызовы, у которых аргументы — невалидный JSON. Когда лимит max_tool_calls исчерпан, Polza просит модель ответить без инструментов тем, что уже удалось найти. Когда исчерпан max_uses, инструмент пропадает из списка для следующих шагов. Вызовы сверх любого из лимитов в том же шаге получают ошибку. stop_server_tools_when — массив условий:
spend_cap — мягкий потолок. Расходы проверяются перед каждым шагом модели, поэтому итоговая стоимость может превысить его: шаг, на котором потолок пройден, и его инструменты уже выполнены, а после них модель ещё раз вызывается, чтобы дать ответ.

Стриминг

При stream: true текст модели приходит по мере генерации, как в обычном запросе. Текст промежуточных шагов («Сейчас поищу…») тоже приходит клиенту; между текстами шагов вставляется пустая строка (\n\n). Пока выполняются инструменты, сервер шлёт SSE-комментарии : polza-progress — строки, начинающиеся с :, которые стандартные SDK игнорируют. По ним видно, какой инструмент сейчас работает. С include_server_tool_events вместо комментариев об инструментах приходят события, остальные комментарии (например, пока проверяется ответ модели) приходят в любом случае:
Последний чанк перед [DONE] несёт finish_reason, все источники в delta.annotations и итоговый usage — даже без stream_options.include_usage. Если модель вызывала серверные инструменты, в нём же поле polza с id запроса:
Все чанки стрима идут с одним id — это id первого шага. Id запроса в истории — polza.parent_generation_id из последнего чанка.

События инструментов

Чтобы видеть в стриме, что делает модель (например, показывать «Ищу: курс доллара ЦБ»), передайте stream_options.include_server_tool_events: true. Тогда в стриме появятся чанки с пустым delta и полем polza:
Когда лимит вызовов исчерпан, перед последним шагом приходит:
summary — краткий итог успешного вызова без полного содержимого. У status: "failed" нет ни summary, ни текста ошибки — его получает только модель: Стоимость шага в step_end уже включает инструменты, результаты которых модель получила на этом шаге.

Только финальный ответ

stream_options.hide_intermediate_text: true убирает из стрима текст промежуточных шагов — клиент получит только финальный ответ. Цена за это — плавность: финальный ответ приходит сразу целиком, когда модель закончила шаг, а не по мере генерации. Опция работает только при stream: true. Без стрима message.content содержит текст всех шагов, разделённый пустой строкой.

Ответ

prompt_tokens_details и completion_tokens_details относятся к последнему шагу. Для итоговой стоимости используйте cost_rub и cost_details: usage.plugins, если он есть, показывает операции только последнего шага.

Другие форматы API

Серверные инструменты подключаются в любом формате. Цикл тот же, отличается только то, как инструменты передаются и как видны в ответе.
Параметры инструмента передаются рядом с type (вложенный parameters, как в Chat Completions, тоже принимается):
Каждый вызов — отдельный элемент output с типом инструмента и итогом в action, после них — сообщение модели:
  • В стриме элемент инструмента приходит событием response.output_item.added со status: "in_progress" и событием response.output_item.done с результатом. include_server_tool_events не нужен.
  • В стриме response.id — id первого шага, id запроса в истории — polza.parent_generation_id в response.completed.
  • Родной web_search (и web_search_preview) ищет провайдер модели, если умеет, иначе Polza через polza:web_search — см. Поиск в интернете. Когда ищет Polza, элемент называется web_search_call, а action.type — search.
  • Работают max_tool_calls (до 30), stop_server_tools_when и stream_options.hide_intermediate_text. max_tool_calls в Responses, как и в OpenAI, ещё и ограничивает число вызовов, которые модель делает за один шаг. Значения stream_options должны быть логическими — строка вернёт 400.

Свои функции вместе с серверными

В одном tools можно смешивать свои функции и серверные инструменты. Серверные Polza выполняет сама; как только модель вызывает вашу функцию, цикл останавливается и управление возвращается вам — как в обычном Tool Calling.
Ответ — finish_reason: "tool_calls" и вызовы шага в tool_calls:
Выполните свою функцию и отправьте следующий запрос как обычно: историю с сообщением ассистента и tool-сообщением с результатом, с тем же tools. Если в том же шаге модель вызвала и серверный инструмент, его вызов тоже будет в tool_calls, но выполнен он не был. Выполнять его не нужно: верните сообщение ассистента как есть, а tool-сообщения добавьте только для своих функций. Polza выполнит оставшиеся серверные вызовы в начале следующего запроса:
Серверный инструмент в запросе занимает своё имя без префикса (web_search, web_fetch, datetime, image_search, wordstat, search_suggestions, find_party, find_company_by_email, clean_address): своя функция с таким же именем рядом с ним вернёт 400.

Инструменты openrouter:*

Если вы переходите с OpenRouter, типы openrouter:* можно не менять: openrouter:web_search, openrouter:web_fetch и openrouter:datetime выполняют инструменты Polza polza:web_search, polza:web_fetch и polza:datetime. В ответе и событиях тип всегда polza:*. Типы, которых нет в GET /v1/server-tools, возвращают 400.

История запросов

Запрос с серверными инструментами — одна запись в истории генераций, шаги модели — вложенные записи. Для шага GET /v1/history/generations/{id} возвращает parentGenerationId — id запроса — и stepIndex.

Ошибки

Запрос проверяется до первого вызова модели. Ошибка возвращается статусом 400 — в том числе при stream: true, до начала стрима. Ошибки внутри цикла — сайт недоступен, поисковик не ответил — не возвращаются клиенту: модель получает текст ошибки и продолжает. Если не ответила сама модель, запрос завершается обычной ошибкой провайдера.

Как списываются деньги

  • Шаги модели оплачиваются по тарифу модели, как обычные запросы. Каждый шаг заново отправляет модели всю историю, поэтому запрос с несколькими шагами дороже одного вызова.
  • Инструменты — фиксированная цена за выполненный вызов (см. таблицу или GET /v1/server-tools). Вызовы с ошибкой и повторы успешного вызова с теми же аргументами бесплатны.
  • Итог — usage.cost_rub, разбивка — usage.cost_details. В истории — cost записи запроса.
  • Если запрос прервался (отмена клиентом, ошибка провайдера), уже выполненные шаги модели оплачиваются.
Ограничить расходы на один запрос можно через stop_server_tools_when — с поправкой на то, что потолок мягкий.

Следующие шаги

Поиск в интернете

Как Polza ищет в интернете и чем инструмент отличается от плагина web

Tool Calling

Свои функции: вызов и возврат результата

Учёт средств

Поля usage и стоимость запроса

История генераций

Записи запросов и шагов