Claude için OpenAI Uyumlu Arayüz Yükseltmesi: Derin Destek

AIHubMix, Claude için OpenAI uyumlu API'sini yükseltti: ek parametre gerektirmeden ara düşünme (interleaved thinking), istem önbellekleme (prompt caching) ve Anthropic beta özelliği desteği.

AIHubMix8 dk okuma
Claude için OpenAI Uyumlu Arayüz Yükseltmesi: Derin Destek

OpenAI uyumlu arayüzü, özellikle Claude serisi modeller için daha derin optimizasyonlarla yükselttik. Artık düşünme ve önbellekleme özelliklerini daha hassas ve kullanışlı bir şekilde kontrol edebilirsiniz. Çok turlu konuşmalarda ara düşünme artık daha kullanıcı dostu; ek parametre olmadan sorunsuz entegrasyon sağlanıyor. Ayrıca Anthropic tarafından sunulan beta özelliklerinin etkinleştirilmesini de destekliyor.

1. Model Düşünmesi (Genişletilmiş Düşünme)

1.1 Ara Düşünmenin Avantajları

Ara düşünme etkin değilken model, bir asistan turunun başında yalnızca bir kez düşünme gerçekleştirir; sonraki yanıtlar araç sonuçlarını aldıktan hemen sonra doğrudan üretilir ve yeni düşünme blokları oluşturulmaz:

User → [Thinking] → Tool Call → Tool Result → Response

Ara düşünme etkinleştirildiğinde model, her araç sonucu aldığında yeni bir düşünme bloğu ekler ve böylece bir akıl yürütme zinciri oluşur:

User → [Thinking] → Tool Call → Tool Result → [Thinking] → Response
                                                ↑ Interleaved Thinking

Bu sayede model:

  • Araç sonuçlarına dayanarak ikincil akıl yürütme yapabilir; yalnızca çıktıları birleştirmekle yetinmez.
  • Birden fazla araç çağrısı arasında akıl yürütmeyi zincirleyebilir; her karar bir önceki adımın analizine dayanır.
Referans: Anthropic Ara Düşünme

1.2 Düşünmeyi Etkinleştirme

Düşünmeyi dört yoldan biriyle etkinleştirebilirsiniz; bunlardan herhangi birini seçin:

Yöntem Örnek Açıklama
reasoning_effort "reasoning_effort": "low" OpenAI standart parametresi, istek gövdesinin üst düzeyine yerleştirilir
reasoning.effort "reasoning": {"effort": "low"} Önceki yöntemle eşdeğer, reasoning nesnesi içine yerleştirilir
reasoning.max_tokens "reasoning": {"max_tokens": 1024} Düşünme için kullanılacak maksimum token sayısını hassas biçimde kontrol eder
Model adına -think eklenmesi "model": "claude-sonnet-4-5-think" En basit yöntem; ek parametre gerektirmez
Öncelik (birden fazla yöntem kullanıldığında): reasoning_effort > reasoning.max_tokens > reasoning.effort > -think eki

effort için olası değerler: minimal / low / medium / high / xhigh

1.3 Düşünme Çıktısı

Yanıt mesajı iki yeni alan içerecektir:

  • reasoning_content: Düşünme içeriği (metin), kolay görüntüleme için.
  • reasoning_details: Düşünme hakkında eksiksiz yapılandırılmış bilgi, çok turlu konuşmalarda olduğu gibi geri gönderilmelidir; iç yapısı sağlayıcılara göre farklılık gösterebilir.

Akışsız yanıt örneği (ilgisiz alanlar çıkarılmıştır):

{
  "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..."
      }
    }
  }]
}

Akış yanıtlarında düşünme içeriği delta.reasoning_content ve delta.reasoning_details aracılığıyla parça parça gönderilir. Tam akış birleştirme mantığı için aşağıdaki eksiksiz örneğe bakın.

1.4 Çok Turlu Konuşmalarda Düşünmeyi Koruma (Ara Düşünme yerleşiktir, ek parametre gerekmez)

Modelin çok turlu konuşmalarda akıl yürütme yeteneğini sürdürebilmesi için, daha önce döndürülen reasoning_details değerini olduğu gibi bir sonraki turdaki asistan mesajına eklemeniz yeterlidir:

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, istekte geçmiş düşünme bilgisi algıladığında ara düşünmeyi otomatik olarak etkinleştirir; böylece model, araç çağrısı sonuçlarını aldıktan sonra ek parametre gerekmeden derin akıl yürütmeye devam edebilir.

1.5 Eksiksiz Örnek

Aşağıdaki iki örnek, çok turlu eksiksiz Araç Çağrısı + ara düşünme sürecini göstermektedir: kullanıcı sorgusu → model düşünür ve bir araç çağırır → araç sonuçlarını ekleyin (reasoning_details korunarak) → model ara düşünme ile nihai yanıtı verir.

Akışsız · Ara Düşünme

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})

Akış · Ara Düşünme

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 Düşünme Yoğunluğu Eşleme Kuralları

Effort Modu:

  • Opus 4.6 / Sonnet 4.6 ve üzeri: Anthropic'in yerel Uyarlanabilir Düşünme effort seviyesine eşlenir.
  • Diğer modeller: budget_tokens formülü kullanılarak hesaplanır:
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

Uyarlanabilir Düşünme Effort Eşlemesi:

Gelen Effort Opus 4.6 Sonnet 4.6
xhigh max high
high high high
medium medium medium
low low low
minimal low low

max_tokens Modu: Doğrudan Anthropic'in budget_tokens değeri olarak atanır.

-think eki: Opus/Sonnet 4.6+ uyarlanabilir düşünmeyi kullanır (effort=medium); diğer modellerde budget_tokens = min(10240, max_tokens - 1) ayarlanır ve varsayılan max_tokens değeri 4096'dır.


2. İstem Önbellekleme

Chat arayüzü üzerinden Claude modeline yapılan isteklerde İstem Önbellekleme (Prompt Caching) kullanabilirsiniz. Mesajlarda cache_control kesme noktaları ayarlanarak rol kartları, RAG verileri, kitap bölümleri gibi büyük metin blokları yeniden kullanım için önbelleğe alınabilir; sonraki istekler doğrudan önbelleğe ulaşır ve maliyetler önemli ölçüde düşer.

Claude Resmi Dokümantasyonu: İstem Önbellekleme

2.1 Önbellekleme Maliyetleri

İşlem Fiyat Çarpanı (orijinal girdi fiyatına göre)
Önbellek Yazma (5 dakika TTL) 1.25x
Önbellek Yazma (1 saat TTL) 2x
Önbellek Okuma 0.1x

2.2 Desteklenen Modeller ve Minimum Önbellek Uzunluğu

Model Minimum Önbellek Token Sayısı
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 (kullanımdan kaldırıldı) 1024
Claude Haiku 4.5 4096
Claude Haiku 3.5 (kullanımdan kaldırıldı) / Haiku 3 2048
Kesme Noktası Sınırı: İstek başına en fazla 4 cache_control kesme noktası.

2.3 Önbellek TTL

TTL Sözdizimi Uygulama Senaryoları
5 dakika (varsayılan) "cache_control": {"type": "ephemeral"} Kısa oturumlar, rutin istekler
1 saat "cache_control": {"type": "ephemeral", "ttl": "1h"} Uzun oturumlar, tekrarlayan önbellek yazmalarından kaçınmak için

1 saatlik TTL için yazma maliyetleri daha yüksektir; ancak uzun oturumlarda tekrarlayan yazmaları azaltarak toplam harcamayı düşürebilirler. Claude 4.5 ve sonrası tüm modeller, tüm sağlayıcılarda (Anthropic, Amazon Bedrock, Google Vertex AI dahil) 1 saatlik TTL'yi destekler.

2.4 Kullanım

system, user (görseller dahil) ve tools içindeki cache_control alanını kullanarak önbellek kesme noktaları ayarlayabilirsiniz. Aşağıdaki örnekler yalnızca temel yapıyı gösterir; büyük metin blokları çıkarılmıştır.

Sistem Mesajı Önbellekleme (varsayılan 5 dakika TTL):

{
  "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"}]
    }
  ]
}

Kullanıcı Mesajı Önbellekleme (1 saat TTL):

{
  "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"}
      ]
    }
  ]
}

Görsel Mesaj Önbellekleme:

{
  "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?"}
  ]
}

Araç Tanımı Önbellekleme:

cache_control, araç nesnesinin üst düzeyine yerleştirilir (type ve function ile aynı seviyede):

{
  "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 Önbellek Durumunu Görüntüleme

Yanıttaki usage alanı, ayrıntılı önbellek bilgilerini kaydeden claude_cache_tokens_details değerini döndürür:

İlk İstek (Önbellek Oluşturma):

{
  "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
    }
  }
}

Sonraki İstekler (Önbellek İsabeti):

{
  "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
    }
  }
}
Alan Anlamı
cache_creation_input_tokens Bu istekte önbelleğe yazılan token sayısı
cache_read_input_tokens Bu istekte önbellekten okunan token sayısı
cache_write_5_minutes_input_tokens 5 dakikalık TTL önbelleğine yazılan token sayısı
cache_write_1_hour_input_tokens 1 saatlik TTL önbelleğine yazılan token sayısı
prompt_tokens_details.cached_tokens Önbellek isabet ettiğinde önbelleğe alınmış token sayısı, OpenAI formatıyla uyumlu

3. anthropic-beta için İstek Başlığı

Claude modelinin beta özelliklerini anthropic-beta HTTP başlığı aracılığıyla etkinleştirebilirsiniz; AIHubMix bu değeri Anthropic API'sine iletir.

Kullanım

İstek başlığına anthropic-beta ekleyin ve değer olarak ilgili beta özellik tanımlayıcısını yazın:

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"}]}
  ]
}'
Kullanılabilir beta tanımlayıcıları için lütfen Anthropic API Dokümantasyonuna bakın.

Son güncelleme: 2026-06-01

Birden çok yapay zekâ sağlayıcısına tek ağ geçidi. Üretim için tasarlandı.

AIHubMix sitesini ziyaret edin