2026-05-18 更新(v19):智能体循环修复。(1)废除“空思考”干扰:重写 AST 历史渲染,彻底移除空
</think>\n</RichMediaReference>块的注入。这解决了一个严重的上下文学习偏差,即模型此前认为只有在不先思考的情况下才能调用工具,这导致了 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)真正的空白字符规范化:修复了一个 bug,该 bug 导致推理绕过和幻觉标签恢复过程中堆叠隐藏的多重换行符(\n\n\n),严格满足所有边缘情况下 100% KV 缓存命中率的声明。(4)代码清理:移除了 XML 工具解析过程中的无效条件分支。2026-05-15 更新(v17):重大架构革新,解决了智能体工具使用和 KV 缓存方面的边缘情况。(1)统一模板:将 Qwen 3.5 和 Qwen 3.6 整合到单个
chat_template.jinja文件中,可无缝处理所有变体。(2)修复“互斥”停止 bug:将历史修剪逻辑从清除整个轮次更改为安全地数组切片仅去除原始工具标签(content.split('<tool_call>')[0])。这保留了历史记录中的对话文本,解决了模型在想同时说话和使用工具时会人为终止其轮次(输出<|im_end|>)的 bug。(3)恢复 100% KV 缓存命中率:完全规范化思考块和工具调用周围的内部空白字符逻辑(\n\n->\n),以精确匹配模型原生的自回归生成间距。这使模板的渲染历史与缓存的生成 tokens 完美同步,完全消除了 v16 中存在的严重缓存失效和全提示重新处理问题。2026-05-14 更新(v16):四部分修复,解决社区报告的回归问题。(1)原生 XML 工具格式:从 JSON revert 回模型训练时使用的原生
<function=name>/<parameter=x>格式,恢复与 vLLM 的qwen3_coder解析器以及所有实现 Qwen 工具协议的推理引擎的完全兼容性。(2)错误路径中尊重--reasoning off:当思考被禁用时(enable_thinking=false/--reasoning off),错误升级指令现在以纯文本形式注入,不打开任何<RichMediaReference>块,防止在无推理会话中出现异常提示。(3)更智能的误报检测:现在正确排除以$开头的短 shell 命令结果和带有时间页脚(Took X.Xs)的搜索结果,防止当命令成功但其输出恰好包含error一词时出现工具重试循环。(4)consecutive_failures计数器在助手消息时不再重置,允许 Tier 2 升级在多轮工具重试链中实际触发。2026-05-13 更新(v15):针对智能体工具循环失败的三部分修复。(1)两级错误升级:用完全前向跟踪的
last_tool_failed+consecutive_failures计数器替换了脆弱的向后前瞻错误检测。首次错误时,生成提示在<RichMediaReference>内预植入纠正指令;第二次及后续连续错误时,绕过思考块并通过带外指令强制立即执行纠正操作。(2)长度门控检测:仅从短工具响应(< 500 字符)中读取错误信号,防止在读取包含error、exception等合法内容的代码文件时出现误报。(3)静态系统提示:工具指令现在完全无条件,永久消除了 v14 中引入的 KV 缓存失效风险。2026-05-12 更新(v14):解决了工具失忆循环和工具使用后过度思考的问题!实施智能循环保留,动态扫描后续工具返回结果中的错误标记,并在工具主动失败期间有条件地保留历史推理上下文。拓宽系统指令范围,将
</think>定义为兼具规划和综合功能的空间,彻底消除了工具检索后的犹豫问题。2026-05-11 更新(v13):彻底简化和兼容性革新!将工具模式和助手输出格式 revert 为标准 JSON,从根本上修复下游 MCP 解析器崩溃和 C++ 隐式枚举强制转换错误。移除
ns_scan历史循环,永久修复对话中 KV 缓存失效问题。用 C++ 安全的局部数组切片方法替换幻觉标签的全局字符串替换,防止在用户代码块上发生数据损坏。2026-05-10 更新(v12):修复了智能体停滞、参数数据丢失和幻觉 bug!恢复动态工具指令和
<IMPORTANT>格式提醒块,以阻止语法解析器崩溃。2026-05-10 更新(v11):修复了智能体循环和过度思考问题!重新实现
preserve_thinking参数,默认从历史中正确剥离推理块,并恢复了推理绕过(</think>\n\n</think>\n\n)。
这是一个即插即用的 Jinja 模板,可修复官方 Qwen 聊天模板中的渲染错误、KV 缓存失效、token 浪费以及致命的智能体停滞问题。
它经过测试,可在 LM Studio、llama.cpp、vLLM、MLX、oMLX 以及任何支持 HuggingFace Jinja 模板的引擎上运行。
官方 Qwen 模板存在限制以及特定于 Python 的 Jinja 逻辑,导致其在许多推理引擎和智能体框架上无法正常使用。
以下是此模板修复的关键问题:
| 类别 | 问题 | 影响 | 修复方案 |
|---|---|---|---|
| 智能体循环 | 过早停滞(停止 bug) | 模型在尝试结合对话与工具调用时提前结束回合(<|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 被忽略 | 当思考功能被禁用时,工具错误升级仍会打开 <RichMediaReference> 块,破坏提示。 | 错误升级分支现在完全遵循 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(llama.cpp、LM Studio 和 MLX 使用的 C++ 运行时)上会崩溃。所有实例均已重构以实现通用支持:
\| items -> for key in mappingloop.previtem -> messages[loop.index0 - 1](v18)map('string') -> join('|')\| first -> '$ ' in content| 特性 | Official Qwen Templates | 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_v18.py测试涵盖:XML工具格式、工具指令、思维绕过、<|think_off|>/<|think_on|>、1级和2级升级、长度门控检测、shell/搜索误报、--reasoning off+错误、计数器重置、历史思维剥离、preserve_thinking、开发者角色、对话中系统提示、工具响应包装以及字符串参数传递。
| 角色 | 作者 |
|---|---|
| 原始模型 | Alibaba Cloud (Qwen team) |
| 模板修复 | froggeric |
Apache-2.0,继承自Qwen。