ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

【Bug已解决】How to send a base64 image to Bedrock via ConverseCommand as bytes 解决方案

【Bug已解决】How to send a base64 image to Bedrock via ConverseCommand as bytes 解决方案 【Bug已解决】How to send a base64 image to Bedrock via ConverseCommand as bytes 解决方案一、现象长什么样你在 AWS Bedrock 用Converse/ConverseCommandSDK v3给 Claude 传一张图想把本地图片以 base64 形式发过去却遇到报错说image块的source格式不对或你传了 base64 字符串但 Bedrock 期望的是bytes二进制两者混用报错文档里写source: { bytes: Uint8Array }但你手里是 base64 文本不知道怎么转你试过直接把 base64 字符串塞进bytes字段报ValidationException图片相关的formatpng/jpeg也填错导致模型收不到图。一句话BedrockConverse的图片块要求source.bytes是一个二进制字节流如Uint8Array/bytes而不是 base64 字符串——你需要先把 base64 解码成字节再作为bytes传入并正确声明format。二、背景Bedrock 的ConverseAPI以及 boto3 的converse、JS SDK 的ConverseCommand对多模态图片有统一结构{ image: { format: png, source: { bytes: 二进制字节 } } }source有两种bytes直接二进制或s3Location存在 S3 的图片。没有base64这个字段——Bedrock 不接收 base64 字符串它要的是解码后的字节。所以我有一张 base64 图的处理链路是base64 文本 →base64.b64decode/Buffer.from(b64, base64)→ 字节 → 放进source.bytes。很多人卡在直接把 base64 字符串当 bytes 传于是校验失败。三、根因根因是把 base64 字符串直接当bytes传而不是先解码成二进制# 错误base64 字符串不是 bytes block {image: {format: png, source: {bytes: iVBORw0KGgo...}}} # 字符串! - 报错 # 正确先解码 import base64 raw base64.b64decode(iVBORw0KGgo...) block {image: {format: png, source: {bytes: raw}}} # bytes!修复方向在发送前把 base64 解码为字节对象bytes/Uint8Array并声明正确的format。四、最小可运行复现下面用 Pythonboto3演示完整链路import base64 import boto3 # 假设你有一张 base64 编码的 PNG b64 iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkM8AAAMBAQDJ/pLvAAAAAElFTkSuQmCC # 1) 解码成 bytes关键 image_bytes base64.b64decode(b64) # 2) 构造 image 块 image_block { image: { format: png, source: {bytes: image_bytes}, # 必须是 bytes不是字符串 } } # 3) 发送 client boto3.client(bedrock-runtime, region_nameus-west-2) resp client.converse( modelIdanthropic.claude-3-5-sonnet-20241022-v2:0, messages[{ role: user, content: [ image_block, {text: 这张图里有什么}, ], }], inferenceConfig{maxTokens: 256}, ) print(resp[output][message][content])JS SDKConverseCommand等价写法import { BedrockRuntimeClient, ConverseCommand } from aws-sdk/client-bedrock-runtime; const b64 iVBORw0KGgo...; const bytes Uint8Array.from(Buffer.from(b64, base64)); // base64 - bytes const cmd new ConverseCommand({ modelId: anthropic.claude-3-5-sonnet-20241022-v2:0, messages: [{ role: user, content: [ { image: { format: png, source: { bytes } } }, { text: 这张图里有什么 }, ], }], }); const res await new BedrockRuntimeClient({ region: us-west-2 }).send(cmd);五、解决方案第一层最小直接修复最小修复是发送前把 base64 解码为字节并声明formatimport base64 def b64_to_image_block(b64: str, fmt: str png) - dict: return { image: { format: fmt, source: {bytes: base64.b64decode(b64)}, } } # 用法 block b64_to_image_block(my_b64, fmtjpeg)要点source.bytes必须是解码后的二进制不是 base64 字符串format必须与实际图片格式一致png/jpeg/gif/webp等若图片已在 S3直接用source: {s3Location: {uri: s3://...}}连解码都省了。六、解决方案第二层结构化改进把图片源构造做成策略统一处理 base64 / 文件路径 / S3 三种来源from dataclasses import dataclass import base64 from pathlib import Path from typing import Union dataclass(frozenTrue) class BedrockImageBytesPolicy: Bedrock 图片块构造策略base64/文件/S3 - 合规 image 块。 规则 - base64: 解码成 bytes 再放 source.bytes - 文件: 读二进制 - s3: 用 s3Location - format 必须显式声明 def from_base64(self, b64: str, fmt: str) - dict: return {image: {format: fmt, source: {bytes: base64.b64decode(b64)}}} def from_file(self, path: Union[str, Path], fmt: str) - dict: data Path(path).read_bytes() return {image: {format: fmt, source: {bytes: data}}} def from_s3(self, uri: str) - dict: return {image: {source: {s3Location: {uri: uri}}}} def demo() - None: policy BedrockImageBytesPolicy() blk policy.from_base64(iVBOR, png) assert blk[image][source][bytes] base64.b64decode(iVBOR) print(base64 - bytes 块 OK) if __name__ __main__: demo()七、解决方案第三层断言 / CI 守护import base64 import pytest from your_module import BedrockImageBytesPolicy def test_from_base64_decodes(): policy BedrockImageBytesPolicy() blk policy.from_base64(aGVsbG8, png) # hello base64 assert blk[image][source][bytes] bhello assert blk[image][format] png def test_from_base64_not_string(): policy BedrockImageBytesPolicy() blk policy.from_base64(aGVsbG8, png) # bytes 字段必须是 bytes 而非 str assert isinstance(blk[image][source][bytes], bytes) assert not isinstance(blk[image][source][bytes], str) def test_from_s3_shape(): policy BedrockImageBytesPolicy() blk policy.from_s3(s3://bucket/k.png) assert blk[image][source][s3Location][uri].startswith(s3://) def test_from_file(tmp_path): policy BedrockImageBytesPolicy() p tmp_path / x.png p.write_bytes(b\x89PNG) blk policy.from_file(p, png) assert blk[image][source][bytes] b\x89PNG def test_format_declared(): policy BedrockImageBytesPolicy() blk policy.from_base64(aGk, jpeg) assert blk[image][format] jpegCI 里加一条对任何图片输入断言source.bytes是字节非字符串避免把 base64 当 bytes 传导致ValidationException。八、排查清单是否把 base64 字符串直接塞进了source.bytes必须先b64decode成字节。format是否与实际图片格式一致png/jpeg/...图片在 S3 吗可直接用s3Location免解码。JS 侧是否用Uint8Array.from(Buffer.from(b64,base64))source字段名是否拼对Bedrock 用bytes/s3Location没有base64字段。多图是否都在同一条user消息的content里九、小结在 Bedrock 用Converse传 base64 图片报格式错误根因是 Bedrock 的图片块要求source.bytes是解码后的二进制字节而你直接把 base64 字符串当bytes传了——Bedrock 没有base64这个 source 字段。最小修复是发送前base64.b64decode成字节并声明format结构化做法是抽成BedrockImageBytesPolicy统一处理 base64/文件/S3 三种来源最后用 pytest 守护source.bytes必为字节非字符串避免校验失败。
返回列表