Prhub

#20004 Multi tool streaming fix

原始 PR 作者 kpham-sgl 合并时间 2026-04-02 12:53 文件变更 2 提交数 4 评论 5 代码增减 +175 / -3

执行摘要

修复 Qwen25 模型流式多工具调用解析失败问题。

PR body引用issue 18102,指出在使用Qwen3-Next-80B-A3B-Thinking模型进行speculative decoding时,流式多工具调用解析失败,仅返回第一个工具调用。修复目标为块状格式(如Qwen25)的流式多工具调用解析,确保正确解析所有工具调用。

建议工程师精读此PR,关注解析逻辑中的错误处理模式和回退机制设计,这对于处理复杂格式的流式解析有参考价值,特别是涉及多工具调用场景时。

讨论亮点

Review讨论较少,两位reviewer(JustinTong0323和hnyls2002)均批准了PR,没有提出异议或深入讨论,表明变更被认为直接且必要。

实现拆解

主要改动在python/sglang/srt/function_call/base_format_detector.py的parse_streaming_increment方法:1. 添加used_separator_branch标志以跟踪解析分支;2. 当JSON解析失败时,回退到搜索bot_token跳过非JSON标记(如Qwen25的标记);3. 扩展异常处理捕获MalformedJSON和json.JSONDecodeError。测试文件test/registered/unit/function_call/test_function_call_parser.py新增TestQwen25Detector类,包含7个测试覆盖单/多工具调用的流式和非流式场景。

文件 模块 状态 重要度
python/sglang/srt/function_call/base_format_detector.py function_call 解析 modified 8.0
test/registered/unit/function_call/test_function_call_parser.py 测试 modified 6.0

分析完成后,这里会展示 LLM 生成的相对完整源码片段和详细注释。

关键符号

parse_streaming_increment

评论区精华

JSON 解析失败回退逻辑 设计

在 parse_streaming_increment 中添加了当 JSON 解析失败时回退到搜索 bot_token 的逻辑,以处理 Qwen25 格式中的非 JSON 标记。

结论:实现了回退机制,确保多工具调用能正确解析,解决了解析失败问题。 · 已解决

风险与影响

风险包括:1. 修改了解析核心路径,可能影响其他格式模型的解析行为,导致回归;2. 异常处理逻辑变化可能掩盖其他潜在错误,但通过新增测试覆盖降低了风险。具体在base_format_detector.py中,回退逻辑可能引入对bot_token的依赖,如果bot_token定义不当,可能导致解析失败。

影响范围:主要影响使用Qwen25或其他类似块状格式模型的用户,修复后能正确解析流式多工具调用,提升功能正确性和用户体验。对系统其他部分无直接影响,但增强了解析模块的健壮性。影响程度中等,局限于特定模型和场景。

核心路径变更 错误处理调整

关联 Issue

#18102 [Bug] Broken multiple tool calls in Qwen3-Next-80B-A3B-Thinking with Speculative Decoding

完整报告

执行摘要

本PR修复了Qwen25模型在流式多工具调用解析中的失败问题,通过修改解析器添加回退机制,确保所有工具调用能正确解析,提升了功能一致性和用户体验。

功能与动机

该PR旨在解决issue 18102中报告的问题:在使用Qwen3-Next-80B-A3B-Thinking模型进行speculative decoding时,流式多工具调用解析失败,仅返回第一个工具调用。PR body明确指出修复目标为块状格式(如Qwen25)的流式多工具调用解析,避免因非JSON标记导致的解析错误。

实现拆解

主要改动集中在两个文件:

  1. python/sglang/srt/function_call/base_format_detector.py:修改了parse_streaming_increment方法。
    - 添加used_separator_branch标志以跟踪解析分支。
    - 当JSON解析失败时,回退到搜索bot_token跳过非JSON标记(例如Qwen25的</tool_call>\n<tool_call>\n)。
    - 扩展异常处理从仅捕获MalformedJSON到捕获MalformedJSONjson.JSONDecodeError
    if used_separator_branch and self.bot_token in current_text:
        start_idx = current_text.find(self.bot_token) + len(self.bot_token)
        obj, end_idx = _partial_json_loads(current_text[start_idx:], flags)
    
  2. test/registered/unit/function_call/test_function_call_parser.py:新增TestQwen25Detector类,包含7个测试用例,覆盖单工具调用、多工具调用的流式和非流式场景,确保修复有效性。

评论区精华

Review讨论较少,两位reviewer(JustinTong0323和hnyls2002)均快速批准了PR,没有深入讨论或争议。这表明变更被认为直接、必要且风险较低。

风险与影响

  • 风险:修改了解析核心路径,可能影响其他格式模型的解析行为,引入回归;异常处理逻辑变化可能掩盖潜在错误。但新增测试覆盖降低了这些风险。
  • 影响:主要影响使用Qwen25模型的用户,修复后流式多工具调用解析将正确工作,提升功能一致性;对系统其他部分无直接影响,但增强了解析模块的健壮性。

关联脉络

从历史PR看,PR 21225涉及speculative decoding和解析改进,与本PR的issue场景相关(issue 18102提到speculative decoding)。这表明项目在持续优化解析和推测解码功能,本PR是这一演进方向中的一环,专注于工具调用解析的细节修复。

参与讨论