【Bug已解决】AWS Bedrock Claude Sonnet 3.5 with image and system prompt 解决方案

【Bug已解决】AWS Bedrock Claude Sonnet 3.5 with image and system prompt 解决方案 【Bug已解决】AWS Bedrock Claude Sonnet 3.5 with image and system prompt 解决方案一、现象长什么样你想在 Bedrock 上用 Claude Sonnet 3.5 同时传系统提示 一张图片却遇到图片和 system 一起传时格式报错malformed / validation或 system 提示被忽略、图片也没被模型看到你不确定在ConverseAPI 里system该放哪、图片块怎么和文本混排用invoke_model时把system当成字符串、把图片块放进错误的位置单独传图片能成、单独传 system 能成合一起就乱。一句话在 Bedrock 的ConverseAPI 里system是请求顶层的独立字段文本块数组图片是user消息content里的一个image块——两者位置不同、格式不同混排错了就会失败。二、背景BedrockConverseAPI 的请求结构与 Anthropic 原生不同system顶层字段值为文本块数组[{text: ...}]不是messages里的一条user消息messages对话历史每条消息content是块数组可混合text块和image块image块{image: {format: png, source: {bytes: ...}}}详见 933。所以带 system 图片的正确姿势是system放顶层、image块和text块一起放某条user消息的content里。常见错误是把system塞进messages当第一条user消息这是 Anthropic 原生做法但 Bedrock Converse 不这么用或把image块放在system里system 只接受文本。三、根因根因是**system与image的位置/格式放错**// 错误把 system 当 messages 第一条 user且 image 块位置不对 { messages: [ {role: user, content: [{text: system: 你是助手}]}, {role: user, content: [{image: {...}}]} ] }// 正确system 顶层数组image 在 user content 里 { system: [{text: 你是助手}], messages: [ {role: user, content: [ {image: {format: png, source: {bytes: ...}}}, {text: 描述这张图} ]} ] }四、最小可运行复现下面用 boto3 演示system image完整结构import base64 import boto3 client boto3.client(bedrock-runtime, region_nameus-west-2) MODEL anthropic.claude-3-5-sonnet-20241022-v2:0 b64_png iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkM8AAAMBAQDJ/pLvAAAAAElFTkSuQmCC image_bytes base64.b64decode(b64_png) response client.converse( modelIdMODEL, # system 是顶层字段文本块数组 system[{text: 你是一名严谨的图片分析助手回答要简洁。}], messages[{ role: user, content: [ {image: {format: png, source: {bytes: image_bytes}}}, {text: 这张图里有什么}, ], }], inferenceConfig{maxTokens: 300}, ) print(response[output][message][content])运行后模型会结合 system 提示来分析图片——这就是 Bedrock 上system image的正确形态。五、解决方案第一层最小直接修复最小修复是把system放顶层数组、image块放进user的contentclient.converse( modelIdMODEL, system[{text: 你的系统提示}], # 顶层 messages[{ role: user, content: [ {image: {format: png, source: {bytes: img_bytes}}}, # 图片块 {text: 请基于图片回答}, # 文本块 ], }], inferenceConfig{maxTokens: 300}, )要点system永不进messagesimage块只出现在user/assistant的content里且必须带formatsource.bytes二进制详见 933。六、解决方案第二层结构化改进把system 多模态消息的构造做成策略集中约束位置与格式from dataclasses import dataclass, field import base64 from typing import Dict, List dataclass(frozenTrue) class BedrockImageSystemPolicy: Bedrock systemimage 构造策略位置与格式正确。 规则 - system 是顶层文本块数组 - image 块在 user content 里source.bytes 为二进制 - text 与 image 可混排在 content 数组 def image_block(self, b64: str, fmt: str) - Dict: return {image: {format: fmt, source: {bytes: base64.b64decode(b64)}}} def build(self, *, system: str, image_b64: str, fmt: str, question: str, max_tokens: int 300) - Dict: return { system: [{text: system}], messages: [{ role: user, content: [ self.image_block(image_b64, fmt), {text: question}, ], }], inferenceConfig: {maxTokens: max_tokens}, } def demo() - None: policy BedrockImageSystemPolicy() req policy.build( system图片分析助手, image_b64aGk, fmtpng, question这是什么, ) assert req[system][0][text] 图片分析助手 assert req[messages][0][content][0][image][format] png print(systemimage 请求 OK) if __name__ __main__: demo()七、解决方案第三层断言 / CI 守护import base64 import pytest from your_module import BedrockImageSystemPolicy def test_system_top_level(): policy BedrockImageSystemPolicy() req policy.build(systems, image_b64aGk, fmtpng, questionq) assert isinstance(req[system], list) assert req[system][0][text] s def test_image_in_user_content(): policy BedrockImageSystemPolicy() req policy.build(systems, image_b64aGk, fmtpng, questionq) content req[messages][0][content] assert any(image in b for b in content) def test_image_bytes_decoded(): policy BedrockImageSystemPolicy() req policy.build(systems, image_b64aGk, fmtpng, questionq) img req[messages][0][content][0][image] assert img[source][bytes] bhi # base64 aGk - hi def test_max_tokens_in_inference_config(): policy BedrockImageSystemPolicy() req policy.build(systems, image_b64aGk, fmtpng, questionq, max_tokens128) assert req[inferenceConfig][maxTokens] 128 def test_content_mixed_text_image(): policy BedrockImageSystemPolicy() req policy.build(systems, image_b64aGk, fmtpng, questionq?) blocks req[messages][0][content] assert any(text in b for b in blocks)CI 里加一条构造请求后断言system在顶层、image在 user content、bytes 已解码避免 system/image 混排错误。八、排查清单system是否放到了请求顶层数组而不是messages第一条图片块是否在user的content里且带formatsource.bytes是否把system写成字符串而非[{text:...}]是否把图片块塞进了systemsystem 只接受文本text与image是否在同一content数组里混排是否漏了inferenceConfig.maxTokens九、小结在 Bedrock 上用 Claude Sonnet 3.5 同时传 system 提示和图片报格式错误根因是位置/格式混淆——BedrockConverse的system是顶层文本块数组而image块应放在user消息的content里且需二进制 bytes见 933。最小修复是把system放顶层、图片块放进 user content 混排结构化做法是抽成BedrockImageSystemPolicy集中构造正确结构最后用 pytest 守护system顶层、image在 user content、bytes 已解码确保多模态 系统提示稳定可用。