执行摘要
- 一句话:新增 MiniCPM5 XML 格式工具调用解析器
- 推荐动作:值得精读。该 PR 是工具调用框架的一次典型扩展,展示了 parser 注册、自动检测规则添加和流式边界处理的完整实践。特别推荐关注
detect_and_parse 中的多路径解析(lxml primary + regex fallback)和 parse_streaming_increment 中的缓冲区管理逻辑。
功能与动机
MiniCPM5 使用 XML 风格的函数调用格式(V3 Schema),与基于 JSON 的解析器不同。没有专用检测器时,SGLang 无法在流式或批推理中正确提取模型输出的工具调用。
实现拆解
- 解析器核心:在
minicpm5_detector.py 中编写 MiniCPM5Detector,继承 BaseFormatDetector,实现 has_tool_call、detect_and_parse、parse_streaming_increment 等方法。使用 lxml(首选)/ stdlib ElementTree 解析 XML,提供 regex 兜底。
- 注册到 FunctionCallParser:在
function_call_parser.py 中导入 MiniCPM5Detector 并加入映射字典,支持 --tool-call-parser minicpm5。
- 自动模板检测:在
template_detection.py 中添加 _is_minicpm5 谓词,并在 TOOL_CALL_PARSER_RULES 中注册 DetectionRule,位于宽泛规则(Mimo/Qwen)之前,避免误匹配。
- 单元测试:为解析器提供单调用、CDATA、多调用、非字符串类型、未知工具等测试用例;为模板检测添加规则优先级测试。
- CI 注册:测试文件通过
register_cpu_ci 注册到 CPU CI 任务。
关键文件:
python/sglang/srt/function_call/minicpm5_detector.py(模块 解析器核心;类别 source;类型 core-logic;符号 MiniCPM5Detector, init, has_tool_call, detect_and_parse): 核心解析器实现,包含 XML 解析、正则兜底、流式增量解析等关键逻辑
test/registered/unit/function_call/test_minicpm5_detector.py(模块 解析器测试;类别 test;类型 test-coverage;符号 make_tools_weather, make_tools_sum, test_detect_and_parse_single_call_v3, test_detect_and_parse_cdata_multiline_v3): 完整的单元测试套件,覆盖单调用、CDATA、多调用、非字符串类型、未知工具等场景
test/registered/unit/managers/test_template_manager.py(模块 模板管理测试;类别 test;类型 test-coverage;符号 test_minicpm5_rule_precedes_broad_fallback_rules, test_minicpm5_not_misclassified_as_qwen): 新增测试验证 MiniCPM5 自动检测规则优先级,避免被误判为 Qwen 或其他模型
python/sglang/srt/managers/template_detection.py(模块 模板检测;类别 source;类型 core-logic;符号 _is_minicpm5): 添加 _is_minicpm5 谓词并在 TOOL_CALL_PARSER_RULES 中注册,使 auto 检测能识别 MiniCPM5
python/sglang/srt/function_call/function_call_parser.py(模块 函数调用注册;类别 source;类型 dependency-wiring): 注册 MiniCPM5Detector 到解析器映射,使 --tool-call-parser minicpm5 可工作
关键符号:MiniCPM5Detector.init, MiniCPM5Detector.has_tool_call, MiniCPM5Detector.detect_and_parse, MiniCPM5Detector._append_tool_call, MiniCPM5Detector.parse_streaming_increment, get_argument_type, parse_arguments, _is_minicpm5
关键源码片段
python/sglang/srt/managers/template_detection.py
添加 _is_minicpm5 谓词并在 TOOL_CALL_PARSER_RULES 中注册,使 auto 检测能识别 MiniCPM5
# python/sglang/srt/managers/template_detection.py
def _is_minicpm5(ctx):
# 检测逻辑:优先检查词表中是否有专用 token
if ctx.has_vocab("<function") and ctx.has_vocab("<param"):
return True
# 兜底:检查模板中是否包含 XML 函数调用模式
return ctx.has_pattern(r"<function\s+name=") and ctx.has_pattern(r"<param\s+name=")
# 在 TOOL_CALL_PARSER_RULES 元组中注册新规则
TOOL_CALL_PARSER_RULES = (
DetectionRule(name="gemma4", value="gemma4", predicate=_is_gemma4),
DetectionRule(name="gpt_oss", value="gpt-oss", predicate=_is_gpt_oss),
DetectionRule(name="kimi_k2", value="kimi_k2", predicate=_is_kimi_k2),
DetectionRule(name="minimax", value="minimax-m2", predicate=_is_minimax),
DetectionRule(name="interns1", value="interns1", predicate=_is_interns1),
DetectionRule(name="mistral", value="mistral", predicate=_is_mistral),
DetectionRule(name="glm45", value="glm45", predicate=_is_glm45),
# 新增 minicpm5 规则,位于宽泛规则(mimo、qwen)之前,避免误匹配
DetectionRule(name="minicpm5", value="minicpm5", predicate=_is_minicpm5),
DetectionRule(name="xml_kv_tool_call", value="glm45", predicate=_is_xml_kv_tool_call),
DetectionRule(name="mimo", value="mimo", predicate=_is_mimo),
DetectionRule(name="qwen", value="qwen", predicate=_is_qwen3),
DetectionRule(name="deepseek_v3", value="deepseekv3", predicate=_is_deepseek_v3),
DetectionRule(name="deepseek_r1", value="deepseekv3", predicate=_is_deepseek_r1),
)
评论区精华
风险与影响
- 风险:
- 流式 token 分割:若 bot_token 被跨 chunk 分割,可能丢失调用。当前代码通过
_ends_with_partial_token 保留部分前缀以缓解,但仍需更多测试覆盖。
- 自动检测误匹配:如果有其他模型也包含
<function 和 <param token,可能被误判为 MiniCPM5。当前规则置于宽泛规则之前,且测试验证了不被 Qwen 捕获。
- 性能:lxml 解析比正则略重,流式场景中每个 chunk 都触发解析,可能影响首 token 延迟;但仅在处理包含工具调用的响应时触发。
- 依赖:lxml 是可选依赖,fallback 到 stdlib ET 功能一致但 CDATA 保留受限。
- 兼容性:不影响其他模型,但 auto 检测的优先级变化需确保回归覆盖。
- 影响:
- 用户影响:MiniCPM5 用户可使用
--tool-call-parser minicpm5 或 auto 启用工具调用,无需自行编写 parser 或 post-processing。
- 系统影响:FunctionCallParser 增加一个映射项,模板检测增加一个规则,无性能退化。
- 团队影响:后续需维护该 parser,并关注 lxml 依赖是否引入新问题。
- 适用范围:仅 MiniCPM5(MiniCPM-4)V3 Schema。
- 风险标记:流式 token 分割, 自动检测误匹配, lxml 可选依赖, 正则 fallback 边缘情况
关联脉络
参与讨论