File size: 5,727 Bytes
38436fc | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | """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()
|