Мы обновили интерфейс, совместимый с OpenAI, с более глубокими оптимизациями, специально для моделей серии Claude. Теперь вы можете более точно и удобно управлять мышлением и кэшированием. Чередующееся мышление в многократных разговорах теперь более удобно для пользователей, позволяя бесшовную интеграцию без дополнительных параметров. Также поддерживается включение бета-функций, предлагаемых Anthropic.
1. Мышление модели (Расширенное мышление)
1.1 Преимущества чередующегося мышления
Когда чередующееся мышление не включено, модель выполняет мышление только один раз в начале поворота помощника; последующие ответы генерируются непосредственно после получения результатов инструмента, без создания новых блоков мышления:
User → [Thinking] → Tool Call → Tool Result → Response
Когда чередующееся мышление включено, модель вставляет новый блок мышления каждый раз, когда получает результат инструмента, формируя цепочку рассуждений:
User → [Thinking] → Tool Call → Tool Result → [Thinking] → Response
↑ Чередующееся мышление
Это позволяет модели:
- Выполнять вторичное рассуждение на основе результатов инструмента, а не просто конкатенировать выводы.
- Связывать рассуждения между несколькими вызовами инструментов, где каждое решение основано на анализе предыдущего шага.
Ссылка: Чередующееся мышление Anthropic
1.2 Включение мышления
Вы можете включить мышление четырьмя способами, выбрав любой из них:
| Метод | Пример | Описание |
|---|---|---|
reasoning_effort |
"reasoning_effort": "low" |
Стандартный параметр OpenAI, размещенный на верхнем уровне тела запроса |
reasoning.effort |
"reasoning": {"effort": "low"} |
Эквивалент предыдущему методу, размещенный внутри объекта reasoning |
reasoning.max_tokens |
"reasoning": {"max_tokens": 1024} |
Точно контролирует максимальное количество токенов для мышления |
Имя модели с -think |
"model": "claude-sonnet-4-5-think" |
Самый простой способ, не требует дополнительных параметров |
Приоритет (при использовании нескольких методов):reasoning_effort>reasoning.max_tokens>reasoning.effort>-thinkсуффикс
Возможные значения для усилий: minimal / low / medium / high / xhigh
1.3 Возврат мышления
Сообщение ответа будет включать два новых поля:
reasoning_content: Содержимое мышления (строка), для удобного отображения.reasoning_details: Полная структурированная информация о мышлении, которая должна быть возвращена как есть в многократных разговорах; внутренняя структура может отличаться между поставщиками.
Пример без потоковой передачи (опуская не относящиеся к делу поля):
{
"choices": [{
"message": {
"role": "assistant",
"content": "Здравствуйте! Чем я могу вам помочь сегодня?",
"reasoning_content": "Пользователь просто говорит привет...",
"reasoning_details": {
"type": "thinking",
"thinking": "Пользователь просто говорит привет...",
"signature": "Er8CCkYI..."
}
}
}]
}
В потоковых ответах содержимое мышления будет отправлено частями через delta.reasoning_content и delta.reasoning_details. Для полной логики конкатенации потоковой передачи смотрите полный пример ниже.
1.4 Сохранение мышления в многократных разговорах (Чередующееся мышление встроено, дополнительные параметры не требуются)
Чтобы модель могла продолжать свои способности к рассуждению в многократных разговорах, просто поместите ранее возвращенные reasoning_details как есть в сообщение помощника следующего раунда:
messages = [
{"role": "user", "content": "Какова погода в Бостоне?"},
{
"role": "assistant",
"content": response.choices[0].message.content,
"tool_calls": response.choices[0].message.tool_calls,
"reasoning_details": response.choices[0].message.reasoning_details,
},
{
"role": "tool",
"tool_call_id": "toolu_xxx",
"content": '{"temperature": 45, "condition": "дождливо"}',
}
]
AIHubMix автоматически включит чередующееся мышление, когда обнаружит историческую информацию о мышлении в запросе, позволяя модели продолжать глубокое рассуждение после получения результатов вызова инструмента без необходимости в дополнительных параметрах.
1.5 Полный пример
Следующие два примера демонстрируют полный процесс многократного вызова инструмента + чередующегося мышления: запрос пользователя → модель думает и вызывает инструмент → внедрить результаты инструмента (сохраняя reasoning_details) → модель чередующееся мышление дает окончательный ответ.
Без потоковой передачи · Чередующееся мышление
import os
import json
from openai import OpenAI
client = OpenAI(
base_url="https://aihubmix.com/v1",
api_key=os.environ.get("AIHUBMIX_API_KEY", "sk-***"),
)
# ── Определение инструмента ───────────────────────────────────────────
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Получить текущую погоду для местоположения",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string", "description": "Название города"}},
"required": ["location"]
}
}
}]
# ── Моковая реализация инструмента ─────────────────────────────────────
WEATHER_DB = {
"boston": {"temperature": "45°F (7°C)", "condition": "дождливо", "humidity": "85%", "wind": "15 mph NE"},
"tokyo": {"temperature": "72°F (22°C)", "condition": "солнечно", "humidity": "45%", "wind": "5 mph S"},
}
def execute_tool(name: str, args: dict) -> str:
if name == "get_weather":
key = next((k for k in WEATHER_DB if k in args.get("location", "").lower()), None)
return json.dumps(WEATHER_DB.get(key, {"temperature": "65°F", "condition": "ясно"}))
return "{}"
# ── Цикл многократного разговора ─────────────────────────────
messages = [
{"role": "user", "content": "Какова погода в Бостоне? Затем порекомендуйте, что надеть."}
]
turn = 0
while True:
turn += 1
print(f"\n── Поворот {turn} ──")
response = client.chat.completions.create(
model="claude-sonnet-4-5",
messages=messages,
tools=tools,
extra_body={"reasoning": {"max_tokens": 2000}},
)
msg = response.choices[0].message
# Печать процесса мышления
if msg.reasoning_content:
label = "Чередующееся мышление" if turn > 1 else "Мышление"
print(f"[{label}] {msg.reasoning_content}")
# Печать содержимого ответа
if msg.content:
print(f"[Ответ] {msg.content}")
# Печать вызовов инструментов
if msg.tool_calls:
for tc in msg.tool_calls:
print(f"[Вызов инструмента: {tc.function.name}] {tc.function.arguments}")
# Создание сообщения помощника, сохранить reasoning_details (критично!)
assistant_msg = {"role": "assistant", "content": msg.content}
if msg.tool_calls:
assistant_msg["tool_calls"] = msg.tool_calls
if msg.reasoning_details:
assistant_msg["reasoning_details"] = msg.reasoning_details # передать обратно без изменений
messages.append(assistant_msg)
# Отсутствие tool_calls означает, что разговор завершен
if not msg.tool_calls:
break
# Выполнение инструментов и добавление результатов в сообщения
for tc in msg.tool_calls:
args = json.loads(tc.function.arguments)
result = execute_tool(tc.function.name, args)
print(f"[Результат инструмента: {tc.function.name}] {result}")
messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})
Потоковая передача · Чередующееся мышление
import os
import sys
import json
from openai import OpenAI
client = OpenAI(
base_url="https://aihubmix.com/v1",
api_key=os.environ.get("AIHUBMIX_API_KEY", "sk-***"),
)
# ── Определение инструмента и моковая реализация ─────────────────────────
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Получить текущую погоду для местоположения",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string", "description": "Название города"}},
"required": ["location"]
}
}
}]
WEATHER_DB = {
"boston": {"temperature": "45°F (7°C)", "condition": "дождливо", "humidity": "85%", "wind": "15 mph NE"},
"tokyo": {"temperature": "72°F (22°C)", "condition": "солнечно", "humidity": "45%", "wind": "5 mph S"},
}
def execute_tool(name: str, args: dict) -> str:
if name == "get_weather":
key = next((k for k in WEATHER_DB if k in args.get("location", "").lower()), None)
return json.dumps(WEATHER_DB.get(key, {"temperature": "65°F", "condition": "ясно"}))
return "{}"
# ── Коллектор потоковых ответов ────────────────────────────────
def stream_and_collect(turn: int, **kwargs):
"""Потоковая передача ответа, печать мышления/содержимого в реальном времени, накопление reasoning_details/tool_calls."""
rd = {} # накопленные reasoning_details
content = "" # накопленный текст ответа
tc_map = {} # накопленные tool_calls (по индексу)
cur = "none" # текущий раздел вывода: none / thinking / content
stream = client.chat.completions.create(stream=True, **kwargs)
for chunk in stream:
if not chunk.choices:
continue
delta = chunk.choices[0].delta
# ── Обработка мышления ──
rd_delta = getattr(delta, "reasoning_details", None)
if rd_delta and isinstance(rd_delta, dict):
for k, v in rd_delta.items():
if k == "type":
rd[k] = v
elif isinstance(v, str):
rd[k] = rd.get(k, "") + v
elif v is not None:
rd[k] = v
# Печать частей мышления в реальном времени
thinking_chunk = rd_delta.get("thinking", "")
if thinking_chunk:
if cur != "thinking":
cur = "thinking"
label = "Чередующееся мышление" if turn > 1 else "Мышление"
sys.stdout.write(f"\n[{label}] ")
sys.stdout.write(thinking_chunk)
sys.stdout.flush()
# ── Обработка содержимого ──
if delta.content:
if cur != "content":
if cur == "thinking":
sys.stdout.write("\n")
cur = "content"
sys.stdout.write("\n[Ответ] ")
sys.stdout.write(delta.content)
sys.stdout.flush()
content += delta.content
# ── Обработка tool_calls ──
for tc in delta.tool_calls or []:
i = tc.index
if i not in tc_map:
tc_map[i] = {"id": "", "type": "function",
"function": {"name": "", "arguments": ""}}
if tc.id:
tc_map[i]["id"] = tc.id
if tc.function:
tc_map[i]["function"]["name"] += tc.function.name or ""
tc_map[i]["function"]["arguments"] += tc.function.arguments or ""
# Завершение текущего раздела вывода
if cur in ("thinking", "content"):
sys.stdout.write("\n")
tool_calls = [tc_map[i] for i in sorted(tc_map)] if tc_map else None
return {
"content": content or None,
"reasoning_details": rd or None,
"tool_calls": tool_calls,
}
# ── Цикл многократного разговора ─────────────────────────────
messages = [
{"role": "user", "content": "Какова погода в Бостоне? Затем порекомендуйте, что надеть."}
]
turn = 0
while True:
turn += 1
print(f"\n── Поворот {turn} ──")
result = stream_and_collect(
turn,
model="claude-sonnet-4-5",
messages=messages,
tools=tools,
extra_body={"reasoning": {"max_tokens": 2000}},
)
# Печать вызовов инструментов
if result["tool_calls"]:
for tc in result["tool_calls"]:
print(f"[Вызов инструмента: {tc['function']['name']}] {tc['function']['arguments']}")
# Создание сообщения помощника, сохранить reasoning_details (критично!)
assistant_msg = {"role": "assistant", "content": result["content"]}
if result["tool_calls"]:
assistant_msg["tool_calls"] = result["tool_calls"]
if result["reasoning_details"]:
assistant_msg["reasoning_details"] = result["reasoning_details"] # передать обратно без изменений
messages.append(assistant_msg)
# Отсутствие tool_calls означает, что разговор завершен
if not result["tool_calls"]:
break
# Выполнение инструментов и добавление результатов в сообщения
for tc in result["tool_calls"]:
args = json.loads(tc["function"]["arguments"])
tool_result = execute_tool(tc["function"]["name"], args)
print(f"[Результат инструмента: {tc['function']['name']}] {tool_result}")
messages.append({"role": "tool", "tool_call_id": tc["id"], "content": tool_result})
1.6 Правила сопоставления интенсивности мышления
Режим усилий:
- Opus 4.6 / Sonnet 4.6 и выше: сопоставляется с родным уровнем усилий Адаптивного мышления Anthropic.
- Другие модели: рассчитываются по формуле для
budget_tokens:
budget_tokens = max(min(max_tokens × effort_ratio, 128000), 1024)
| усилие | усилие_ratio |
|---|---|
| xhigh | 0.95 |
| high | 0.80 |
| medium | 0.50 |
| low | 0.20 |
| minimal | 0.10 |
Сопоставление усилий адаптивного мышления:
| Входящее усилие | Opus 4.6 | Sonnet 4.6 |
|---|---|---|
| xhigh | max | high |
| high | high | high |
| medium | medium | medium |
| low | low | low |
| minimal | low | low |
Режим max_tokens: Непосредственно назначается как budget_tokens Anthropic.
-think суффикс: Opus/Sonnet 4.6+ использует адаптивное мышление (усилие=среднее); другие модели устанавливают budget_tokens = min(10240, max_tokens - 1), с умолчательным max_tokens равным 4096.
2. Кэширование подсказок
Вы можете использовать кэширование подсказок при отправке запросов к модели Claude через интерфейс чата. Установив контрольные точки cache_control в сообщениях, большие блоки текста (такие как карточки ролей, данные RAG, главы книг и т. д.) могут быть закэшированы для повторного использования, позволяя последующим запросам напрямую обращаться к кэшу и значительно снижать затраты.
Официальная документация Claude: Кэширование подсказок
2.1 Затраты на кэширование
| Операция | Множитель цены (относительно оригинальной цены ввода) |
|---|---|
| Запись в кэш (TTL 5 минут) | 1.25x |
| Запись в кэш (TTL 1 час) | 2x |
| Чтение из кэша | 0.1x |
2.2 Поддерживаемые модели и минимальная длина кэша
| Модель | Минимальное количество токенов в кэше |
|---|---|
| Claude Opus 4.8 | 1024 |
| Claude Opus 4.7 | 2048 |
| Claude Opus 4.6 / Opus 4.5 | 4096 |
| Claude Sonnet 4.6 / Sonnet 4.5 / Opus 4.1 / Opus 4 / Sonnet 4 / Sonnet 3.7 (устаревшая) | 1024 |
| Claude Haiku 4.5 | 4096 |
| Claude Haiku 3.5 (устаревшая) / Haiku 3 | 2048 |
Ограничение на количество контрольных точек: Максимум 4 контрольные точки cache_control на запрос.2.3 TTL кэша
| TTL | Синтаксис | Применимые сценарии |
|---|---|---|
| 5 минут (по умолчанию) | "cache_control": {"type": "ephemeral"} |
Короткие сессии, рутинные запросы |
| 1 час | "cache_control": {"type": "ephemeral", "ttl": "1h"} |
Долгие сессии, чтобы избежать повторных записей в кэш |
Затраты на запись для TTL 1 час выше, но они могут сэкономить общие расходы, снижая повторные записи в длительных сессиях. Все модели с Claude 4.5 и выше от всех поставщиков (включая Anthropic, Amazon Bedrock, Google Vertex AI) поддерживают TTL 1 час.
2.4 Использование
Вы можете установить контрольные точки кэша, используя поле cache_control в system, user (включая изображения) и tools. Следующие примеры показывают только ключевую структуру, опуская большие блоки текста.
Кэширование системного сообщения (по умолчанию TTL 5 минут):
{
"model": "claude-opus-4-5",
"messages": [
{
"role": "system",
"content": [
{"type": "text", "text": "Вы - AI помощник"},
{
"type": "text",
"text": "(долгий контекст)",
"cache_control": {"type": "ephemeral"}
}
]
},
{
"role": "user",
"content": [{"type": "text", "text": "Здравствуйте"}]
}
]
}
Кэширование пользовательского сообщения (TTL 1 час):
{
"model": "claude-opus-4-5",
"messages": [
{
"role": "system",
"content": [{"type": "text", "text": "Вы - AI помощник"}]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "(долгий контекст)",
"cache_control": {"type": "ephemeral", "ttl": "1h"}
},
{"type": "text", "text": "Здравствуйте"}
]
}
]
}
Кэширование сообщения с изображением:
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {"detail": "auto", "url": "data:image/jpeg;base64,/9j/4AAQ..."},
"cache_control": {"type": "ephemeral"}
},
{"type": "text", "text": "Что это?"}
]
}
Кэширование определения инструмента:
cache_control размещается на верхнем уровне объекта инструмента (наряду с type и function):
{
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Получить текущую погоду для местоположения",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
},
"cache_control": {"type": "ephemeral", "ttl": "1h"}
}]
}
2.5 Просмотр статуса кэша
Поле usage ответа вернет claude_cache_tokens_details, записывая подробную информацию о кэше:
Первый запрос (Создание кэша):
{
"usage": {
"prompt_tokens": 22,
"completion_tokens": 890,
"total_tokens": 912,
"claude_cache_tokens_details": {
"cache_creation_input_tokens": 6266,
"cache_read_input_tokens": 0,
"cache_write_5_minutes_input_tokens": 6266,
"cache_write_1_hour_input_tokens": 0
}
}
}
Последующие запросы (Кэш попал):
{
"usage": {
"prompt_tokens": 22,
"completion_tokens": 810,
"total_tokens": 832,
"prompt_tokens_details": {
"cached_tokens": 6266
},
"claude_cache_tokens_details": {
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 6266,
"cache_write_5_minutes_input_tokens": 0,
"cache_write_1_hour_input_tokens": 0
}
}
}
| Поле | Значение |
|---|---|
cache_creation_input_tokens |
Количество токенов, записанных в кэш в этом запросе |
cache_read_input_tokens |
Количество токенов, прочитанных из кэша в этом запросе |
cache_write_5_minutes_input_tokens |
Количество токенов, записанных в кэш с TTL 5 минут |
cache_write_1_hour_input_tokens |
Количество токенов, записанных в кэш с TTL 1 час |
prompt_tokens_details.cached_tokens |
Количество закэшированных токенов при попадании в кэш, совместимо с форматом OpenAI |
3. Заголовок запроса для anthropic-beta
Вы можете включить бета-функции модели Claude через HTTP-заголовок anthropic-beta, который AIHubMix передаст в API Anthropic.
Использование
Добавьте anthropic-beta в заголовок запроса, значение которого будет соответствующим идентификатором бета-функции:
curl "https://aihubmix.com/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $AIHUBMIX_API_KEY" \
-H "anthropic-beta: context-1m-2025-08-07" \
-d '{
"model": "claude-opus-4-5",
"messages": [
{
"role": "system",
"content": [
{"type": "text", "text": "Вы - AI помощник"},
{
"type": "text",
"text": "(долгий контекст)",
"cache_control": {"type": "ephemeral"}
}
]
},
{"role": "user", "content": [{"type": "text", "text": "привет"}]}
]
}'
Для конкретных доступных идентификаторов бета-версий, пожалуйста, обратитесь к Документации API Anthropic.
Последнее обновление: 2026-06-01