快速结论:该报错发生在 LangChain 中通过 Bedrock Converse 模型提供商读取 AIMessage.content_blocks 属性时,翻译器直接修改了原始消息内容,导致源消息被污染、连续两次读取返回不同结果。优先检查是否使用了 bedrock_converse 作为 model_provider,并确保 langchain-core 已更新到包含修复的版本。
适用环境:langchain-core 包;使用 Bedrock Converse 模型提供商(model_provider: "bedrock_converse")的场景;涉及 AIMessage 和 AIMessageChunk。
最快修复方案:升级 langchain-core 到包含修复的最新版本。Issue 确认的修复方式是在 bedrock_converse.py 的 _convert_to_v1_from_converse() 函数中,对字符串内容使用局部列表转换、对未识别块进行浅拷贝后再移动 index 字段,避免修改原始消息内容。尚未确认具体修复版本号。
注意事项:修复仅针对 Bedrock Converse 翻译器,其他模型提供商的翻译器未受影响;如果遇到类似问题但不在该场景下,可能是其他原因。
问题场景
用户在使用 LangChain 且模型提供商为 Bedrock Converse(model_provider: "bedrock_converse")时,读取 AIMessage.content_blocks 属性会导致原始消息内容被修改。具体表现为:当 message.content 是字符串时,第一次读取后会被替换为文本块列表;当内容包含带 index 字段的未识别字典块时,读取操作会从原始字典中移除该字段。这导致连续两次调用 content_blocks 返回不同的值。
报错原文
AIMessage.content_blocks mutates Bedrock Converse message content
No exception is raised.
original: hello
content after reads: [{'type': 'text', 'text': 'hello'}]
first read: [{'type': 'text', 'text': 'hello'}]
second read: [{'type': 'text', 'text': 'hello'}]
原因分析
问题出在 libs/core/langchain_core/messages/block_translators/bedrock_converse.py 文件的 _convert_to_v1_from_converse() 函数中,存在两处直接修改原始消息内容的位置:
1. 字符串内容修改(约 162-163 行):
if isinstance(message.content, str):
message.content = [{"type": "text", "text": message.content}]
2. 未识别块的修改(约 276-277 行):
if "index" in new_block["value"]:
new_block["index"] = new_block["value"].pop("index")
其中 new_block["value"] 引用的是 message.content 中的原始块,调用 .pop("index") 会直接删除原始消息内容中的 index 字段。已知问题在于 Bedrock Converse 翻译器在构建标准化内容块时被设计为“非修改性”操作,但实现中违反了这一约束;其他模型提供商的翻译器均保持了源消息不变。
环境排查
- 确认 langchain-core 的当前版本,检查是否已包含修复提交(提交信息涉及“preserving original content”且修复了
bedrock_converse.py)。 - 确认用于复现的 Python 版本(Issue 未明确给出具体版本号)。
- 确认
response_metadata中的model_provider是否为"bedrock_converse"。需要确认AIMessage和AIMessageChunk两个类的行为。
解决步骤
- 升级 langchain-core:将 langchain-core 升级到最新版本,该问题已被修复并合并进主分支。
- 验证修复效果(可优先尝试):如果升级后问题仍存在,可先尝试在读取
content_blocks之前对消息内容执行deepcopy作为临时规避方案。已确认修复方案采用了局部变量和浅拷贝方式,因此升级是最直接的解决途径。 - 检查回归覆盖:修复提交中包含了对
AIMessage和AIMessageChunk的回归测试,覆盖了以下场景:字符串内容在读取后保持不变、带index的未识别块保留原始index、连续两次读取结果一致。如果升级后仍有异常,可对照这些测试场景检查代码。 - 检查自定义代码:确认自己的代码中是否有对
message.content的直接或间接修改,特别是在调用content_blocks前后。
验证方法
使用 Issue 中的复现代码验证问题已解决:
from copy import deepcopy
from langchain_core.messages import AIMessage
for content in [
"hello",
[{"type": "custom", "payload": "value", "index": 3}],
]:
message = AIMessage(
content=content,
response_metadata={"model_provider": "bedrock_converse"},
)
original = deepcopy(message.content)
first = message.content_blocks
second = message.content_blocks
print("original:", original)
print("content after reads:", message.content)
print("first read:", first)
print("second read:", second)
正确行为应为:message.content 在读取 content_blocks 前后保持不变,且 first 与 second 返回值相同。
参考来源
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。
![[bug]: InvokeAI v6.14.0-RC1 Crashed while generating Krea-2 Image](https://www.chat-gpts.plus/wp-content/uploads/2026/09/9444-d6bdc60c-768x403.jpg)
![[Question]: Shared embedded chat URL fails to access documents after logout or when accessed by other users](https://www.chat-gpts.plus/wp-content/uploads/2026/09/15895-cf3f7033-768x403.jpg)
