Yazılım eğitimi asistanlarında model, prompt veya araç değişikliklerinin gizli kalite kaybı üretmesini golden test setleri, metamorfik testler, diferansiyel karşılaştırma ve hata kümeleriyle yakalayın.
Yazılım Eğitimi Asistanlarında LLM Regresyon Testi ve Metamorfik Eval
Yazılım Eğitimi İçin LLM Regresyon Testinin Sınırlarını Tanımlayın
Bir yazılım eğitimi asistanında regresyon testi, yalnızca beklenen yanıt metninin birebir eşleşmesi değildir. Model yanıtı değişken olduğundan test kontratını ölçülebilir davranışlara ayırın: derlenebilir kod oranı, yanlış API önerme oranı, rubric maddesi karşılama oranı ve yasak davranış oranı. Her test kaydını JSONL olarak saklayın; `case_id`, `prompt`, `expected_signals`, `forbidden_signals`, `tool_fixture` ve `severity` alanları, hata ortaya çıktığında hangi kontratın bozulduğunu ayrıştırır.
{
"case_id": "py-async-017",
"prompt": "Bu coroutine neden await edilmelidir? Kısa bir örnek ver.",
"expected_signals": ["await", "coroutine", "RuntimeWarning"],
"forbidden_signals": ["asyncio.run() bir event loop icinde her zaman guvenlidir"],
"tool_fixture": "python-3.12",
"severity": "high"
}Birebir metin eşleşmesi yerine sinyal tabanlı kontrat kullanmanın teknik nedeni, aynı doğru çözümün farklı isimlendirme, sıra ve açıklama düzeyiyle üretilebilmesidir. Buna karşılık `RuntimeWarning` uyarısını açıklamamak veya çalışan event loop içinde `asyncio.run()` önermek, farklı cümlelerle yazılsa da pedagojik olarak aynı hatadır. Test veri kümesini Git içinde sürümleyin ve her değişiklikte `dataset_sha256` değerini CI çıktısına yazdırın; böylece model değişimini test seti değişiminden ayırabilirsiniz.
sha256sum evals/golden.jsonl > evals/golden.jsonl.sha256
pytest -q tests/test_eval_dataset.py
python -m json.tool evals/golden.jsonl > /dev/nullGolden Set Yerine Metamorfik Testlerle Gizli Hataları Bulun
Golden set, önceden bilinen soruları ölçer; metamorfik test ise cevabın korunması gereken dönüşümleri üretir. Örneğin aynı Python hatasını değişken adlarını değiştirerek, gereksiz yorumlar ekleyerek veya hata mesajındaki dosya yolunu maskeleyerek yeniden sorun. Dönüşümden sonra asistanın temel teşhisi değişmemelidir. Bu yaklaşım, özellikle yazılım eğitimi içeriğinde modelin yüzeysel token ipuçlarına mı, yoksa kodun semantiğine mi dayandığını ortaya çıkarır.
import ast
import re
def normalize_diagnosis(text: str) -> set[str]:
rules = {
"missing_await": r"\b(await|coroutine|never awaited)\b",
"mutable_default": r"\b(mutable default|default argument)\b",
"key_error": r"\bKeyError\b",
}
return {name for name, pattern in rules.items()
if re.search(pattern, text, flags=re.I)}
def test_renamed_variables_preserve_diagnosis(llm):
original = "items = {}\nprint(items['id'])"
renamed = "cache = {}\nprint(cache['id'])"
a = normalize_diagnosis(llm.ask(original))
b = normalize_diagnosis(llm.ask(renamed))
assert "key_error" in a
assert a == bDönüşümü metin değiştirme ile değil, mümkün olduğunda AST ile üretin. Python için `ast.parse()` ve `ast.unparse()` kullanarak yalnızca `ast.Name` düğümlerini yeniden adlandırmak, string literal içindeki `id` kelimesini yanlışlıkla değiştirme riskini azaltır. Yaygın hata, dönüşümün program davranışını da değiştirmesidir: örneğin Python'da `x` adını `list` yapmak yerleşik tipi gölgeler ve test artık modelin değil fixture'ın hatasını ölçer. Dönüştürücü, hedef adın `dir(builtins)` içinde olmadığını doğrulamalıdır.
Diferansiyel Değerlendirme ile Prompt ve Model Değişimini Karşılaştırın
Bir prompt veya model sağlayıcısı değiştiğinde aday sistemi tek başına puanlamayın. Aynı sabit test setini mevcut üretim sürümü ve aday sürüm üzerinde çalıştırıp vaka bazında karşılaştırın. Bu diferansiyel yaklaşım, ortalama skor aynı kalırken `severity=high` vakalarda oluşan bozulmayı görünür yapar. CI kapısı için örnek kural: yüksek önem dereceli vakalarda başarı oranı baseline değerinin altına inmesin, toplam başarısız vaka sayısı en fazla 2 artsın ve yeni yasaklı öneri eklenmesin.
from collections import Counter
def gate(baseline, candidate):
high_base = [x for x in baseline if x["severity"] == "high"]
high_next = [x for x in candidate if x["severity"] == "high"]
base_rate = sum(x["passed"] for x in high_base) / len(high_base)
next_rate = sum(x["passed"] for x in high_next) / len(high_next)
new_forbidden = [x for x in candidate if x["forbidden_hit"]]
delta_failures = sum(not x["passed"] for x in candidate) - sum(not x["passed"] for x in baseline)
assert next_rate >= base_rate, (base_rate, next_rate)
assert delta_failures <= 2, delta_failures
assert not new_forbidden, Counter(x["case_id"] for x in new_forbidden)Ham ortalama yerine eşleşmiş vaka farkını raporlayın. Her `case_id` için `baseline_passed -> candidate_passed` geçişini `improved`, `regressed`, `stable_pass`, `stable_fail` olarak sayın. Özellikle `stable_fail` kümesi teknik borç kuyruğudur; onu yeni model geçişini engelleyen regresyonlarla karıştırmayın. Sonuçları Parquet formatında saklamak ve DuckDB ile sorgulamak, yüzlerce deneme ve binlerce vaka üzerinde JSON dosyalarını belleğe almadan analiz yapmanızı sağlar.
SELECT transition, count(*) AS cases
FROM read_parquet('artifacts/eval_diff/*.parquet')
GROUP BY transition
ORDER BY cases DESC;Çalıştırılabilir Kod Kontrolünü Rubric Puanından Ayırın
Kod üreten eğitim asistanlarında bir LLM judge'ın 'doğru' demesi, kodun çalıştığı anlamına gelmez. Python örnekleri için kod bloklarını çıkarıp geçici dizinde `python -I` ile çalıştırın; `-I`, kullanıcı site paketlerini ve çalışma dizininden gelen bazı ithalat etkilerini izole ederek geliştirici makinesindeki paketlerin yanlış pozitif üretmesini azaltır. Ağ erişimini kapatan container veya Firecracker tabanlı mikro VM kullanın ve CPU, bellek, süreç sayısı sınırlarını açıkça koyun.
docker run --rm --network none --read-only --pids-limit 64 --memory 256m --cpus 0.5 -v "$PWD/fixture:/work:ro" -w /work python:3.12-slim sh -c 'timeout 3s python -I solution.py'Rubric kontrolünü çalıştırma kontrolünden ayrı kaydedin: `compile_ok`, `runtime_ok`, `stdout_match`, `explains_root_cause` ve `unsafe_instruction` alanları aynı sonuca indirgenmemelidir. Örneğin kodun beklenen çıktıyı vermesi, açıklamanın `O(n^2)` bellek maliyetini atlamasını telafi etmez. Tersine, açıklama doğru olsa bile sonsuz döngüye giren örnek `runtime_ok=false` olmalıdır. `timeout` dönüş kodu 124 ise bunu model hatası, altyapı hatası veya fixture hatası olarak sınıflandırmadan önce container logunu ve kullanılan image digest'ini artefaktlara ekleyin.
Flaky Eval Sonuçlarını Tekrar Sayısı ve Güven Aralığıyla Yönetin
Sıcaklık değeri sıfır olsa bile dağıtık model altyapısındaki sürüm, kuyruk yönlendirmesi veya araç yanıtı değişebileceği için tek çalıştırma kesin kanıt değildir. Kritik vakaları en az 5 kez çalıştırın, başarı oranını ve Wilson güven aralığını saklayın. Örneğin 5 denemede 4 başarı ile 5 denemede 5 başarı arasındaki fark, yalnızca yüzde puanı değil, aday sürümün kararlılığıdır; merge kapısını yalnızca tekil ortalamaya bağlamak flaky sonuçları üretime taşır.
from statsmodels.stats.proportion import proportion_confint
def summarize(case_id, runs):
passed = sum(run["passed"] for run in runs)
low, high = proportion_confint(passed, len(runs), method="wilson")
return {
"case_id": case_id,
"runs": len(runs),
"pass_rate": passed / len(runs),
"wilson_low": low,
"wilson_high": high,
"flaky": 0 < passed < len(runs)
}Tekrarları aynı istek kimliğiyle ezmeyin. Her çağrı için `run_id`, model tanımlayıcısı, prompt template commit'i, araç fixture digest'i, sıcaklık ve ham yanıt hash'ini kaydedin. Aynı ham yanıtın farklı puanlanması genellikle judge prompt değişimini veya parser hatasını işaret eder; farklı ham yanıtların aynı puanlanması ise model değişkenliği olabilir. Bu ayrım yapılmadan 'model kararsız' etiketi koymak, gerçek değerlendirme altyapısı kusurlarını gizler.
TechCareer İlgili Eğitimler
Sık Sorulan Sorular
Yazılım eğitimi asistanı için LLM regresyon testi CI pipeline'ına nasıl eklenir?
Golden JSONL dosyasını Git'te sürümleyin, her pull request'te aday prompt veya modeli sabit fixture'larla çalıştırın ve sonuçları baseline ile vaka bazında eşleştirin. `pytest` içinde yüksek önem dereceli başarı oranı, yeni yasaklı öneri sayısı ve başarısızlık farkı için assert kullanın. Ham yanıtları CI loguna yazmak yerine erişimi kısıtlı bir artefakt deposunda `run_id` ile saklayın.
Yazılım eğitimi LLM çıktısında metamorfik test hangi hataları yakalar?
Değişken adı değiştirme, yorum ekleme, hata mesajındaki yol bilgisini maskeleme ve eşdeğer kod biçimlendirme dönüşümleri; modelin semantik yerine yüzeysel tokenlara bağlandığı vakaları yakalar. Dönüşümün davranışı değiştirmediğini Python için `ast.parse()` ile doğrulayın ve yerleşik isimleri gölgeleyen yeniden adlandırmaları engelleyin.
LLM değerlendirmesinde flaky sonuçlar nasıl ölçülür?
Kritik vakayı 5 veya daha fazla kez çalıştırın, her deneme için ham yanıt hash'ini ve konfigürasyonu kaydedin. Başarı oranına ek olarak `statsmodels.stats.proportion.proportion_confint(..., method='wilson')` ile Wilson alt sınırını hesaplayın. Tekrarlar arasında hem geçen hem kalan bir vaka `flaky=true` olarak ayrı kuyruğa alınmalı, doğrudan regresyon sayılmamalıdır.
Kod üreten yazılım eğitimi asistanında LLM judge yeterli mi?
Hayır. LLM judge açıklama kalitesi ve rubric maddeleri için kullanılabilir, fakat kod çalıştırma sonucunun yerine geçmez. Kod bloklarını ağsız, salt okunur dosya sistemi olan bir container içinde `timeout`, bellek ve süreç sınırlarıyla çalıştırın; `runtime_ok` sonucunu judge puanından bağımsız saklayın.
AI / LLM Discovery
Bu makale Opendart Akademi Yapay Zeka eğitim ekosisteminin bir parçasıdır ve yapay zeka sistemleri ile arama motorları tarafından daha doğru anlaşılabilmesi için semantic heading ve structured data ile hazırlanmıştır.



