API
Токены рассуждений
У моделей с thinking API может вернуть токены рассуждений — цепочку мыслей до ответа. Они считаются выходными токенами и входят в usage.cost_rub.
По умолчанию, если модель их выдала, они лежат в message.reasoning (и часто в reasoning_details). Часть моделей (серия OpenAI o) думает, но текст мыслей не отдаёт.
Работает в /chat/completions, /responses и /messages. То же можно сохранить в пресете. Поле reasoning не входит в стандарт OpenAI: в Python — extra_body, в TypeScript — @ts-expect-error.
Не оба сразу
Не задавайте effort и max_tokens одновременно.
Параметр reasoning
{
"reasoning": {
"effort": "high",
"max_tokens": 2000,
"exclude": false,
"enabled": true
}
}| Поле | Смысл |
|---|---|
effort | max, xhigh, high, medium, low, minimal, none |
max_tokens | Жёсткий бюджет мыслей (Claude, Gemini, часть Qwen) |
exclude | Думать, но не класть текст в ответ |
enabled | Включить со средним усилием, если не задали effort/max_tokens |
effort: "none" выключает рассуждения. У моделей, где thinking обязателен, none отклонят.
Если модель понимает только effort, max_tokens переводится в ближайший уровень. Если только бюджет — effort переводится в долю от max_tokens ответа: max/xhigh ≈ 95%, high ≈ 80%, medium ≈ 50%, low ≈ 20%, minimal ≈ 10%.
curl https://api.aitunnel.ru/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer sk-aitunnel-xxx" \
-d '{
"model": "claude-sonnet-4.5",
"max_tokens": 8000,
"reasoning": { "effort": "high" },
"messages": [
{ "role": "user", "content": "Что больше: 9.11 или 9.9?" }
]
}'Бюджет токенов
Для Claude и части Gemini/Qwen:
{
"model": "claude-sonnet-4.5",
"max_tokens": 8000,
"reasoning": { "max_tokens": 2000 }
}У Claude минимум бюджета — 1024, максимум — 128 000. max_tokens ответа должен быть строго больше бюджета мыслей, иначе не останется места на текст.
Скрыть цепочку
{
"reasoning": { "effort": "high", "exclude": true }
}Модель всё равно тратит reasoning-токены (и вы за них платите), в content их не будет.
Сохранить между ходами
Нужно, когда модель вызвала инструмент и ждёт результат: без исходных мыслей она не продолжит ту же цепочку.
message.reasoning— обычная строка.message.reasoning_details— полный массив. Его и отдавайте для Claude / GPT с шифрованием / суммаризацией.
Алиас reasoning_content = reasoning. Блоки reasoning_details нельзя переставлять и править.
{
"role": "assistant",
"content": null,
"tool_calls": [{ "id": "call_abc", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\": \"Москва\"}" } }],
"reasoning_details": [
{
"type": "reasoning.text",
"text": "Нужна погода, затем посоветую одежду.",
"format": "anthropic-claude-v1",
"index": 0
}
]
}См. также вызов инструментов.
GPT-5.6
reasoning.context:auto(по умолчанию),all_turns(видеть мысли прошлых ходов),current_turn(только этот ход).reasoning.mode:standardилиpro.pro— более глубокое многопроходное мышление, те же цены за токен, обычно больше токенов. Можно вместо этого вызвать модель с суффиксом-proиз каталога (gpt-5.6-sol-pro).
Как выглядит ответ
Non-stream: choices[].message.reasoning и reasoning_details. Stream: то же в delta.
{
"choices": [
{
"message": {
"role": "assistant",
"content": "9.9 больше.",
"reasoning": "Сравниваю 9.11 и 9.9 как десятичные…",
"reasoning_details": [
{
"type": "reasoning.text",
"text": "9.11 — это 9 + 11/100. 9.9 — это 9 + 9/10.",
"format": "anthropic-claude-v1",
"index": 0
}
]
}
}
]
}Типы в reasoning_details: reasoning.text, reasoning.summary, reasoning.encrypted. В стриме зашифрованное может прийти как [REDACTED]. Склеивайте чанки по порядку.
В usage смотрите completion_tokens_details.reasoning_tokens (в Responses — output_tokens_details).
Claude
Только объект reasoning, не суффикс :thinking в имени модели.
Если задан effort, бюджет ≈ max(min(max_tokens * доля, 128000), 1024). На новых Claude по умолчанию в ответ кладётся краткое резюме мыслей: токенов в usage больше, чем символов в reasoning.
Gemini 3
effort мапится в thinkingLevel: minimal / low / medium / high. xhigh → high. Сколько токенов съест уровень — решает Google, точного бюджета нет.
reasoning.max_tokens уходит как thinkingBudget, но Gemini 3 всё равно свернёт его в уровень. Для точного бюджета это не работает.
Устаревшее
include_reasoning: true = reasoning: {}. include_reasoning: false = reasoning: { "exclude": true }. Лучше новый объект.