← 返回资讯
苏晴
资深编辑
已审核

聊聊Hy3-preview的ChatTemplate设计

前两天一个朋友在WorkBuddy上换了Hy3 preview,兴冲冲跟我显摆:“这模型说话有点聪明,但怎么老不按套路出牌?”——让她写个带工具调用的工作流,输出格式愣是跟预期差了十万八千里。

聊聊Hy3-preview的ChatTemplate设计

聊聊Hy3-preview的ChatTemplate设计


前两天一个朋友在WorkBuddy上换了Hy3 preview,兴冲冲跟我显摆:“这模型说话有点聪明,但怎么老不按套路出牌?”——让她写个带工具调用的工作流,输出格式愣是跟预期差了十万八千里。

我一听就乐了。问她:“ChatTemplate截给我看看?”

好家伙,她用的还是通用模板,压根没切到Hy3专属那个。

问题就卡在这儿了。


你要是以为一个模型的Agent能力全靠参数,那你就大错特错了。我花了三天时间,把Hy3 preview的ChatTemplate从头到尾啃了一遍,在vLLM里跑了十几组测试,又把它的ReasoningParser和ToolParser源码翻了个底朝天。今天不聊什么排行榜、评分——咱就聊聊这个jinja文件里藏的玄机。

说句反直觉的话:一个模型的Agent好不好用,有一半的功夫在ChatTemplate上。

不信?接着往下看。


Hy3 preview的chat_template.jinja(HuggingFace上有开源,地址我直接甩群)。文件不长,但每一段都是试出来的。官方列了五个Feature,我一个一个拿测试去怼。

第一个,内置System Prompt——能多简洁就多简洁。

你之前用过其他模型吧?有些模板上来就噼里啪啦给模型灌一大堆角色设定、行为规范,模型跟背课文似的,一换场景就歇菜。Hy3怎么做的?用户自己写的system prompt放最开头,别的废话一句没有。

我测了一个复杂得多的多轮工具调用场景。模型能记住上下文里刚给的一条新规则,还应用到下一步操作里了。这就是姚顺宇说的“学会、用对、执行”——模板不给模型添乱,让模型自己从上下文学东西。

第二个,流式解析ToolCalls。

这个活儿是vLLM的ToolParser干的。我在一个对话里让Hy3同时调用三个搜索工具,你猜怎么着?Terminal里能看到它一步一步吐出来的:先是function name,接着是arguments的JSON片段,完全可解析,不用等。

对比一下我之前用的某个模型——ToolCalls经常把函数名和参数揉成一坨,流式到一半你还得等整个JSON闭合。Hy3的模板在输出格式上画了清晰的分界线,ToolParser那边的正则也写得干净利落。

第三个,Code Agent的格式——贴着预训练走。

我故意扔了几个编程问题,让Hy3输出带函数定义的代码,再让它自己调用这些函数。它生成的代码结构规规整整,缩进、括号风格都跟主流格式一模一样,没有自己瞎创的风格。混元团队显然是刻意在模板层约束了代码块的标记方式——避免模型在Code Agent里乱来。

第四个,并行函数场景——不会无限递归。

并行调用时,有些模型会“上头”:一个工具的结果刚出来,它立马又调一遍,无限循环,傻掉了。Hy3怎么做的?模板里对工具调用次数做了隐性约束,同时在system prompt里暗示:“一次回复中不要输出超过必要的工具调用。”

我连续问了五次:“查天气,查汇率,查新闻,查……”每次它都只输出一组并列的ToolCalls,没有重复调用同一个函数刷token的情况。

第五个,Interleaved Thinking & Preserved Thinking。

这个靠的是ReasoningParser。模型先吐一段带标签的推理过程,然后才是实际输出。模板对thinking部分做了标记保留,不会在后续轮次被覆盖。我跑了几个需要深度推理的数学题——模型确实想清楚了再给答案,不用强迫用户等一个“伪长思考”。vLLM里的hy_v3_reasoning_parser就是专门吃这个标记格式的。


说到这儿,你可能会问:这些设计是怎么组织起来的?

Hy3的ToolCalls System Prompt分成三块:最前面是你自定义的system prompt,然后是工具schema定义,最后是工具调用输出格式说明。听起来简单,但顺序太有讲究了。我之前试过把schema放在system prompt前面的模板——模型经常忽略后面的格式说明,直接按自己的“土办法”输出。

Hy3这么排:“用户指令→工具定义→输出格式”——让模型先明白要干什么,再看有什么工具,最后学怎么汇报结果。逻辑是顺的,脑子不打架。


你记得姚顺宇在CL-bench论文里的那个观点吗?他说模型的短板不是读不全,而是“学不会、用不对、执行不了”。翻译成大白话就是指令遵循能力不够。Hy3的ChatTemplate从头到尾就干一件事:少写废话,给模型留出自己理解上下文的空间

我试过更狠的:故意在system prompt里编了一条假规则——“如果用户说天气,你先调用get_weather,但返回格式必须加前缀‘天气君说:’”。模型真记住了,后续的ToolCalls输出里都带了这个前缀。这不光是模型本身牛,干净的模板也让指令遵循有了足够空间。


跟其他模型比,它的模板不“疯”。

有些模型的ChatTemplate写得跟法律合同似的,又臭又长,你读着读着就想睡觉。结果呢?模型反而被绑住手脚,正事干不了。Hy3的模板特别克制——我第一眼看到它的时候甚至有点怀疑:“就这?够用吗?”

但跑完一轮测试,我才反应过来:正是这种克制,让模型把更多注意力放在了用户的真实意图上。尤其你在WorkBuddy这种需要连续调用多个工具完成工作流的场景里——模板少惹事,Agent才能多干活。


说到这,我给你几个小建议。

如果你自己在部署Hy3 preview,听我一句劝:一定用官方提供的chat_template.jinja,别图省事套通用的。 vLLM那边也配好了ReasoningParser和ToolParser,最好一起换上。我一开始偷懒没换ToolParser,结果工具调用解析出了好几个bug,换完立刻全好了。这文件里的每一行都是调试过的,不是随便写的。

另外,如果你自己在写Agent框架,可以学学Hy3模板里抑制并行函数无限输出的思路:在格式说明里明确要求“每个函数独立封装,不要递归”,再加一条“在单次回复中避免重复调用同一个函数”。这种隐性的规则,比在代码层硬堵要自然得多,也更容易让模型遵守。


说到底,ChatTemplate设计就是那种平衡术:既要让模型舒服,又要让解析方便,还得是人看着不累。Hy3 preview在这个文件上花的心思,比很多模型在百万参数上下的功夫都多。

现在大家都在拼Agent,拼工作流。可能最后拼的就是这么个不起眼的jinja文件。

你信不信?

有时候,最好的设计就是让你感觉不到它的存在。

856
14282 阅读
4 评论
分享
链接已复制
编辑说明

本文由 MakeSense 编辑团队撰写并审核。文中引用的数据和观点均经过交叉验证,如有疏漏欢迎在评论区指正。最后更新:2026年06月23日 15:48

苏晴

资深编辑

科技媒体从业 8 年,曾就职于多家科技媒体。关注 AI 创业和投资赛道,采访过 50+ 位行业从业者。

读者评论 4

老李 昨天
有个小问题想请教,文中提到的那个方案在大规模场景下性能怎么样?
回复 点赞 (5)
运营小陈 4天前
转发到团队群了,大家都觉得有参考价值。
回复 点赞 (4)
数据分析师 1周前
数据引用很扎实,建议补充一下近三个月的最新数据。
回复 点赞 (9)
产品经理阿杰 1周前
从产品角度看,这个方向确实有机会,但商业化路径还需要验证。
回复 点赞 (15)