Regresyon testi
Salı günü bozulan çalıştırma, sonraki her sürümün geçmesi gereken vaka olur.
Kapatmak için var olan döngü
Bir ajan gerçek bir soruda başarısız olur. Biri bunu elle yeniden üretir, bir prompt'u değiştirir ve durum düzelmiş görünür. Üç hafta sonra aynı soruda yine başarısız olur, çünkü onu saklayan hiçbir şey yoktur.
Veri kümesi onu saklar. Başarısız çalıştırmayı yakalayın; artık bir anekdot olmaktan çıkar ve bir girdisi, elinizde varsa beklenen bir yanıtı ve geldiği trace'e giden bir işaretçisi olan bir vaka olur. Sonraki her sürüm ona karşı çalışır.
Bir çalıştırmayı yakalamak
Çalıştırmayı arayüzde ya da API üzerinden bulun, sonra trace kimliğini veri kümesine verin.
başarısız bir çalıştırmayı vaka olarak yakala
curl -X POST localhost:4317/v1/api/datasets/$DATASET/capture \
-H 'content-type: application/json' \
-d '{"trace_ids": ["b3d9e71a4c0f428eb6a5d2317f90c684"]}'
Yakalanan vaka source_trace_id alanını saklar; böylece aylar
sonra ona sebep olan çalıştırmayı açıp girdiye bakarak tahmin yürütmek
yerine gerçekte ne olduğunu okuyabilirsiniz.
- agent support_agent fail
- model chat
- tool returns_policy
- model chat
- tool returns_policy
- model chat
- tool returns_policy
The model called one tool three times and never answered. That is visible in four seconds here, and invisible in a log file.
Çalıştırmanın kendi yanıtı, beklenen yanıt değildir
use_output_as_expected varsayılan olarak kapalıdır ve önemli
olan kısım bu varsayılandır. Yakalamaya değer çalıştırmalar genellikle ters
gidenlerdir; yanlış bir yanıtı referans olarak kaydetmek de hatayı
kalıcılaştırır: sonraki her sürüm o hatayı yeniden üretme becerisine göre
ölçülür.
Zaten beğendiğiniz bir davranışı yerinde tutmak için doğru sonuçlanmış çalıştırmaları yakalarken bunu açın. Bir başarısızlığı yakalarken kapalı bırakın ve beklenen yanıtı kendiniz yazın.
Yerleşik puanlayıcılar
mcpd on üç deterministik puanlayıcıyla gelir: saklanmış bir çalıştırmayı okuyup bir sayı döndüren sıradan kod. Hiçbir maliyetleri yoktur, hiçbir zaman bir model çağırmazlar ve iki kez aynı yanıtı verirler; bir regresyon testinin ihtiyaç duyduğu, bir yargıç modelde ise bulunmayan özellik budur.
| Puanlayıcı | Ne zaman geçer |
|---|---|
answered | Çalıştırma boş olmayan bir yanıt üretti. |
no_errors | Çalıştırmadaki hiçbir span başarısız olmadı. |
exact_match | Yanıt beklenenin aynısı. |
contains | Yanıt, istenen dizeyi içeriyor. |
json_valid | Yanıt JSON olarak ayrıştırılıyor. |
latency_budget | Çalıştırma, milisaniye cinsinden bir bütçenin içinde bitti. |
cost_budget | Çalıştırma, belirlenen tutardan fazlaya mal olmadı. |
no_tool_loop | Hiçbir araç aynı girdiyle iki kez çağrılmadı. |
tool_efficiency | Çalıştırma, araç çağrısı bütçesinin içinde kaldı. |
not_a_refusal | Yanıt bir ret ya da özür değil. |
no_leaked_secret | Yanıtta hiçbir anahtar, token ya da kimlik bilgisi geçmiyor. |
span_present | Çalıştırma, istenen türde ya da adda bir span kaydetti. |
tool_succeeded | İstenen araç çalıştı ve en az bir çağrısı düzgün bitti. |
GET /v1/api/scorers aynı listeyi bir needs_config
bayrağıyla döndürür. Beklenen bir yanıta ihtiyaç duyan ama kendisine
verilmeyen bir puanlayıcı tahmin etmek yerine puan üretmez ve bu durum
bildirilir.
Notu bir model verdiğinde
Bazı soruları hiçbir deterministik kod yanıtlayamaz. Bir yanıtın soruyu gerçekten karşılayıp karşılamadığı, bir özetin anlamı koruyup korumadığı, bir üslubun yerinde olup olmadığı: bunlar bir okuyucu ister ve ucuz okuyucu bir modeldir.
Yargıçlı puanlama siz yapılandırana kadar kapalıdır ve yargıçlı bir puanlayıcı siz adını vermedikçe hiç çalışmaz. İki varsayılan da aynı nedenle vardır: not verme, okuduğu her çalıştırma için para harcar ve bunu sessizce yapan bir özellik, varlığını bir faturada öğrendiğiniz özelliktir.
{
"judge": {
"endpoint": "http://localhost:11434/v1",
"model": "qwen2.5:14b",
"api_key": "",
"timeout_seconds": 30,
"criteria": {
"answer_relevance": "Does the answer address the question that was asked?",
"no_hedging": "Does the answer commit, rather than hedge?"
}
}
}
İstek, OpenAI chat-completions biçimindedir; bu bir sağlayıcı tercihi
değildir: Ollama, vLLM, llama.cpp, LM Studio, OpenRouter ve barındırılan
sağlayıcıların hepsi bunu kabul eder, yani aynı yapılandırma hem
dizüstünüzdeki bir modele hem de üretimdeki bir ağ geçidine ulaşır. Anahtar
istemeyen yerel bir model için api_key alanını boş bırakın.
Sıcaklık sıfırdır, çünkü her seferinde farklı yanıt veren bir yargıç kendisiyle
karşılaştırılamaz, ki puanların tek işi budur.
Ölçütler her istekte gönderilmek yerine yapılandırılır. Ürettiği her puanın üzerinde bir puanlayıcı kimliği saklanır ve sonraki bir karşılaştırma buna göre gruplar; her çağrının hem kimliği hem soruyu kendi uydurmasına izin vermek de kimsenin güvenemeyeceği bir sütun kurardı.
Yapılandırılmış ölçütler GET /v1/api/scorers içinde görünmez. O
endpoint yalnızca yerleşik on üç puanlayıcıyı listeler, başka bir şey
listelemez; dolayısıyla puanlayıcı menüsünü ondan kuran bir istemci sizin
ölçütlerinizi sunmayacaktır. Daemon'un bunları size geri söylediği tek yer,
bilinmeyen bir puanlayıcı kimliği için aldığınız hatadır; o hata yerleşik
olanlarla yapılandırılmış ölçütleri bir arada listeler.
son çalıştırmada yargıçlı bir puanlayıcı çalıştır
curl -X POST localhost:4317/v1/api/score \
-H 'content-type: application/json' \
-d '{"limit": 1, "scorers": ["answer_relevance"]}' timeout_seconds, tek bir puanlama çağrısının bağlanmadan
yanıtın son baytına kadar ne kadar sürebileceğidir: varsayılan 30, aralık 1
ile 300. Bunu aşan çağrı anahtarı adlandırarak puan üretmez ve mcpd bir
yanıtın en fazla 1 MiB'ını okur.
Her yargıçlı puanlayıcı, çalıştırma başına bir model çağrısıdır ve istek
--request-timeout-seconds içinde bitmek zorundadır. Bu yüzden
bir istek, her çağrı timeout_seconds süresinin tamamını
kullansa bile bu süreye sığacak kadar çalıştırmayı puanlar. Varsayılan 30 ve
30 ile tek bir yargıçlı puanlayıcıda bu bir çalıştırmadır.
trace_ids ya da limit içinde daha fazlasını
isteyen bir istek, hiçbir model çağrılmadan sınırı adlandıran bir 400 ile
reddedilir. limit verilmezse istek, sığdığı kadar son
çalıştırmayı puanlar. Tek istekte daha fazlasını puanlamak için
--request-timeout-seconds değerini yükseltin. Her yargıçlı
puan, model yanıt verir vermez saklanır; böylece yarıda kesilen bir istek
bitirdiği puanları korur.
Tahmin etmek yerine puan üretmez
Türetmediği bir sayıyı döndüren bir yargıç, hiç yargıç olmamasından
kötüdür, çünkü kanıt gibi görünür. Bu yüzden aşağıdakilerin her biri,
nedeniyle birlikte skipped içinde bildirilir ve hiçbiri bir
puan üretmez.
| Ne oldu | mcpd ne yapar |
|---|---|
| Çalıştırma hiçbir yanıt kaydetmedi | Puan üretmez. Yanıtı olmayan bir çalıştırma ilgililikte düşük puan almış olmaz, hiç ölçülmemiştir. |
| Model düz metinle yanıtladı | Puan üretmez ve yanıtı alıntılar. Kod bloğuna ya da bir cümlenin içine sarılmış JSON yine de okunur. |
| Model ölçeğin dışında yanıt verdi | Puan üretmez. Bir üzerinden verilen bir yedi, onda dokuz demek değildir; sayıyı sınıra çekmek de bir sayı uydurmak olurdu. |
| Modele ulaşılamadı | Puan üretmez, durum kodunu ve gövdeyi verir. Hız sınırı bir nedendir, sıfır değil. |
| Yanıt 1 MiB'tan büyüktü | Gerisini okumadan puan üretmez. Bir karar birkaç yüz bayttır, o boyutta bir yanıt karar değildir. |
| İsteğin süresi çağrı için zaman bırakmadı | Modeli çağırmadan reddeder. Geçiş, 503 yerine süre içinde bitirdiği puanlarla yanıt verir. |
Yargıçlı her puan, modeli kendi scorer_version alanına
kaydeder. İki farklı yargıçtan gelen iki puan karşılaştırılabilir değildir
ve kayıtta bunu söyleyen alan budur.
Puanlama olaydan sonra olur
POST /v1/api/score, puanlayıcıları hâlihazırda saklanmış
çalıştırmalar üzerinde çalıştırır. Hiçbir şey satır içinde değerlendirilmez.
İstek yolundaki bir değerlendirme, kendi gecikmesini yargıladığı şeyin
üzerine ekler ve hata fırlatan bir değerlendirme hiçbir zaman bir
kullanıcının isteğini düşürmemelidir.
son yüz çalıştırmayı puanla
curl -X POST localhost:4317/v1/api/score \
-H 'content-type: application/json' \
-d '{"project": "support-desk", "limit": 100, "config": {"max_ms": 4000}}'
Yanıt, yazdığı puanları ve bunlardan ayrı olarak puan üretmeyen her
puanlayıcıyı nedeniyle birlikte taşır. Yanıt veremeyen bir puanlayıcı, bir
sayı döndürenden daha ilginçtir, o yüzden mcpd bunu asla yutmaz. Projenin
alım tavanı da bu kapıya kadar gelir: taramanın hesapladığı, projeyi
--quota-per-minute sınırının üstüne çıkaracak bir puan
saklanmaz; tavanın ötesine yazılmak ya da sessizce atılmak yerine bunu
söyleyerek skipped içinde listelenir.
Hiçbir şey saklamadan bir taramanın ne üreteceğini görmek için
"dry_run": true gönderin.
Bir taramanın hangi çalıştırmaları okuyacağına trace_ids,
from ve limit karar verir. Tam olarak belirli
çalıştırmaları puanlamak için onları trace_ids içinde
adlandırın. Boş bırakırsanız tarama, projedeki en yeni limit
kadar çalıştırmayı en yeniden başlayarak alır; from da o sayfayı
sınırlar: from ile gönderilen bir tarama yalnızca o anda ya da
sonrasında başlayan çalıştırmaları okur, ki bir dağıtımdan sonraki her şeyi
kimlik listelemeden puanlamanın yolu budur.
İki sürümü karşılaştırmak
Karşılaştırmak istediğiniz her sürüm için bir deney kaydedin, puanlarını o deneyin kimliğiyle etiketleyin ve mcpd'den farkı isteyin.
yeni prompt işe yaradı mı
curl 'localhost:4317/v1/api/experiments/compare?baseline=v3&candidate=v4'
Yanıt, her iki taraftaki örneklem boyutuyla birlikte puanlayıcı başına bir
fark ve bir decidable bayrağıdır. Yirmi gözlemin altında mcpd,
bir hareket bildirmek yerine karşılaştırmanın karara bağlanamayacağını
söyler.
Bu bilerek kaba bir kuraldır, anlamlılık testi değildir. Önlediği hata, yaygın olanıdır: dört çalıştırmada kımıldayan, sayısı yazılmadan basılan, sonuç diye okunup yayına alınan bir ortalama. Sayıları farkın yanına basmak, gürültünün bulgu sanılmasını durduran şeydir.
Bunun çalışacağı yer
Hepsi HTTP API'sidir, yani döngünün yeri CI'dır: başarısızlıkları oluştukça
yakalayın, test takımınızın ürettiği çalıştırmaları puanlayın, derlemeyi bir
deney olarak kaydedin ve karara bağlanabilir bir karşılaştırmada
regressed değeri true dönerse işi başarısız sayın.
Sırada
- Bir puanın yanında durduğu iki sinyal: Puanlar ve geri bildirim.
- Üretimde bir puanlayıcının ortalamasını izlemek: İzleyiciler ve uyarılar.
- Her endpoint ve her alan: HTTP API.