Актуализирахме 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.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 | макс | високо |
| high | високо | високо |
| medium | средно | средно |
| low | ниско | ниско |
| minimal | ниско | ниско |
Режим max_tokens: Пряко зададен като budget_tokens на Anthropic.
-think суфикс: Opus/Sonnet 4.6+ използва адаптивно мислене (усилие=средно); другите модели задават budget_tokens = min(10240, max_tokens - 1), с подразбираща се стойност max_tokens от 4096.
2. Кеширане на подсказки
Можете да използвате кеширане на подсказки, когато правите заявки към модела Claude чрез интерфейса за чат. Чрез задаване на точки за контрол на кеша в съобщенията, големи блокове текст (като карти на роли, 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 ще предаде на Anthropic API.
Използване
Добавете 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": "здравей"}]}
]
}'
За конкретни налични бета идентификатори, моля, вижте Документация на Anthropic API.
Последна актуализация: 2026-06-01