Zaktualizowaliśmy interfejs zgodny z OpenAI o głębsze optymalizacje, szczególnie dla modeli serii Claude. Teraz możesz kontrolować myślenie i pamięć podręczną w sposób bardziej precyzyjny i wygodny. Przeplatane myślenie w rozmowach wieloturnowych jest teraz bardziej przyjazne dla użytkownika, umożliwiając płynne włączenie bez dodatkowych parametrów. Obsługuje również włączanie funkcji beta oferowanych przez Anthropic.
1. Myślenie modelu (Rozszerzone myślenie)
1.1 Zalety przeplatanego myślenia
Gdy przeplatane myślenie nie jest włączone, model wykonuje myślenie tylko raz na początku tury asystenta; kolejne odpowiedzi są generowane bezpośrednio po otrzymaniu wyników narzędzi, bez tworzenia nowych bloków myślenia:
Użytkownik → [Myślenie] → Wywołanie narzędzia → Wynik narzędzia → Odpowiedź
Gdy przeplatane myślenie jest włączone, model wstawia nowy blok myślenia za każdym razem, gdy otrzymuje wynik narzędzia, tworząc łańcuch rozumowania:
Użytkownik → [Myślenie] → Wywołanie narzędzia → Wynik narzędzia → [Myślenie] → Odpowiedź
↑ Przeplatane myślenie
To umożliwia modelowi:
- Wykonywanie wtórnego rozumowania na podstawie wyników narzędzi, zamiast po prostu łączyć wyniki.
- Łączenie rozumowania między wieloma wywołaniami narzędzi, gdzie każda decyzja opiera się na analizie poprzedniego kroku.
Źródło: Przeplatane myślenie Anthropic
1.2 Włączanie myślenia
Możesz włączyć myślenie na cztery sposoby, wybierając dowolny z nich:
| Metoda | Przykład | Opis |
|---|---|---|
reasoning_effort |
"reasoning_effort": "low" |
Standardowy parametr OpenAI, umieszczony na najwyższym poziomie ciała żądania |
reasoning.effort |
"reasoning": {"effort": "low"} |
Równoważne poprzedniej metodzie, umieszczone w obiekcie reasoning |
reasoning.max_tokens |
"reasoning": {"max_tokens": 1024} |
Precyzyjnie kontroluje maksymalną liczbę tokenów dla myślenia |
Nazwa modelu z -think |
"model": "claude-sonnet-4-5-think" |
Najprostszy sposób, nie wymaga dodatkowych parametrów |
Priorytet (gdy używane są wiele metod):reasoning_effort>reasoning.max_tokens>reasoning.effort>-thinksuffix
Możliwe wartości dla wysiłku: minimal / low / medium / high / xhigh
1.3 Zwracanie myślenia
W wiadomości odpowiedzi znajdą się dwa nowe pola:
reasoning_content: Treść myślenia (ciąg), do łatwego wyświetlania.reasoning_details: Pełne zorganizowane informacje o myśleniu, które muszą być zwracane w takiej samej formie w rozmowach wieloturnowych; wewnętrzna struktura może różnić się między dostawcami.
Przykład bez strumieniowania (pomijając niepowiązane pola):
{
"choices": [{
"message": {
"role": "assistant",
"content": "Cześć! Jak mogę Ci dzisiaj pomóc?",
"reasoning_content": "Użytkownik tylko mówi cześć...",
"reasoning_details": {
"type": "thinking",
"thinking": "Użytkownik tylko mówi cześć...",
"signature": "Er8CCkYI..."
}
}
}]
}
W odpowiedziach strumieniowych treść myślenia będzie wysyłana w kawałkach za pomocą delta.reasoning_content i delta.reasoning_details. Aby uzyskać pełną logikę konkatenacji strumieniowej, zapoznaj się z pełnym przykładem poniżej.
1.4 Zachowanie myślenia w rozmowach wieloturnowych (Przeplatane myślenie jest wbudowane, nie są potrzebne dodatkowe parametry)
Aby umożliwić modelowi kontynuowanie swoich zdolności rozumowania w rozmowach wieloturnowych, wystarczy umieścić wcześniej zwrócone reasoning_details w takiej samej formie w wiadomości asystenta w następnej turze:
messages = [
{"role": "user", "content": "Jaka jest pogoda w Bostonie?"},
{
"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 automatycznie włączy przeplatane myślenie, gdy wykryje historyczne informacje o myśleniu w żądaniu, umożliwiając modelowi kontynuowanie głębokiego rozumowania po otrzymaniu wyników wywołania narzędzia bez konieczności dodatkowych parametrów.
1.5 Pełny przykład
Poniższe dwa przykłady ilustrują pełny proces wieloturnowego wywołania narzędzia + przeplatane myślenie: zapytanie użytkownika → model myśli i wywołuje narzędzie → wstrzykuje wyniki narzędzia (zachowując reasoning_details) → model przeplatane myślenie daje ostateczną odpowiedź.
Bez strumieniowania · Przeplatane myślenie
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-***"),
)
# ── Definicja narzędzia ───────────────────────────────────────────
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Pobierz aktualną pogodę dla lokalizacji",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string", "description": "Nazwa miasta"}},
"required": ["location"]
}
}
}]
# ── Wykonanie narzędzia w trybie symulacji ───────────────────────
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 "{}"
# ── Pętla rozmowy wieloturnowej ─────────────────────────────
messages = [
{"role": "user", "content": "Jaka jest pogoda w Bostonie? A potem poleć, co ubrać."}
]
turn = 0
while True:
turn += 1
print(f"\n── Tura {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
# Wyświetl proces myślenia
if msg.reasoning_content:
label = "Przeplatane myślenie" if turn > 1 else "Myślenie"
print(f"[{label}] {msg.reasoning_content}")
# Wyświetl treść odpowiedzi
if msg.content:
print(f"[Odpowiedź] {msg.content}")
# Wyświetl wywołania narzędzi
if msg.tool_calls:
for tc in msg.tool_calls:
print(f"[Wywołanie narzędzia: {tc.function.name}] {tc.function.arguments}")
# Zbuduj wiadomość asystenta, zachowując reasoning_details (krytyczne!)
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 # przekaż w niezmienionej formie
messages.append(assistant_msg)
# Brak wywołań narzędzi oznacza, że rozmowa się zakończyła
if not msg.tool_calls:
break
# Wykonaj narzędzia i dodaj wyniki do wiadomości
for tc in msg.tool_calls:
args = json.loads(tc.function.arguments)
result = execute_tool(tc.function.name, args)
print(f"[Wynik narzędzia: {tc.function.name}] {result}")
messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})
Strumieniowanie · Przeplatane myślenie
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-***"),
)
# ── Definicja narzędzia i symulacja wykonania ─────────────────────────
tools = [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Pobierz aktualną pogodę dla lokalizacji",
"parameters": {
"type": "object",
"properties": {"location": {"type": "string", "description": "Nazwa miasta"}},
"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 "{}"
# ── Zbieracz odpowiedzi strumieniowej ────────────────────────────────
def stream_and_collect(turn: int, **kwargs):
"""Strumieniuj odpowiedź, wyświetlaj myślenie/treść w czasie rzeczywistym, gromadź reasoning_details/tool_calls."""
rd = {} # zgromadzone reasoning_details
content = "" # zgromadzony tekst odpowiedzi
tc_map = {} # zgromadzone tool_calls (według indeksu)
cur = "none" # bieżąca sekcja wyjściowa: 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
# ── Obsługuje myślenie ──
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
# Wyświetlaj kawałki myślenia w czasie rzeczywistym
thinking_chunk = rd_delta.get("thinking", "")
if thinking_chunk:
if cur != "thinking":
cur = "thinking"
label = "Przeplatane myślenie" if turn > 1 else "Myślenie"
sys.stdout.write(f"\n[{label}] ")
sys.stdout.write(thinking_chunk)
sys.stdout.flush()
# ── Obsługuje treść ──
if delta.content:
if cur != "content":
if cur == "thinking":
sys.stdout.write("\n")
cur = "content"
sys.stdout.write("\n[Odpowiedź] ")
sys.stdout.write(delta.content)
sys.stdout.flush()
content += delta.content
# ── Obsługuje 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 ""
# Zakończ bieżącą sekcję wyjściową
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,
}
# ── Pętla rozmowy wieloturnowej ─────────────────────────────
messages = [
{"role": "user", "content": "Jaka jest pogoda w Bostonie? A potem poleć, co ubrać."}
]
turn = 0
while True:
turn += 1
print(f"\n── Tura {turn} ──")
result = stream_and_collect(
turn,
model="claude-sonnet-4-5",
messages=messages,
tools=tools,
extra_body={"reasoning": {"max_tokens": 2000}},
)
# Wyświetl wywołania narzędzi
if result["tool_calls"]:
for tc in result["tool_calls"]:
print(f"[Wywołanie narzędzia: {tc['function']['name']}] {tc['function']['arguments']}")
# Zbuduj wiadomość asystenta, zachowując reasoning_details (krytyczne!)
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"] # przekaż w niezmienionej formie
messages.append(assistant_msg)
# Brak wywołań narzędzi oznacza, że rozmowa się zakończyła
if not result["tool_calls"]:
break
# Wykonaj narzędzia i dodaj wyniki do wiadomości
for tc in result["tool_calls"]:
args = json.loads(tc["function"]["arguments"])
tool_result = execute_tool(tc["function"]["name"], args)
print(f"[Wynik narzędzia: {tc['function']['name']}] {tool_result}")
messages.append({"role": "tool", "tool_call_id": tc["id"], "content": tool_result})
1.6 Zasady mapowania intensywności myślenia
Tryb wysiłku:
- Opus 4.6 / Sonnet 4.6 i wyżej: mapuje do natywnego poziomu wysiłku Adaptive Thinking Anthropic.
- Inne modele: obliczane za pomocą wzoru na
budget_tokens:
budget_tokens = max(min(max_tokens × effort_ratio, 128000), 1024)
| wysiłek | effort_ratio |
|---|---|
| xhigh | 0.95 |
| high | 0.80 |
| medium | 0.50 |
| low | 0.20 |
| minimal | 0.10 |
Mapowanie wysiłku Adaptive Thinking:
| Przychodzący wysiłek | Opus 4.6 | Sonnet 4.6 |
|---|---|---|
| xhigh | max | high |
| high | high | high |
| medium | medium | medium |
| low | low | low |
| minimal | low | low |
Tryb max_tokens: Bezpośrednio przypisany jako budget_tokens Anthropic.
-think suffix: Opus/Sonnet 4.6+ używa myślenia adaptacyjnego (wysiłek=medium); inne modele ustawiają budget_tokens = min(10240, max_tokens - 1), z domyślnym max_tokens równym 4096.
2. Pamięć podręczna zapytań
Możesz używać pamięci podręcznej zapytań podczas składania żądań do modelu Claude za pośrednictwem interfejsu czatu. Ustawiając punkty przerwania cache_control w wiadomościach, duże bloki tekstu (takie jak karty ról, dane RAG, rozdziały książek itp.) mogą być przechowywane w pamięci podręcznej do ponownego użycia, co pozwala na bezpośrednie trafienie do pamięci podręcznej w kolejnych żądaniach i znaczne obniżenie kosztów.
Oficjalna dokumentacja Claude: Pamięć podręczna zapytań
2.1 Koszty pamięci podręcznej
| Operacja | Mnożnik ceny (względem oryginalnej ceny wejściowej) |
|---|---|
| Zapis pamięci podręcznej (TTL 5 minut) | 1.25x |
| Zapis pamięci podręcznej (TTL 1 godzina) | 2x |
| Odczyt pamięci podręcznej | 0.1x |
2.2 Obsługiwane modele i minimalna długość pamięci podręcznej
| Model | Minimalna liczba tokenów w pamięci podręcznej |
|---|---|
| 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 (przestarzałe) | 1024 |
| Claude Haiku 4.5 | 4096 |
| Claude Haiku 3.5 (przestarzałe) / Haiku 3 | 2048 |
Limit ilości punktów przerwania: Maksymalnie 4 cache_control punkty przerwania na żądanie.2.3 TTL pamięci podręcznej
| TTL | Składnia | Scenariusze zastosowania |
|---|---|---|
| 5 minut (domyślnie) | "cache_control": {"type": "ephemeral"} |
Krótkie sesje, rutynowe żądania |
| 1 godzina | "cache_control": {"type": "ephemeral", "ttl": "1h"} |
Długie sesje, aby uniknąć powtarzających się zapisów pamięci podręcznej |
Koszty zapisu dla TTL 1-godzinnego są wyższe, ale mogą zaoszczędzić całkowite wydatki, redukując powtarzające się zapisy w długich sesjach. Wszystkie modele od Claude 4.5 i później od wszystkich dostawców (w tym Anthropic, Amazon Bedrock, Google Vertex AI) obsługują TTL 1-godzinny.
2.4 Użycie
Możesz ustawić punkty przerwania pamięci podręcznej, używając pola cache_control w system, user (w tym obrazy) oraz tools. Poniższe przykłady pokazują tylko kluczową strukturę, pomijając duże bloki tekstu.
Pamięć podręczna wiadomości systemowej (domyślnie TTL 5 minut):
{
"model": "claude-opus-4-5",
"messages": [
{
"role": "system",
"content": [
{"type": "text", "text": "Jesteś asystentem AI"},
{
"type": "text",
"text": "(długi kontekst)",
"cache_control": {"type": "ephemeral"}
}
]
},
{
"role": "user",
"content": [{"type": "text", "text": "Cześć"}]
}
]
}
Pamięć podręczna wiadomości użytkownika (TTL 1 godzina):
{
"model": "claude-opus-4-5",
"messages": [
{
"role": "system",
"content": [{"type": "text", "text": "Jesteś asystentem AI"}]
},
{
"role": "user",
"content": [
{
"type": "text",
"text": "(długi kontekst)",
"cache_control": {"type": "ephemeral", "ttl": "1h"}
},
{"type": "text", "text": "Cześć"}
]
}
]
}
Pamięć podręczna wiadomości obrazkowej:
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {"detail": "auto", "url": "data:image/jpeg;base64,/9j/4AAQ..."},
"cache_control": {"type": "ephemeral"}
},
{"type": "text", "text": "Co to jest?"}
]
}
Pamięć podręczna definicji narzędzia:
cache_control jest umieszczane na najwyższym poziomie obiektu narzędzia (obok type i function):
{
"tools": [{
"type": "function",
"function": {
"name": "get_weather",
"description": "Pobierz aktualną pogodę dla lokalizacji",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"]
}
},
"cache_control": {"type": "ephemeral", "ttl": "1h"}
}]
}
2.5 Wyświetlanie statusu pamięci podręcznej
Pole usage odpowiedzi zwróci claude_cache_tokens_details, rejestrując szczegółowe informacje o pamięci podręcznej:
Pierwsze żądanie (tworzenie pamięci podręcznej):
{
"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
}
}
}
Kolejne żądania (trafienie w pamięć podręczną):
{
"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
}
}
}
| Pole | Znaczenie |
|---|---|
cache_creation_input_tokens |
Liczba tokenów zapisanych w pamięci podręcznej w tym żądaniu |
cache_read_input_tokens |
Liczba tokenów odczytanych z pamięci podręcznej w tym żądaniu |
cache_write_5_minutes_input_tokens |
Liczba tokenów zapisanych w pamięci podręcznej TTL 5 minut |
cache_write_1_hour_input_tokens |
Liczba tokenów zapisanych w pamięci podręcznej TTL 1 godzina |
prompt_tokens_details.cached_tokens |
Liczba tokenów w pamięci podręcznej, gdy pamięć podręczna jest trafiona, zgodna z formatem OpenAI |
3. Nagłówek żądania dla anthropic-beta
Możesz włączyć funkcje beta modelu Claude za pomocą nagłówka HTTP anthropic-beta, który AIHubMix przekaże do API Anthropic.
Użycie
Dodaj anthropic-beta do nagłówka żądania, a wartość powinna być odpowiednim identyfikatorem funkcji 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": "Jesteś asystentem AI"},
{
"type": "text",
"text": "(długi kontekst)",
"cache_control": {"type": "ephemeral"}
}
]
},
{"role": "user", "content": [{"type": "text", "text": "cześć"}]}
]
}'
Aby uzyskać szczegółowe identyfikatory beta, zapoznaj się z Dokumentacją API Anthropic.
Ostatnia aktualizacja: 2026-06-01