Prhub

#38168 [Bugfix] Fix Hermes tool parser when stream interval > 1

原始 PR 作者 sfeng33 合并时间 2026-03-27 14:42 文件变更 3 提交数 3 评论 7 代码增减 +349 / -382

执行摘要

修复 Hermes 工具解析器在流式处理间隔大于 1 时的解析错误。

PR body 中明确说明:'The Hermes parser tried to interpret each delta_text independently... This broke when stream_interval > 1 caused tokens to arrive in multi-token chunks.' 这导致在设置 stream interval 大于 1 时,工具调用无法正确解析,影响用户体验和系统可靠性。

该 PR 值得精读,特别是新的 diff-based 解析策略,可用于理解和设计流式解析器。建议关注 extract_tool_calls_streaming 方法的实现,以及如何通过文本 diff 和状态追踪避免复杂状态机,同时留意测试用例以验证各种边界情况。

讨论亮点

讨论中,gemini-code-assist[bot] 指出解析器状态可能跨请求泄露,但作者 sfeng33 澄清 parser 每个请求新实例化,无泄露;chaunceyjiang 担忧从增量状态机改为全文本搜索可能降低性能,sfeng33 解释旧代码也进行全文本操作,新设计性能相似;bbrowning 请求额外测试以覆盖内容+工具调用在同一 chunk 的大 stream_interval 情况,作者添加测试后问题解决,并获得批准。

实现拆解

关键改动包括:移除了对 partial_json_parser 的依赖;新增了 _partial_tag_overlap_is_valid_json 辅助函数以处理部分标签和 JSON 验证;完全重写了 Hermes2ProToolParser.extract_tool_calls_streaming 方法,从基于 token buffer 的增量状态机改为基于 current_text 的 diff 解析,使用 _sent_content_idxstreamed_args_for_tool 追踪已发送内容;更新了 LongcatToolParser 移除了不必要的 token-related 属性以保持一致;在测试文件中添加了 _simulate_streaming 函数和多个测试用例,覆盖不同 stream_interval 场景(包括内容前后和工具调用),确保解析正确性。

文件 模块 状态 重要度
vllm/tool_parsers/hermes_tool_parser.py tool_parsers modified 8.0
tests/tool_parsers/test_hermes_tool_parser.py tests modified 7.0
vllm/tool_parsers/longcat_tool_parser.py tool_parsers modified 4.0

关键符号

_partial_tag_overlap _is_valid_json Hermes2ProToolParser.extract_tool_calls_streaming _simulate_streaming

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

评论区精华

状态泄露风险 正确性

gemini-code-assist[bot] 指出解析器状态可能跨请求泄露,导致错误行为。

结论:作者 sfeng33 澄清 parser 每个请求新实例化,状态不会泄露。 · 已解决

性能担忧 性能

chaunceyjiang 担忧从增量状态机改为全文本搜索可能降低性能。

结论:sfeng33 解释旧代码也进行全文本操作,新设计性能相似,无显著下降。 · 已解决

测试覆盖 测试

bbrowning 请求测试以覆盖内容 + 工具调用在同一 chunk 的大 stream_interval 情况。

结论:作者添加了测试用例,验证了修复,并获得批准。 · 已解决

风险与影响

主要风险包括:

1) 解析逻辑大幅变更可能引入新 bug,但新增测试覆盖了多种场景,降低了回归风险;
2) 移除了 partial_json_parser 依赖,需确保无其他模块依赖该库,但 PR 显示其内部处理 JSON,减少外部依赖;
3) 性能变化可能,但讨论表明新实现与旧实现复杂度相似,性能监控建议在真实场景验证。整体风险较低,因为测试充分且讨论解决了关键疑虑。

对用户:修复了 stream interval > 1 时的解析错误,提升流式工具调用可靠性和用户体验;对系统:解析逻辑更健壮,独立于流式块大小,增强了系统稳定性;对团队:解决了多个历史 bug(如 PR 37098、32518、32517 中提到的工具解析问题),避免了类似问题重现,并提供了可复用的 diff-based 解析策略参考。

核心路径变更 移除外部依赖 性能监控需求

关联 Issue

未识别关联 Issue

当前没有检测到明确关联的 Issue 链接,后续同步到相关引用后会出现在这里。

完整报告

参与讨论