Prhub

#43872 [Rust Frontend] Add `hy_v3` tool parser

原始 PR 作者 BugenZhao 合并时间 2026-05-28 22:42 文件变更 6 提交数 2 评论 0 代码增减 +583 / -7

执行摘要

添加 hy_v3 工具解析器,支持 HY3 模型工具调用

需要为上游 HY3 模型(如 tencent/Hy3-preview)提供 Rust 前端的工具调用解析支持。现有解析器不兼容 HY3 的 XML 标记格式,因此新增 HyV3ToolParser。

值得精读。该 PR 展示了如何以最小代价在已有架构下新增工具解析器:复用 ToolSchema 转换和 parse_buffered_event 工具,同时灵活处理非标准类型别名。对后续支持类似 XML 格式模型有参考价值。

讨论亮点

无 review 评论;PR 由 njhill 直接批准合并,实现符合预期。

实现拆解

  1. 新建 hy_v3.rs:定义 HyV3Mode、HyV3Event 等类型,基于 winnow 实现解析器,识别 块中的 条目,提取 / 对。
  2. 扩展 parameters.rs:在 from_type_name 中增加 "double" / "map" / "list" 的映射,以兼容 HY3 的 schema 类型名称。
  3. 模块导出:在 tool-parser 的 lib.rs 中声明 hy_v3 模块并公开 HyV3ToolParser。
  4. 注册解析器:在 chat 的 mod.rs 中注册 parser 名称 "hy_v3" 和模型匹配模式 "hy3" / "hy_v3",并将 HyV3ToolParser 接入工厂。
  5. 测试更新:在 chat 的 tests.rs 中添加 tencent/Hy3-preview 模型解析测试,更新 lib.rs 中的 expect_test 快照。
文件 模块 状态 重要度
rust/src/tool-parser/src/hy_v3.rs 解析器 added 8.89
rust/src/tool-parser/src/parameters.rs 参数 modified 5.8
rust/src/chat/src/parser/tool/mod.rs 注册层 modified 5.2
rust/src/chat/src/parser/tool/tests.rs 测试 modified 4.5
rust/src/chat/src/lib.rs 前端 modified 4.09
rust/src/tool-parser/src/lib.rs 导出层 modified 3.92

关键符号

HyV3ToolParser::new HyV3ToolParser::apply_event HyV3ToolParser::parse_into HyV3ToolParser::finish parse_next_hy_v3_event parse_text_event parse_tool_block_event parse_tool_call parse_arg_pair

关键源码片段

rust/src/tool-parser/src/parameters.rs core-logic

扩展参数类型别名映射,增加 double、map、list 以兼容 HY3 schema 类型名称。

// 在 from_type_name 函数中,本次 PR 增加了以下三行以支持 HY3 的类型别名
// ( 原 "number" | "float" 后添加 "double",原 "object" 后添加 "dict" | "map",原 "array" | "arr" 后添加 "list")
fn from_type_name(kind: &str) -> Option<Self> {
    let kind = kind.trim().to_ascii_lowercase();
    match kind.as_str() {
        "string" | "str" | "text" | "varchar" | "char" | "enum" => Some(Self::String),
        "integer" | "int" => Some(Self::Integer),
        // 增加 "double" 映射为 Number
        "number" | "float" | "double" => Some(Self::Number),
        "boolean" | "bool" | "binary" => Some(Self::Boolean),
        // 增加 "map" 映射为 Object
        "object" | "dict" | "map" => Some(Self::Object),
        // 增加 "list" 映射为 Array
        "array" | "arr" | "list" | "sequence" => Some(Self::Array),
        "null" => Some(Self::Null),
        _ if kind.starts_with("int")
            || kind.starts_with("uint")
            || kind.starts_with("long")
            || kind.starts_with("short")
            || kind.starts_with("unsigned") =>
        {
            Some(Self::Integer)
        }
        _ if kind.starts_with("num") || kind.starts_with("float") => Some(Self::Number),
        _ if kind.starts_with("dict") => Some(Self::Object),
        _ if kind.starts_with("list") => Some(Self::Array),
        _ => None,
    }
}
// 对应的测试:验证新增类型名称的转换正确性
mod tests {
    #[test]
    fn converts_supported_types() {
        let params = ToolSchema::from_schema(&json!({
            "type": "object",
            "properties": {
                // 原有类型 ...
                "ratio": { "type": "double" }, // 新增
                "mapping": { "type": "map" }, // 新增
                "names": { "type": "list" }, // 新增
            }
        }));
        assert_eq!(params.convert("ratio", "2.5"), json!(2.5));
        assert_eq!(params.convert("mapping", r#"{"k":1}"#), json!({"k":1}));
        assert_eq!(params.convert("names", r#"["a","b"]"#), json!(["a", "b"]));
    }
}

评论区精华

没有提炼出高价值讨论线程

当前评论区没有形成足够清晰的争议点或结论,后续有更多讨论时会体现在这里。

风险与影响

新增解析器仅影响 Rust 前端工具解析流程,与 Python 后端隔离。主要风险包括:HY3 标记并非 tokenizer special token,parse_into 可能因模型输出异常格式导致解析失败(已测试覆盖 malformed input);参数类型别名扩展不影响已有解析器。尚无集成测试覆盖完整模型调用链。

对使用 HY3 模型的用户,工具调用功能可用;对其他模型无影响。团队需后续维护 HY3 相关 issue。影响程度中等。

新增解析器缺少集成测试 依赖模型输出格式稳定性

关联 Issue

未识别关联 Issue

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

完整报告

参与讨论