File size: 5,213 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 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 | # Özel Chat Template (Jinja2)
Bir dil modelinin `system`, `user`, `assistant` ve `tool` rollerini ayırt
edebilmesi ve tool calling (function calling) yapabilmesi için hazırlanmış
Jinja2 sohbet şablonu.
## Chat template nedir?
Dil modelleri mesaj listesi göremez; yalnızca düz metin (token dizisi) işler.
Kod tarafında şöyle bir yapı kullanılır:
```python
[
{"role": "user", "content": "Merhaba"},
{"role": "assistant", "content": "Selam!"}
]
```
Chat template bu yapıyı modelin anlayacağı düz metne çevirir:
```
<|im_start|>mustafa
Merhaba<|im_end|>
<|im_start|>AI
Selam!<|im_end|>
```
Her model eğitim sırasında belirli bir biçim görür; çıkarımda da aynı biçimi
bekler. Biçim uyuşmazsa model beklenmedik davranır.
## Bu şablonun özellikleri
| Özellik | Açıklama |
|---|---|
| Rol dönüşümü | `user` → `mustafa`, `assistant` → `AI` |
| Araç tanımları | `tools` listesi sistem bloğuna JSON olarak gömülür |
| Araç çağrısı | Assistant mesajındaki `tool_calls` alanı `<tool_call>` etiketleriyle sarmalanır |
| Çoklu çağrı | Model aynı turda birden fazla araç çağırabilir |
| Araç sonucu | `tool` rolü `<tool_response>` etiketleriyle sarmalanır |
| Üretim istemi | `add_generation_prompt` ile son satır açık bırakılır |
| Doğrulama | Bilinmeyen rol gelirse hata fırlatılır |
## Rol eşlemesi
Şablon, standart rol adlarını kendi adlarına çevirir:
| Standart (kodda kullanılan) | Şablonda üretilen |
|---|---|
| `system` | `system` |
| `user` | **`mustafa`** |
| `assistant` | **`AI`** |
| `tool` | `tool` |
Bu sayede kod tarafında OpenAI/Hugging Face standardı korunur; dönüşümü şablon
yapar. Model değiştirildiğinde uygulama kodunu değiştirmek gerekmez.
## Örnek çıktı
**Girdi:**
```python
messages = [
{"role": "system", "content": "Sen yardımcı bir asistansın."},
{"role": "user", "content": "Ankara'da hava nasıl?"},
{"role": "assistant", "content": None, "tool_calls": [
{"function": {"name": "get_weather", "arguments": {"city": "Ankara"}}}
]},
{"role": "tool", "content": '{"sehir": "Ankara", "sicaklik_c": 27}'},
{"role": "assistant", "content": "Ankara'da hava 27°C."},
]
```
**Çıktı:**
```
<|im_start|>system
Sen yardımcı bir asistansın.
Kullanabileceğin araçlar:
<tools>
{"name": "get_weather", "description": "Bir şehrin güncel hava durumunu döndürür.", "parameters": {...}}
</tools>
Bir aracı çağırmak için şu biçimi kullan:
<tool_call>
{"name": "araç_adı", "arguments": {...}}
</tool_call><|im_end|>
<|im_start|>mustafa
Ankara'da hava nasıl?<|im_end|>
<|im_start|>AI
<tool_call>
{"name": "get_weather", "arguments": {"city": "Ankara"}}
</tool_call><|im_end|>
<|im_start|>tool
<tool_response>
{"sehir": "Ankara", "sicaklik_c": 27}
</tool_response><|im_end|>
<|im_start|>AI
Ankara'da hava 27°C.<|im_end|>
```
## Kullanım
### Hugging Face tokenizer ile
```python
from transformers import AutoTokenizer
tokenizer = AutoTokenizer.from_pretrained("model-adi")
tokenizer.chat_template = open("chat_template.jinja", encoding="utf-8").read()
metin = tokenizer.apply_chat_template(
messages,
tools=tools,
add_generation_prompt=True, # çıkarımda True, eğitimde False
tokenize=False,
)
```
Şablonu modelle birlikte yayınlamak için `chat_template.jinja` dosyasını model
deposuna eklemek yeterlidir.
### Doğrudan Jinja2 ile
```python
from jinja2 import Environment
env = Environment()
env.globals["raise_exception"] = lambda m: (_ for _ in ()).throw(ValueError(m))
env.policies["json.dumps_kwargs"] = {"ensure_ascii": False, "sort_keys": False}
sablon = env.from_string(open("chat_template.jinja", encoding="utf-8").read())
print(sablon.render(messages=messages, tools=tools, add_generation_prompt=True))
```
`ensure_ascii=False` ayarı önemlidir: Türkçe karakterlerin `\u015f` gibi kaçış
dizilerine dönüşmesini engeller ve gereksiz token harcanmasını önler.
## `add_generation_prompt` nedir?
Aynı şablon iki farklı amaçla kullanılır:
**Eğitimde (`False`)** — konuşma tamamlanmıştır, model bunu öğrenecektir:
```
<|im_start|>mustafa
Nasılsın?<|im_end|>
<|im_start|>AI
İyiyim!<|im_end|>
```
**Çıkarımda (`True`)** — son satır açık bırakılır, model buradan devam eder:
```
<|im_start|>mustafa
Nasılsın?<|im_end|>
<|im_start|>AI
```
Bu açık satır olmazsa model ne yapacağını bilemez; kendi kullanıcı mesajı
uydurabilir veya konuşmayı sonlandırabilir.
## Test
```bash
pip install jinja2
python test_template.py
```
Test scripti beş senaryoyu kontrol eder:
1. Basit konuşma (araçsız)
2. Üretim istemi davranışı
3. Tam tool calling akışı (çok turlu, çoklu çağrı)
4. Sistem mesajı olmadan araç kullanımı
5. Geçersiz rol reddi
Ayrıca sekiz doğrulama yapar: HTML kaçışı olmaması, Türkçe karakterlerin
korunması, rol dönüşümleri, etiket sarmalama ve üretilen JSON'ların
ayrıştırılabilir olması.
## Dosyalar
| Dosya | İçerik |
|---|---|
| `chat_template.jinja` | Şablonun kendisi |
| `test_template.py` | Test ve doğrulama scripti |
| `README.md` | Bu dosya |
## Lisans
MIT
|