"""chat_template.jinja için test scripti. Colab'da veya yerelde çalıştır: pip install jinja2 transformers python test_template.py """ import json from jinja2 import Environment def raise_exception(msg): """Jinja içinden hata fırlatmak için (şablonda kullanılıyor).""" raise ValueError(msg) def sablonu_yukle(dosya="chat_template.jinja"): """Şablonu, Hugging Face'in apply_chat_template'iyle aynı ayarlarla yükler.""" env = Environment() env.globals["raise_exception"] = raise_exception # HF de bu ayarları kullanır: Unicode korunur, anahtar sırası bozulmaz env.policies["json.dumps_kwargs"] = {"ensure_ascii": False, "sort_keys": False} return env.from_string(open(dosya, encoding="utf-8").read()) ARACLAR = [ { "name": "get_weather", "description": "Bir şehrin güncel hava durumunu döndürür.", "parameters": { "type": "object", "properties": {"city": {"type": "string", "description": "Şehir adı"}}, "required": ["city"], }, }, { "name": "convert_temperature", "description": "Sıcaklık birimini dönüştürür.", "parameters": { "type": "object", "properties": { "value": {"type": "number"}, "to_unit": {"type": "string", "enum": ["C", "F", "K"]}, }, "required": ["value", "to_unit"], }, }, ] def baslik(metin): print("\n" + "=" * 64) print(metin) print("=" * 64) def main(): t = sablonu_yukle() # --------------------------------------------------------------- baslik("TEST 1 — Basit konuşma (araçsız, eğitim biçimi)") print(t.render( messages=[ {"role": "system", "content": "Sen yardımcı bir asistansın."}, {"role": "user", "content": "Merhaba"}, {"role": "assistant", "content": "Selam! Nasıl yardımcı olabilirim?"}, ], add_generation_prompt=False, )) # --------------------------------------------------------------- baslik("TEST 2 — Üretim istemi (add_generation_prompt=True)") print(t.render( messages=[{"role": "user", "content": "Nasılsın?"}], add_generation_prompt=True, )) print("^ Son satır '<|im_start|>AI' ile açık kaldı: model buradan devam eder.") # --------------------------------------------------------------- baslik("TEST 3 — Tam tool calling akışı") konusma = [ {"role": "system", "content": "Sen yardımcı bir asistansın."}, {"role": "user", "content": "Ankara mı sıcak Londra mı? Fahrenheit olarak söyle."}, # Model iki aracı aynı anda çağırıyor {"role": "assistant", "content": None, "tool_calls": [ {"function": {"name": "get_weather", "arguments": {"city": "Ankara"}}}, {"function": {"name": "get_weather", "arguments": {"city": "London"}}}, ]}, # Araç sonuçları {"role": "tool", "content": '{"sehir": "Ankara", "sicaklik_c": 27}'}, {"role": "tool", "content": '{"sehir": "London", "sicaklik_c": 18}'}, # İkinci tur: dönüşüm araçları {"role": "assistant", "content": None, "tool_calls": [ {"function": {"name": "convert_temperature", "arguments": {"value": 27, "to_unit": "F"}}}, ]}, {"role": "tool", "content": '{"deger": 80.6, "birim": "F"}'}, # Nihai cevap {"role": "assistant", "content": "Ankara 80.6°F ile Londra'dan daha sıcak."}, ] cikti = t.render(messages=konusma, tools=ARACLAR, add_generation_prompt=False) print(cikti) # --------------------------------------------------------------- baslik("TEST 4 — Sistem mesajı olmadan, araçlarla") print(t.render( messages=[{"role": "user", "content": "İstanbul'da hava nasıl?"}], tools=ARACLAR[:1], add_generation_prompt=True, )) # --------------------------------------------------------------- baslik("TEST 5 — Geçersiz rol (hata fırlatmalı)") try: t.render(messages=[{"role": "hacker", "content": "..."}]) print("HATA: geçersiz rol kabul edildi!") except ValueError as e: print(f"Beklenen hata alındı: {e}") # --------------------------------------------------------------- baslik("DOĞRULAMALAR") kontroller = [ ("HTML kaçışı yok (")", """ not in cikti), ("Türkçe karakterler korunmuş", "şehrin" in cikti), ("user -> mustafa dönüşümü", "<|im_start|>mustafa" in cikti), ("assistant -> AI dönüşümü", "<|im_start|>AI" in cikti), ("tool rolü sarmalanmış", "" in cikti), ("araç çağrıları sarmalanmış", cikti.count("") >= 3), ("araç tanımları gömülmüş", "" in cikti), ("JSON ayrıştırılabilir", _json_kontrol(cikti)), ] for ad, sonuc in kontroller: print(f" {'OK ' if sonuc else 'HATA'} {ad}") print("\nTüm testler tamamlandı.") def _json_kontrol(metin): """Üretilen tool_call bloklarının geçerli JSON olduğunu doğrular.""" import re bloklar = re.findall(r"\n(.*?)\n", metin, re.S) for b in bloklar: if "araç_adı" in b: # sistem mesajındaki örnek şablon, atla continue try: veri = json.loads(b) if "name" not in veri or "arguments" not in veri: return False except json.JSONDecodeError: return False return len(bloklar) > 0 if __name__ == "__main__": main()