LawAgent-backend / src /evaluator.py
hllerdgn's picture
Deploy full project structure
b8e1a65
Raw
History Blame Contribute Delete
19.6 kB
import argparse
import json
import math
import os
import time
import logging
from datetime import datetime
from collections import defaultdict
from typing import Dict, List, Tuple, Any
# Kendi modüllerimizden import
from retriever import LegalRetriever, detect_kanun, extract_madde
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s [%(levelname)s] %(name)s — %(message)s",
datefmt="%H:%M:%S",
)
log = logging.getLogger("LawAgent.Evaluator")
# ═══════════════════════════════════════════════════════════════════════════════
# HİBRİT BENCHMARK SETİ (Mevzuat + İçtihat)
# Sorgu, Beklenen Kanun, Beklenen Madde Listesi, Beklenen Karar ID (Opsiyonel)
# ═══════════════════════════════════════════════════════════════════════════════
BENCHMARK = [
# ─────────────────────────────────────────────
# TBK — Türk Borçlar Kanunu (6098)
# ─────────────────────────────────────────────
# Sözleşmenin Kurulması & İrade Sakatlıkları
(
"Sözleşmenin esaslı noktalarında irade uyuşması olmadan sözleşme kurulmuş sayılır mı?",
"TBK",
["1", "2"],
None,
),
(
"Aldatma (hile) durumunda karşı tarafın sözleşmeyi iptal etme hakkının kullanım süresi nedir?",
"TBK",
["36", "39"],
None,
),
(
"Aşırı yararlanma (gabin) şartları nelerdir ve hâkimin sözleşmeyi değiştirme yetkisi var mıdır?",
"TBK",
["28"],
None,
),
# Haksız Fiil Sorumluluğu
(
"Haksız fiil sorumluluğunun dört temel unsuru nedir ve ispat yükü kime aittir?",
"TBK",
["49", "50"],
None,
),
(
"Haksız fiilden doğan tazminat davasında zamanaşımı süreleri nelerdir?",
"TBK",
["72"],
None,
),
(
"Tehlike sorumluluğunda zarar görenin tazminat talep edebilmesinin koşulları nelerdir?",
"TBK",
["71"],
None,
),
(
"Adam çalıştıranın sorumluluğunda kurtuluş beyyinesi nasıl işler?",
"TBK",
["66"],
None,
),
(
"Kişilik hakkı ihlalinde manevi tazminatın takdirinde hâkim hangi ölçütleri gözetir?",
"TBK",
["58"],
None,
),
# Borçların İfası & Temerrüt
(
"Muaccel bir borcun borçlusu hangi şartla temerrüde düşer ve ihtar gerekmediği haller nelerdir?",
"TBK",
["117"],
None,
),
(
"Temerrüde düşen borçlunun beklenmedik halden (mücbir sebepten) doğan sorumluluğu nedir?",
"TBK",
["119"],
None,
),
(
"Alacaklı temerrüdünün şartları ve borçlunun ifa etmeksizin serbest kalma hakkı nedir?",
"TBK",
["106", "107"],
None,
),
(
"Karşılıklı borç yükleyen sözleşmelerde süre verilmeksizin sözleşmeden dönülebilecek haller nelerdir?",
"TBK",
["124"],
None,
),
# Sözleşmenin Sona Ermesi & Zamanaşımı
(
"Borçlunun ikrarının zamanaşımını keseceği ve yeni sürenin nasıl başlayacağı hükmü nedir?",
"TBK",
["154"],
None,
),
(
"Zamanaşımının durmasına yol açan haller nelerdir?",
"TBK",
["153"],
None,
),
# Çeşitli Sözleşme Türleri
(
"Satım sözleşmesinde ayıbın gizlenmesi (hile ile saklama) durumunda satıcının sorumluluğu sınırlanabilir mi?",
"TBK",
["221"],
None,
),
(
"Kira sözleşmesinde kiraya verenin ayıba karşı tekeffül borcu ve kiracının seçimlik hakları nelerdir?",
"TBK",
["305", "306"],
None,
),
(
"Kiracının kira bedelini ödememesi hâlinde kiraya verenin yazılı bildirim yaparak tahliye isteme süreci nasıl işler?",
"TBK",
["315"],
None,
),
(
"Konut ve çatılı işyeri kiralarında kiracı aleyhine düzenleme yasağının kapsamı nedir?",
"TBK",
["346"],
None,
),
(
"Eser sözleşmesinde yaklaşık bedelin aşılması hâlinde iş sahibinin dönme hakkı ne zaman doğar?",
"TBK",
["482"],
None,
),
(
"Vekâletin sona ermesinde vekâlet verenin ölümü hâlinde vekilin yükümlülükleri nelerdir?",
"TBK",
["513"],
None,
),
(
"Kefalet sözleşmesinin geçerliliği için aranan yazılı şekil ve eşin rızasına ilişkin kurallar nelerdir?",
"TBK",
["583", "584"],
None,
),
# Borç İlişkilerinin Çeşitli Konuları
(
"Alacağın devri (temlik) sözleşmesinin geçerlilik şartları ve borçlunun bilgilendirilmesinin sonuçları nelerdir?",
"TBK",
["184", "186"],
None,
),
(
"Müteselsil borçlulukta borçlulardan birinin ödeme yapması diğer borçluların borcunu nasıl etkiler?",
"TBK",
["166", "167"],
None,
),
(
"Sebepsiz zenginleşen kişinin iyiniyetli olması hâlinde geri verme yükümlülüğünün kapsamı nasıl daralır?",
"TBK",
["79", "80"],
None,
),
(
"Borcun bizzat borçlu tarafından ifa edilmesinde alacaklının menfaatinin varlığı hangi ölçütle belirlenir?",
"TBK",
["83"],
None,
),
# ─────────────────────────────────────────────
# TKHK — Tüketicinin Korunması Hakkında Kanun (6502)
# ─────────────────────────────────────────────
# Ayıplı Mal & Hizmet
(
"Ayıplı malın tespitinde 'teslim tarihinden itibaren altı ay' içinde ortaya çıkan ayıplara ilişkin ispat karinesi nasıl işler?",
"TKHK",
["10"],
None,
),
(
"Ayıplı mal durumunda tüketicinin dört seçimlik hakkı nelerdir ve satıcı, üretici, ithalatçının müteselsil sorumluluğu nasıl düzenlenir?",
"TKHK",
["11"],
None,
),
(
"Ayıplı hizmet hâlinde tüketicinin seçimlik hakları ve sağlayıcının ücretsiz yeniden ifa yükümlülüğünün azami süresi nedir?",
"TKHK",
["15"],
None,
),
(
"Tüketici sözleşmelerinde haksız şartların kesin hükümsüzlüğü ve sözleşmenin geri kalanının geçerliliği nasıl korunur?",
"TKHK",
["5"],
None,
),
# Mesafeli & İşyeri Dışı Sözleşmeler
(
"Mesafeli sözleşmelerde tüketicinin 14 günlük cayma hakkına getirilen istisnalar nelerdir?",
"TKHK",
["48"],
None,
),
(
"İşyeri dışında kurulan sözleşmelerde satıcının tüketiciyi bilgilendirme yükümlülüğü ve cayma süresi nedir?",
"TKHK",
["47"],
None,
),
# Tüketici Kredisi & Finansman
(
"Tüketici kredisi sözleşmesinin geçerlilik şartları ve kredi verenin geçersizliği tüketici aleyhine ileri süremeyeceği kuralı nedir?",
"TKHK",
["23"],
None,
),
(
"Tüketici kredisinde belirsiz süreli sözleşmelerde faiz artışının tüketiciye bildirim yükümlülüğü ve tüketicinin sözleşmeden çıkma hakkı nasıl işler?",
"TKHK",
["26"],
None,
),
(
"Tüketici kredisinin erken kapatılması hâlinde tüketicinin faiz ve masraf indiriminden yararlanma hakkı nedir?",
"TKHK",
["27"],
None,
),
(
"Konut finansmanı sözleşmelerinde tüketicinin temerrüdü hâlinde kalan borcun tamamının muaccel kılınabilmesinin şartları nelerdir?",
"TKHK",
["33"],
None,
),
# Tüketici Hakem Heyeti & Uyuşmazlık Çözümü
(
"Tüketici hakem heyetine başvuru parasal sınırları nelerdir ve verilen kararların bağlayıcılık rejimi nasıl işler?",
"TKHK",
["68", "70"],
None,
),
(
"Tüketicinin konut alımından kaynaklanan uyuşmazlıklarda yetkili mahkeme hangisidir?",
"TKHK",
["73"],
None,
),
# Özel Sözleşme Türleri (TKHK)
(
"Devre tatil sözleşmelerinde tüketicinin cayma hakkı süresi ve sözleşmeden dönme bedeline ilişkin yasak nedir?",
"TKHK",
["50"],
None,
),
(
"Paket tur sözleşmesinde düzenleyicinin seyahat öncesi esaslı değişiklik yapması hâlinde tüketicinin hakları nelerdir?",
"TKHK",
["51"],
None,
),
(
"Abonelik sözleşmelerinin tüketici tarafından feshedilmesi hâlinde sağlayıcının depozito iade yükümlülüğü ve süresi nedir?",
"TKHK",
["52"],
None,
),
(
"Garanti belgesi düzenleme yükümlülüğüne aykırılık hâlinde tüketiciye tanınan ek haklar nelerdir?",
"TKHK",
["56"],
None,
),
(
"Sipariş edilmeyen mal veya hizmet gönderilmesi durumunda satıcı tüketiciden herhangi bir bedel talep edebilir mi?",
"TKHK",
["7"],
None,
),
# ─────────────────────────────────────────────
# TTK — Türk Ticaret Kanunu (6102)
# ─────────────────────────────────────────────
# Ticari İşletme & Tacir
(
"Tacir sıfatının kazanılması ve tacire özgü yükümlülükler (basiretli işletme, ticaret unvanı, tescil) nelerdir?",
"TTK",
["11", "18"],
None,
),
(
"Ticaret siciline tescil ve ilanın olumlu (müspet) ve olumsuz (menfi) aleniyet etkisi nedir?",
"TTK",
["36", "37"],
None,
),
(
"Ticari işlemlerde fatura ve teyit mektubuna itiraz edilmemesinin hukuki sonuçları nelerdir?",
"TTK",
["21"],
None,
),
# Haksız Rekabet
(
"Haksız rekabet sayılan dürüstlük kuralına aykırı davranışlara karşı açılabilecek hukuk davalarının türleri nelerdir?",
"TTK",
["56"],
None,
),
(
"Haksız rekabet nedeniyle açılacak hukuk davalarında zamanaşımı süresi ve başlangıç anı nedir?",
"TTK",
["60"],
None,
),
# Anonim Şirket
(
"Anonim şirket yönetim kurulunun devredilemez ve vazgeçilemez görev ve yetkileri nelerdir?",
"TTK",
["375"],
None,
),
(
"2024 TTK değişikliğiyle anonim şirket yönetim kurulunu toplantıya çağırma yetkisi kime tanınmıştır?",
"TTK",
["392"],
"18-1", # PwC bülteni referansı
),
(
"Anonim şirket genel kurul kararlarının butlanı ile iptalinin farkları nelerdir ve iptal davası açma süresi nedir?",
"TTK",
["445", "447"],
None,
),
(
"Anonim şirkette nama yazılı pay devrinin pay defterine kaydından şirketin hangi gerekçelerle kaçınabileceği durumlar nelerdir?",
"TTK",
["490", "493"],
None,
),
(
"Hamiline yazılı pay senetlerinin devri ve MKK'ya bildirim yükümlülüğü nasıl düzenlenmiştir?",
"TTK",
["489", "486"],
None,
),
(
"Anonim şirkette yönetim kurulu üyesinin azlinde gündeme bağlılık ilkesi ve istisnaları nelerdir?",
"TTK",
["413"],
None,
),
(
"Anonim şirket yönetim kurulu üyelerinin şirkete, pay sahiplerine ve alacaklılara karşı tazminat sorumluluğunun şartları nelerdir?",
"TTK",
["553"],
None,
),
# Limited Şirket
(
"Limited şirkette esas sermaye payının devri için gereken noter onaylı yazılı şekil şartı ve genel kurul onayı zorunluluğu nedir?",
"TTK",
["595"],
None,
),
(
"Limited şirkette müdürün devredilemez ve vazgeçilemez görev ve yetkileri nelerdir?",
"TTK",
["625"],
None,
),
(
"Limited şirkette ortaklar genel kurulunun devredilemez yetkileri nelerdir?",
"TTK",
["616"],
None,
),
(
"Limited şirkette ortağın haklı sebeple şirketten çıkma ve şirket tarafından çıkarılma halleri nasıl düzenlenmiştir?",
"TTK",
["638", "640"],
None,
),
# Kıymetli Evrak
(
"Poliçede kabul etmeme veya ödememe protestosunun çekilme süresi ve müracaat haklarına etkisi nedir?",
"TTK",
["713", "714"],
None,
),
(
"Çekin ibraz süreleri nelerdir ve ibraz edilmeksizin süresi geçen çekte hamilin keşideciye ve ciranta karşı haklarının durumu ne olur?",
"TTK",
["796", "808"],
None,
),
(
"Karşılıksız çeken hakkında hamilin talep edebileceği tazminat oranı ve cezai yaptırımlar nelerdir?",
"TTK",
["814"],
None,
),
(
"Bonoyu (emre yazılı senedi) poliçeden ayıran temel özellikler ve ciranta sorumluluğu nasıl düzenlenir?",
"TTK",
["776", "777"],
None,
),
# Ticari İşlemler
(
"Ticari işlerde gecikme faizinin belirlenmesinde tarafların serbestisi ve Merkez Bankası referans faizinin rolü nedir?",
"TTK",
["1530"],
None,
),
(
"Ticari defterlerin ispat aracı olarak kullanılmasının şartları ve aleyhine delil teşkil etmesi hâlleri nelerdir?",
"TTK",
["64", "222"],
None,
),
]
# ═══════════════════════════════════════════════════════════════════════════════
# METRİK FONKSİYONLARI (İçtihat Destekli)
# ═══════════════════════════════════════════════════════════════════════════════
def is_hit(
result: Dict, expected_maddeler: List[str], expected_decision: str = None
) -> bool:
"""
Bir sonucun 'doğru' kabul edilmesi için:
Ya beklenen maddelerden biri olmalı YA DA beklenen karar ID'si olmalı.
"""
res_art = str(result.get("article_no", ""))
res_dec = str(result.get("decision_id", ""))
if res_art in expected_maddeler:
return True
if expected_decision and res_dec == expected_decision:
return True
return False
def recall_at_k(
results: List[Dict], expected_m: List[str], expected_d: str, k: int
) -> float:
if not expected_m and not expected_d:
return 0.0
found_count = 0
seen_targets = set()
for r in results[:k]:
if is_hit(r, expected_m, expected_d):
# Aynı madde/kararın farklı chunklarını mükerrer saymamak için
target_key = r.get("article_no") or r.get("decision_id")
if target_key not in seen_targets:
found_count += 1
seen_targets.add(target_key)
total_expected = len(expected_m) + (1 if expected_d else 0)
return found_count / total_expected
def mrr_at_k(
results: List[Dict], expected_m: List[str], expected_d: str, k: int
) -> float:
for rank, r in enumerate(results[:k], 1):
if is_hit(r, expected_m, expected_d):
return 1.0 / rank
return 0.0
def ndcg_at_k(
results: List[Dict], expected_m: List[str], expected_d: str, k: int
) -> float:
dcg = sum(
1.0 / math.log2(i + 1)
for i, r in enumerate(results[:k], 1)
if is_hit(r, expected_m, expected_d)
)
total_targets = len(expected_m) + (1 if expected_d else 0)
idcg = sum(1.0 / math.log2(i + 1) for i in range(1, min(total_targets, k) + 1))
return dcg / idcg if idcg > 0 else 0.0
# ═══════════════════════════════════════════════════════════════════════════════
# DEĞERLENDİRME MOTORU
# ═══════════════════════════════════════════════════════════════════════════════
def run_evaluation(retriever: LegalRetriever, k: int = 10):
stats = {"recall": [], "mrr": [], "ndcg": [], "hit": [], "time": []}
detailed_results = []
print(f"\n🚀 {len(BENCHMARK)} benchmark sorgusu test ediliyor...")
for query, kanun, maddeler, karar_id in BENCHMARK:
t0 = time.time()
results = retriever.retrieve(query, k=k)
duration = (time.time() - t0) * 1000
rec = recall_at_k(results, maddeler, karar_id, k)
mrr = mrr_at_k(results, maddeler, karar_id, k)
ndcg = ndcg_at_k(results, maddeler, karar_id, k)
hit = 1 if mrr > 0 else 0
stats["recall"].append(rec)
stats["mrr"].append(mrr)
stats["ndcg"].append(ndcg)
stats["hit"].append(hit)
stats["time"].append(duration)
detailed_results.append(
{
"query": query,
"hit": hit,
"mrr": mrr,
"top_result": results[0]["text"][:100] if results else "Yok",
}
)
status = "✅" if hit else "❌"
print(f" {status} Sorgu: {query[:50]}... (MRR: {mrr:.2f})")
# Ortalama Hesaplama
avg_stats = {m: sum(v) / len(v) for m, v in stats.items()}
_print_report(avg_stats, k)
def _print_report(results: Dict, k: int):
print(f"\n{'='*60}")
print(f"📊 LAWAGENT RETRIEVAL PERFORMANS RAPORU (k={k})")
print(f"{'='*60}")
print(f" Recall@{k} : {results['recall']:.4f} (Hedef: ≥0.75)")
print(f" MRR@{k} : {results['mrr']:.4f} (Hedef: ≥0.60)")
print(f" nDCG@{k} : {results['ndcg']:.4f} (Hedef: ≥0.70)")
print(f" Hit Rate@{k} : {results['hit']:.4f}")
print(f" Ort. Süre : {results['time']:.1f} ms")
print(f"{'='*60}")
# TÜBİTAK Hedef Kontrolü
if results["recall"] >= 0.75 and results["mrr"] >= 0.60:
print("🎉 TEBRİKLER: Proje formu hedeflerine ulaşıldı!")
else:
print("⚠️ DİKKAT: Bazı metrikler hedef değerlerin altında.")
if __name__ == "__main__":
# Önce retriever'ı başlatalım (Cache varsa hızlı yüklenir)
r = LegalRetriever(quantize=False)
run_evaluation(r, k=10)