Kılavuzlara dön
Sorun giderme·28 Ağustos 2026·6 dk okuma

Claude API 400 “tool_use ids were found without tool_result blocks” — sıralama kuralı

Bu bir araç hatası değil, mesaj sıralama hatasıdır. Claude, bir assistant dönüşündeki her tool_use bloğunun hemen sonraki user dönüşünde aynı kimliklere sahip bir tool_result bloğuyla yanıtlanmasını gerektirir — arada hiçbir şey olmamalıdır. Döngünüz birini düşürmüştür; genellikle bunun nedeni aracın hata vermesidir.

Son inceleme tarihi: .

Bu bir araç hatası değil, mesaj sıralama hatasıdır. Claude, bir assistant dönüşündeki her tool_use bloğunun hemen sonraki user dönüşünde aynı kimliklere sahip bir tool_result bloğuyla yanıtlanmasını gerektirir — arada hiçbir şey olmamalıdır. Döngünüz birini düşürmüştür; genellikle bunun nedeni aracın hata vermesidir.

Hata

yanıt (HTTP 400)
{
  "type": "error",
  "error": {
    "type": "invalid_request_error",
    "message": "messages.1: tool_use ids were found without tool_result blocks immediately after: toolu_01A... Each tool_use block must have a corresponding tool_result block in the next message."
  }
}

Nedenler ve çözümler özeti

NedenÇözüm
Aracınız hata verdi, bu yüzden hiçbir şey eklenmediYine de is_error: true ve hata metni içeren bir tool_result gönderin.
tool_result daha sonraki bir mesaja yerleştirildiTam olarak hemen sonraki mesaj olmalıdır — arada hiçbir assistant veya user dönüşü bulunamaz.
tool_use_id eşleşmiyortool_use bloğundaki kimliği aynen geri yansıtın; yeniden üretmeyin.
Geçmiş, gidiş-dönüşün ortasında kırpıldıKırpmayı her zaman tam araç gidiş-dönüşlerinde yapın; tek bir turun iki yarısı arasından asla kırpmayın.

Değişmez kural, tek seferde

Bir asistan turundaki her tool_use bloğu, hemen sonraki kullanıcı mesajında aynı tool_use_id'yi taşıyan tam olarak bir tool_result bloğu gerektirir. Tek turdaki birden fazla tool_use bloğu, sonraki tek mesajda birden fazla tool_result bloğu gerektirir. Bu iki turun arasına hiçbir şey giremez.

Araç başarısız olsa bile her zaman yanıt verin

Model, başarısız bir aracı gayet iyi yönetebilir; eksik bir aracı yönetemez. Hatayı tool_result olarak döndürmek konuşmanın geçerliliğini korur ve genellikle 400 hatası yerine makul bir kurtarma sağlar.

tool_loop.py
results = []
for block in (b for b in resp.content if b.type == "tool_use"):
    try:
        out = run_tool(block.name, block.input)
        results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": str(out),
        })
    except Exception as e:
        # A failed tool still owes the model an answer.
        results.append({
            "type": "tool_result",
            "tool_use_id": block.id,
            "content": f"Tool failed: {e}",
            "is_error": True,
        })

messages.append({"role": "assistant", "content": resp.content})
messages.append({"role": "user", "content": results})

Göndermeden önce son iki turu doğrulayın

Bir düzine satırlık assertion, bunu ağdan gelen bir 400 yerine çağrı noktasında yakalar — asistan turundaki tool_use kimliklerini dolaşın ve sonraki kullanıcı turunun tümünü yanıtladığını doğrulayın.

validate.py
def check_pairs(messages):
    for i, m in enumerate(messages):
        if m["role"] != "assistant" or not isinstance(m.get("content"), list):
            continue
        ids = {b.get("id") for b in m["content"]
               if isinstance(b, dict) and b.get("type") == "tool_use"}
        if not ids:
            continue
        nxt = messages[i + 1] if i + 1 < len(messages) else None
        answered = {b.get("tool_use_id") for b in (nxt or {}).get("content", [])
                    if isinstance(b, dict) and b.get("type") == "tool_result"}
        missing = ids - answered
        assert not missing, f"message {i}: unanswered tool_use {missing}"

Geçmişi gidiş-dönüş sınırlarında kırpın

Mesaj sayısına göre yapılan bağlam penceresi kırpması, er ya da geç bir tool_use ile tool_result arasını kesecektir. Neyin atılacağına karar verirken çifti bölünemez tek birim olarak ele alın.

Kunavo üzerinden çağrı yapıyorsanız

Bu yük size aittir ve Kunavo bunu örtbas etmez: 400 yeniden denenemezler listesindedir; bu nedenle hatalı bir tool gidiş-dönüşü, aynı hataya ulaşmak için ikinci bir upstream gidiş-dönüş gecikmesi harcamadan bir kez başarısız olur ve reddedilen istek sıfır maliyetle kaydedilir. /v1/messages üzerinde doğrudan Messages protokolüyle konuştuğunuz için tools, tool_use ve tool_result blokları çevrilmeden iletilir. Burada 400, Anthropic API'sinde olduğu gibi typed invalid_request_error olarak geri döner; upstream'in mesaj metnini, ardından upstream'in kendi request id'sini içerir ve request_id alanı bulunmaz. 24 Eylül 2026'ya kadar tür api_error olarak okunuyordu; bu nedenle günlükleriniz daha eskiye gidiyorsa HTTP durumuna ve mesaj metnine göre dallanın.

Sık sorulan sorular

Yanıtlamak yerine tool_use turunu tamamen kaldırabilir miyim?

Evet, asistan turunun tamamını kaldırırsanız. Geçersiz olan, tool_use'u tutup tool_result'ı eksik bırakmaktır.

OpenAI uyumlu uç nokta da aynı kurala mı sahip?

Aynı eşleştirme gerekir, ancak farklı adlandırılır — asistan mesajında tool_calls, ardından her çağrı için tool_call_id taşıyan bir role: "tool" mesajı.

Reddedilen bir istek ücretlendirilir mi?

Kunavo'da hayır. Başarısız istekler sıfır maliyetle kaydedilir ve ücretlendirilen bir upstream çağrısına hiçbir zaman ulaşmaz.

İlgili kılavuzlar

Hata anlamlarına ilişkin daha fazla bilgi hata referansı bölümünde; anahtar almak kayıt ve kimlik doğrulama kılavuzu üzerinden bir dakika sürer.