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

JSON
{
  "reasoning": {
    "effort": "high",
    "max_tokens": 2000,
    "exclude": false,
    "enabled": true
  }
}
ПолеСмысл
effortmax, 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:

JSON
{
  "model": "claude-sonnet-4.5",
  "max_tokens": 8000,
  "reasoning": { "max_tokens": 2000 }
}

У Claude минимум бюджета — 1024, максимум — 128 000. max_tokens ответа должен быть строго больше бюджета мыслей, иначе не останется места на текст.

Скрыть цепочку

JSON
{
  "reasoning": { "effort": "high", "exclude": true }
}

Модель всё равно тратит reasoning-токены (и вы за них платите), в content их не будет.

Сохранить между ходами

Нужно, когда модель вызвала инструмент и ждёт результат: без исходных мыслей она не продолжит ту же цепочку.

  1. message.reasoning — обычная строка.
  2. message.reasoning_details — полный массив. Его и отдавайте для Claude / GPT с шифрованием / суммаризацией.

Алиас reasoning_content = reasoning. Блоки reasoning_details нельзя переставлять и править.

JSON
{
  "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.

JSON
{
  "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. xhighhigh. Сколько токенов съест уровень — решает Google, точного бюджета нет.

reasoning.max_tokens уходит как thinkingBudget, но Gemini 3 всё равно свернёт его в уровень. Для точного бюджета это не работает.

Устаревшее

include_reasoning: true = reasoning: {}. include_reasoning: false = reasoning: { "exclude": true }. Лучше новый объект.