执行摘要
本 PR 修复了 Gemma4 在工具调用返回多模态内容(图像、音频、视频)时因模板缺失对应占位符而静默失败的问题。在示例模板中添加了多模态占位符输出逻辑,并新增两个回归测试。变更已与上游 HuggingFace 仓库对齐。
功能与动机
Issue #41452 报告:当工具消息 content 包含 [{"type": "text"}, {"type": "image"}] 时,Gemma4 的 chat_template.jinja 仅提取 type == "text" 的部分,图像/音频/视频条目被直接丢弃且无警告。原因在于模板中遍历 tool_body 的循环只处理了文本块,未处理多模态类型。此 PR 为该问题提供最小修复。
实现拆解
- 模板修复(
examples/tool_chat_template_gemma4.jinja):在现有 {%- for part in tool_body -%} 循环中增加 {%- if part.get('type') == 'image' -%} 等分支,输出 <|image|>、<|audio|>、<|video|> 占位符。这些占位符会被后续多模态处理步骤替换为实际的视觉/音频嵌入。
- 回归测试(
tests/renderers/test_gemma4_chat_template.py):新增两个测试方法 – test_tool_response_with_multimodal_content(单图像)和 test_tool_response_with_all_modalities(三种多模态类型一起),验证渲染后的字符串中包含相应标签。
- 同步上游:与 HF 上已合并的修复同步,解决与 #42188 的冲突,确保 DCO 合规。
模板新增部分(Jinja)
{%- for part in tool_body -%}
{%- if part.get('type') == 'image' -%}
{{- '<|image|>' -}}
{%- elif part.get('type') == 'audio' -%}
{{- '<|audio|>' -}}
{%- elif part.get('type') == 'video' -%}
{{- '<|video|>' -}}
{%- endif -%}
{%- endfor -%}
该片段置于文本块渲染之后,确保多模态占位符出现在
<tool_response> 块内。
测试代码(Python)
def test_tool_response_with_multimodal_content(self, gemma4_template):
messages = [
{"role": "user", "content": "Download the image and describe it."},
{"role": "assistant", "content": "", "tool_calls": [{"id": "call_1", ...}]},
{"role": "tool", "tool_call_id": "call_1",
"content": [{"type": "text", "text": "Image downloaded successfully."},
{"type": "image"}]},
]
result = _render(gemma4_template, messages, add_generation_prompt=True)
assert "<|image|>" in result
两个测试用例分别覆盖单多模态和全部三种模态类型。
评论区精华
- 上游同步:维护者 @bbrowning 建议保持与 HF 官方模板一致,作者在 HF 提交修复并已合并。
- API 规格:@bbrowning 提醒 Chat Completions API 仅允许文本,Responses API 才允许多模态;需要确保模板在 Responses 路径下正确工作。作者表示已关注。
- 测试必要性:@lucianommartins 询问仍需本 PR 的原因,作者解释离线用户不会自动获取 HF 更新,且测试直接加载本地模板,因此示例模板的修复仍有必要。
风险与影响
- 风险:极低。仅 Jinja 模板变更,不涉及核心推理路径。新增测试覆盖了多模态 case,回退场景存在。
- 影响:用户使用
--chat-template examples/tool_chat_template_gemma4.jinja 并启用工具调用时,能正确处理多模态 tool response;其他用户无影响。
关联脉络
- 直接关联 Issue #41452。
- 与 HuggingFace 上的 Gemma4 模板修复同步(4 个模型 variant)。
- 与 #42188 产生合并冲突,经协调解决。
- 后续可关注:Responses API 对多模态 tool response 的支持完善。
参与讨论