图片 URL 报 Malformed
ChatAnthropic 的 data URL 报 Malformed url parameter,检查 Base64 内部 MIME 换行;从真实图片字节生成连续编码,并分开验收本地转换与模型接收。
ChatAnthropic 接收到 data:image/png;base64,...,却报 Malformed url parameter。图片内容还没发给模型时,可以检查 Base64 payload 内部有没有换行,特别是由 Python 的 base64.encodebytes 或 MIME 编码器生成的长字符串。
已核对的正式 langchain-anthropic 1.7.6 图片转换路径仍使用不匹配内部换行的正则。这里检查的是消息里的 image_url 数据地址转换,不是 Claude 已收到图片后判断格式或内容失败。
MIME 折行进了数据地址
base64.encodebytes 会按 MIME 规则每 76 个输出字符加入换行,并保留末尾换行。把这种长文本直接拼进 data URL,就可能在 payload 中间包含多行。
ChatAnthropic 的转换器检查整个 data URL,payload 部分使用 .+,没有启用 DOTALL。内部换行不能被这段匹配覆盖,于是地址无法转换成 Anthropic 的 base64 image source。
不要把所有末尾空白都当成完全相同的条件;这条判断针对 payload 内部已经折成多行的情况。HTTP 图片 URL 走另一条转换分支,替换成远程地址会改变读取与网络条件,不是相同输入的编码修正。
先检查数据地址的 MIME 前缀、Base64 部分及其中的换行位置。日志只保留格式、长度与是否有换行,不输出整张图片的编码。前缀不是图片类型、传了路径字符串、或原始二进制已经损坏,也会有别的处理问题。
从原始图片字节生成连续 Base64
手里还有原始图片时,使用不做 MIME 折行的标准编码入口。下面只读取既有 PNG 并构造数据地址,不调用模型:
import base64
from pathlib import Path
payload = base64.b64encode(
Path("image.png").read_bytes()
).decode("ascii")
image_url = f"data:image/png;base64,{payload}"
image.png 是示例路径,必须换成应用已经获准读取的真实 PNG;其他格式使用对应的真实 MIME 类型。把 JPEG 的字节配上 image/png,并不会因为正则通过就变成 PNG。
将这个地址合入原来的 HumanMessage 图片字段,保留其他内容与消息顺序。不要把整个消息字符串中的换行统一删除:正文换行、其他内容块和编码数据不是同一种信息。
只有折行文本时,应先按已知编码契约检查并恢复正确二进制,再生成连续 Base64;不是任意来历不明的字符串都可以通过删空白变成有效图片。也不要修改私有 _format_image,让畸形输入直接绕过边界。
本地转换和模型接收分开验收
先核对连续 Base64 对应原图片字节,消息转换不再报这条 Malformed 错误。再沿应用原来获准的模型调用流程检查真实图片是否被接受,格式、大小、模型能力等条件仍需满足实际接口约定。
本地正则匹配成功,不能证明图片可解码或模型已经理解内容。若仍在转换前失败,继续检查实际传入的字段与数据地址;若错误来自模型服务,则保留服务端状态与具体错误,按那一层处理,不反复替换 Base64 编码方式。


