【免费下载链接】IQuest-Q1
IQuest-Q1 Chat Template 决定了这款 320B 参数 MoE 大模型“如何说话、如何调用工具、如何思考”。本文带你读懂 IQuest-Q1 对话模板的两大核心——自定义 XML 工具调用格式与reasoning推理块,一文讲清特殊 Token、生成配置与模板渲染原理。
Chat Template 是什么:模型的“说话规则书”
Chat Template(对话模板)是一套用Jinja2编写的渲染规则:它把一条条messages(用户、助手、工具的消息列表)拼成模型真正能读懂的 token 文本流。
可以把它理解为模型的说话规则书——角色谁先谁后、工具怎么声明、推理怎么包裹,全部写死在这份模板里。IQuest-Q1 的完整规则就放在仓库根目录的 chat_template.jinja,配合 config.json 与 generation_config.json 一起工作。
💡 一句话:模型不“认识”JSON 或 Python,它只认识模板渲染出来的那串特殊符号。所以模板写得对不对,直接决定 Agent 能不能顺利调工具、能不能把思考过程隔离出来。
IQuest-Q1 是面向Agentic Coding、推理与多步工具调用的模型,因此它的模板特别为“长链条工具调用”做了优化。
特殊 Token 体系:模型的“对话标点符号”
模板里反复出现的<|...|>就是 IQuest 自研的特殊 Token,它们在 tokenizer_config.json 与 special_tokens_map.json 中注册为词表里的独立 token(vocab_size = 160000)。
| 特殊 Token | 作用 | 通俗理解 |
|---|---|---|
<\|iquest_system\|> | 系统 / 开发者指令段起点 | “这是后台规则” |
<\|iquest_user\|> | 用户消息起点 | “用户说” |
<\|iquest_assistant\|> | 助手回复起点 | “模型答” |
<\|iquest_tool\|> | 工具执行结果起点 | “工具跑完返回” |
<\|iquest_developer\|> | 开发者(更高优先级)指令 | “开发者插话” |
<\|iquest_end\|> | 每段结束,同时是eos / pad标记 | “这段说完了” |
其中<|iquest_end|>身兼三职:它是段落结束符、结束符 eos_token_id(在 config.json 中对应 id0)和填充符pad_token_id。这意味着模型一旦“说完一段”,就会自然吐出这个 token 来收尾——非常利于流式解析器切分。
渲染一条普通消息时,结构就是“角色 token + 内容 + 结束 token”,例如:
<|iquest_user|>今天北京天气如何?<|iquest_end|>工具调用格式:<iquest_tool_call>的 XML 设计
IQuest-Q1 没有采用常见的 JSON 数组式工具调用,而是用了一套紧凑的 XML 风格,在 chat_template.jinja#L1-L71 中定义。
工具如何被“翻译”成 Python 风格描述
当请求里带上了tools,模板会先注入一段系统提示,把每个工具函数渲染成类 Python 的函数签名 + docstring(见 chat_template.jinja#L25-L68):
<|iquest_system|> # Tools You have access to the following functions: <tools> def get_weather(city: str, unit: str = None) -> any: 获取指定城市的实时天气 Args: city (str): 城市名称 unit (str, optional): 温度单位 """ </tools> For each function call, output the function name and arguments within the following XML format: <iquest_tool_call>{function-name}<arg_key>...</arg_key><arg_value>...</arg_value></iquest_tool_call> <|iquest_end|>这个设计有两个巧妙之处:
- 必填 vs 可选一目了然:不在
required里的参数会被自动补= None,并标注, optional。 - 扩展字段自动兜底:模板里的
render_extra_keys宏(chat_template.jinja#L14-L24)会把type / properties / required之外的任意额外字段,用<key>...</key>标签兜底渲染,保证工具描述不丢信息。
一次工具调用的完整文本长什么样
助手发起调用时,content与tool_calls会被拼在同一个 assistant 段内(chat_template.jinja#L131-L155),每个参数用一对<arg_key>/<arg_value>表示:
<|iquest_assistant|> </think><iquest_tool_call>get_weather<arg_key>city</arg_key><arg_value>北京</arg_value></iquest_tool_call><|iquest_end|>工具执行完,结果以role: "tool"回填,用<tool_response> ... </tool_response>包裹(chat_template.jinja#L156-L184):
<|iquest_tool|> <tool_response> {"city": "北京", "temp": 25} </tool_response><|iquest_end|>最后助手给出面向用户的自然语言回答:
<|iquest_assistant|> </think>今天北京的温度是 25 度。<|iquest_end|>📌 为什么用 XML 而不是 JSON?XML 标签顺序固定、边界清晰、无需转义引号,对自回归生成更友好,解析器也更容易在流式输出中“边收边判”,非常适合多步 Agent 场景。
两个进阶能力:多工具合并 & 工具引用
- 连续工具结果合并:若连续多条
tool消息,模板只在第一条前加一次<|iquest_tool|>、在最后一条后加一次<|iquest_end|>(chat_template.jinja#L157-L184),中间各自保留<tool_response>,省 token 又不歧义。 tool_reference按需引用:当工具结果里声明引用了某些工具(tool_reference),模板会调用tool_to_json宏(chat_template.jinja#L2-L13)把对应工具定义序列化成 JSON 一并写回上下文,跳过defer_loading、strict等内部字段。
reasoning 推理块:think标签的实现原理
IQuest-Q1 把“思考过程”和“正式回答”严格分离,核心就是think/end这对标签。
think与reasoning_content的对应关系
渲染助手消息时,模板会先确定“推理内容”从哪来(chat_template.jinja#L102-L110):
- 显式传入:若消息带有
reasoning_content字符串,直接用它; - 自动拆解:若没有该字段、但正文里出现了
end,就从正文中切出think之后到end之前的内容作为推理,剩余部分作为正式回答; - 空推理:若既无字段也无标签,则填空串。
随后按“先推理块、再正文/工具调用”的顺序拼接(chat_template.jinja#L111-L155):
<|iquest_assistant|> </think> 今天北京的温度是 25 度。 <|iquest_end|>推理块与正文在 token 层面被think/end明确切开,服务端(SGLang / vLLM 的--reasoning-parser iquest_q1)就能据此把推理流式地分流到独立的 reasoning 通道,而不污染最终答案。
三个控制开关:推理该不该“露出来”
模板还内置了若干推理策略开关,都是面向推理服务与 Agent 框架的:
enable_thinking:生成提示时,true输出think(模型自由思考);false直接输出think end(跳过思考,直接作答),见 chat_template.jinja#L191-L193。clear_thinking(历史压缩):置为true时,会把较早轮次的推理块替换成空的think end,只保留最近一轮(最后一条 user 之后)的思考。这样在多轮 Agent 长跑里能大幅省 token,又不丢失当下最相关的推理线索(chat_template.jinja#L111 的loop.index0 > ns.last_user_index判断)。add_generation_prompt:为 true 时在末尾补一个带think的 assistant 起点,提示模型“轮到你了”。
🧠 这套
think+ 历史压缩机制,正是长程 Agent“边思考边省 token”的关键。
多模态兜底与训练掩码:模板的另一面
多模态占位:visible_text宏(chat_template.jinja#L72-L91)统一处理内容。由于该 checkpoint 是纯文本模型,遇到image / video / audio等内容块时,不会报错,而是插入一条<reminder>占位,提示“我无法处理该多模态输入,请换方法”——这与 README 里“tokenize 时把多模态内容替换为占位符”的说明一致。
训练掩码:模板里还有content_mask、reasoning_content_mask、boundary_token_mask以及{%- generation -%}等特殊标记,用于在 SFT / RL 训练时精确控制哪些 token 参与损失计算。也就是说,同一份chat_template.jinja既是推理模板,也是训练模板,做到了训练-推理一致,避免“训推不一致”导致的工具调用翻车。
生成配置:温度、top-p 与 top-k 怎么选
generation_config.json 给出了官方推荐采样参数,与 README.md 的基准测试建议完全对齐:
| 参数 | 值 | 说明 |
|---|---|---|
do_sample | true | 启用采样 |
temperature | 1.0 | 温度,保持原始分布 |
top_p | 0.95 | 核采样阈值 |
top_k | 20 | 只在最优 20 个 token 中采样 |
eos_token_id | [0] | 即<\|iquest_end\|> |
pad_token_id | 0 | 填充符同上 |
trust_remote_code | true | 依赖自定义模型代码 |
⚙️ 复现官方跑分(如 SWE / 终端基准)时,建议就采用
temperature=1.0, top_p=0.95, top_k=20,这是团队验证过的稳定组合。
相关文件清单
如果你想深入源码,下面这些文件是理解 IQuest-Q1 模板行为的“钥匙”:
- 对话模板主文件:chat_template.jinja —— 工具调用、推理块、特殊 Token 全部在此
- 模型结构配置:config.json —— 88 层、256 专家(激活 8)、512K 上下文
- 生成/采样配置:generation_config.json
- 分词器与特殊 Token:tokenizer_config.json、special_tokens_map.json
- 投机解码草稿模型(MTP)配置:mtp/config.json
- 模型规格与部署说明:README.md
小结
IQuest-Q1 的 Chat Template 是一份为Agentic Coding 与多步工具调用量身定制的规则书:
- 用
<|iquest_*|>特殊 Token清晰切分角色; - 用XML 风格
<iquest_tool_call>+<arg_key>/<arg_value>让工具调用稳定可解析; - 用
think推理块 +clear_thinking历史压缩隔离思考、节省 token; - 用统一的
chat_template.jinja同时服务训练与推理,保证训推一致。
读懂这份模板,你就掌握了 IQuest-Q1 行为的一半秘密——另一半在 config.json 的架构设计里。
【免费下载链接】IQuest-Q1
相关推荐
Gemma-4 Chat Template 深度解析:工具调用与思考通道如何实现
Gemma 4 Chat Template 深度解析:工具调用与思考通道如何实现 Gemma 4 E2B 的官方 Chat Template 采用 Jinja
IQuest-Q1推理加速全攻略:MTP多token预测与EAGLE投机采样原理详解
IQuest Q1推理加速全攻略:MTP多token预测与EAGLE投机采样原理详解 IQuest Q1 是 IQuest 面向 agentic coding、
深度拆解 MiniCPM5-2B-chat-mlx-16bit 的 Chat Template:工具调用与思维链背后的机制
深度拆解 MiniCPM5 2B chat mlx 16bit 的 Chat Template:工具调用与思维链背后的机制 MiniCPM5 2B chat m
大模型本地部署模型量化openBMB
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考