Ми оновили OpenAI-сумісний інтерфейс із глибшою оптимізацією саме для моделей серії Claude. Тепер ви можете точніше й зручніше керувати мисленням і кешуванням. Чергування мислення в багатоходових розмовах стало зручнішим: його можна інтегрувати без додаткових параметрів. Також підтримується ввімкнення бета-функцій, які пропонує Anthropic.
1. Мислення моделі (Extended Thinking)
1.1 Переваги чергування мислення
Коли чергування мислення не увімкнено, модель виконує мислення лише один раз на початку ходу асистента; наступні відповіді генеруються безпосередньо після отримання результатів інструментів, без створення нових блоків мислення:
User → [Thinking] → Tool Call → Tool Result → Response
Коли чергування мислення увімкнено, модель вставляє новий блок мислення щоразу, коли отримує результат інструмента, формуючи ланцюжок міркувань:
User → [Thinking] → Tool Call → Tool Result → [Thinking] → Response
↑ Interleaved Thinking
Це дозволяє моделі:
- виконувати вторинні міркування на основі результатів інструментів, а не просто об’єднувати вихідні дані.
- ланцюжково міркувати між кількома викликами інструментів, де кожне рішення ґрунтується на аналізі попереднього кроку.
Довідка: Anthropic Interleaved Thinking
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
Можливі значення effort: minimal / low / medium / high / xhigh
1.3 Повернення мислення
Повідомлення відповіді міститиме два нові поля:
reasoning_content: вміст мислення (рядок) для зручного відображення.reasoning_details: повна структурована інформація про мислення, яку потрібно повертати без змін у багатоходових розмовах; внутрішня структура може відрізнятися між провайдерами.
Приклад для непотокової відповіді (нерелевантні поля опущено):
{
"choices": [{
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?",
"reasoning_content": "The user is just saying hello...",
"reasoning_details": {
"type": "thinking",
"thinking": "The user is just saying hello...",
"signature": "Er8CCkYI..."
}
}
}]
}
У потокових відповідях вміст мислення надсилатиметься частинами через delta.reasoning_content і delta.reasoning_details. Повну логіку конкатенації потоку див. у повному прикладі нижче.
1.4 Збереження мислення в багатоходових розмовах (чергування мислення вбудовано, додаткові параметри не потрібні)
Щоб модель продовжувала використовувати свої міркувальні можливості в багатоходових розмовах, просто вставте раніше повернуті reasoning_details без змін у повідомлення асистента наступного раунду:
messages = [
{"role": "user", "content": "What's the weather like in Boston?"},
{
"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": "rainy"}',
}
]
AIHubMix автоматично увімкне чергування мислення, коли виявить у запиті історичну інформацію про мислення, що дозволить моделі продовжувати глибокі міркування після отримання результатів викликів інструментів без додаткових параметрів.
1.5 Повний приклад
Наведені два приклади демонструють повний багатоходовий процес Tool Call + чергування мислення: запит користувача → модель міркує та викликає інструмент → додавання результатів інструмента (із збереженням 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-***"),
)
# ── Tool definition ───────────────────────────────────────────
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string", "description": "City name"}},
"required": ["location"]
}
}
}]
# ── Mock tool execution ───────────────────────────────────────
WEATHER_DB = {
"boston": {"temperature": "45°F (7°C)", "condition": "rainy", "humidity": "85%", "wind": "15 mph NE"},
"tokyo": {"temperature": "72°F (22°C)", "condition": "sunny", "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": "clear"}))
return "{}"
# ── Multi-turn conversation loop ─────────────────────────────
messages = [
{"role": "user", "content": "What's the weather like in Boston? Then recommend what to wear."}
]
turn = 0
while True:
turn += 1
print(f"\n── Turn {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
# Print thinking process
if msg.reasoning_content:
label = "Interleaved Thinking" if turn > 1 else "Thinking"
print(f"[{label}] {msg.reasoning_content}")
# Print response content
if msg.content:
print(f"[Response] {msg.content}")
# Print tool calls
if msg.tool_calls:
for tc in msg.tool_calls:
print(f"[Tool Call: {tc.function.name}] {tc.function.arguments}")
# Build assistant message, preserve reasoning_details (critical!)
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 # pass back unmodified
messages.append(assistant_msg)
# No tool_calls means conversation is done
if not msg.tool_calls:
break
# Execute tools and append results to messages
for tc in msg.tool_calls:
args = json.loads(tc.function.arguments)
result = execute_tool(tc.function.name, args)
print(f"[Tool Result: {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-***"),
)
# ── Tool definition & mock execution ─────────────────────────
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string", "description": "City name"}},
"required": ["location"]
}
}
}]
WEATHER_DB = {
"boston": {"temperature": "45°F (7°C)", "condition": "rainy", "humidity": "85%", "wind": "15 mph NE"},
"tokyo": {"temperature": "72°F (22°C)", "condition": "sunny", "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": "clear"}))
return "{}"
# ── Stream response collector ────────────────────────────────
def stream_and_collect(turn: int, **kwargs):
"""Stream response, print thinking/content in real-time, accumulate reasoning_details/tool_calls."""
rd = {} # accumulated reasoning_details
content = "" # accumulated response text
tc_map = {} # accumulated tool_calls (by index)
cur = "none" # current output section: 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
# ── Handle thinking ──
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
# Print thinking chunks in real-time
thinking_chunk = rd_delta.get("thinking", "")
if thinking_chunk:
if cur != "thinking":
cur = "thinking"
label = "Interleaved Thinking" if turn > 1 else "Thinking"
sys.stdout.write(f"\n[{label}] ")
sys.stdout.write(thinking_chunk)
sys.stdout.flush()
# ── Handle content ──
if delta.content:
if cur != "content":
if cur == "thinking":
sys.stdout.write("\n")
cur = "content"
sys.stdout.write("\n[Response] ")
sys.stdout.write(delta.content)
sys.stdout.flush()
content += delta.content
# ── Handle 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 ""
# End current output section
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,
}
# ── Multi-turn conversation loop ─────────────────────────────
messages = [
{"role": "user", "content": "What's the weather like in Boston? Then recommend what to wear."}
]
turn = 0
while True:
turn += 1
print(f"\n── Turn {turn} ──")
result = stream_and_collect(
turn,
model="claude-sonnet-4-5",
messages=messages,
tools=tools,
extra_body={"reasoning": {"max_tokens": 2000}},
)
# Print tool calls
if result["tool_calls"]:
for tc in result["tool_calls"]:
print(f"[Tool Call: {tc['function']['name']}] {tc['function']['arguments']}")
# Build assistant message, preserve reasoning_details (critical!)
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"] # pass back unmodified
messages.append(assistant_msg)
# No tool_calls means conversation is done
if not result["tool_calls"]:
break
# Execute tools and append results to messages
for tc in result["tool_calls"]:
args = json.loads(tc["function"]["arguments"])
tool_result = execute_tool(tc["function"]["name"], args)
print(f"[Tool Result: {tc['function']['name']}] {tool_result}")
messages.append({"role": "tool", "tool_call_id": tc["id"], "content": tool_result})
1.6 Правила відображення інтенсивності мислення
Режим effort:
- Opus 4.6 / Sonnet 4.6 і новіші: відображаються на рівень effort рідного Adaptive Thinking від Anthropic.
- Інші моделі: обчислюються за формулою для
budget_tokens:
budget_tokens = max(min(max_tokens × effort_ratio, 128000), 1024)
| effort | effort_ratio |
|---|---|
| xhigh | 0.95 |
| high | 0.80 |
| medium | 0.50 |
| low | 0.20 |
| minimal | 0.10 |
Відображення effort для Adaptive Thinking:
| Вхідний effort | 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+ використовують adaptive thinking (effort=medium); для інших моделей budget_tokens = min(10240, max_tokens - 1), а типове значення max_tokens становить 4096.
2. Кешування промптів
Кешування промптів можна використовувати під час запитів до моделі Claude через інтерфейс Chat. Встановлюючи точки переривання cache_control у повідомленнях, великі блоки тексту (наприклад, картки персонажів, дані RAG, розділи книг тощо) можна кешувати для повторного використання, а наступні запити будуть напряму звертатися до кешу, що суттєво знижує витрати.
Офіційна документація Claude: Prompt Caching
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": "You are an AI assistant"},
{
"type": "text",
"text": "(long context)",
"cache_control": {"type": "ephemeral"}
}
]
},
{
"role": "user",
"content": [{"type": "text", "text": "Hello"}]
}
]
}
Кешування повідомлення користувача (TTL 1 година):
{
"model": "claude-opus-4-5",
"messages": [
{
"role": "system",
"content": [{"type": "text", "text": "You are an AI assistant"}]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "(long context)",
"cache_control": {"type": "ephemeral", "ttl": "1h"}
},
{"type": "text", "text": "Hello"}
]
}
]
}
Кешування повідомлення із зображенням:
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {"detail": "auto", "url": "data:image/jpeg;base64,/9j/4AAQ..."},
"cache_control": {"type": "ephemeral"}
},
{"type": "text", "text": "What's this?"}
]
}
Кешування визначення інструмента:
cache_control розміщується на верхньому рівні об’єкта інструмента (поруч із type і function):
{
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"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": "You are an AI assistant"},
{
"type": "text",
"text": "(long context)",
"cache_control": {"type": "ephemeral"}
}
]
},
{"role": "user", "content": [{"type": "text", "text": "hello"}]}
]
}'
Актуальні ідентифікатори бета-функцій дивіться в документації Anthropic API.
Останнє оновлення: 2026-06-01



