※ この文書は自分自身の知識を整理するため、ChatGPT/Gemini を用いて調査・整形したメモです。
Gemma 4 チャットテンプレート仕様まとめ
本ドキュメントは、google/gemma-4-31B-it モデルのチャットテンプレート仕様まとめです。公開されている chat_template.jinja や tokenizer_config.json を中心に、Gemma 4 の Model Card、Google AI for Developers の Function Calling ガイド、そして Hugging Face Transformers の Gemma4Processor 実装を突き合わせて整理したものです。
0. ドキュメントの目的と前提構造
Gemma 4 のプロンプト処理を正確に理解するためには、入出力が以下の 3 つの層で構成されていることを意識する必要があります。
- メッセージ API 層:
messages=[{"role": ..., "content": ...}] や tools=[...]、enable_thinking=True/False といった、Python コード上で指定するデータ構造の層です。
- チャットテンプレート層:
processor.apply_chat_template(..., tokenize=False) によって変換された生のテキストプロトコルの層です。ここでは <|turn> や <|tool_call> のような制御トークンが文字列として可視化されます。
- プロセッサ展開層:
Gemma4Processor が、画像・音声・動画などの高レベルなプレースホルダーを、Tokenizer に渡すための長い特殊トークン列へと内部的に展開する層です。
これらの層を混同しないことが、実装上のトラブルを防ぐ鍵となります。特に、<|image|>、<|audio|>、<|video|> といったトークンは、あくまでテンプレート層における高レベルなプレースホルダーであり、Tokenizer に渡される最終的な文字列では、さらに細かいトークン列へと展開される点に注意が必要です。
1. Gemma 4 プロンプトプロトコル アーキテクチャ概要
Gemma 4 の公式テンプレートは、API から受け取った会話履歴を以下のような独自のマークアップ形式へと変換します。
<bos>
<|turn>system
[任意: <|think|>][任意: system/developer 内容][任意: <|tool>...<tool|> ...]
<turn|>
<|turn>user
...
<turn|>
<|turn>model
[過去 assistant content / tool_calls / tool_responses]
<turn|>
...
<|turn>model
[生成開始位置]
このプロトコルには、実装上押さえておくべき重要な特性がいくつかあります。
- Role の変換: 入力時の
assistant ロールは、テンプレートを経由すると自動的に model に変換されます。つまり、API 層では assistant として定義したものが、生テキスト層では <|turn>model として出力されます。
- Reasoning のトリガー: モデルの推論プロセスを有効化するスイッチは
<|think|> トークンです。これは最初の System Turn の冒頭に挿入されます。
- Tool の定義と呼び出し: Tool の定義は、System Turn 内に
<|tool>declaration:...<tool|> の形で列挙されます。一方、実際の Tool Call と Response は、Assistant の Turn 内に <|tool_call>...<tool_call|> および <|tool_response>...<tool_response|> として配置されます。
- 履歴における思考プロセスの除外: 過去の Assistant の出力を履歴として再入力する際、Thinking Channel の内容は自動的に除去されます。マルチターンの会話履歴に、過去の思考プロセス自体は残さない仕様です。
- 非 JSON 形式の採用:
apply_chat_template(..., tokenize=False) が出力する形式は JSON ではありません。疑似 JSON 風の構造をしていますが、キーはクォーテーションで囲まれず、文字列値は <|"|> で囲まれます。また、型名も STRING や OBJECT のように大文字で表記される独自仕様です。
2. 特殊トークン仕様
Gemma 4 で利用される特殊トークンは、用途によって大きく 2 つに分けられます。ここでは、それぞれの役割と主に出現する処理層について整理します。
2.1 会話・推論・ツール呼び出し用トークン
会話の制御や思考プロセス、ツール呼び出しに関わる主なトークンは以下の通りです。これらは主に tokenizer_config.json の設定に基づいています。
| tokenizer_config キー | 文字列表現 | 用途 | 主に出現する層 |
bos_token | <bos> | 文頭トークンです。テンプレートの先頭に必ず挿入されます。 | テンプレート |
eos_token | <eos> | 文末トークンです。テンプレート自体は自動挿入しません。 | Tokenizer 一般 |
sot_token | <|turn> | 発話の開始を示します。 | テンプレート |
eot_token | <turn|> | 発話の終了を示します。 | テンプレート |
soc_token | <|channel> | チャンネルの開始を示します。Thinking ブロックの先頭などに使われます。 | モデル出力 / 履歴整形 |
eoc_token | <channel|> | チャンネルの終了を示します。 | モデル出力 / 履歴整形 |
think_token | <|think|> | Thinking モードを有効化するための制御トークンです。 | テンプレート |
std_token | <|tool> | ツールの宣言を開始します。 | テンプレート |
etd_token | <tool|> | ツールの宣言を終了します。 | テンプレート |
stc_token | <|tool_call> | ツールの呼び出しを開始します。 | モデル出力 / 履歴 |
etc_token | <tool_call|> | ツールの呼び出しを終了します。 | モデル出力 / 履歴 |
str_token | <|tool_response> | ツールの実行結果を開始します。 | 履歴 |
etr_token | <tool_response|> | ツールの実行結果を終了します。 | 履歴 |
escape_token | <|"|> | ツールスキーマや引数、レスポンス内の文字列リテラルの区切りとして使用されます。 | ツール関連処理全般 |
pad_token | <pad> | パディング用トークンです。 | Tokenizer 一般 |
mask_token | <mask> | マスク用トークンです。 | Tokenizer 一般 |
unk_token | <unk> | 未知の語彙を示します。 | Tokenizer 一般 |
2.2 マルチモーダル入力用トークン
画像や音声、動画などのマルチモーダルデータを処理するためのトークンです。
| tokenizer_config キー | 文字列表現 | 用途 | 主に出現する層 |
image_token | <|image|> | 画像のプレースホルダーです。 | テンプレート |
boi_token | <|image> | 画像・動画の Soft Token 列の開始を示す境界です。 | プロセッサ展開 |
eoi_token | <image|> | 画像・動画の Soft Token 列の終了を示す境界です。 | プロセッサ展開 |
audio_token | <|audio|> | 音声のプレースホルダーです。 | テンプレート |
boa_token | <|audio> | 音声の Soft Token 列の開始を示す境界です。 | プロセッサ展開 |
eoa_token | <audio|> | 音声の Soft Token 列の終了を示す境界です。 | プロセッサ展開 |
extra_special_tokens[0] | <|video|> | 動画のプレースホルダーです。 | テンプレート |
マルチモーダル対応における注意点として、31B の Dense モデルは音声エンコーダに非対応であり、音声のネイティブサポートは E2B/E4B モデルに限られます。一方で、Tokenizer やテンプレート自体には音声用のトークンや分岐が用意されています。テンプレートはモデルファミリー間で共通化されており、実際の対応能力は個別のモデルに依存すると認識しておくのが安全です。
また、現在の Transformers 実装では、<|video|> を追加の特殊トークンとして再登録している点にも留意してください。
3. チャットテンプレートのシリアライズ規則
ここでは、メッセージがどのようなルールで生のテキストプロトコルに変換されるかを解説します。
3.1 System ブロックの生成条件
テンプレートは、以下のいずれかの条件を満たした場合に、自動的に System の Turn を先頭に出力します。
enable_thinking=True が設定されている場合。
tools が定義されている場合。
- 最初のメッセージの Role が
system または developer の場合。
つまり、明示的に System メッセージを与えていなくても、Thinking モードやツールを利用すると、自動的に System ブロックが生成されます。
3.2 Role のマッピング規則
メッセージのループ処理において、Role の名称は次のように変換されます。特に assistant が model に変わる点に注意してください。
assistant は model に変換されます。
user は user のまま維持されます。
system は system のまま維持されます。
developer は、先頭メッセージの場合は System ブロックに吸収され、それ以外は developer のまま出力される実装です。
実運用上は、予期せぬ動作を防ぐため、先頭以外で developer ロールを使用しないことが推奨されます。
3.3 Turn の基本構造
各メッセージは、原則として以下のフォーマットで出力されます。
<|turn>{role}
{シリアライズされた本文}<turn|>
ただし例外として、assistant の Turn が tool_responses を保持しており、かつ content が空の場合に限り、末尾の <turn|> の出力が抑制されます。これは、ツール実行結果の直後から、同じ Turn の続きとしてモデルに最終回答を生成させるための仕様です。
3.4 System 本文と Tool 宣言の隣接規則
最初の System 本文の直後にツールの定義を出力する場合、テンプレートは意図的な改行や空白を挿入しません。そのため、出力結果は以下のような密着したテキストになります。
<|turn>system
You are a helpful assistant.<|tool>declaration:get_current_weather{...}<tool|><turn|>
一見すると見づらく感じるかもしれませんが、これは想定通りの挙動です。
3.5 Content のデータ型による処理の差異
Content に渡すデータ型によって、テンプレートの処理が変わります。
user、system、developer の文字列は trim 処理されてそのまま出力されます。
assistant の文字列は、strip_thinking() を通して処理された後に出力されます。これにより、履歴に生の出力をそのまま戻したとしても、Thinking ブロックは自動的に削除される設計になっています。
テンプレートが直接処理できる要素の Type は以下の 4 つのみです。
これ以外のタイプは、明示的には処理されません。また、複数の要素は順番通りに単純結合されます。特に text 要素は個別に trim 処理がかかるため、複数のテキスト要素に分割して渡すと、境界部分の空白が意図せず消えてしまうことがあります。単語間のスペースや改行を維持したいテキストは、1 つの text 要素にまとめて渡す方が安全です。
4. Reasoning プロセスのフォーマット仕様
4.1 Thinking モードの有効化条件とプロンプト構造
テンプレート上で Thinking モードを有効にする条件はシンプルで、最初の System Turn の冒頭に <|think|> トークンを挿入するだけです。
Thinking モードが有効な場合、プロンプトの末尾に空の思考ブロックは事前に追加されません。プロンプトの末尾は以下のような状態になり、<|think|> を認識したモデルが自ら思考プロセスを生成し始めることを想定しています。
<bos><|turn>system
<|think|>You are a helpful assistant.<turn|>
<|turn>user
What is 2 + 2?<turn|>
<|turn>model
実際のモデル出力では、思考プロセスは <|channel>thought と <channel|> に囲まれた形で生成され、その後に最終的な回答が続きます。
4.2 Thinking モード無効時のプロンプト構造
Thinking モードを無効にした場合、テンプレートは生成プロンプトの末尾に空の Thought Channel をあらかじめ挿入します。
<|turn>model
<|channel>thought
<channel|>
モデルはこの空ブロックに続く形で、最終的な回答だけを直接生成する動きになります。
4.3 複数ターンにおける Thinking 履歴の破棄規則
複数ターンの会話を行う際、過去の Assistant の発言を履歴として再投入しますが、このときに思考プロセスは履歴に残さない仕様になっています。
テンプレート内部の strip_thinking(text) という処理によって、履歴文字列の中から <|channel> ... <channel|> で囲まれた部分は自動的に削除され、最終的な回答部分のみが次の推論へ引き継がれます。
4.4 公式ドキュメントと実際の実装における差異
公開されている Jinja テンプレートでは、Thinking 無効時に空の Thought ブロックが追加される仕様ですが、Google の公式ドキュメントに掲載されている一部の出力例では、この部分が省略されて記載されていることがあります。
デバッグや開発を行う際は、ドキュメントの表示例よりも、実際の apply_chat_template() が出力する生テキストを正として確認するのが安全です。
5. Tool のシリアライズ仕様
5.1 Tool 宣言の配置
利用可能な Tool の情報は、tools=[...] として渡されると、最初の System Turn の中に列挙されます。具体的には以下のフォーマットで記述されます。
<|tool>declaration:{function_name}{...}<tool|>
5.2 Tool スキーマの独自 DSL 仕様
Tool のスキーマは、一般的な JSON 形式ではなく、Gemma 独自の DSL に変換されてシリアライズされます。主な特徴は以下の通りです。
- キー名はクォーテーションなしのベア表記。
- 文字列の値は
<|"|> で囲む。
- 真偽値は小文字の
true / false。
- 型名は
STRING、OBJECT、ARRAY のようにすべて大文字。
- 配列は
[ ... ]、オブジェクトは { ... } で表現。
この文字列を手作業で組み立てるのはミスの原因になりやすいため、基本的には apply_chat_template() の処理に任せるのが安全です。
5.3 スキーマパラメータのプロンプト変換規則
JSON Schema のすべてのキーワードがそのままプロンプトに埋め込まれるわけではありません。テンプレート側で処理され反映される主な情報は以下の項目です。
- 関数の
name と description
- パラメータの
type、properties、required
- 各プロパティの
description、type、nullable
- String 型のプロパティにおける
enum
- 配列アイテムの構造や、任意の
response 宣言
また、実装上の大きな特徴として、プロパティや引数の辞書は元の挿入順ではなく、すべて辞書順にソートされて出力されます。
5.4 Tool 実行要求のフォーマット
モデルが関数を呼び出す際は、以下のフォーマットで出力されます。
<|tool_call>call:{function_name}{arg1:value1,arg2:value2,...}<tool_call|>
引数の値も独自のルールでフォーマットされており、文字列は <|"|>text<|"|>、数値はそのまま、真偽値は true / false として表現されます。
5.5 Tool 実行結果のフォーマット
関数の実行結果をモデルに返すときは、Assistant のメッセージ内に tool_responses として含めます。独立した Tool ロールを使うのではなく、Assistant の Turn 内にぶら下げる形式をとります。
- オブジェクトのレスポンス:
{temperature:15,weather:<|"|>sunny<|"|>} のような形で出力されます。
- スカラー値のレスポンス: マッピング形式ではない場合、テンプレートが自動的に
{value:<|"|>結果<|"|>} のように value: というキーで包んでフォーマットします。
5.6 同一 Turn 内における Call と Response の共存
公開されているテンプレートでは、Assistant の Turn 内における要素の並び順が厳密に固定されています。
tool_calls
tool_responses
content
この順番通りに処理されるため、Tool の呼び出しと結果、そして最終的な回答は同じ Turn の中にすべて共存する形になります。
5.7 Tool 実行結果に基づく最終回答の生成
アプリケーション側で関数を実行した直後、まだ content を持たない Assistant の Turn を履歴に追加して再推論を行うのが一般的な流れです。
このときテンプレートは、意図的に Turn を終了させるトークン <turn|> を出力せず、Tool Response が記述された直後の位置からモデルに続きの最終回答を生成させます。これが Gemma 4 の Function Calling における核となる動作です。
5.8 複数 Tool の同時呼び出しと応答
複数の Tool を同時に呼び出したり、複数の結果を返す場合、単純にそれぞれのタグがループで順番に並べられます。
<|tool_call>call:f1{...}<tool_call|><|tool_call>call:f2{...}<tool_call|>
複数並んだ状態でも、Tokenizer 側の正規表現イテレーターで個別に分割・パースできるよう設計されています。
5.9 スキーマの自動生成と手動定義の使い分け
Google の公式ガイドでは、Python の関数からスキーマを自動生成する方法と、手動で定義した辞書を渡す方法の 2 種類が案内されています。
しかし、カスタムオブジェクトを引数に取るなど複雑な関数の場合、自動変換の過程で内部のプロパティ情報が欠落するリスクがあります。そのため、複雑なスキーマを扱う場合は、手動でのスキーマ定義が推奨されます。
6. レスポンスのパース処理と Schema 仕様
Gemma 4 の応答をパースするための response_schema は、tokenizer_config.json に組み込まれています。
このスキーマの構造を読み解くと、アシスタントの出力は主に以下の 4 つの要素に分解される設計になっていることがわかります。
role: 常に assistant
thinking: 任意の文字列としての思考プロセス
content: 任意の文字列としての回答テキスト
tool_calls: 任意の配列としてのツール呼び出しリスト
ここで重要なのは、tool_responses がパース対象に含まれていない点です。これは、ツール実行結果がモデル自身がパース対象として出力するものではなく、アプリケーション側が履歴としてモデルに渡し直す情報であるためと考えれば自然です。
6.1 Top-level Regex の意味合い
response_schema.x-regex で定義されている正規表現は、大まかに以下の順序で構成されています。
- 任意の thought ブロック
- 任意の content
- 任意の tool_calls ブロック
- 任意の末尾
<turn|>
したがって、processor.parse_response() を使用することで、生の出力文字列から <|channel>thought ... <channel|> の部分や平文の回答テキスト、そして <|tool_call> ... <tool_call|> の各ブロックを抽出できます。
6.2 デバッグ時の基本方針
開発やデバッグを進める際は、目的によって以下のようにアプローチを使い分けるのが有効です。
- 生のプロトコルを確認したい場合:
skip_special_tokens=False を指定してデコードします。これにより、内部的な特殊トークンの配置を直接確認できます。
- 思考プロセス、回答、ツール呼び出しを構造化して扱いたい場合:
processor.parse_response() を活用します。
7. マルチモーダル入力の処理仕様
7.1 テンプレート層におけるプレースホルダーの単一化
入力されたシーケンスの中に画像・音声・動画が含まれている場合、Jinja テンプレートはそれぞれのメディアに対して以下のプレースホルダーを挿入します。
- 画像:
\n\n<|image|>\n\n
- 音声:
<|audio|>
- 動画:
\n\n<|video|>\n\n
チャットテンプレートの処理時点では、画像 1 枚につき <|image|> は 1 つ、音声 1 本につき <|audio|> 1 つ、動画 1 本につき <|video|> 1 つだけが出力される仕様です。
7.2 Tokenizer 処理前の Soft Token 展開仕様
これらの高レベルなプレースホルダーは、そのままではモデルに渡りません。Tokenizer に渡される直前に、Gemma4Processor が内部用の長いプレースホルダー列へと展開します。
- 画像: 各
<|image|> は、画像ごとの Soft Token 数に応じて、前後の境界トークンに挟まれた複数の <|image|> に置換されます。
- 音声: 各
<|audio|> も同様に、音声の長さに応じて計算された Token 数分の <|audio|> に展開され、境界トークンで挟まれます。現在の Gemma4Processor では音声波形の長さから動的に計算され、基本的には 40ms あたり 1 トークン、上限 750 トークンとして扱われます。
- 動画: 動画はフレームごとのタイムスタンプが付与された形式に展開されます。特徴的なのは、動画であっても境界トークンには画像と同じ
<|image> / <image|> が再利用される点です。各フレームのトークン列の前に mm:ss 形式のタイムスタンプが挿入される形になります。
7.3 マルチモーダル要素の配置順序に関する推奨事項
Gemma 4 のモデルカードでは、画像や音声といったマルチモーダルコンテンツは、テキストよりも前に配置することが推奨されています。
テンプレートの仕様上、入力した要素は配列の順序通りにそのまま連結されます。そのため、実際の運用では以下のようにメディア要素を先に配置し、最後にテキストを置く構成にするのが自然です。
[
{"type": "image", "url": "..."},
{"type": "audio", "url": "..."},
{"type": "text", "text": "What is shown in this image?"}
]
8. ユースケース別 プロンプト生成実例
ここでは、代表的なユースケースにおける入力と、テンプレートによって生成されるプロンプトの出力例を示します。
8.1 最小構成の Single-turn
messages = [
{"role": "user", "content": "Write a haiku about memory."}
]
<bos><|turn>user
Write a haiku about memory.<turn|>
<|turn>model
<|channel>thought
<channel|>
モデルはここから、続けて最終的な回答を生成します。
8.2 System 適用および Thinking 有効時の Single-turn
messages = [
{"role": "system", "content": "You are a concise assistant."},
{"role": "user", "content": "What is 2 + 2?"},
]
<bos><|turn>system
<|think|>You are a concise assistant.<turn|>
<|turn>user
What is 2 + 2?<turn|>
<|turn>model
この場合、モデルが返す生の出力は次のような形式になることが想定されます。
<|channel>thought
2+2 を短く計算する。<channel|>4<turn|>
8.3 Tool 宣言と Call
tools = [WEATHER_TOOL]
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Hey, what's the weather in Tokyo right now?"},
]
<bos><|turn>system
You are a helpful assistant.<|tool>declaration:get_current_weather{description:<|"|>Gets the current weather in a given location.<|"|>,parameters:{properties:{location:{description:<|"|>The city and state, e.g. "San Francisco, CA" or "Tokyo, JP"<|"|>,type:<|"|>STRING<|"|>},unit:{description:<|"|>The unit to return the temperature in.<|"|>,enum:[<|"|>celsius<|"|>,<|"|>fahrenheit<|"|>],type:<|"|>STRING<|"|>} },required:[<|"|>location<|"|>],type:<|"|>OBJECT<|"|>} }<tool|><turn|>
<|turn>user
Hey, what's the weather in Tokyo right now?<turn|>
<|turn>model
<|tool_call>call:get_current_weather{location:<|"|>Tokyo, JP<|"|>}<tool_call|>
出力された Tool Call は、アプリケーション側でパースし、内容を検証した上で実行します。
8.4 Tool Response の適用と最終回答の生成
Tool 実行後、以下のような結果を履歴に追加します。
{
"role": "assistant",
"tool_calls": [
{"function": {"name": "get_current_weather", "arguments": {"location": "Tokyo, JP"}}}
],
"tool_responses": [
{"name": "get_current_weather", "response": {"temperature": 15, "weather": "sunny"}}
]
}
テンプレートが構成する同一ターン内の断面は以下のようになります。
<|turn>model
<|tool_call>call:get_current_weather{location:<|"|>Tokyo, JP<|"|>}<tool_call|><|tool_response>response:get_current_weather{temperature:15,weather:<|"|>sunny<|"|>}<tool_response|>
モデルはここから続けて、最終的な回答本文を生成します。Google の公式例にある最終的な履歴の出力結果は以下の通りです。
<|turn>model
<|tool_call>call:get_current_weather{location:<|"|>Tokyo, JP<|"|>}<tool_call|><|tool_response>response:get_current_weather{temperature:15,weather:<|"|>sunny<|"|>}<tool_response|>The current weather in Tokyo is 15 degrees and sunny.<turn|>
8.5 マルチモーダル入力
messages = [
{
"role": "user",
"content": [
{"type": "image", "url": "https://.../cat.jpg"},
{"type": "text", "text": "What is shown in this image?"},
],
}
]
<bos><|turn>user
<|image|>
What is shown in this image?<turn|>
<|turn>model
<|channel>thought
<channel|>
一方で、プロセッサ展開層での概念的な出力は以下のようになります。
<bos><|turn>user
<|image><|image|><|image|>...<image|>
What is shown in this image?<turn|>
<|turn>model
<|channel>thought
<channel|>
ここで省略している ... の長さは、画像のサイズと max_soft_tokens の設定によって変動します。
9. 実装上の留意点
9.1 Assistant 履歴の保持ポリシー
テンプレートは strip_thinking() を用いて thought channel を削除するよう設計されています。そのため、メッセージ履歴として保存すべき Assistant の正規の内容は、生の全文ではなく最終回答のみとするのが自然です。
9.2 Tool 実行の責任分界点
Gemma 4 が出力するのは、あくまで Tool Call オブジェクトに相当する文字列のみであり、実際の関数実行はアプリケーション側の責任で行う必要があります。Google の公式ドキュメントでも、生成されたコードや関数呼び出しの検証が強く推奨されています。
9.3 辞書キー順序の自動ソート仕様
内部で dictsort が多用されているため、スキーマ、引数、レスポンスのキーはすべて辞書順にソートされて出力されます。元の Python の辞書の挿入順序に依存したテストコードを書かないように注意してください。
9.4 複数 Text Item 結合時の空白消失リスク
複数の Text Item を使用する場合、各 Item に対して trim 処理がかかります。そのため、["Hello ", " world"] のように、Item を分割することで意図的にスペースを作るような記述は避けるのが無難です。
9.5 空の messages 配列の取り扱い
テンプレートは内部的に messages[0] を直接参照する実装になっているため、空の配列を入力として渡すのは安全ではありません。
9.6 eos_token の自動付与に関する制限
このテンプレートが明示的に出力する汎用トークンは、先頭の <bos> のみです。<eos> は Jinja テンプレート上では自動的に追加されません。
9.7 ドキュメントの表示例とテンプレート実装間の差異
一部の公式ドキュメントにおける表示例は、現在の Jinja テンプレートの実際の出力と完全には一致していないように見える場合があります。実装やデバッグを行う際は、最終的に chat_template.jinja と apply_chat_template() の実出力を正とすることが推奨されます。
10. 本番環境向け 推奨ワークフロー
実稼働環境や開発フェーズにおいて、Gemma 4 を安全かつ確実に使うための推奨ワークフローは以下の通りです。
- プロンプトやデバッグ時は生文字列を確認する: 開発時には、必ず一度
apply_chat_template(..., tokenize=False) の出力を確認してください。モデルに実際にどのような文字列が渡されているかを把握することが、トラブルシューティングの第一歩になります。
- 生の出力を確認する際は特殊トークンをスキップしない: プロトコルレベルのトークンの挙動を確認したい場合は、デコード時に
skip_special_tokens=False を指定してください。
- 本番環境での解析には専用メソッドを利用する: 実際のアプリケーションでは、生の出力を自前でパースするのではなく、
processor.parse_response() を活用してください。
- ツールの実行はホワイトリスト方式で管理する: モデルが返すツール呼び出しは、あくまで文字列によるリクエストです。関数名や引数のバリデーションを実施してから実行してください。
- 複雑なツールスキーマは手動で定義する: ネストされたオブジェクトやカスタムクラスを含む複雑な関数の場合、自動スキーマ生成に頼るよりも、手動でスキーマを定義する方が安全です。
- マルチモーダル入力の内部展開を意識する: テンプレート上では
<|image|> のようなプレースホルダーが 1 つだけ見えている場合でも、内部では多数の Soft Token へと展開されます。このプレースホルダー層と内部展開層の違いを区別して設計してください。
11. 参考文献 / 一次ソース
本ドキュメントの記述は、以下の公式リソースおよび実装ファイルに基づいています。