
【免费下载链接】AREX-Turbo项目地址https://ai.gitcode.com/BAAI/AREX-Turbo点击查看免费下载AREX-Turbo 是 BAAI北京智源人工智能研究院发布的 4B 深度研究 Agent 模型其 chat_template.jinja 采用XML 工具调用协议靠tool_call、tool_response、think三组标签撑起 256K 长对话中的多轮工具执行。本文将这份 154 行的 Jinja2 模板逐块拆解帮助新手快速看懂协议设计与用法。1. 为什么 AREX-Turbo 用 XML 做工具调用很多人默认函数调用 JSON。但 AREX-Turbo 基于 Qwen3.5-4B 骨干见 config.json 中model_type: qwen3_5该系列在聊天模板中采用的是纯文本XML 协议模型直接用标签写出函数调用。对深度研究deep research这种动辄几十轮工具调用的场景XML 方案有三个明显好处标签稀疏协议标签已预先注册为独立词元见 tokenizer_config.jsontool_call、think对应 248058–248069 号 token每个标签只占 1 个 token输出稳定、开销小人类可读长对话里 XML 文本比嵌套 JSON 更容易肉眼排查规则可写进提示词模板能把工具定义和调用格式直接注入 system 提示模型照示例学规则无需额外训练适配。2. 模板在哪里如何生效模板文件就是仓库根目录的 chat_template.jinja同样内容也内嵌在 tokenizer_config.json 中。用 transformers、vLLM 或 SGLang 加载模型时会自动读取无需手工干预。推荐部署命令见 inference/README.mdvllm serve . \ --served-model-name AREX-Turbo \ --tensor-parallel-size 1 \ --max-model-len 262144 \ --reasoning-parser qwen3 \ --language-model-only其中--reasoning-parser qwen3让服务端把think推理块从模型输出中拆到独立字段正文更干净。3. 逐块全解析6 个部分各自干什么模板可拆成 6 个部分先给一张全景表模板块行号作用计数器与render_content宏L1–L41统计图片/视频数把消息内容转成文本空消息校验L42–L44messages为空时直接报错工具声明块L45–L66向 system 注入toolsJSON 与 XML 调用示例反向扫描L67–L80找到最后一次真实用户提问决定推理块出现在哪主渲染循环L81–L146按 user / assistant / tool 角色渲染消息生成提示L147–L154输出assistantthink为模型留好续写位置3.1 计数器与渲染宏L1–L41对应 chat_template.jinja#L1-L41L1–L2 用 Jinja2 的namespace定义可变计数器image_count、video_countJinja2 循环内无法直接重赋值变量必须借助namespace变通L3–L41 定义核心宏render_content负责把消息内容转成文本纯字符串 → 原样输出列表 → 逐项处理图片 →img视觉 token视频 →video视觉 token开启add_vision_id时额外加 Picture N: 前缀文本 → 直接输出system 消息禁止包含图片/视频违反则raise_exception直接报错空内容 → 空字符串。虽然 AREX-Turbo 主打文本文档研究模板仍保留了完整的多模态渲染能力视觉 token 定义见 config.jsonimg248056、video248057。3.2 参数校验L42–L44对应 chat_template.jinja#L42-L44messages为空时抛出No messages provided.避免悄悄生成空提示词。3.3 工具声明块协议从这里开始L45–L66对应 chat_template.jinja#L45-L66。只要传入了tools数组模板就先输出一段固定 system 块渲染后大致如下system # Tools You have access to the following functions: tools {type: function, function: {name: search, ...}} {type: function, function: {name: visit, ...}} /tools If you choose to call a function ONLY reply in the following format with NO suffix: tool_call functionexample_function_name parameterexample_parameter_1 value_1 parameter function IMPORTANT Reminder: - Function calls MUST follow the specified format ... IMPORTANT system四个关键点工具定义以JSONtojson渲染塞进tools紧跟着一个XML 调用示例把输出格式钉死tool_call→function名称→parameter参数名→ 值 →parameter→function→tool_call且明确NO suffix——调用之后不许再写字IMPORTANT提醒块强调必填参数必须给全、推理说明只能写在调用之前若首条消息是 system其内容会被拼接进这个工具块否则走普通 system 渲染。这一段就是让模型遵守 XML 协议的规则手册——不靠模型自觉而是把规则明写在提示词头部。3.4 反向扫描定位最后一次真实用户提问L67–L80对应 chat_template.jinja#L67-L80是全模板最绕的一段初始化multi_step_tooltrue假设当前处于多轮工具执行中与last_query_index从后往前扫消息找最后一条内容不是单纯tool_response的 user 消息——也就是真正的用户提问若所有 user 消息都只是工具结果抛错No user query found in messages.。为什么需要它因为模板只在最后一次真实提问之后的 assistant 轮次渲染think推理块更早的历史 assistant 消息只渲染正文。这样旧轮次的推理过程不会残留在上下文里干扰当前推理。3.5 主循环按角色渲染L81–L146对应 chat_template.jinja#L81-L146userL87–L88最朴素user\n{内容}\n。assistantL89–L130推理文本优先取reasoning_content字段否则从正文里把think…think之间的内容抽出来L90–L99若该轮位于最后一次真实提问之后输出assistant\nthink\n{推理}\nthink\n\n{正文}否则只输出正文L100–L104若消息带tool_calls逐个渲染成 XML 块外层tool_call内层function名称每个参数一对parameter参数名参数序列化规则L119–L127对象/数组统一tojson成 JSON 文本标量直接转字符串——这决定了下游解析器要先尝试json.loads失败再当纯文本。toolL131–L142——XML 协议最有特色的设计工具结果没有独立角色而是折叠进user块user tool_response {工具真实返回} tool_response user连续多条 tool 消息共享同一对user包裹上一条不是 tool 才开user下一条不是 tool 或已到末尾才闭合。工具返回与用户发言共用同一角色边界模型只需学会一对角色标签在长对话中更稳、更省 token。3.6 生成提示为模型留好舞台L147–L154对应 chat_template.jinja#L147-L154。当add_generation_prompttrue时模板以如下内容收尾assistant think模型于是自然地在think内继续推理随后输出工具调用或最终答案。若enable_thinkingfalse则改为think 空行 think 空行——留一个空推理块模型跳过思考直接作答即非思考模式。4. 完整 XML 协议一览把上面拼起来一次深度研究对话经模板渲染后的样子简化user Question: Qwen3.5 是什么时候发布的 user assistant think 先批量搜两个角度。 think tool_call functionsearch parameterquery [Qwen3.5 发布时间, Qwen3.5 technical report] parameter function user tool_response 1. Qwen3.5 技术报告example.com/report tool_response user assistant think 第一条是权威来源打开全文确认。 think tool_call functionvisit parameterurl https://example.com/report parameter parametergoal 确认 Qwen3.5 的发布日期 parameter function核心标签速查表标签方向作用think/think模型输出推理块非思考模式渲染为空块跳过tool_call/tool_call模型输出函数调用容器function名称模型输出函数名嵌套在tool_call内parameter参数名模型输出单个参数对象/数组值为 JSON 文本tool_response/tool_response工具结果工具真实返回包裹在user块中配套的调用纪律写在 inference/prompts.py 的提示词里每一步最多调一个工具、工具调用后不许再写字、finish与update_context只能单独调用——模板负责格式提示词负责纪律。5. 实战要点第一次就用对协议对话循环模型吐出tool_call后你的程序执行工具把模型输出作为 assistant 消息、把工具结果作为tool角色消息追加进历史——user包裹和tool_response标签由模板自动完成不要手工拼标签。最小示例见 inference/inference.py。⚠️参数解析parameter内容可能是 JSON 也可能是纯文本chat_template.jinja#L119-L127解析时先json.loads失败再退回字符串。⚠️常见坑system 消息里放图片/视频会直接报错连续的 tool 消息要保持连续不要中间插别的角色工具调用之后再写任何文字都会破坏协议。提示词复用BrowseComp 的 system/user 提示词工具描述已内嵌直接从 inference/prompts.py 导出BROWSECOMP_SYSTEM_PROMPT/BROWSECOMP_USER_PROMPT.format(question...)即可组装首轮消息。6. 总结这份模板的设计哲学可以概括为一句话规则写进提示词头部推理放在工具调用之前工具结果折叠进用户消息。think/tool_call/tool_response三层标签正是 AREX-Turbo 这个 4B 小模型能在 256K 上下文里完成多轮深度研究search、visit、update_context、finish的地基。读懂它之后无论是自建 Agent 部署还是把同一协议迁移到其他 Qwen3.5 系模型都有据可依。 参考文件模板本体chat_template.jinja特殊 token 定义tokenizer_config.json模型配置config.json部署与推理说明inference/README.mdBrowseComp 提示词与工具定义inference/prompts.py最小推理脚本inference/inference.py项目介绍与评测README.md赞分享【免费下载链接】AREX-Turbo项目地址https://ai.gitcode.com/BAAI/AREX-Turbo点击查看免费下载相关推荐chat_template.jinja 逐行拆解Fara1.5-27B-OptiQ-4bit 的工具调用协议与多模态消息渲染原理chat_template.jinja 逐行拆解Fara1.5 27B OptiQ 4bit 的工具调用协议与多模态消息渲染原理 Fara1.5 27B Op大模型人工智能多模态模型量化本地部署AI Agent从 Jupyter 迁移到 marimo执行模型、变量作用域与文件格式的完整适配指南从 Jupyter 迁移到 marimo执行模型、变量作用域与文件格式的完整适配指南 marimo 是面向 Python 的响应式reactive笔记本大模型模型量化模型优化本地部署人工智能chat_template.jinja 逐行注解Nemotron-Labs-3-Competitive-Coding 的 enable_thinking 与工具调用机制chat_template.jinja 逐行注解Nemotron Labs 3 Competitive Coding 的 enable_thinking 与工上一篇KeyStore Explorer多平台部署Windows、macOS和Linux完整教程下一篇Fontsource终极多语言字体支持指南中文、日文、韩文字体处理技巧创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考