Discrepancy between how `history` is treated for streaming/non-streaming `gr.ChatInterface`

这个报错发生在 Gradio gr.ChatInterface 中,当你在聊天函数内部修改 history 时,流式(streaming)与非流式(non-streaming)模式的修改结果不一致。优先排查你使用的是生成器(yield)还是普通函数(return),因为两者的历史记录处理路径不同。

快速结论:这个报错发生在 Gradio gr.ChatInterface 中,当你在聊天函数内部修改 history 时,流式(streaming)与非流式(non-streaming)模式的修改结果不一致。优先排查你使用的是生成器(yield)还是普通函数(return),因为两者的历史记录处理路径不同。

适用环境:Gradio 6.22.0(bf3b4e39c)已确认复现,最新发布版 6.23.1 仍存在。Python 3.12+ 环境,不涉及 CUDA、显卡等硬件依赖。

最快修复方案:暂无确认的一步修复方案;官方已在 PR #13742 中修复,可等待合并或使用对应 wheel 包验证。

注意事项:该修复同时解决 #10823 和 #11331 两个问题;在官方发布修复前,不建议依赖在聊天函数内直接修改 history 来注入消息或元数据。

问题场景

当你在 gr.ChatInterface 的聊天函数中直接修改 history 参数(例如追加一条 assistant 消息),并通过 save_history=True 保存对话时,会发现修改结果取决于该函数是普通函数(非流式)还是生成器(流式)。这导致无法可靠地通过修改 history 来注入元数据或附加消息。

报错原文

Discrepancy between how `history` is treated for streaming/non-streaming `gr.ChatInterface`
non-streaming: [{'role': 'assistant', 'content': 'INJECTED BY FN'},
                {'role': 'user', 'content': 'hi'},
                {'role': 'assistant', 'content': 'reply'}]
streaming:     [{'role': 'user', 'content': 'hi'},
                {'role': 'assistant', 'content': 'reply'}]

原因分析

核心原因在于 _append_message_to_history 函数会执行 history = list(history) 重新绑定一个全新的列表,而流式与非流式路径执行此操作的时间点不同:

  • 非流式(_submit_fn:先等待 self.fn(...) 执行完毕,再调用 _append_message_to_history。因此函数内部对 history 的修改发生在列表被复制之前,修改结果会被保留。
  • 流式(_stream_fn:先创建生成器(此时函数体尚未执行),然后调用 _append_message_to_historyhistory 重新绑定为新列表,最后才推进生成器。生成器内部修改的是原始列表(已被丢弃的那个),所以修改被静默丢弃,不会反映到最终结果中。

这个问题源于两条代码路径对 history 的处理顺序不一致,是 Gradio 内部实现差异导致的,而非用户代码错误。

环境排查

  • 确认 Gradio 版本:6.22.0bf3b4e39c)已确认复现,6.23.1 仍存在。
  • 检查 gr.ChatInterface 使用的是普通函数(return)还是生成器(yield)。
  • 确认 save_history=True 是否开启——该问题在使用历史保存时影响更明显(元数据注入需求)。

解决步骤

  1. 复现验证:使用 Issue 中提供的最小复现代码,分别用普通函数和生成器测试,确认输出差异。
  2. 检查修复状态:如果 Gradio 版本已包含 PR #13742 的修复,升级后验证行为是否一致。
  3. 临时规避方案(可优先尝试):在聊天函数外部管理需要注入的元数据,不要依赖直接修改 history;或将流式函数改为非流式(用 return 替代 yield)作为临时手段,但需注意这可能影响流式输出体验。
  4. 跟踪官方发布:关注 Gradio 版本更新日志,获取包含修复的正式版本。

验证方法

运行 Issue 中的对比测试代码,确认流式与非流式两种模式下 history 的输出结构完全一致(即 INJECTED BY FN 要么都保留,要么都不保留),且行为符合预期。

参考来源

gradio-app/gradio #10823

GamsGo AI

AI 工具推荐

想把多个 AI 模型放在一个入口?

GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。

了解 GamsGo AI

推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。

这个方案解决了吗?

celebrityanime
celebrityanime
文章: 18452

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注