Qwen-3 的聊天模板教会我们的 4 件事
一个无聊的 Jinja 片段揭示了关于新 Qwen-3 模型的信息。
由 Qwen 推出的新 Qwen-3 模型配备了比其前身 Qwen-2.5 和 QwQ 复杂得多的聊天模板。通过查看 Jinja 模板中的差异,我们可以发现关于新模型的有趣见解。
聊天模板
什么是聊天模板?
聊天模板定义了用户和模型之间对话的结构和格式。该模板充当翻译器,将人类可读的对话
[
{ role: "user", content: "Hi there!" },
{ role: "assistant", content: "Hi there, how can I help you today?" },
{ role: "user", content: "I'm looking for a new pair of shoes." },
]
转换为模型友好的格式
<|im_start|>user
Hi there!<|im_end|>
<|im_start|>assistant
Hi there, how can I help you today?<|im_end|>
<|im_start|>user
I'm looking for a new pair of shoes.<|im_end|>
<|im_start|>assistant
<think>
</think>
您可以在 Hugging Face 模型页面轻松查看给定模型的聊天模板。
Qwen/Qwen3-235B-A22B 的聊天模板
让我们深入了解 Qwen-3 聊天模板,看看能学到什么!
1. 推理不必强制
您可以通过简单的预填充使其可选...
Qwen-3 的独特之处在于它能够通过 `enable_thinking` 标志切换推理。当设置为 false 时,模板会插入一个空的 `<think></think>` 对,告诉模型跳过逐步思考。早期的模型将 `<think>` 标签嵌入到每个生成中,无论您是否需要,都强制进行思维链。
{# Qwen-3 #}
{%- if enable_thinking is defined and enable_thinking is false %}
{{- '<think>\n\n</think>\n\n' }}
{%- endif %}
例如,QwQ 在每次对话中都强制进行推理。
{# QwQ #}
{%- if add_generation_prompt %}
{{- '<|im_start|>assistant\n<think>\n' }}
{%- endif %}
如果 `enable_thinking` 为 true,模型可以决定是否进行思考。
您可以使用以下代码测试模板
import { Template } from "@huggingface/jinja";
import { downloadFile } from "@huggingface/hub";
const HF_TOKEN = process.env.HF_TOKEN;
const file = await downloadFile({
repo: "Qwen/Qwen3-235B-A22B",
path: "tokenizer_config.json",
accessToken: HF_TOKEN,
});
const config = await file!.json();
const template = new Template(config.chat_template);
const result = template.render({
messages,
add_generation_prompt: true,
enable_thinking: false,
bos_token: config.bos_token,
eos_token: config.eos_token,
});
2. 上下文管理应是动态的
Qwen-3 采用滚动检查点系统,智能地保留或修剪推理块以维持相关上下文。旧模型会过早地丢弃推理以节省令牌。
Qwen-3 引入了“**滚动检查点**”,通过反向遍历消息列表来查找最新的非工具调用的用户轮次。对于该索引之后的所有助手回复,它会保留完整的 `<think>` 块;所有更早的内容都会被剥离。
为什么这很重要:
- 在多步工具调用期间保持活动计划可见。
- 支持嵌套工具工作流,而不会丢失上下文。
- 通过修剪模型不再需要的思考来节省令牌。
- 防止“陈旧”推理渗入新任务。
示例
这是 Qwen-3 和 QwQ 通过工具调用保留思维链的示例。
查看 @huggingface/jinja 以测试聊天模板
3. 工具参数需要更好的序列化
以前,每个 `tool_call.arguments` 字段都会通过 `| tojson` 管道传输,即使它已经是 JSON 编码的字符串——这会带来双重转义的风险。Qwen-3 首先检查类型,只在必要时进行序列化。
{# Qwen3 #}
{%- if tool_call.arguments is string %}
{{- tool_call.arguments }}
{%- else %}
{{- tool_call.arguments | tojson }}
{%- endif %}
4. 不需要默认的系统提示
与许多模型一样,Qwen-2.5 系列具有默认系统提示。
您是 Qwen,由阿里云创建。您是一个有用的助手。
这很常见,因为它有助于模型回答用户问题,例如“你是谁?”
Qwen-3 和 QwQ 发布时没有此默认系统提示。尽管如此,如果您询问,模型仍然可以准确识别其创建者。
结论
Qwen-3 向我们展示了通过 `chat_template` 我们可以提供更好的灵活性、更智能的上下文处理和改进的工具交互。这些改进不仅提高了能力,还使代理工作流更可靠和高效。