Токены мыслей
Для моделей, которые это поддерживают, API AITUNNEL может возвращать токены мыслей (reasoning tokens), также известные как thinking tokens. AITUNNEL нормализует различные способы настройки количества токенов рассуждений, которые будет использовать модель, предоставляя единый интерфейс для разных провайдеров.
Токены мыслей дают прозрачный взгляд на шаги рассуждений, которые делает модель. Токены мыслей считаются выходными токенами и оплачиваются соответственно.
Токены мыслей включены в ответ по умолчанию, если модель решает их вывести. Токены мыслей будут появляться в поле reasoning
каждого сообщения, если вы не решите их исключить.
Некоторые модели не возвращают токены мыслей
Хотя большинство моделей и провайдеров делают токены мыслей доступными в ответе, некоторые (например, OpenAI o-series и Gemini Flash Thinking) этого не делают.
Управление токенами мыслей
Вы можете управлять токенами мыслей в ваших запросах, используя параметр reasoning
:
{
"model": "your-model",
"messages": [],
"reasoning": {
// Один из следующих (не оба):
"effort": "high", // Может быть "high", "medium" или "low" (стиль OpenAI)
"max_tokens": 2000, // Конкретный лимит токенов (стиль Anthropic)
// Опционально: По умолчанию false. Поддерживается всеми моделями.
"exclude": false // Установите true, чтобы исключить токены мыслей из ответа
}
}
Объект конфигурации reasoning
объединяет настройки для управления силой рассуждений в разных моделях. Смотрите примечание для каждого варианта ниже, чтобы узнать, какие модели поддерживаются и как будут вести себя другие модели.
Максимальное количество токенов для рассуждений
Поддерживаемые модели
В настоящее время поддерживается моделями Anthropic и Gemini thinking
Для моделей, которые поддерживают выделение токенов для рассуждений, вы можете управлять этим следующим образом:
"max_tokens": 2000
- Напрямую указывает максимальное количество токенов для использования в рассуждениях
Для моделей, которые поддерживают только reasoning.effort
(см. ниже), значение max_tokens
будет использоваться для определения уровня усилий.
Уровень усилий рассуждений
Поддерживаемые модели
В настоящее время поддерживается моделями OpenAI o-series и Grok
"effort": "high"
- Выделяет большую часть токенов для рассуждений (примерно 80% от max_tokens)"effort": "medium"
- Выделяет умеренную часть токенов (примерно 50% от max_tokens)"effort": "low"
- Выделяет меньшую часть токенов (примерно 20% от max_tokens)
Для моделей, которые поддерживают только reasoning.max_tokens
, уровень усилий будет установлен на основе процентов выше.
Исключение токенов мыслей
Если вы хотите, чтобы модель использовала рассуждения внутренне, но не включала их в ответ:
"exclude": true
- Модель все равно будет использовать рассуждения, но они не будут возвращены в ответе
Токены мыслей будут появляться в поле reasoning
каждого сообщения.
Устаревшие параметры
Для обратной совместимости AITUNNEL все еще поддерживает следующие устаревшие параметры:
include_reasoning: true
- Эквивалентноreasoning: {}
include_reasoning: false
- Эквивалентноreasoning: { exclude: true }
Однако мы рекомендуем использовать новый унифицированный параметр reasoning
для лучшего контроля и совместимости в будущем.
Примеры
Базовое использование с токенами мыслей
import requests
import json
url = "https://api.aitunnel.ru/v1/chat/completions"
headers = {
"Authorization": f"Bearer <AITUNNEL_API_KEY>",
"Content-Type": "application/json"
}
payload = {
"model": "o3",
"messages": [
{"role": "user", "content": "Как бы вы построили самый высокий небоскреб в мире?"}
],
"reasoning": {
"effort": "high" # Использовать высокий уровень усилий для рассуждений
}
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
print(response.json()['choices'][0]['message']['reasoning'])
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: "https://api.aitunnel.ru/v1",
apiKey: "<AITUNNEL_API_KEY>",
});
async function getResponseWithReasoning() {
const response = await openai.chat.completions.create({
model: "o3",
messages: [
{
role: "user",
content: "Как бы вы построили самый высокий небоскреб в мире?",
},
],
reasoning: {
effort: "high", // Использовать высокий уровень усилий для рассуждений
},
});
console.log("REASONING:", response.choices[0].message.reasoning);
console.log("CONTENT:", response.choices[0].message.content);
}
getResponseWithReasoning();
Использование максимального количества токенов для рассуждений
Для моделей, которые поддерживают прямое выделение токенов (например, модели Anthropic), вы можете указать точное количество токенов для использования в рассуждениях:
import requests
import json
url = "https://api.aitunnel.ru/v1/chat/completions"
headers = {
"Authorization": f"Bearer <AITUNNEL_API_KEY>",
"Content-Type": "application/json"
}
payload = {
"model": "claude-3.7-sonnet",
"messages": [
{"role": "user", "content": "Какой самый эффективный алгоритм для сортировки большого набора данных?"}
],
"reasoning": {
"max_tokens": 2000 # Выделить 2000 токенов (или приблизительное усилие) для рассуждений
}
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
print(response.json()['choices'][0]['message']['reasoning'])
print(response.json()['choices'][0]['message']['content'])
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: "https://api.aitunnel.ru/v1",
apiKey: "<AITUNNEL_API_KEY>",
});
async function getResponseWithReasoning() {
const response = await openai.chat.completions.create({
model: "claude-3.7-sonnet",
messages: [
{
role: "user",
content:
"Какой самый эффективный алгоритм для сортировки большого набора данных?",
},
],
reasoning: {
max_tokens: 2000, // Выделить 2000 токенов (или приблизительное усилие) для рассуждений
},
});
console.log("REASONING:", response.choices[0].message.reasoning);
console.log("CONTENT:", response.choices[0].message.content);
}
getResponseWithReasoning();
Исключение токенов мыслей из ответа
Если вы хотите, чтобы модель использовала рассуждения внутренне, но не включала их в ответ:
import requests
import json
url = "https://api.aitunnel.ru/v1/chat/completions"
headers = {
"Authorization": f"Bearer <AITUNNEL_API_KEY>",
"Content-Type": "application/json"
}
payload = {
"model": "deepseek-r1",
"messages": [
{"role": "user", "content": "Объясните квантовые вычисления простыми словами."}
],
"reasoning": {
"effort": "high",
"exclude": true # Использовать рассуждения, но не включать их в ответ
}
}
response = requests.post(url, headers=headers, data=json.dumps(payload))
# Нет поля reasoning в ответе
print(response.json()['choices'][0]['message']['content'])
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: "https://api.aitunnel.ru/v1",
apiKey: "<AITUNNEL_API_KEY>",
});
async function getResponseWithReasoning() {
const response = await openai.chat.completions.create({
model: "deepseek-r1",
messages: [
{
role: "user",
content: "Объясните квантовые вычисления простыми словами.",
},
],
reasoning: {
effort: "high",
exclude: true, // Использовать рассуждения, но не включать их в ответ
},
});
console.log("REASONING:", response.choices[0].message.reasoning);
console.log("CONTENT:", response.choices[0].message.content);
}
getResponseWithReasoning();
Продвинутое использование: Цепочка рассуждений
Этот пример показывает, как использовать токены мыслей в более сложном рабочем процессе. Он внедряет рассуждения одной модели в другую для улучшения качества ответа:
import requests
import json
question = "Что больше: 9.11 или 9.9?"
url = "https://api.aitunnel.ru/v1/chat/completions"
headers = {
"Authorization": f"Bearer <AITUNNEL_API_KEY>",
"Content-Type": "application/json"
}
def do_req(model, content, reasoning_config=None):
payload = {
"model": model,
"messages": [
{"role": "user", "content": content}
],
"stop": "</think>"
}
return requests.post(url, headers=headers, data=json.dumps(payload))
# Получить рассуждения от способной модели
content = f"{question} Пожалуйста, подумайте об этом, но не выводите ответ"
reasoning_response = do_req("deepseek-r1", content)
reasoning = reasoning_response.json()['choices'][0]['message']['reasoning']
# Давайте проверим! Вот наивный ответ:
simple_response = do_req("gpt-4o-mini", question)
print(simple_response.json()['choices'][0]['message']['content'])
# Вот ответ с внедренным токеном рассуждений:
content = f"{question}. Вот контекст, который поможет вам: {reasoning}"
smart_response = do_req("gpt-4o-mini", content)
print(smart_response.json()['choices'][0]['message']['content'])
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: "https://api.aitunnel.ru/v1",
apiKey: "<AITUNNEL_API_KEY>",
});
async function doReq(model, content, reasoningConfig) {
const payload = {
model,
messages: [{ role: "user", content }],
stop: "</think>",
...reasoningConfig,
};
return openai.chat.completions.create(payload);
}
async function getResponseWithReasoning() {
const question = "Что больше: 9.11 или 9.9?";
const reasoningResponse = await doReq(
"deepseek/deepseek-r1",
`${question} Пожалуйста, подумайте об этом, но не выводите ответ`
);
const reasoning = reasoningResponse.choices[0].message.reasoning;
// Давайте проверим! Вот наивный ответ:
const simpleResponse = await doReq("gpt-4o-mini", question);
console.log(simpleResponse.choices[0].message.content);
// Вот ответ с внедренным токеном рассуждений:
const content = `${question}. Вот контекст, который поможет вам: ${reasoning}`;
const smartResponse = await doReq("gpt-4o-mini", content);
console.log(smartResponse.choices[0].message.content);
}
getResponseWithReasoning();
Реализация рассуждений для конкретных провайдеров
Модели Anthropic с токенами мыслей
Последние модели Claude, такие как claude-3.7-sonnet, поддерживают работу с токенами мыслей и их возврат.
Вы можете включить рассуждения в моделях Anthropic двумя способами:
- Используя суффикс варианта
-thinking
(например,claude-3.7-sonnet-thinking
). Вариант thinking по умолчанию использует высокий уровень усилий. - Используя унифицированный параметр
reasoning
сeffort
илиmax_tokens
Максимальное количество токенов для рассуждений в моделях Anthropic
При использовании моделей Anthropic с рассуждениями:
- При использовании параметра
reasoning.max_tokens
это значение используется напрямую с минимумом 1024 токенов. - При использовании суффикса варианта
-thinking
или параметраreasoning.effort
бюджет токенов рассчитывается на основе значенияmax_tokens
.
Выделение токенов для рассуждений ограничено максимумом 32 000 токенов и минимумом 1024 токена. Формула для расчета budget_tokens: budget_tokens = max(min(max_tokens * {effort_ratio}, 32000), 1024)
effort_ratio составляет 0.8 для высокого уровня усилий, 0.5 для среднего уровня и 0.2 для низкого уровня.
Важно
max_tokens
должен быть строго больше бюджета рассуждений, чтобы гарантировать наличие токенов для финального ответа после размышлений.
Использование токенов и биллинг
Обратите внимание, что токены мыслей считаются выходными токенами для целей биллинга. Использование токенов мыслей увеличит ваше использование токенов, но может значительно улучшить качество ответов модели.
Примеры с моделями Anthropic
Пример 1: Режим стриминга с токенами мыслей
from openai import OpenAI
client = OpenAI(
base_url="https://api.aitunnel.ru/v1",
api_key="<AITUNNEL_API_KEY>",
)
def chat_completion_with_reasoning(messages):
response = client.chat.completions.create(
model="claude-3.7-sonnet",
messages=messages,
max_tokens=10000,
reasoning={
"max_tokens": 8000 # Напрямую указать бюджет токенов для рассуждений
},
stream=True
)
return response
for chunk in chat_completion_with_reasoning([
{"role": "user", "content": "Что больше, 9.9 или 9.11?"}
]):
if hasattr(chunk.choices[0].delta, 'reasoning') and chunk.choices[0].delta.reasoning:
print(f"REASONING: {chunk.choices[0].delta.reasoning}")
elif chunk.choices[0].delta.content:
print(f"CONTENT: {chunk.choices[0].delta.content}")
import OpenAI from "openai";
const openai = new OpenAI({
baseURL: "https://api.aitunnel.ru/v1",
apiKey: "<AITUNNEL_API_KEY>",
});
async function chatCompletionWithReasoning(messages) {
const response = await openai.chat.completions.create({
model: "claude-3.7-sonnet",
messages,
max_tokens: 10000,
reasoning: {
max_tokens: 8000, // Напрямую указать бюджет токенов для рассуждений
},
stream: true,
});
return response;
}
(async () => {
for await (const chunk of chatCompletionWithReasoning([
{ role: "user", content: "Что больше, 9.9 или 9.11?" },
])) {
if (chunk.choices[0].delta.reasoning) {
console.log(`REASONING: ${chunk.choices[0].delta.reasoning}`);
} else if (chunk.choices[0].delta.content) {
console.log(`CONTENT: ${chunk.choices[0].delta.content}`);
}
}
})();