DEV Community

Cover image for Belirsiz Yapay Zeka Ajanları Nasıl Test Edilir? (temperature=0 Yetersiz Kaldığında)
Tobias Hoffmann
Tobias Hoffmann

Posted on • Originally published at apidog.com

Belirsiz Yapay Zeka Ajanları Nasıl Test Edilir? (temperature=0 Yetersiz Kaldığında)

Testiniz Pazartesi günü geçti: aynı girdi, aynı kod ve temperature=0. Salı günü ise siz hiçbir şeyi değiştirmeden başarısız oldu. Onaylama tam dize eşleşmesi arıyordu, model de aynı cevabı farklı biçimde ifade etti. Test kırmızı, ajan doğru çalışıyor ve artık ürün yerine test paketinizi hata ayıklıyorsunuz.

Apidog'u bugün deneyin

Bir dil modeli kullanan sistemlerde bu durum normaldir. Çıktı, istemeseniz de değişebilir. temperature=0 ayarlasanız bile çalıştırmalar arasında bayt düzeyinde özdeş yanıt garantisi yoktur. Bu yüzden testleri tam metne değil, değişmeyen sözleşmeye göre tasarlamanız gerekir. Bu yazı, yapay zeka ajanlarının üretimde neden bozulduğuna dair kılavuzumuzdaki üçüncü hata moduna odaklanır.

Neden temperature=0 belirleyici değildir?

Sıcaklık, modelin sonraki token'ı nasıl örneklediğini kontrol eder. Sıfırda model en olası token'ı seçer; bu da teoride yeniden üretilebilir görünür. Pratikte ise çıkarım altyapısı sonucu etkiler.

GPU'larda kayan noktalı işlemler ilişkilendirici değildir. Aynı sayıları farklı sırayla toplamak, son ondalık basamaklarda farklı sonuçlar üretebilir. Bu küçük fark, en yüksek olasılıklı token'ın değişmesine neden olabilir. İlk token değiştiğinde, devamındaki tüm çıktı da değişebilir.

Bu işlem sırası şunlara bağlı olabilir:

  • Sağlayıcının istekleri nasıl toplu işlediği
  • İsteğin hangi donanımda çalıştığı
  • Dağıtılan çekirdek veya çıkarım kütüphanesi sürümü
  • Çağrının yönlendirildiği bölge
  • Model ağırlıklarının veya nicemleme yapılandırmasının değişmesi

vLLM üzerindeki bu uzun tartışma, sabit çekirdek ve temperature=0 kullanılsa bile bit düzeyinde yeniden üretilebilirliğin neden garanti olmadığını açıklar.

Özet: determinizm, API isteğinde ayarladığınız tek bir bayrak değildir. Tüm sunum yığınının özelliğidir.

Bu nedenle test varsayımınızı değiştirin:

  • Yanlış varsayım: “Model tam olarak bu metni döndürmeli.”
  • Doğru varsayım: “Model, sözleşmedeki yapıyı ve iş kurallarını karşılayan bir yanıt döndürmeli.”

Tam dize onaylamaları neden kararsız test üretir?

Şu test ilk çalıştırmada mantıklı görünebilir:

assert response == "Siparişinizin toplamı 42,00 $'dır."
Enter fullscreen mode Exit fullscreen mode

Ancak model sonraki çalıştırmada aşağıdakini döndürürse test başarısız olur:

Toplamınız 42,00 $'a geliyor.
Enter fullscreen mode Exit fullscreen mode

Yanıt doğru olduğu halde test kırmızıya döner.

Doğru yanıtta başarısız olan testler, hiç test olmamasından daha zararlıdır. Ekip zamanla bu testleri tekrar çalıştırmayı, başarısızlıkları görmezden gelmeyi ve gerçek regresyonları gürültü içinde kaçırmayı öğrenir. Kararsız testlerin nedenleri ve nasıl yayıldıkları bu yüzden önemlidir.

Tam dize eşleşmesi, snapshot veya metin farkı alma yaklaşımı genellikle sorunu çözmez. Testi, değişmesi en muhtemel katmana bağlamış olursunuz.

Bunun yerine yapıyı, türleri, sınırları ve iş kurallarını doğrulayın.

Tam metin yerine yapıyı ve anlamı doğrulayın

Bir destek ajanı geri ödeme onayını onlarca farklı şekilde yazabilir. Ancak geçerli her yanıt aynı temel bilgileri taşımalıdır:

  • Geri ödeme miktarı
  • Sipariş kimliği
  • İşlem durumu
  • Kullanıcıya gösterilmesi güvenli açıklama

Testlerinizin hedefi cümle yapısı değil, bu sözleşme olmalıdır.

Aşağıdaki stratejileri birlikte kullanın.

Yanıtı JSON şemasına göre doğrulayın

Ajanınız yapılandırılmış veri döndürüyorsa, önce bir JSON şeması tanımlayın. Ardından her yanıtı bu şemaya göre doğrulayın.

Örnek bir geri ödeme yanıtı:

{
  "order_id": "ORD-12345",
  "status": "refunded",
  "amount": 42.0,
  "currency": "USD",
  "resolution": "Geri ödeme işlemi başlatıldı."
}
Enter fullscreen mode Exit fullscreen mode

Bu yanıt için şema:

{
  "type": "object",
  "required": [
    "order_id",
    "status",
    "amount",
    "currency",
    "resolution"
  ],
  "properties": {
    "order_id": {
      "type": "string",
      "pattern": "^ORD-[0-9]+$"
    },
    "status": {
      "type": "string",
      "enum": ["refunded", "pending", "denied"]
    },
    "amount": {
      "type": "number",
      "minimum": 0
    },
    "currency": {
      "type": "string",
      "enum": ["USD", "EUR", "TRY"]
    },
    "resolution": {
      "type": "string",
      "minLength": 1
    }
  },
  "additionalProperties": false
}
Enter fullscreen mode Exit fullscreen mode

Bu yaklaşım şu hataları yakalar:

  • Modelin zorunlu alanı atlaması
  • Sayı yerine dize döndürmesi
  • Nesneyi yanlış iç içe yerleştirmesi
  • Beklenen JSON yerine düz metin döndürmesi
  • Geçersiz durum değeri üretmesi

Yanıt şemanızı Apidog'a yükleyerek canlı veya test yanıtlarını doğrulayabilirsiniz. Böylece hata mesajı, yüzlerce karakterlik metin farkı yerine bozuk alanı gösterir.

Araç çağrılarının şeklini ve hedefini doğrulayın

Ajan bir araç çağırdığında, çağrıyı üreten doğal dil açıklamasını değil, aracın kendisini test edin.

Her araç çağrısında üç soruyu yanıtlayın:

  1. Doğru araç seçildi mi?
  2. Doğru uç nokta veya hedef kullanıldı mı?
  3. Gönderilen yük araç şemasıyla eşleşiyor mu?

Örneğin bir rezervasyon ajanı şu çağrıyı üretiyorsa:

POST /reservations
Enter fullscreen mode Exit fullscreen mode

Gönderilen yükü doğrulayın:

{
  "date": "2025-06-20",
  "guests": 2,
  "customer_id": "CUS-1001"
}
Enter fullscreen mode Exit fullscreen mode

Örnek kontroller:

assert tool_call["name"] == "create_reservation"
assert tool_call["method"] == "POST"
assert tool_call["path"] == "/reservations"

payload = tool_call["body"]

assert isinstance(payload["guests"], int)
assert payload["guests"] > 0
assert "date" in payload
assert "customer_id" in payload
assert "internal_reasoning" not in payload
Enter fullscreen mode Exit fullscreen mode

Bu test, modelin “rezervasyonunuzu oluşturdum” veya “hemen rezervasyonunuzu hazırlıyorum” demesinden etkilenmez. Önemli olan, API sözleşmesine uygun isteği göndermesidir.

Bir ajanın API çağrılarını test etmeye yönelik uçtan uca yöntem, araç şemalarını yakalama ve bunlara göre onaylama sürecini ayrıntılı olarak ele alır.

Tam değer yerine sayısal aralık kullanın

Modelin ürettiği veya aktardığı sayılarda tam eşleşme yerine geçerli aralıkları doğrulayın.

Örneğin, bir alışveriş sepeti ajanının toplam tutarı hesapladığını düşünün. Her sepet için kesin rakamı test içinde sabitlemek yerine bilinen iş sınırlarını kullanın:

assert response["total"] >= 0
assert response["total"] <= cart_subtotal + max_shipping + max_tax
Enter fullscreen mode Exit fullscreen mode

Bu kontroller şunları yakalar:

  • Negatif toplam
  • Mantıksız derecede yüksek toplam
  • Dolu sepet için sıfır toplam
  • Sayısal olmayan değer

Aynı yaklaşım şuralarda da kullanışlıdır:

  • Güven skorları
  • Öğe sayıları
  • Token kullanımı
  • Gecikme bütçeleri
  • İndirim oranları
  • Tahmini teslimat süreleri

Kural basit: Gerçek hata oluştuğunda başarısız olacak en geniş sınırı seçin.

Zorunlu alanları ve yasaklı alanları kontrol edin

İki basit kontrol, yüksek değer sağlar:

  1. Gerekli alanlar mevcut ve null değil mi?
  2. Asla görünmemesi gereken alanlar yok mu?

Örnek:

required_fields = ["order_id", "status", "resolution"]

for field in required_fields:
    assert field in response
    assert response[field] is not None

forbidden_fields = ["internal_notes", "raw_prompt", "system_message"]:
    assert field not in response
Enter fullscreen mode Exit fullscreen mode

Bir destek ajanı müşteriye resolution alanını döndürmelidir. Ancak internal_notes, raw_prompt veya sistem mesajını asla döndürmemelidir.

Bu kontroller metinden bağımsızdır. Ayrıca modelin yararlı olmaya çalışırken gizli verileri sızdırmasına karşı düşük maliyetli bir güvenlik katmanı sağlar.

Serbest metinde anlamsal ve eşik kontrolleri kullanın

Bazı yanıtlar kaçınılmaz olarak düz metindir. Bu durumda tam eşleşme yerine ölçülebilir özellikleri kontrol edin.

Örnek:

assert order_id in response_text
assert len(response_text) <= 500
assert "şifre" not in response_text.lower()
assert "sistem mesajı" not in response_text.lower()
Enter fullscreen mode Exit fullscreen mode

Kontrol edebileceğiniz özellikler:

  • Girdi sipariş numarasının yanıt içinde bulunması
  • Maksimum karakter veya kelime sınırı
  • Yasaklı ifadelerin bulunmaması
  • Beklenen bağlantının veya yönlendirmenin yer alması
  • Gerekli açıklama veya uyarının mevcut olması

Gerçekten anlamsal yakınlığı ölçmeniz gerekiyorsa, yanıtı referans cevaba yerleştirme benzerliği ile karşılaştırabilir ve eşik belirleyebilirsiniz:

similarity = cosine_similarity(response_embedding, expected_embedding)

assert similarity >= 0.82
Enter fullscreen mode Exit fullscreen mode

Ancak bu kontrolü hassas bir doğruluk kapısı olarak kullanmayın. Anlamsal benzerlik, konu dışına çıkan yanıtları yakalamada faydalıdır; ince iş mantığı hatalarını tek başına güvenilir biçimde yakalayamaz. Şema, tür, sınır ve güvenlik kontrolleriyle birlikte kullanın.

Tam snapshot yerine snapshot aralığı kullanın

Snapshot testleri tamamen bırakmanız gerekmez. Ancak serbest metni dondurmak yerine kararlı özelliklerin anlık görüntüsünü alın.

Örneğin şu yapı korunabilir:

{
  "keys": ["amount", "currency", "order_id", "resolution", "status"],
  "status_enum": ["refunded", "pending", "denied"],
  "amount_range": [0, 10000]
}
Enter fullscreen mode Exit fullscreen mode

Bu yaklaşım, aşağıdaki değişikliklerde testi başarısız kılar:

  • Alanın kaldırılması
  • Alan türünün değiştirilmesi
  • Yeni ve beklenmeyen alan eklenmesi
  • Enum dışı değer dönmesi
  • Sayısal sınırın aşılması

Ancak resolution metnindeki eş anlamlı değişiklikler nedeniyle başarısız olmaz.

Durum ve bellek testi zorlaştırır

Yukarıdaki örnekler tek istek ve tek yanıt varsayar. Ajanlar genellikle konuşmalar arasında bellek taşır.

Durumlu bir ajanın yanıtı şunlara bağlıdır:

  • Geçerli kullanıcı girdisi
  • Önceki dönüşlerde saklanan bellek
  • Araç çağrılarının sırası
  • Alma veya arama sonuçlarının sıralaması
  • Önceki dönüşlerde üretilen özetler

Bu nedenle aynı konuşma iki farklı çalıştırmada farklı sonuç verebilir. Bunun nedeni hem modelin belirsizliği hem de başlangıç durumunun değişmesidir.

Yapay zeka ajanı belleğinin nasıl çalıştığına dair açıklayıcı, bu durumun nerede tutulduğunu ve nasıl oluştuğunu ele alır.

Durumlu ajanları test ederken iki alışkanlık uygulayın.

1. Başlangıç durumunu sabitleyin

Her testten önce bellek ve konuşma durumunu bilinen bir başlangıç noktasına getirin.

def setup_test_agent():
    agent.reset_memory()
    agent.seed_memory({
        "customer_id": "CUS-1001",
        "active_order_id": "ORD-12345"
    })
Enter fullscreen mode Exit fullscreen mode

Böylece test başarısız olduğunda hem istemin hem belleğin aynı anda değişip değişmediğini tahmin etmek zorunda kalmazsınız.

2. Yoldan bağımsız değişmezleri doğrulayın

Ajanın hangi ara adımları attığından bağımsız olarak geçerli olması gereken kuralları test edin.

Örnekler:

assert employee_balance >= 0
assert reservation_count == 1
assert payment_attempts <= 3
assert final_state in {"confirmed", "cancelled", "needs_review"}
Enter fullscreen mode Exit fullscreen mode

Bir uçuş rezervasyonu konuşması üç veya on dönüş sürebilir. Ancak tamamlandığında tam olarak bir rezervasyon oluşmalı ya da açık bir hata durumu dönmelidir.

Bağımlılıkları taklit ederek testleri tekrarlanabilir yapın

Canlı üçüncü taraf API'leri test ortamında ek rastgelelik üretir:

  • Hız limiti uygularlar
  • Verileri değişir
  • Bakım veya kesinti yaşayabilirler
  • Gecikmeleri farklılaşır
  • Farklı hata yanıtları döndürebilirler

Tekrarlanabilir test için, ajanın davranışı dışındaki her şeyi sabitleyin.

Ajanın çağırdığı bağımlılıkları taklit edin ve sabit yanıtlar tanımlayın:

{
  "payment_api": {
    "receipt_id": "RCP-001",
    "status": "paid",
    "amount": 42.0
  },
  "search_api": {
    "results": [
      {"id": "DOC-1", "title": "İade politikası"},
      {"id": "DOC-2", "title": "Teslimat bilgisi"},
      {"id": "DOC-3", "title": "Sipariş takibi"}
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Bu sayede:

  • Ödeme API'si her seferinde aynı makbuzu döndürür.
  • Arama API'si her seferinde aynı sonuçları döndürür.
  • Testte değişen ana unsur, gözlemlemek istediğiniz ajan davranışı olur.

Taklitler ayrıca canlı ortamda üretmesi zor olan uç durumları zorlamanızı sağlar:

{
  "error": "payment_provider_timeout",
  "retry_after_seconds": 30
}
Enter fullscreen mode Exit fullscreen mode

Ardından ajanın doğru davranışı gösterdiğini doğrulayabilirsiniz:

assert response["status"] == "needs_review"
assert "tekrar deneyin" in response["resolution"].lower()
Enter fullscreen mode Exit fullscreen mode

Apidog ile ajan bağımlılıkları için kararlı mock yanıtları oluşturabilir, ardından bunları şema ve sözleşme kontrolleriyle birleştirebilirsiniz. Bu yaklaşım, daha geniş ajanlı yapay zeka testi uygulamasının temel parçalarından biridir.

Apidog nerede uyar, nerede uymaz?

Aracın sorumluluğunu doğru konumlandırın.

Apidog; API tasarımı, test ve mock platformudur. Bir ajan çerçevesi, model barındırıcısı, ajan çalışma zamanı veya muhakeme puanlama platformu değildir.

Apidog şunları yapmaz:

  • Ajanınızı oluşturmaz
  • Modelinizi barındırmaz
  • Ajan adımlarını orkestre etmez
  • Muhakeme zincirini değerlendirmez

Ancak ajanın konuştuğu API katmanında güçlüdür.

Bu yazıdaki kullanım alanları şunlardır:

  1. API yanıtı sözleşmelerini doğrulamak

    • JSON şeması
    • Yanıt şekli
    • Sayısal aralıklar
    • Zorunlu alanlar
    • Yasaklı alanlar
    • Araç çağrısı yükleri
  2. Ajan bağımlılıklarını mocklamak

    • Sabit API yanıtları
    • Kontrollü hata senaryoları
    • Tekrarlanabilir entegrasyon testleri

Apidog'un doldurduğu boşluk budur: modeli değil, modelin ürettiği istek ve yanıtların sözleşmesini test etmek.

Sözleşmeyi test edin, kelimeleri değil

Belirsizlik, yapılandırma ile tamamen kaldırabileceğiniz bir hata değildir. Dil modeli çalıştırmanın doğal sonucudur ve temperature=0 bunu ortadan kaldırmaz.

Güvenilir ajanlar geliştiren ekipler, değişen metinle savaşmak yerine sabit kalan özellikleri test eder:

  • Şema
  • Alan türleri
  • Yanıt şekli
  • Sayısal aralıklar
  • Zorunlu alanlar
  • Yasaklı alanlar
  • Araç çağrısı sözleşmeleri
  • Durum değişmezleri

Bu yaklaşımı benimsediğinizde test paketiniz daha sessiz hale gelir: metin farklı ifade edildiğinde yeşil kalır, yalnızca sözleşme gerçekten bozulduğunda kırmızıya döner.

Bu hafta test paketinizdeki bir tam dize onaylamasını seçin. Onu bir şema doğrulaması, aralık kontrolü veya zorunlu/yasaklı alan kontrolü olarak yeniden yazın. Ardından ajanın bağımlılıklarını mocklayarak testi tekrarlanabilir hale getirin.

Top comments (0)