Download test_template.py from Mustafa2735/chat_template: direct link, hf CLI and curl.
- Browser
- Download file 5.73 kB
-
https://huggingface.co/Mustafa2735/chat_template/resolve/main/test_template.py
- Command line
-
hf download hf://Mustafa2735/chat_template/test_template.py
-
curl -L -o test_template.py https://huggingface.co/Mustafa2735/chat_template/resolve/main/test_template.py
5.73 kB
| """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ış", "<tool_response>" in cikti), | |
| ("araç çağrıları sarmalanmış", cikti.count("<tool_call>") >= 3), | |
| ("araç tanımları gömülmüş", "<tools>" 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"<tool_call>\n(.*?)\n</tool_call>", 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() | |