Перейти к содержимому
EN

Веб-поиск

Модель отвечает по данным, на которых её обучили, поэтому про вчерашние новости, текущий курс или свежий релиз она либо промолчит, либо придумает. Параметр web_search в POST /v1/chat/completions включает поиск: модель сама решает, когда искать, и возвращает ответ со ссылками на источники.

Значение Что делает
true или "auto" Нативный поиск провайдера, если он у модели есть; иначе Exa
"native" Только встроенный поиск провайдера
"exa" Нейтральный поиск Exa независимо от модели
отсутствует или false Поиска нет

Нативный поиск есть у моделей OpenAI, Anthropic, Google и xAI — кроме старых GPT (gpt-4o, chatgpt-4o, gpt-4-turbo), которые уходят на Exa. Проверять не по имени, а по каталогу: GET /v1/models отдаёт capabilities.native_search.

"native" у модели без встроенного поиска не ошибка — значение автоматически понижается до "auto", и запрос уходит на Exa. Так сделано намеренно: выбор движка обычно живёт в настройках клиента и переживает смену модели, и жёсткая ошибка ломала бы диалог на ровном месте.

Ссылки приходят в message.annotations в формате OpenAI:

{
"message": {
"role": "assistant",
"content": "Курс ЦБ на сегодня — 81,42 ₽ за доллар.",
"annotations": [
{"type": "url_citation", "url_citation": {"url": "https://cbr.ru/currency_base/daily/", "title": "Банк России"}}
]
}
}

В стриминге источники приезжают отдельным чанком с delta.annotations перед финальным чанком с finish_reason — если клиент дочитывает поток до конца, он их не пропустит. В текст ответа ссылки не подмешиваются: content остаётся чистым, ссылки лежат структурой.

Модели perplexity/sonar, sonar-pro и sonar-deep-research ищут всегда, независимо от web_search: поиск встроен в саму модель, отключить его нечем. Параметр им передавать не нужно, а выбор движка к ним неприменим — capabilities.native_search у них false именно поэтому. Источники приходят так же, в annotations.

Поиск тарифицируется за запрос, отдельно от токенов, и добавляется к обычной оплате ответа. Цену нативного поиска каждая модель объявляет своей — она лежит в каталоге в pricing.web_search_rub_per_requestweb_search_usd_per_request). У Exa цена одна на все модели, поэтому в карточке модели её нет; фактическую плату за конкретный запрос видно в GET /v1/history.

curl -s https://api.mixen.ai/v1/models \
-H "Authorization: Bearer $MIXEN_API_KEY" \
| python -c "import json,sys; [print(m['id'], m['pricing'].get('web_search_rub_per_request')) for m in json.load(sys.stdin)['data'] if m['pricing'].get('web_search_rub_per_request')]"

Перед генерацией с включённым поиском мы резервируем на балансе плату за поиск и за подмешанную в контекст выдачу — то есть запрос не пройдёт, если денег хватает только на сам ответ. Резерв не списание: неиспользованная часть остаётся на балансе, списывается фактический расход.

from openai import OpenAI
client = OpenAI(base_url="https://api.mixen.ai/v1", api_key=MIXEN_API_KEY)
resp = client.chat.completions.create(
model="gemini-3.1-pro",
messages=[{"role": "user", "content": "Что нового вышло у OpenAI на этой неделе?"}],
extra_body={"web_search": "native"},
)
print(resp.choices[0].message.content)
for a in resp.choices[0].message.annotations or []:
print("", a["url_citation"]["url"])
  • Ищет модель, а не вы. web_search только разрешает поиск; пойдёт ли модель в интернет, решает она сама. На вопрос, ответ на который она знает, поиска не будет — и платы за него тоже.
  • Выдача приезжает входными токенами. Найденное подмешивается в контекст, поэтому счёт за такой запрос выше обычного даже сверх платы за сам поиск.
  • web_search — не поле OpenAI. В официальных SDK его передают через extra_body (Python) или как дополнительное поле тела (TypeScript, cURL).