o
openharmony-models/Qwen-Fixed-Chat-Templates
模型介绍文件和版本Pull Requests讨论分析
下载使用量0

Qwen 3.5 和 3.6 的修复版聊天模板

2026-05-05 — 根据社区合并的模板(allanchan339、fakezeta)进行了审核。确认所有有用功能均已包含;from_json 字符串参数解析无法移植到 C++ 引擎。感谢 allanchan339 添加了未闭合思考块的自动关闭功能。

即插即用的 Jinja 模板,可修复官方 Qwen 聊天模板中的渲染错误、令牌浪费和功能缺失问题。适用于 LM Studio、llama.cpp、vLLM、MLX、oMLX 以及任何支持 HuggingFace Jinja 模板的引擎。

为什么需要此模板

官方 Qwen 模板存在一些 bug,影响实际使用:

问题影响
C++ 引擎上工具调用失败LM Studio、llama.cpp、MLX、oMLX 中不存在 `
developer 角色被拒绝现代 API 会发送此角色;官方模板会引发错误
空思考块占用上下文即使内容为空,每个过往对话轮次都会被标签包裹
无法切换思考模式只能使用模型默认的思考模式
Qwen 3.6:</thinking> 幻觉模型有时会生成错误的闭合标签;解析器失败
无用户查询异常中断工具调用raise_exception 会导致 OpenClaw 及类似运行时中的智能体循环崩溃并重置
工具调用前思考块未闭合模型开始推理后调用工具,但未关闭思考块 — 输出格式错误

此处已修复所有上述七个问题,并添加了简洁的 <|think_on|> / <|think_off|> 切换开关,您可将其插入任何消息中。

快速安装

LM Studio

  1. 在右侧面板中打开您的 Qwen 模型
  2. 滚动至 Prompt Template(提示模板)
  3. 将模板替换为 qwen3.5/chat_template.jinja 或 qwen3.6/chat_template.jinja 的内容
  4. 保存

llama.cpp / koboldcpp

--jinja --chat-template-file qwen3.6/chat_template.jinja

vLLM / TextGen

将 tokenizer_config.json 中的 chat_template 字符串替换为文件内容。

oMLX

覆盖本地模型目录中的 chat_template.jinja 文件。使用 --jinja 参数加载。移除所有 chat_template_kwargs 覆盖项——模板会在内部处理所有内容。

我应该使用哪个文件?

文件适用模型
qwen3.5/chat_template.jinjaQwen3.5-35B-A3B、Qwen3.5-32B、Qwen3.5-14B 以及所有 Qwen 3.5 变体
qwen3.6/chat_template.jinjaQwen3.6-27B、Qwen3.6-35B-A3B 以及所有 Qwen 3.6 变体

3.6 版本的模板是一个超集——它额外支持 preserve_thinking、</thinking> 幻觉恢复以及中断的思维流。如果您使用的是 3.6 版本模型,请使用 3.6 版本的文件。

思维模式切换

在系统提示或用户提示的任意位置插入 <|think_on|> 或 <|think_off|>。模板会拦截该标签,将其从上下文中移除(模型永远不会看到它),并切换模式。

快速回答,无需推理:

System: You are a coding assistant. <|think_off|>
User: What's 2+2?

深度推理:

System: You are a coding assistant. <|think_on|>
User: Implement a red-black tree in Rust.

标签语法(<|think_on|>、<|think_off|>)采用了Qwen的控制令牌分隔符,因此绝不会与真实文本发生冲突。早期的社区模板使用/think,这会破坏像cd /mnt/project/think这样的合法路径。

预安装模型

这些模板已捆绑在以下模型中:

  • froggeric/Qwen3.6-27B-MLX-8bit
  • froggeric/Qwen3.6-27B-MLX-4bit
  • froggeric/Qwen3.5-35B-A3B-Uncensored-FernflowerAI-MLX-8bit
  • froggeric/Qwen3.5-35B-A3B-Uncensored-FernflowerAI-MLX-4bit
  • froggeric/Qwen3.6-27B-Uncensored-Heretic-v2-MLX-8bit
  • froggeric/Qwen3.6-27B-Uncensored-Heretic-v2-MLX-6bit
  • froggeric/Qwen3.6-27B-Uncensored-Heretic-v2-MLX-4bit
  • froggeric/Qwen3.6-35B-A3B-Uncensored-Heretic-MLX-8bit
  • froggeric/Qwen3.6-35B-A3B-Uncensored-Heretic-MLX-6bit
  • froggeric/Qwen3.6-35B-A3B-Uncensored-Heretic-MLX-4bit

如果您正在使用上述模型之一,那么您已经拥有该模板。本仓库是为其他用户准备的。


技术细节 — 具体修复了哪些问题

C++引擎上的工具调用

官方模板使用|items来迭代工具调用参数:

{%- for key, value in tool_call.arguments|items %}

Python 的 Jinja 支持 |items。C++ 运行时(LM Studio、llama.cpp、MLX)不支持——模板会产生渲染错误而非输出。本模板改用直接字典键查找:

{%- for args_name in tool_call.arguments %}
    {%- set args_value = tool_call.arguments[args_name] %}

它还将 is sequence 替换为 is iterable(更严格的 C++ 运行时要求如此),移除了 |safe 包装器(这也是仅限 Python 的),并处理以原始字符串而非对象形式返回的参数。

developer 角色

OpenAI 兼容的 API 规范会为系统级指令发送 message.role == "developer"。官方 Qwen 模板仅检查 "system",遇到其他值时会抛出错误。此处的两个模板均接受 "developer" 并将其映射到系统角色。

空思考块

官方模板会将每个过往的助手轮次都包装在思考标签中:

<|im_start|>assistant
<think/>
</think >

Here is the answer...

当不存在推理内容时,这些标签就成了无用的累赘——它们会浪费上下文 tokens 并破坏前缀缓存。Qwen 3.5 模板在输出前会检查 reasoning_content。Qwen 3.6 模板则更进一步:它会尊重 preserve_thinking 参数,检查 reasoning_content|trim|length > 0,并将历史可见性与 <|think_off|> 覆盖标记关联起来。

</thinking> 幻觉问题(仅 Qwen 3.6)

Qwen 3.6 模型有时会生成 </thinking> 而非预期的闭合标签。官方解析器仅按 </think > 进行拆分,因此会解析失败。3.6 模板会检测实际使用的闭合标签,并据此进行拆分:

{%- if '</think >' in content %}
    {%- set think_end_token = '</think >' %}
{%- elif '</thinking>' in content %}
    {%- set think_end_token = '</thinking>' %}

它还能处理生成中断的情况(思考过程中达到最大 tokens 限制),通过挽救不完整的流,而非注入损坏的标签对。

参数序列化

官方模板无条件使用 |tojson 序列化参数值,这虽然能正确将 Python 的 True 转换为 JSON 的 true,但当值本身已是字符串时会出错。修复后的模板会先检查类型——字符串原样保留,其他所有内容则通过 |tojson 处理。

工具调用前自动关闭未闭合的思考块

模型有时会启动一个思考块,然后立即调用工具,而不输出闭合标签。官方模板不处理这种情况——未闭合的思考标签会渗入工具调用,导致输出格式错误。两个修复后的模板都能检测到此模式,并在工具调用边界前自动注入闭合标签。

无用户查询异常

官方模板会反向扫描消息列表,寻找最后一条“真实”的用户查询(跳过工具结果包装器)。如果所有用户消息都是工具结果——或者根本没有用户消息——它会触发 raise_exception('No user query found in messages.'),导致模板硬崩溃。

这会破坏实际使用场景:

  • 智能体工具调用链,其中对话以工具结果结束,没有新的用户查询
  • 在 OpenClaw 等运行时中执行 /reset 或 /new 之后,先前会话的工具结果仍然存在,但没有新的用户消息
  • 无用户消息的纯系统上下文

修复方案用优雅的回退机制替代了异常:{%- set ns.last_query_index = messages|length - 1 %}。这样,思考显示逻辑会自然降级——当启用 preserve_thinking 时,包含推理内容的助手轮次仍然会显示思考标签。

Comparison — Qwen 3.5 templates
特性官方LuffyTheFoxmod-ellaryPneuny本模板
工具参数失败已修复缺失已修复已修复
移除 |safe失败已修复缺失已修复已修复
developer 角色缺失缺失缺失缺失已添加
思考切换无无/think(仅系统消息)无任意位置使用 <|think_off|>
历史记录中的空思考块损坏损坏标签被省略损坏已修复
文本安全性N/AN/A在路径中遇到 /think 时出错N/A安全
清晰的指令是是是注入 "I cannot call a tool"是
无用户查询时崩溃崩溃崩溃崩溃崩溃优雅回退
工具调用前自动关闭思考块未处理未处理未处理未处理自动注入闭合标签
Comparison — Qwen 3.6 template
特性官方本模板
工具参数失败(|items)已修复
移除 |safe失败已修复
developer 角色缺失已添加
思考切换无任意位置使用 <|think_off|>
preserve_thinking生成大量空块动态长度检查
</thinking> 幻觉处理失败已检测并处理
中断的流标签损坏已挽救
工具调用前自动关闭思考块未处理自动注入闭合标签
无用户查询时崩溃崩溃优雅回退

作者信息

角色作者
原始模型Alibaba Cloud (Qwen team)
模板修复froggeric

许可证

Apache-2.0,继承自Qwen。