快速结论:当使用 langchain_anthropic.ChatAnthropic 且 output_version="v1" 时,如果 SystemMessage 的 content_blocks 通过 create_text_block() 创建,其生成的 id 字段会被原样转发到 Anthropic API,导致 400 错误 “system.0.id: Extra inputs are not permitted”。优先排查 SystemMessage 中是否存在多余的 id 字段,或升级 langchain-anthropic 到包含修复的版本。
适用环境:langchain-anthropic 包、ChatAnthropic 模型、Anthropic API。Issue 中未提及特定操作系统、Python、CUDA 或显卡版本。
最快修复方案:暂无官方发布的一步修复方案(截至 Issue 关闭时修复尚未合并到稳定版)。可优先尝试手动修改本地 langchain_anthropic/chat_models.py 中 _format_messages 方法,对系统文本块(system text block)进行字段过滤,仅保留 Anthropic 允许的字段(type、text、cache_control、citations),其余字段如 id 将被移除。
注意事项:手动修改后需确认本地 langchain-anthropic 版本与修改的代码兼容;非文本类型的系统块(如图像块)不受影响。该修复也已影响 get_num_tokens_from_messages 方法。
问题场景
用户在 langchain_anthropic 的 ChatAnthropic 中调用 llm.invoke() 或 get_num_tokens_from_messages(),传入一个由 create_text_block() 构建的 SystemMessage。示例代码如下:
from langchain_anthropic import ChatAnthropic
from langchain_core.messages import HumanMessage, SystemMessage
from langchain_core.messages.content import create_text_block
llm = ChatAnthropic(model_name="claude-haiku-4-5", output_version="v1", max_tokens=16)
system_message = SystemMessage(content_blocks=[create_text_block("You are a helpful assistant.")])
llm.invoke([system_message, HumanMessage("Say hi.")]) # 触发 BadRequestError
报错原文
ChatAnthropic: SystemMessage v1 content blocks are forwarded verbatim, so create_text_block()'s id causes 400 "system.0.id: Extra inputs are not permitted"
# 完整错误堆栈片段:
File "dev/scratch.py", line 12, in
llm.invoke([system_message, HumanMessage("Say hi.")])
...
File ".../langchain_anthropic/chat_models.py", line 1566, in _create
return self._client.messages.create(**payload)
File ".../anthropic/_utils/_utils.py", line 294, in wrapper
return func(*args, **kwargs)
...
anthropic.BadRequestError: Error code: 400 - {'type': 'error', 'error': {'type': 'invalid_request_error', 'message': 'system.0.id: Extra inputs are not permitted'}}
原因分析
在 langchain_anthropic/chat_models.py 的 _format_messages 方法中,处理 SystemMessage 时,对于已经是字典的 content block 采取了“直接透传”逻辑:
system = [
(block if isinstance(block, dict) else {"type": "text", "text": block})
for block in message.content
]
而 create_text_block() 生成的字典会自带一个 id 字段(例如 "lc_fcd78d19-...")。Anthropic API 对 system 参数中的文本块只允许 type、text、cache_control、citations 这四个字段,多余的 id 字段会导致 400 错误。
作为对比,对于非 system 角色的消息(human/assistant),_format_messages 已经实现了字段白名单过滤,因此不会出现此问题。
环境排查
- 确认
langchain-anthropic版本(Issue 中未给出具体版本,建议检查当前安装版本是否包含此修复)。 - 确认是否使用了
output_version="v1"(v1 版本会透传 content blocks 中的额外字段)。 - 检查
SystemMessage中的content_blocks字典是否包含id字段(例如通过print(system_message.content_blocks)可观察到id)。



