Views
No views yet
system, user, assistant ve tool mesajlarını doğru ayırt edebilmesi
ve tool-calling parametrelerini beklenen biçimde üretebilmesi için yazılmış özel bir Jinja2
sohbet şablonu.| Dosya | Açıklama |
|---|---|
chat_template.jinja | Şablonun kendisi |
test_render.py | Şablonu 4 farklı sohbet üzerinde render eder (model gerekmez) |
test_ollama.py | Şablonun ürettiği metni gerçek modele gönderip davranışı ölçer |
1messages # OpenAI biçiminde mesaj listesi (system / user / assistant / tool)
2tools # OpenAI biçiminde araç şeması listesi (opsiyonel)
3add_generation_prompt # True ise sonda boş model turu açılır
4bos_token # opsiyonel
5varsayilan_talimat # system mesajı yokken kullanılacak talimat<bos><|turn>system
Sen bir biyoloji çalışma koçusun. Yanıtlarını YALNIZCA araçlardan dönen veriye dayandır.
<|tool>declaration:terim_ara{description:<|"|>...<|"|>,parameters:{properties:{terim:{
description:<|"|>Aranacak biyoloji terimi<|"|>,type:<|"|>STRING<|"|>}},
required:[<|"|>terim<|"|>],type:<|"|>OBJECT<|"|>}}<tool|><turn|>
<|turn>user
Mayoz nedir?<turn|>
<|turn>model
<|tool_call>call:terim_ara{terim:<|"|>mayoz<|"|>}<tool_call|>
<|tool_response>response:terim_ara{bulundu:true,kitap_sayfasi:87,tanim:<|"|>...<|"|>}<tool_response|>
Mayoz, ... (Kaynak: ders kitabı s.87)<turn|>
<|turn>model<|msg|> gibi) tokenizer'da tanımsız olduğu için <, |, msg,
|, > şeklinde parçalanır ve model bunu sıradan metin sanar. Sonuç hata değil, sessiz kalite
kaybıdır: model rolleri karıştırır, tool çağrısı üretmez. Bu yüzden alfabe modelden alındı,
şablonun yapısı ve mantığı bu projede kuruldu.user/assistant/user/assistant sırası zorlanır ve bozulursa
raise_exception fırlatılır. Tool calling bu kuralı kırar, çünkü gerçek akış
user → assistant(tool çağırır) → tool(sonuç) → assistant(cevaplar) şeklindedir. Bu şablonda
böyle bir kontrol bilinçli olarak yoktur.assistant rolü metinde model adıyla yazılır.tool sonuçları kendi turunu açmaz; açık model turunun içine girer. Böylece
model → tool → model zinciri tek bir tur içinde kalır.<|think|>, <|channel>), multimodal içerik (görüntü/ses/video), legacy Google + OpenAI çift
tool formatı ve derin şema özyinelemesi taşır. Bu şablon yalnızca metin + tool-calling akışına
odaklanır. Kullanılmayan özelliği taşımamak hata yüzeyini küçültür.<|"|> escape token'ı. Gemma argümanları JSON yerine kendi kompakt biçiminde yazar ve
string sınırlarını <|"|> özel token'ıyla işaretler. Bu token kullanıcı metninden üretilemediği
için kaçış (escape) sorunu tokenizer seviyesinde çözülür — JSON'daki " karakterinin aksine
kırılgan değildir.1pip install jinja2
2python test_render.pyStrictUndefined ile çalışır; şablondaki
opsiyonel alan erişimleri bu sayede sessizce boş geçmek yerine hata verir.1ollama pull gemma4
2python test_ollama.pyraw=True ile gönderilir. Bu, Ollama'nın kendi şablonunu devre
dışı bırakır; modele giden her karakteri bu şablon belirler.| Test | Beklenen | Sonuç |
|---|---|---|
| A | Modelin aracı çağırması | <|tool_call>call:terim_ara{terim:<|"|>Mayoz<|"|>}<tool_call|> |
| B | Araç sonucundan cevap üretmesi | Tanımı verdi, "Kaynak: Sayfa 87" atfıyla |
| C | Araç boş dönünce uydurmaması | "…kullandığım biyoloji sözlüğünde bulunmamaktadır." |
bulundu:false gelince tanım uydurmayı reddetti.1from jinja2 import Environment
2from pathlib import Path
3
4sablon = Environment().from_string(Path("chat_template.jinja").read_text())
5prompt = sablon.render(
6 messages=[{"role": "user", "content": "Mayoz nedir?"}],
7 tools=TOOLS,
8 add_generation_prompt=True,
9 bos_token="<bos>",
10)prompt doğrudan Ollama'ya raw=True ile veya bir tokenizer'a verilebilir.terim_ara, quiz_getir) o projeden gelir. Şablonun kendisi
senaryodan bağımsızdır ve herhangi bir OpenAI biçimli araç şemasıyla çalışır.