Bloga dön

Sorun gidermeKılavuz

Araç çağrısından sonra 400: reasoning_content'i geri gönderin

Bir araç çağrısı döngüsünün ikinci isteğinin bir düşünme modelinde neden 400 döndürdüğü, tam mesajı ekleyen bir Python düzeltmesi ve bunu ne zaman atlayabileceğiniz.

Yazan: CheapTokens TeamYayınlanma tarihi: 4 dk okuma

Kapak: reasoning_content'in asistan mesajından bir sonraki isteğe gittiği bir araç çağrısı döngüsü
Bu sayfada
  1. Birinci istek ile ikinci istek arasında ne olur
  2. Çözüm: mesajı döndürüldüğü gibi ekleyin
  3. Yaygın bir suçlu: elle yeniden oluşturulmuş bir mesaj
  4. Buna ne zaman ihtiyacınız yok
  5. Hâlâ 400 döndürüyorsa

Ajan döngünüz ilk istekte çalışıp ikinci istekte 400 ile başarısız oluyor. Bir düşünme modelinde, belgelenmiş nedenlerden biri eksik bir alandır: geri gönderdiğiniz asistan mesajı reasoning_content alanını kaybetmiştir. Neden buysa, mesajın tamamını API'nin döndürdüğü şekliyle eklemek sorunu çözer.

DeepSeek'in düşünme modu kılavuzu (dokümanlar, 8 Kasım 2026'da kontrol edildi) kuralı tek cümlede koyuyor: istekte tools parametresi varsa, reasoning_content sonraki tüm isteklerde, araç çağrısı olmayan turlar dahil, tam olarak geri iletilmelidir. Aksi halde API 400 döndürür. Aynı sayfa düşünmenin varsayılan olarak açık olduğunu ve çabanın high olduğunu söylüyor. Yani düşünmeyen bir model için yazdığınız bir döngü, tek bir satır değişmeden bozulabilir.

Birinci istek ile ikinci istek arasında ne olur#

Düşünme modunda düşünce zinciri reasoning_content içinde, content ile aynı seviyedeki bir alanda geri gelir. Döngüyü gözünüzde canlandırın:

  1. Soruyu ve tools listesini gönderirsiniz.
  2. Model tool_calls ile yanıtlar (ve yanlarında reasoning_content).
  3. Aracı çalıştırır ve her şeyi geri gönderirsiniz: geçmiş, asistan mesajı ve sonucu içeren bir tool mesajı.

400, 3. adımdaki istekte, içindeki asistan mesajında reasoning_content yoksa gelir.

Bir araç döngüsünün üç adımı: istek, reasoning_content içeren asistan mesajı, ikinci istek
Alanın gitmesi gereken yer: asistan mesajından bir sonraki isteğe

DeepSeek sayfası 400'ü yalnızca bu araç çağrısı durumu için belgeliyor ve bir hata metni alıntılamıyor, bu yüzden bu sorunu yaşayıp yaşamadığınızı kontrol ederken belirli bir mesaja değil HTTP durum koduna bakın.

Çözüm: mesajı döndürüldüğü gibi ekleyin#

En güvenli hamle asistan mesajını hiç yeniden oluşturmamaktır. Yanıttan alın ve tamamını ekleyin. İşte CheapTokens'e yönlendirilmiş OpenAI Python SDK'sı ile eksiksiz bir döngü. Hava durumu aracı bir saplamadır, yani olduğu gibi çalıştırabilirsiniz.

python
import json, os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)
MODEL = "deepseek-ai/DeepSeek-V4-Flash-0731"

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Current weather for a city",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
        },
    },
}]

def get_weather(city):
    return {"city": city, "temp_c": 7}  # stub

messages = [{"role": "user", "content": "Do I need a jacket in Oslo today?"}]

for _ in range(5):  # hard step limit
    resp = client.chat.completions.create(model=MODEL, messages=messages, tools=tools)
    msg = resp.choices[0].message
    messages.append(msg.model_dump(exclude_none=True))  # the whole message
    if not msg.tool_calls:
        print(msg.content)
        break
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        messages.append({
            "role": "tool",
            "tool_call_id": call.id,
            "content": json.dumps(get_weather(**args)),
        })

Önemli olan tek satır messages.append(msg.model_dump(exclude_none=True)). SDK, bilmediği alanları korur, yani API mesaja ne koyduysa, reasoning_content dahil, onunla birlikte geri gider. Son yanıt da eklenir, ki kuralın istediği budur: ilk araç çağrısından sonra her sonraki istek, önceki asistan turlarının düşüncesini taşır.

Araç çağrısı mekaniğinin kendisi (şema, tool_call_id, argümanları ayrıştırma) OpenAI uyumlu bir API ile Python'da fonksiyon çağırma yazısında. Temel URL, anahtar ve model kimliği CheapTokens dokümanlar sayfasında; burada kullanılan model DeepSeek sayfasında açıklanıyor: 380K bağlam ve yanıt başına 32.768'e kadar çıktı token'ı, bu da uzun düşünme artı bir yanıt için yer bırakır.

Yaygın bir suçlu: elle yeniden oluşturulmuş bir mesaj#

Alanı kaybetmenin yaygın bir yolu, yanıt nesnesini eklemek yerine yeni bir dict oluşturan koddur. Zararsız görünür: rol, içerik, araç çağrıları. Çerçeveler ve sarmalayıcılar, geçmişi kendi formatlarında sakladıklarında aynısını yapar. Hiç duymadıkları tek alan, kaybolan alandır.

Sol: rol, içerik, tool_calls'tan yeniden oluşturulmuş asistan mesajı. Sağ: döndürüldüğü gibi, reasoning_content ile birlikte mesaj
İki asistan mesajı arasındaki fark tek bir alan

Karşılaştır

Elle yeniden oluşturulmuş vs tamamen eklenmiş

Elle yeniden oluşturulmuş (bozulur)

python
messages.append({
    "role": "assistant",
    "content": msg.content,
    "tool_calls": [c.model_dump() for c in msg.tool_calls],
})

Tamamen eklenmiş (çalışır)

python
messages.append(msg.model_dump(exclude_none=True))

Bir çerçeve kullanıyorsanız ve o satıra dokunamıyorsanız, asistan turlarını nasıl sakladığını kontrol edin. Yalnızca content ve tool_calls alanlarını tutan bir serileştiriciden geçen geçmişte de aynı hata vardır, sadece bir katman daha aşağıda.

Buna ne zaman ihtiyacınız yok#

Her düşünme modeli çağrısı ekstra özen gerektirmez. Araçsız çok turlu sohbet için DeepSeek'in kılavuzu reasoning_content alanının geri iletilmesi gerekmediğini söylüyor; yine de gönderirseniz yok sayılır ve önceki düşünce bağlama eklenmez. Yani düz bir sohbet onu düşürmeye devam edebilir ve hiçbir şey bozulmaz.

Durumunu seç

Sizin durumunuz hangisi?

İstekte tools var, model düşünüyor

Her turda asistan mesajının tamamını ekleyin, araç turları ve son yanıtlar dahil.

Düz sohbet, tools parametresi yok

Düzeltme gerekmez. reasoning_content alanını geçmişten düşürebilir veya gönderebilirsiniz; yok sayılır.

Geçmişi sizin için bir çerçeve oluşturuyor

Asistan mesajlarını nerede serileştirdiğini bulun ve reasoning_content alanının hayatta kaldığından emin olun. Kalamıyorsa, araç kısmı için API'yi kendi döngünüzle çağırın.

Akılda tutulması gereken bir yan etki: yeniden gönderdiğiniz geçmiş her istekte girdidir, bu yüzden uzun bir döngüdeki uzun düşünme birikir. Düşünme token'larının nasıl sayıldığı Akıl yürütme çabası ve düşünme token'ları yazısında, bir istek modelin sınırlarını aştığında ne yapılacağı ise İstek çok uzun: 400 vs 413 yazısında ele alınıyor.

Hâlâ 400 döndürüyorsa#

Bunları sırayla gözden geçirin:

  • Başarısız çağrıdan hemen önce messages yazdırın. Modelden gelen her asistan mesajında, yanıtta varsa reasoning_content var mı?
  • Herhangi bir yerde bir mesajı yeniden oluşturuyor musunuz: bir yardımcı, bir geçmiş sınıfı, sabit bir anahtar listesiyle json.dumps ve geri dönüş?
  • Her tool_call_id için tool mesajı aynı id ile mevcut mu?
  • Gerçekten uzunluk mu? Bağlam sınırını aşan bir istek, yukarıdaki yazıda açıklanan farklı bir 400'dür.

Hızlı kontrol

Model bir araç istedikten sonra ne eklersiniz?

Cevabı göster

Cevap: Döndürüldüğü gibi asistan mesajının tamamı, reasoning_content dahil

Araç mesajlarınızın yanıtladığı şey tool_calls'tır ve istekte araçlar varken düşünce onlarla birlikte gitmelidir.

Çözümün tamamı bu: tek bir ekleme, yeniden oluşturma yok. Örnekteki adım sınırını yayınladığınız her döngüye ekleyin, böylece kötü bir tur beş yüz istek değil, beş isteğe mal olsun.