peg-native: lazy grammar fails to prevent malformed tool-call XML (duplicate ) on Qwen3.6-35B-A3B; parser then drops the whole tool call and

用户在 llama-server (多模型路由预设)中加载 unsloth/Qwen3.6-35B-A3B (推理型 MoE 模型,UD-Q8_K_XL 量化),通过外部 --chat-template-file (社区修复的 Qwen3.6 家族模板,XML 工具调用方言)并设置 --jinja

peg-native: lazy grammar fails to prevent malformed tool-call XML (duplicate ) on Qwen3.6-35B-A3B; parser then drops the whole tool call and

peg-native: lazy grammar fails to prevent malformed tool-call XML (duplicate </parameter>) on Qwen3.6-35B-A3B; parser then drops the whole tool call and

快速结论:该报错发生在使用 llama-server 通过 peg-native 自动生成惰性语法(lazy grammar)进行 XML 工具调用时,模型偶尔会生成重复的 </parameter> 闭合标签。优先排查 llama.cpp 版本是否为 b9728 之前(尤其是 b9608 之后),并尝试升级到包含修复补丁的版本(如 b9728+ 或 #24839 后的构建)。

问题场景

用户在 llama-server(多模型路由预设)中加载 unsloth/Qwen3.6-35B-A3B(推理型 MoE 模型,UD-Q8_K_XL 量化),通过外部 --chat-template-file(社区修复的 Qwen3.6 家族模板,XML 工具调用方言)并设置 --jinja--chat-template-kwargs '{"preserve_thinking": false}' 启动服务。客户端(如 VS Code Copilot 风格)使用 tool_choice: "auto" 进行流式工具调用时触发。问题在推理型模型上出现概率约 1/128 次请求,在非推理型模型上未重现。

报错原文

common_chat_peg_parse: unparsed peg-native output: <tool_call>
<function=read_file>
<parameter=filePath>
/Users/.../pallium-finish-done.story
</parameter>
</parameter>                <!-- stray duplicate close tag (model slip) -->
<parameter=startLine>
1
</parameter>
<parameter=endLine>
50
</parameter>
</function>
</tool_call>

srv          stop: cancel task, id_task = 3431

客户端进一步报错:

The model produced output that does not match the expected peg-native format

原因分析

这是两个问题叠加的后果:

  1. 生成阶段:自动生成的惰性语法未能有效约束模型输出。在 tool_choice: "auto" 下,peg-native 路径设置 grammar_lazy=true,以 <tool_call> 作为触发器。但触发器被触发后,语法理论上应只允许 <parameter=</function>,然而模型仍然采样了重复的 </parameter>。这可能是因为语法定义中 parameter 的闭合被定义为 Until('\n</parameter>\n'),在惰性模式下边界处理不够严密。
  2. 解析阶段(更关键):解析器在遇到无法解析的语法块时,没有降级处理(如 best-effort 恢复已解析的参数),而是直接丢弃整个 <tool_call> 块并终止流。这导致即使模型在重复闭合标签之外生成了有效的参数(如 startLineendLine),也无法被利用。

在 b9608 之前的版本中该问题未出现,因此可能是在 b9608 至 b9728 之间的某个提交引入了解析或语法生成的变化。

环境排查

  • llama.cpp 版本:确认是否在 b9608 之后、b9728 之前(问题于 b9722 首次报告)。升级到包含 #24839 修复的分支或晚于 2026-06-21 的构建。
  • 模型:Qwen3.6-35B-A3B(推理型 MoE)——仅在推理型模型上观察到,非推理型模型(如 Qwen3.6 27B)不受影响?实测 27B 也遇到。
  • 客户端行为:VS Code Copilot 风格的客户端可能不发送回 reasoning traces,但这并非根因。即使在自定义推理应用且启用了 reasoning traces 的配置下也可能复现。
  • 工具定义(次要):检查工具函数的参数中是否缺少必填字段。某些案例显示当模型省略了必填 content 参数时也可能触发类似报错(但表现为无重复标签的单个 </function> 直接结束)。

解决步骤

  1. 升级 llama.cpp 版本:首先尝试升级到包含 #24839 修复的构建(预计在 b9728+)。该修复专门针对重复的 </parameter> 标签问题。如果无法立即升级,可降级到 b9608 或更早版本。
  2. 验证语法修复(若使用自定义构建):检查修改了 peg-native 语法生成逻辑的提交 #24839。该提交应确保惰性语法正确禁止在已闭合的 <parameter> 后生成重复标签。
  3. 临时降级方案:如果不便升级,可将模型切换为非推理型模型(如 Qwen3.6 27B 的某些变体),或禁用 grammar_lazy=true 特性(如果服务器配置允许)。
  4. 客户端配置(可优先尝试):如果使用 VS Code Copilot 客户端,确保发送推理痕迹(reasoning traces)给服务器。虽然不是根本原因,但某些客户端配置差异可能影响模型行为(社区报告该问题在 b9608 下正常,因此客户端作用有限)。
  5. 工具定义检查(仅针对 “missing mandatory parameter” 模式):如果报错中没有重复 </parameter> 而是直接闭合 </function>,请检查工具函数的 required 字段是否完整。模型可能省略了必填参数,导致解析器因不匹配直接取消流。

验证方法

升级后,使用相同的工作负载(多轮代理工具调用,特别是涉及 read_file 等返回文件内容的调用)进行测试。如果问题不再出现(重复 </parameter> 标签消失,所有 <tool_call> 块均被正确解析),则修复成功。也可以通过触发边缘情况(如在工具调用中故意包含复杂嵌套内容)来验证语法约束的健壮性。

参考来源

ggml-org/llama.cpp #24807

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

celebrityanime
celebrityanime
文章: 9201

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注