ValueError: ChatMessage contains multiple blocks, use ‘ChatMessage.blocks’ instead.

用户在 LlamaIndex 框架的 SimpleChatEngine 中使用 astream_chat() 进行流式对话,然后调用 get_full_response() 消费流式响应。在响应的后台处理过程中, awrite_response_to_history() 方法试图将最终的助手消息写回

ValueError: ChatMessage contains multiple blocks, use 'ChatMessage.blocks' instead.

ValueError: ChatMessage contains multiple blocks, use ‘ChatMessage.blocks’ instead.

快速结论:此报错发生在使用 SimpleChatEngine.astream_chat() 并调用 get_full_response() 消费流式响应时,后台任务尝试直接给 ChatMessage.content 赋值,但消息包含多个块(multiple blocks),触发了 Pydantic 校验异常。优先排查是否使用了会产生多块响应(如包含文本块和工具调用块)的 LLM 配置。

问题场景

用户在 LlamaIndex 框架的 SimpleChatEngine 中使用 astream_chat() 进行流式对话,然后调用 get_full_response() 消费流式响应。在响应的后台处理过程中,awrite_response_to_history() 方法试图将最终的助手消息写回聊天历史时引发该错误。文档工作流中的 chat_no_relevant_context 路径下也触发了此问题。

报错原文

File ".../llama_index/core/chat_engine/types.py", line 252, in awrite_response_to_history
    chat.message.content = final_text.strip()  # final message
    ^^^^^^^^^^^^^^^^^^^^
  File ".../llama_index/core/base/llms/types.py", line 1233, in content
    raise ValueError(
ValueError: ChatMessage contains multiple blocks, use 'ChatMessage.blocks' instead.

原因分析

这是一个已确认的 bug,根源在 llama-index-corechat_engine/types.py 第 251 行(awrite_response_to_history 方法)中直接对 chat.message.content 进行赋值。当 ChatMessage 包含多个块(例如 TextBlock + 其他块)时,content 属性 setter 会导致 Pydantic 校验失败并抛出 ValueError。因为 ChatMessage.content 仅支持单个文本块,多块情况应通过 blocks 属性操作。

环境排查

  • llama-index-core 版本:至少 0.14.22(该版本确认存在此问题)
  • LLM 配置:确认使用的 LLM 是否产生包含多个块(如文本 + 函数调用/工具调用)的响应
  • 聊天引擎类型:确认使用 SimpleChatEngineastream_chat 路径

解决步骤

注意:以下修复基于 Issue 中提供的建议代码,尚未合并到主分支,属于临时解决方法。

  1. 定位错误代码:找到本地的 chat_engine/types.py 文件,定位到 awrite_response_to_history 方法中的 chat.message.content = final_text.strip() 这一行。
  2. 替换赋值逻辑:将该行替换为 Issue 评论中提供的方法,即遍历 chat.message.blocks 并直接修改 TextBlock.text
    from llama_index.core.base.llms.types import TextBlock
    
    text_set = False
    for block in chat.message.blocks:
        if isinstance(block, TextBlock):
            block.text = final_text.strip()
            text_set = True
            break
    if not text_set:
        chat.message.blocks = [TextBlock(text=final_text.strip())]
  3. 临时规避(可优先尝试):在调用 get_full_response() 处捕获异常,或避免使用会产生多块响应的 LLM 配置(如禁用工具调用)。
  4. 关注官方更新:关注 run-llama/llama_index 仓库的后续 PR,参考类似的已修复模式(如 ReActAgent 的 finalize() 修复 PR #20196、AG-UI 消息转换修复 PR #20648、Google GenAI 集成修复 PR #19954)。

验证方法

SimpleChatEngine 发起流式聊天请求,并成功调用 chat_response.get_full_response(),不再抛出 ValueError: ChatMessage contains multiple blocks 异常。确认聊天历史中的助手消息被正确写入且内容一致。

参考来源

run-llama/llama_index #21679

GamsGo AI

AI 工具推荐

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

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

了解 GamsGo AI

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

celebrityanime
celebrityanime
文章: 14524

发表回复

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