Amazon Bedrock MaaS API
- InvokeModel / InvokeModelWithResponseStream
- 适合单次调用、模型原生 body、大 payload、非消息型/特殊模型
- Converse / ConverseStream
- 新的统一消息接口
- 适合 chat/multi-turn/tool use
- provider-specific endpoint / model-specific body
- Amazon Bedrock Runtime API
- Converse API
- Streaming
- Amazon Event Stream
Runtime API
| API | 用途 | MaaS 适配注意 |
|---|---|---|
Converse | 统一对话接口 | 优先用于跨模型 text / multimodal / tool use 适配 |
ConverseStream | 统一对话流式接口 | 返回 application/vnd.amazon.eventstream,不是 text/event-stream |
InvokeModel | 模型原生请求/响应 | body 是模型私有 schema,适合保留 provider 原生能力 |
InvokeModelWithResponseStream | 模型原生流式响应 | 事件通常是 chunk,payload 仍需按模型原生格式解析 |
建议 MaaS 内部优先以 Converse / ConverseStream 建立通用语义;只有在模型能力或供应商私有参数无法表达时,才降到 InvokeModel* 原生接口。
Converse message
Converse 的核心结构和 OpenAI / Anthropic 不同:
system是独立字段,不是messages[]里的systemrole。messages[].role通常只有user/assistant。messages[].content[]是 block 列表,常见 block 包括:textimagedocumentvideotoolUsetoolResultguardContentcachePointreasoningContent
inferenceConfig承载通用推理参数,例如maxTokens、temperature、topP、stopSequences。additionalModelRequestFields承载模型/供应商私有字段。additionalModelResponseFieldPaths用于请求返回模型私有字段。
{
"modelId": "anthropic.claude-3-5-sonnet-20240620-v1:0",
"system": [{ "text": "You are a concise assistant." }],
"messages": [
{
"role": "user",
"content": [{ "text": "hello" }]
}
],
"inferenceConfig": {
"maxTokens": 1024,
"temperature": 0.7,
"topP": 0.9
}
}
Streaming / EventStream
Bedrock streaming 使用 Amazon Event Stream 二进制分帧:
- HTTP
Content-Type通常是application/vnd.amazon.eventstream。 - 这不是 WHATWG
text/event-stream,不能用普通 SSE line parser 解析。 - 每条 eventstream message 有:
total_lengthheaders_lengthprelude_crc- typed headers
- payload
message_crc
- 常见 headers:
:message-type:event/exception/error:event-type: modeled event 名称:exception-type: modeled exception 名称:content-type: payload media type
MaaS codec 层应先完成 eventstream framing 和 CRC 校验,再把 payload 交给 Bedrock 事件语义层解析。
ConverseStream events
ConverseStream 常见事件:
| event type | 说明 | 通用流式语义 |
|---|---|---|
messageStart | assistant 消息开始 | lifecycle |
contentBlockStart | content block 开始 | lifecycle |
contentBlockDelta | content block 增量 | delta |
contentBlockStop | content block 结束 | done |
messageStop | assistant 消息结束 | done |
metadata | usage / metrics 等尾部元数据 | terminal |
注意:metadata 可能在 messageStop 后出现。通用 stream 聚合器不能在 messageStop 后立即丢弃连接上下文,否则会漏掉 usage / metrics。
常见 contentBlockDelta.delta 类型:
textreasoningContenttoolUsetoolResultcitation
InvokeModelWithResponseStream events
InvokeModelWithResponseStream 更接近模型原生流式接口:
- 常见 event type 是
chunk。 chunk.bytes里承载模型原生响应片段。- MaaS 适配层需要先解 eventstream,再按目标模型原生协议解析 chunk 内容。
Stream exceptions
Bedrock stream 中异常可能作为 eventstream message 返回,而不是普通 HTTP body。
| exception type | 常见接口 | 说明 |
|---|---|---|
internalServerException | ConverseStream / Invoke stream | 服务内部错误 |
modelStreamErrorException | ConverseStream / Invoke stream | 模型流式生成错误 |
modelTimeoutException | Invoke stream | 模型处理超时 |
serviceUnavailableException | ConverseStream / Invoke stream | 服务暂不可用 |
throttlingException | ConverseStream / Invoke stream | 限流 |
validationException | ConverseStream / Invoke stream | 请求参数不合法 |
MaaS 错误处理建议:
:message-type=exception时优先读取:exception-type。- 未知但非空的 exception type 也应按 error 处理。
- stream 中断时可能没有最终 usage,需要结合已收到 chunk 做估算或标记为 incomplete。
Tool use
Bedrock Converse 的 tool 语义接近 Anthropic,但字段名不同。
Tool 定义
{
"toolConfig": {
"tools": [
{
"toolSpec": {
"name": "get_weather",
"description": "Get weather by city",
"inputSchema": {
"json": {
"type": "object",
"properties": {
"city": { "type": "string" }
},
"required": ["city"]
}
}
}
}
],
"toolChoice": { "auto": {} }
}
}
Assistant tool call
{
"role": "assistant",
"content": [
{
"toolUse": {
"toolUseId": "tooluse_1",
"name": "get_weather",
"input": { "city": "Shanghai" }
}
}
]
}
Tool result
{
"role": "user",
"content": [
{
"toolResult": {
"toolUseId": "tooluse_1",
"status": "success",
"content": [
{ "json": { "temperature": 25 } }
]
}
}
]
}
适配注意:
- Bedrock 没有 OpenAI 的
role=tool;tool result 通常作为userrole 的toolResultblock 回传。 toolUseId是关联 tool result 的稳定 ID。- OpenAI
tool_calls[].id/ Anthropictool_use.id映射到 Bedrock 时应保留为toolUseId。 toolChoice常见形状是auto/any/tool,具体模型支持需要按 model capability 判断。
Cache
Bedrock Converse 支持通过 cachePoint 表达 prompt cache 断点,但并非所有模型都支持。
适配建议:
- cache 能力应按模型维度声明,不能全局默认开启。
cachePoint是 content block 的一部分,和 OpenAI / Anthropic 的 cache control 表达不同。- usage 里若返回 cache read/write token,应映射到 MaaS 统一 usage 字段。
Usage / metrics
Bedrock Converse / ConverseStream 常见 usage 字段:
inputTokensoutputTokenstotalTokens- cache read/write token,按模型和接口返回情况确认
ConverseStream 的 usage / metrics 往往在 metadata 事件中返回。MaaS 统计逻辑需要:
- 收到
metadata后再确认最终 usage。 - 如果 stream abort / network reset 导致没有
metadata,需要标记 usage 不完整。 - 计费口径应区分 provider 原始 usage、MaaS 估算 usage、最终可结算 usage。
MaaS 映射建议
| MaaS / OpenAI 风格 | Bedrock Converse |
|---|---|
system message | top-level system[] |
user message | messages[].role=user |
assistant message | messages[].role=assistant |
tool result message | messages[].role=user + toolResult block |
tools[].function.parameters | toolConfig.tools[].toolSpec.inputSchema.json |
tool_choice=auto | toolChoice.auto |
tool_choice=required / Anthropic any | toolChoice.any |
| forced tool | toolChoice.tool.name |
| text stream delta | contentBlockDelta.delta.text |
| reasoning delta | contentBlockDelta.delta.reasoningContent |
| final usage | metadata.usage |
参考实现注意
ConverseStream的messageStop不一定是最后一个有价值事件,后续metadata仍可能包含 usage / metrics。- eventstream CRC 错误应终止 stream,不应继续解析 payload。
InvokeModel*原生接口的 body schema 和 event chunk 内容由模型决定,不应强行套 Converse schema。- Bedrock 的跨区域 inference profile、guardrail、performance config、request metadata 都属于网关路由和审计层需要保留的信息。