测试报告

Vibe API 多图支持测试报告

客户反馈使用 OpenAI 兼容格式发送 4-5 张图、容量超过 5MB 时收到 502 Bad Gateway。本报告通过实测验证 Anthropic 原生格式下多图能力完全正常,并定位 OpenAI 兼容格式的转换问题。

一、客户反馈

日期: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 KB5,990✅ 正确识别所有图片
8 张(含大截图)3.0 MB9,123✅ 正确识别所有图片
5 张(大图为主)6.6 MB11,201✅ 正确识别所有图片
8 张(全大图)12.4 MB16,582✅ 正确识别所有图片
10 张(全大图)15.5 MB19,687✅ 正确识别所有图片
12 张(全大图)18.6 MB22,795✅ 正确识别所有图片
15 张(全大图)23.6 MB27,455✅ 正确识别所有图片
18 张(全大图)27.9 MB32,147✅ 正确识别所有图片
20 张(全大图)31.1 MB—❌ Context window is full

2.2 限制因素分析

图片数量没有硬性上限,唯一的限制是上下文 token 总量:

注:上下文窗口大小取决于上游 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

认证方式(二选一):

支持的图片格式: 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"])

四、结论与建议

  1. Anthropic 原生格式多图能力完全正常 — 实测 18 张大图 / 28MB payload 均可正常处理
  2. 图片数量无硬性上限 — 限制因素仅为上下文 token 总量,而非图片张数或文件大小
  3. OpenAI 兼容格式存在问题 — /v1/chat/completions 的多模态转换在大 payload 时报错,待排查
  4. 建议多图场景使用 Anthropic 原生格式 — /v1/messages 端点,稳定可靠
  5. 关于 [1m] 上下文 — 该参数是 Claude Code / Claude Desktop SDK 层面的兼容处理,直接调用 API 时可能不生效,实际上下文窗口由上游分配决定