2026-06-05 更新(v20):架构师补丁。 针对深度智能体循环和 C++ 推理引擎兼容性的重大结构性革新。(1)Minja AST 扁平化: 大幅优化 Jinja 嵌套深度,解决了在
llama.cpp上导致推理吞吐量下降 80% 的严重解析瓶颈。(2)Minja Replace 错误修复(热修复): 绕过了llama.cpp中的一个严重 C++ 解析错误,该错误会在用户提示的索引 0 处使用replace过滤器时,静默丢弃整个文本负载。内联思考切换现在使用split和join进行稳健的剥离。(3)自动禁用思考: 引入auto_disable_thinking_with_tools参数(默认false),允许用户在工具使用期间立即关闭推理块。(4)深度智能体回退: 解决了由对话中期系统提示或缺少人类user消息的循环触发的异常。(5)负载截断: 实现max_tool_arg_chars和max_tool_response_chars配置,以明确阻止大量数据返回导致的上下文窗口爆炸。(非常感谢barubary/spiritbuun对这些 C++ 架构优化的贡献!)
2026-05-18 更新(v19):智能体循环修复。 (1)消除“空思考”干扰: 重写 AST 历史渲染,完全移除空
</think>\nsuperscript:块的注入。这解决了一个严重的上下文学习偏差,即模型假设只有在不先思考的情况下才能调用工具,这导致了 80% 以上的过早<|im_end|>轮次中止。(2)移除系统提示逻辑陷阱: 软化了<IMPORTANT>块中的绝对工具使用要求,并恢复了通用综合指令。现在明确允许模型从</think>平稳过渡到对话式回答,无需恐慌。(3)真正 100% KV 缓存和记忆缺失修复:preserve_thinking现在默认为true。保留过去的思考内容按时间顺序排列,永久解决了多步骤工具循环中的“记忆缺失停滞”问题,同时从数学上保证了开箱即用的 100% KV 缓存前缀匹配。
2026-05-16 更新(v18):稳定性和精确性补丁。 (1)防弹级误报检测: 将智能体错误检测从广泛的子字符串匹配转变为严格的结构格式(例如
"error":、Exception:、Traceback),彻底解决了当成功的 JSON 返回仅包含“error”或“fail”等词时出现的误报重试循环问题。(2)旧版引擎兼容性: 用显式数组索引替换loop.previtem,修复了在不跟踪循环状态项的旧版llama.cpp和minijinja构建上的 AST 崩溃问题。(3)真正的空白字符规范化: 修复了一个错误,即推理绕过和幻觉标签恢复会堆叠隐藏的多重换行符(\n\n\n),严格满足所有边缘情况下 100% KV 缓存命中率的要求。(4)代码清理: 移除了 XML 工具解析期间的无效条件分支。2026-05-15 更新(v17): 重大架构革新,解决智能体工具使用和 KV 缓存的边缘情况。(1)统一模板: 将 Qwen 3.5 和 Qwen 3.6 合并到单个
chat_template.jinja文件中,无缝处理所有变体。(2)修复“互斥”停止错误: 将历史修剪逻辑从擦除整个轮次更改为安全地数组切片出仅原始工具标签(content.split('<tool_call>')[0])。这保留了历史中的对话文本,解决了模型在想要同时交谈和使用工具时会人为中止其轮次(输出<|im_end|>)的错误。(3)恢复 100% KV 缓存命中率: 完全规范化思考块和工具调用周围的内部空白逻辑(\n\n->\n),以精确匹配模型的原生自回归生成间距。这使模板的渲染历史与缓存的生成标记完美同步,完全消除了 v16 中存在的严重缓存失效和全提示重新处理问题。2026-05-14 更新(v16): 四部分修复,解决社区报告的回归问题。(1)原生 XML 工具格式: 从 JSON 恢复为模型训练时使用的原生
<function=name>/<parameter=x>格式,恢复与 vLLM 的qwen3_coder解析器以及所有实现 Qwen 工具协议的推理引擎的完全兼容性。(2)错误路径中尊重--reasoning off: 当思考被禁用(enable_thinking=false/--reasoning off)时,错误升级指令现在以纯文本形式注入,不打开任何</think>块,防止在无推理会话中出现异常提示。(3)更智能的误报检测: 现在正确排除以$开头的短 shell 命令结果和带有时间页脚(Took X.Xs)的搜索结果,防止当命令成功但其输出恰好包含“error”一词时出现工具重试循环。(4)consecutive_failures计数器在助手消息时不再重置,允许二级升级在多轮工具重试链中实际触发。2026-05-13 更新(v15): 三部分修复智能体工具循环失败问题。(1)两级错误升级: 用完全前向跟踪的
last_tool_failed+consecutive_failures计数器替换脆弱的后向超前错误检测。第一次错误时,生成提示在</think>内预植入修正指令;第二次及后续连续错误时,绕过思考块并通过带外指令强制立即执行修正操作。(2)长度门控检测: 仅从短工具响应(<500 字符)中读取错误信号,防止在读取包含error、exception等合法内容的代码文件时出现误报。(3)静态系统提示: 工具指令现在完全无条件,永久消除 v14 中引入的 KV 缓存失效问题。2026-05-12 更新(v14): 解决了工具记忆缺失循环和工具使用后过度思考的问题!实施 智能循环保留,动态扫描后续工具返回中的错误标记,并在工具主动失败期间有条件地保留历史推理上下文。扩大系统指令范围,将
</think>定义为兼具规划和综合功能的空间,彻底消除工具检索后的犹豫问题。2026-05-11 更新(v13): 彻底简化和兼容性革新!将工具模式和助手输出格式恢复为标准 JSON,从根本上修复下游 MCP 解析器崩溃和 C++ 隐式枚举强制转换错误。移除
ns_scan历史循环,永久修复对话中期的 KV 缓存失效问题。将全局字符串替换幻觉标签的方法替换为 C++ 安全的局部数组切片方法,防止在用户代码块上的数据损坏。2026-05-10 更新(v12): 修复智能体停滞、参数数据丢失和幻觉错误!恢复动态工具指令和
<IMPORTANT>格式提醒块,以阻止语法解析器崩溃。2026-05-10 更新(v11): 修复智能体循环和过度思考!重新实现
preserve_thinking参数,默认从历史中正确剥离推理块,并恢复推理绕过(</think>\n\nsuperscript:\n\n)。
这是一个即插即用的 Jinja 模板,可修复官方 Qwen 聊天模板中的渲染错误、KV 缓存失效、令牌浪费和致命的智能体停滞问题。
它经过测试,可在 LM Studio、llama.cpp、vLLM、MLX、oMLX 以及任何支持 HuggingFace Jinja 模板的引擎上运行。
官方 Qwen 模板存在限制以及特定于 Python 的 Jinja 逻辑,导致其在许多推理引擎和智能体框架上无法正常使用。
以下是此模板修复的关键问题:
| 类别 | 问题 | 影响 | 修复措施 |
|---|---|---|---|
| 智能体循环 | 过早停滞(停止错误) | 模型在尝试结合对话和工具调用时会中止其轮次(<|im_end|>)。 | 解决了系统提示逻辑陷阱,并修复了“空思考”干扰问题(v19 版本)。 |
| 智能体循环 | 重试停滞与推理螺旋 | 模型能正确诊断工具错误,但会重复发出相同的失败 <tool_call>。 | 两级升级机制:通过 </think> 植入修正指令;注入紧急带外指令。 |
| 智能体循环 | 工具调用后过度思考 | 强制的 </think> 块预填充导致模型在获取数据后陷入恐慌并纠结内部规则。 | 扩展指令以将 </think> 定义为兼具规划 或 综合功能的空间。 |
| 智能体循环 | 误报错误检测 | 包含 error 一词的简短成功 API/JSON 返回会触发错误的重试循环。 | 采用严格的结构检查,仅查找确切的系统故障(如 "error":、Traceback 等),而非宽泛的词汇(v18 版本)。 |
| 性能 | KV 缓存失效 | 历史记录修剪会动态改变过往轮次,导致每轮都需重新处理完整提示。 | preserve_thinking 默认设为 true,维持严格的按时间顺序渲染,实现 100% KV 缓存命中率(v19 版本)。 |
| 性能 | 空思考干扰 | 剥离过往轮次后留下空的 </think>superscript: 标签,使模型陷入严重的上下文学习偏差。 | 模板彻底废除了空思考块的注入(v19 版本)。 |
| 兼容性 | 旧引擎崩溃 | 较旧的 C++ 解析引擎在计算 loop.previtem 时会崩溃。 | 采用严格的按时间顺序数组索引,普遍支持所有 Jinja 迭代(v18 版本)。 |
| 兼容性 | 工具调用格式错误 | Qwen 原生解析器(如 vLLM 的 qwen3_coder)期望 XML <function=name> 格式。JSON 格式会使其失效。 | 恢复原生 XML 格式,同时保持 C++ 安全性。 |
| 兼容性 | Jinja C++ 崩溃 | 特定于 Python 的过滤器(如对字符串使用 map、first)在 minijinja 上会崩溃。 | 所有过滤器均替换为普遍兼容的等效项。 |
| 稳定性 | 对话中系统崩溃 | 框架在对话中注入引导指令会触发硬崩溃。 | 对历史记录中任何位置的系统消息采用原生、按时间顺序的渲染。 |
| 稳定性 | 无用户查询崩溃 | raise_exception 会导致智能体循环或纯系统上下文崩溃。 | 实现了优雅的回退机制。 |
| 稳定性 | 工具调用前未关闭思考 | 模型调用工具时未关闭其推理过程,导致 XML 标签渗入工具解析器。 | 在工具边界前自动安全地注入闭合标签。 |
| 边缘情况 | developer 角色被拒 | 现代 API 会发送 developer 角色;官方模板拒绝该角色。 | 增加了对 "developer" 的全面支持。 |
| 边缘情况 | --reasoning off 被忽略 | 当思考被禁用时,工具错误升级仍会打开 </think> 块,破坏提示。 | 错误升级分支现在完全遵循 enable_thinking=false。 |
| 边缘情况 | 推理绕过幻觉 | 当思考被禁用时,Qwen 模型本质上仍会幻觉出推理标签。 | 注入安全边界,成功强制绕过推理,且不会堆叠换行符(v18 版本)。 |
选择您的环境并更新模板:
chat_template.jinja 文件的内容。--jinja --chat-template-file chat_template.jinja将 tokenizer_config.json 中的 "chat_template" 字符串替换为原始文件内容。使用 qwen3_coder 工具解析器:
--tool-call-parser qwen3_coder覆盖本地模型目录中的 chat_template.jinja 文件。使用 --jinja 参数加载。移除所有 chat_template_kwargs 覆盖项,因为模板会在内部处理所有内容。
Qwen 3.5 和 Qwen 3.6 的所有变体(包括 35B、32B、27B 和 14B 参数版本)已整合。您只需使用仓库根目录下的单个 chat_template.jinja 文件即可。
单行版本(chat_template_oneline.txt)已预先压缩,适用于要求模板字符串为单行的引擎。
您可以控制模型的推理行为。在系统提示或用户提示的任意位置插入 <|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.(标签语法使用Qwen的控制令牌分隔符,以确保它永远不会与合法文本或文件路径冲突,这与早期社区模板使用/think的方式不同)
在v19版本中,此模板默认保留聊天历史中的所有过往</think>块。这是有意为之:它可防止模型在复杂的多步骤智能体循环中出现“失忆停滞”,并在数学上保证本地推理引擎的前缀KV缓存命中率达到100%。
但是,如果您运行在硬件资源受限的环境中,需要节省上下文令牌,可以在引擎的模板参数中显式禁用此功能,以自动剥离过往思考:
{
"preserve_thinking": false
}(注意:将此设置为 false 会在多轮对话中自然降低 KV 缓存命中率,因为提示字符串会动态变化。)
早期版本尝试通过将过往思考替换为空的 </think>\nsuperscript: 块来节省 tokens,并结合绝对的系统提示,要求在 superscript: 之后立即调用工具。这导致了一种有害的上下文学习模式:模型将空思考与工具调用相关联,将完整思考与禁止的对话文本相关联,从而造成 80% 以上的过早 <|im_end|> 停滞率。v19 版本废除了空思考注入,并重写了 <IMPORTANT> 指令,明确授权在思考块之后进行对话内容生成。
Llama.cpp 和 vLLM 利用前缀 KV 缓存来加速生成过程。由于 v19 版本现在默认按时间顺序保留历史思考,渲染后的历史记录与缓存的生成 tokens 实现了完美同步。结合在自回归边界处严格的单个 \n 规范化,这使得在多轮循环中实现了 100% 的 KV 缓存命中率。
该模型使用 Qwen3-Coder 所采用的基于 XML 的工具调用格式进行训练:
<tool_call>
<function=tool_name>
<parameter=param_name>
value
</parameter>
</function>
</tool_call>v16 版本原生恢复了此格式,通过使用 C++ 安全的键迭代(for args_name in tool_call.arguments),在绕过 |items 崩溃问题的同时,确保了与所有解析器的兼容性。
当工具调用反复验证失败时,模型可能会陷入退化的推理循环。本模板利用由前向跟踪的 consecutive_failures 计数器驱动的双层升级系统:
tool_response 块内。v18 不再使用可能在包含“error”等词的成功数据库返回结果上触发错误重试循环的宽泛子字符串匹配,而是采用严格的结构化检查,查找 Exception:、"error":、Traceback 和 command not found,并结合长度限制和 shell 回显排除($ )。
仅 Python 支持的 Jinja2 特性在 minijinja/minja(llama.cpp、LM Studio 和 MLX 所使用的 C++ 运行时)上会崩溃或运行异常。所有相关实例均已重构以实现通用支持:
content | replace('<|think_on|>', '') -> content.split('<|think_on|>') | join('')(修复了一个严重 bug:如果被替换的字符串出现在索引 0 处,minja 会静默丢弃整个文本有效负载)。\| items -> for key in mappingloop.previtem -> messages[loop.index0 - 1]map('string') -> join('|')\| first -> '$ ' in content| 特性 | 官方 Qwen 模板 | LuffyTheFox | mod-ellary | Pneuny | 本修复模板 (v19) |
|---|---|---|---|---|---|
| 工具调用格式 | XML(原生) | JSON | JSON | JSON | XML(原生,兼容 qwen3_coder) |
| 工具参数 | 存在故障(|items) | 已修复 | 缺失 | 已修复 | 已修复(C++ 安全的 XML) |
| 提前停滞(停止 bug) | 会停滞 | 会停滞 | 会停滞 | 会停滞 | 通过移除逻辑陷阱/干扰代码修复 (v19) |
| 智能体重试停滞与推理循环 | 会停滞 | 会停滞 | 会停滞 | 会停滞 | 双层升级系统 |
| 工具错误误报 | N/A | N/A | N/A | N/A | 已防护(严格结构化匹配) |
| 工具调用后过度思考 | 产生垃圾信息/停滞 | 功能损坏 | 功能损坏 | 功能损坏 | 通用综合 |
工具错误时 --reasoning off | N/A | N/A | N/A | N/A | 完全支持 |
developer 角色 | 缺失 | 缺失 | 缺失 | 缺失 | 已添加 |
| 思考切换 | 无 | 无 | /think(仅系统可用) | 无 | 任意位置使用 <|think_off|> |
| 历史记录中的空思考块 | 生成空块 | 功能损坏 | 标签省略 | 功能损坏 | 完全废除 (v19) |
| KV 前缀缓存 | 动态历史时失效 | 失效 | 失效 | 失效 | 开箱即稳定 100% (v19) |
| 对话中系统提示 | 崩溃 | 崩溃 | 崩溃 | 崩溃 | 已修复 |
| 无用户查询时崩溃 | 崩溃 | 崩溃 | 崩溃 | 崩溃 | 优雅回退 |
| 旧版 AST 支持 | 失败(previtem) | 失败 | 失败 | 失败 | 已修复(index0) |
</thinking> 幻觉 | 处理失败 | N/A | N/A | N/A | 可检测并安全修剪 |
python3 scripts/test_v20.py测试涵盖:auto_disable_thinking_with_tools、负载截断逻辑、并行工具间距、对话中系统提示渲染、深度智能体循环回退、XML 工具格式、<|think_off|>/<|think_on|> 内联覆盖,以及所有旧版 v19 回归测试。
Apache-2.0,继承自 Qwen。