localaiforum
ログイン
ガイド › モデルの活用

プロンプトとチャットテンプレート

あなたが送るすべてのメッセージは、モデルが見る前にマークアップで包まれる。チャットテンプレートはロールタグ付きメッセージを1つの平坦なトークン列に変え、モデルはそのまさにその文字列を読むよう学習された——あなたの整ったAPIオブジェクトではない。封筒を正しくすれば3Bのinstructモデルが行儀よく振る舞い、間違えれば70Bモデルが単語スープを吐く。

封筒:1つの会話、3つの方言

APIはロールを公開する。system、user、assistant。モデルは特殊トークンを見る。同じ2メッセージの会話を3通りに描画。

ChatML——QwenファミリーとHermes系統のファインチューニング。

<|im_start|>system
You are a concise assistant.<|im_end|>
<|im_start|>user
Summarize this file.<|im_end|>
<|im_start|>assistant

Llama 2スタイル——システムマーカーが最初の指示の中に入れ子。

<s>[INST] <<SYS>>You are a concise assistant.<</SYS>>

Summarize this file. [/INST] The file implements a tokenizer... </s>

Gemmaスタイル——システムロールは存在せず、指示は最初のユーザーターンに乗り、アシスタントはmodelと呼ばれる。

<bos><start_of_turn>user
You are a concise assistant.

Summarize this file.<end_of_turn>
<start_of_turn>model

同じ会話、互換性のない3つの封筒。ChatMLで学習されたモデルがLlamaのマークアップを「察する」ことはない——迷子のマークアップを通常のテキストとして扱い、それにならって応答する。

エンジンはモデルファイルからテンプレートを読む

GGUFメタデータはchat_template(Jinjaスニペット)を埋め込む。llama.cpp、Ollama、LM Studio、Open WebUIはそれを読み、メッセージを自動描画する。ちゃんとしたGGUFでチャットが箱から出してすぐ動く理由。古典的な罠が2つ。生の補完エンドポイント(/completion)はテンプレートを飛ばし、モデルに素のテキストを渡す——チャットエンドポイントを使うこと。そしてGGUFはテンプレート欠落や誤りで出荷されることがある——明示的に渡すか(llama.cppの--chat-template、OllamaのModelfile)、正しく作ったソースから同じモデルの別の量子化を取ること。

誤ったテンプレートの症状

  • 即座の空の返信——描画済みプロンプトがすでに終わった会話に見えるので、モデルは即座にEOSを出す。
  • ロール漏れ——出力がuser: sure thing! assistant:と読める——モデルが回答の代わりに封筒を模倣する。
  • ゴミ——1時間前まで普通にチャットできたモデルからのベースモデル風の単語スープ。テンプレートを変えずにファイルを交換したから。

診断には描画済みプロンプトをダンプ——llama.cppサーバは詳細にログに出し、OLLAMA_DEBUG=1でOllamaに表示される。それからテンプレートかファイルを直す。トラブルシューティング。

システムプロンプトと優先順位

システムロールは永続的な挙動を設定する。ペルソナ、言語、出力形式、安全姿勢。これはファームウェアではなくコンテキスト——長い会話に流され得て、小さいモデルはあなたが望むより軽く扱う。実用ルールが2つ。要となるもの(言語、形式契約、厳しい制約)はシステムプロンプトに入れ、かつ最後のユーザーメッセージで言い直す。生成に最も近い指示が勝つ。

ゼロショット対few-shot

ゼロショットは頼み、few-shotは見せる。3Bモデルでバグ報告から構造化フィールドを抽出する場合、ゼロショット——「タイトル、コンポーネント、重要度をJSONとして抽出して」——は、3分の2ほどの確率で有効で一貫したキーのJSONを返すが、キー名は漂う(あるターンはseverity、次はpriority)。

few-shot:同じモデル、実例2つ、3つ目の報告を開いたまま。

Report: "Safari 17でログインボタンが反応しない。"
{"title": "ログインボタン無反応", "component": "auth", "severity": "medium"}

Report: "4K動画のアップロード時にアプリがクラッシュする。"
{"title": "4Kアップロードでクラッシュ", "component": "upload", "severity": "high"}

Report: "ダークモードで設定の文字が読めない。"

実例が形式契約を運ぶので、サンプラはスキーマを発明する代わりに内容を選ぶ。このクラスのタスクでは、形式失敗率は典型的に約30%から数%へ下がる。実例2〜3個が曲線の膝。それ以上はコンテキストトークンの支払い。厳格なスキーマには、当て推量を完全に飛ばすこと:構造化出力。

小さいモデルが生き残れるパターン

パターン 機能する理由
プロンプトごとに1タスク タスクは注意を取り合う。負けたものは捨てられる
明示的な出力形式(「キーa, b, cのJSON」) 形式をほぼ決定的な選択に変える
番号付きステップ(「1)特定 2)説明 3)修正」) チェーンが彷徨わず線路に留まる
記述より実例 モデルは文章に従うより模倣が上手い
短いメタ指示 追加ルールごとに他のルールが薄まる

コンテキストの中盤は指示の墓場

アテンションはプロンプトの始端と終端で最も強い——「lost in the middle」効果で、モデルファミリーをまたいで安定。実用的な配置:目標と形式契約を最上段に、処理する文書を最下段に、長文書ではペイロードの後に1行の指示の繰り返しを。位置は内容と同じほど要になる——そしてコンテキストの追加ターンごとにメモリを要求する:KVキャッシュ。

ストップシーケンス

生成はモデルがEOSトークンを出したときに終わる——どのトークンかはテンプレートが定義する。追加のストップシーケンス(llama.cppサーバとOpenAI互換APIのstopパラメータ)は、代わりに文字列で切り詰める。おしゃべりなモデルがあなたの次のユーザーターンを書き始めたときに有用。「ターン終了」だけを意味できるもの(ChatMLモデルでは\n<|im_start|>)を選び、正当な回答の中に出る文字列は決して選ばない——素の改行は複数行コードをブロック途中で切る。

約7B未満では簡潔が冗長に勝る

小さいinstructモデルは、400語のルーブリックより40語の指示に良く従う。限られた注意が渡されたものすべてに広がるから。構造と実例が文章ルールの代用をする。小論文のようなプロンプトは大きいモデルに取っておくこと。全行を読むのは彼らだけ。

再利用可能なスニペットテンプレート

抽出。

以下のテキストから抽出:人名、日付、金額。
JSON配列を返すこと。項目ごとに1オブジェクト、キー: name, date, amount。
JSONの前後に文章を入れないこと。
Text: {text}

要約。

会議を欠席した人向けに、正確に3つの箇条書きで要約。各15語未満。
最重要の決定を最初に。
Text: {text}

コードレビュー。

以下のdiffをレビュー。発見事項は最大5件、重要度順。
各件の形式: [severity] file:line — 問題 — 修正案。
称賛と要約は省く。Diff: {diff}

関連: トークン · 構造化出力 · エンジンパラメータ · トラブルシューティング