一、客户反馈
日期:2026-05-16
事由:客户反馈多图请求报错(502 Bad Gateway)
测试端点:https://www.vibeapi.cn(主站)
客户在使用 /v1/chat/completions(OpenAI 兼容格式)发送 4-5 张图片、容量超过 5MB 时,收到 502 Bad Gateway 错误:
{
"error": {
"message": "上游 API 调用失败: 非流式 API 请求失败: 400 Bad Request {\"message\":\"Improperly formed request.\",\"reason\":null}",
"type": "api_error"
}
}
二、测试结果
2.1 Anthropic 原生格式 (/v1/messages)
测试端点:https://www.vibeapi.cn/v1/messages
| 图片数 | Payload 大小 | input_tokens | 结果 |
|---|---|---|---|
| 6 张(混合格式) | 525 KB | 5,990 | ✅ 正确识别所有图片 |
| 8 张(含大截图) | 3.0 MB | 9,123 | ✅ 正确识别所有图片 |
| 5 张(大图为主) | 6.6 MB | 11,201 | ✅ 正确识别所有图片 |
| 8 张(全大图) | 12.4 MB | 16,582 | ✅ 正确识别所有图片 |
| 10 张(全大图) | 15.5 MB | 19,687 | ✅ 正确识别所有图片 |
| 12 张(全大图) | 18.6 MB | 22,795 | ✅ 正确识别所有图片 |
| 15 张(全大图) | 23.6 MB | 27,455 | ✅ 正确识别所有图片 |
| 18 张(全大图) | 27.9 MB | 32,147 | ✅ 正确识别所有图片 |
| 20 张(全大图) | 31.1 MB | — | ❌ Context window is full |
2.2 限制因素分析
图片数量没有硬性上限,唯一的限制是上下文 token 总量:
- 每张大图(1MB+ PNG 截图)约消耗 1,500 tokens
- 每张小图(10-50KB WebP)约消耗 500 tokens
- 系统提示(Kiro IDE 内置)约占 4,000 tokens
- 默认上下文窗口下,大约能容纳 15-18 张大图 或 数十张小图
注:上下文窗口大小取决于上游 Kiro IDE 的配额分配,
[1m]后缀是 Claude Code / Claude Desktop 的 SDK 层面做的兼容处理,直接调用 API 时该参数不生效,实际上下文由上游决定。
2.3 OpenAI 兼容格式 (/v1/chat/completions)
客户反馈在此格式下,4-5 张图、容量超过 5MB 时报错 502。
初步判断: 问题出在网关层的 OpenAI → Anthropic 格式转换逻辑,而非底层代理。Anthropic 原生格式下同等数据量完全正常。
三、调用说明
3.1 推荐方式:Anthropic 原生格式
端点: POST https://www.vibeapi.cn/v1/messages
认证方式(二选一):
- Header:
x-api-key: YOUR_API_KEY - Header:
Authorization: Bearer YOUR_API_KEY
支持的图片格式: JPEG、PNG、GIF、WebP
图片传递方式: base64 编码,内嵌在 message content 数组中
3.2 单图请求示例
curl -X POST "https://www.vibeapi.cn/v1/messages" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"model": "claude-opus-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "BASE64_ENCODED_IMAGE_DATA"
}
},
{
"type": "text",
"text": "这张图片里有什么?"
}
]
}
]
}'
3.3 多图请求示例
curl -X POST "https://www.vibeapi.cn/v1/messages" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"model": "claude-opus-4-6",
"max_tokens": 1024,
"messages": [
{
"role": "user",
"content": [
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/jpeg",
"data": "BASE64_IMAGE_1"
}
},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/png",
"data": "BASE64_IMAGE_2"
}
},
{
"type": "image",
"source": {
"type": "base64",
"media_type": "image/webp",
"data": "BASE64_IMAGE_3"
}
},
{
"type": "text",
"text": "对比这三张图片,分别描述它们的内容"
}
]
}
]
}'
3.4 Python 调用示例
import base64
import httpx
API_URL = "https://www.vibeapi.cn/v1/messages"
API_KEY = "YOUR_API_KEY"
def encode_image(file_path: str) -> tuple[str, str]:
"""读取图片并返回 (base64_data, media_type)"""
ext = file_path.rsplit(".", 1)[-1].lower()
media_types = {"jpg": "image/jpeg", "jpeg": "image/jpeg",
"png": "image/png", "gif": "image/gif", "webp": "image/webp"}
with open(file_path, "rb") as f:
data = base64.b64encode(f.read()).decode()
return data, media_types.get(ext, "image/png")
def ask_with_images(image_paths: list[str], question: str, model: str = "claude-opus-4-6"):
"""发送多图请求"""
content = []
for path in image_paths:
data, media_type = encode_image(path)
content.append({
"type": "image",
"source": {"type": "base64", "media_type": media_type, "data": data}
})
content.append({"type": "text", "text": question})
response = httpx.post(
API_URL,
headers={"x-api-key": API_KEY, "Content-Type": "application/json"},
json={
"model": model,
"max_tokens": 2048,
"messages": [{"role": "user", "content": content}]
},
timeout=120.0
)
return response.json()
# 使用示例
result = ask_with_images(
["photo1.jpg", "photo2.png", "screenshot.webp"],
"对比这三张图片的内容"
)
print(result["content"][0]["text"])
四、结论与建议
- Anthropic 原生格式多图能力完全正常 — 实测 18 张大图 / 28MB payload 均可正常处理
- 图片数量无硬性上限 — 限制因素仅为上下文 token 总量,而非图片张数或文件大小
- OpenAI 兼容格式存在问题 —
/v1/chat/completions的多模态转换在大 payload 时报错,待排查 - 建议多图场景使用 Anthropic 原生格式 —
/v1/messages端点,稳定可靠 - 关于
[1m]上下文 — 该参数是 Claude Code / Claude Desktop SDK 层面的兼容处理,直接调用 API 时可能不生效,实际上下文窗口由上游分配决定