chat_template / test_template.py
Mustafa2735's picture
Upload 3 files
38436fc verified
Raw History Blame Contribute Delete
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 (&#34;)", "&#34;" 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()