TypeError: unsupported operand type(s) for +=: ‘dict’ and ‘dict’

该问题发生在使用 LangChain 的 langchain-fireworks 包时,用户调用 llm.generate([[HumanMessage("a")], [HumanMessage("b")]]) 或 agenerate() 批量处理多个 prompt。调用链包括:

TypeError: unsupported operand type(s) for +=: 'dict' and 'dict'

TypeError: unsupported operand type(s) for +=: ‘dict’ and ‘dict’

快速结论:该报错发生在使用 LangChain Fireworks 集成调用 generate()agenerate() 批量处理多个 prompt 时,Fireworks API 返回了嵌套的 token usage 结构(如 prompt_tokens_details.cached_tokens),而 _combine_llm_outputs 方法无法处理 dict 类型的嵌套值,直接尝试对 dict 执行 += 操作导致崩溃。优先排查是否使用了 generate() 传入多 prompt 列表,并确认 Fireworks 响应的 token_usage 中是否包含字典类型的嵌套字段。

问题场景

该问题发生在使用 LangChain 的 langchain-fireworks 包时,用户调用 llm.generate([[HumanMessage("a")], [HumanMessage("b")]])agenerate() 批量处理多个 prompt。调用链包括:

  • 直接应用代码主动调用 llm.generate()
  • 已弃用的经典链抽象(如 LLMChain)内部通过 generate_prompt() 调用 generate()
  • MapReduceDocumentsChain.combine_docs() 使用 llm_chain.apply() 跨文档处理
  • 第三方库(如 ragas)通过 generate_prompt 路由调用

核心触发条件是 Fireworks API 在 token_usage 中返回嵌套的 prompt_tokens_details 结构(包含 cached_tokens 等字典字段),而旧版 _combine_llm_outputs 假定所有 usage 值均为 int 类型。

报错原文

Traceback (most recent call last):
  File "repro_fireworks.py", line 44, in <module>
    combined = llm._combine_llm_outputs(llm_outputs)
               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File ".../langchain_fireworks/chat_models.py", line 967, in _combine_llm_outputs
    overall_token_usage[k] += v
TypeError: unsupported operand type(s) for +=: 'dict' and 'dict'

原因分析

ChatFireworks._combine_llm_outputs 方法(位于 libs/partners/fireworks/langchain_fireworks/chat_models.py:956)使用 overall_token_usage[k] += v 合并多个 llm_output 的 token_usage 字典,但该方法假设所有 usage 字段值均为 int 类型。当 Fireworks API 返回包含嵌套字典的 usage 结构(如 prompt_tokens_details: {"cached_tokens": 41518})时,+= 操作无法合并两个 dict 对象,触发 TypeError

该路径在之前是稳定的,因为早期 API 不会返回嵌套的 *_tokens_details 块。Fireworks 引入缓存 token 计数后,现有代码在无用户侧修改的情况下直接崩溃。

环境排查

  • 包版本:确认 langchain-fireworks 版本(特别是 0.1.x 或更早版本)
  • 依赖项:langchain-core 版本(影响 LLMResult 等基类行为)
  • API 响应:检查 Fireworks API 返回的 token_usage 是否包含嵌套字典(如 prompt_tokens_details
  • 调用路径:排查代码中是否直接或间接使用 generate() / agenerate() 传入多 prompt 列表(batch() 通常不会触发此问题,因为默认 batch() 将多 prompt 拆分为多个 invoke() 调用)
  • 其他包:类似问题已在 langchain-mistralai(#38482)中出现,可能影响其他使用相同合并模式的 partner 包

解决步骤

  1. 升级包版本:更新 langchain-fireworks 到包含修复的版本(PR #38646 已提交修复,具体合并版本需查阅 Changelog)。修复方法参考了 langchain-openai_update_token_usage 的实现逻辑。
  2. 临时绕过:避免直接调用 generate()agenerate() 传入多 prompt 列表。优先使用 invoke()batch()stream() 等推荐的 API 路径。注意 batch() 默认不会触发此问题,因为它内部走的是 invoke() 循环。
  3. 替换遗留链:如果问题来源于 LLMChainMapReduceDocumentsChain 等经典链,将这些链迁移到 LangChain 2.0 的新 API(如 RunnableSequenceLCEL 表达式)。
  4. 自定义修复(源代码级别):如果无法升级,可修改本地 langchain_fireworks/chat_models.py 中的 _combine_llm_outputs 方法,参考 langchain-openai_update_token_usage 实现,递归处理字典类型的嵌套值,为每个嵌套键内部进行 int 类型合并。

验证方法

使用 Issue 中提供的离线复现脚本测试,确认 llm._combine_llm_outputs() 在处理包含嵌套 prompt_tokens_details 的 llm_outputs 列表时不再抛出 TypeError。更贴近生产环境的验证:执行 llm.generate([[HumanMessage("a")], [HumanMessage("b")]]) 并确认返回正常的 LLMResult 对象(需要有效的 Fireworks API key)。

参考来源

langchain-ai/langchain #38648

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

celebrityanime
celebrityanime
文章: 12167

发表回复

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