概述 对转发端口的 /v1/chat/completions 发送带图请求(OpenAI image_url + data URL 形态)时,若上游或上游路由到的模型拒绝图片,转发端口返回 HTTP 502 且响应体为空。 客户端侧在这时只能看到「服务器错误」,无法区分以下任何一种情况: 上游网络故障(真的该重试) 模型不支持图片输入(该换模型——组合场景换下一个候选) 图片尺寸/格式不被接受(该换图) 三者对应的正确客户端行为完全不同,但转发端口统一吐一个裸 502,组合的降级逻辑也只能盲试。实测中同一个模型(deepseek-v4.1-flash-free)带图请求约一半 502、纯文字 100% 成功(详见发现②的取样数据),每次撞雷都要等整条链轮转空转一圈。 复现步骤 打开转发监听器,发一个带图请求: bash # PNG_B64 = 256x256 纯色 PNG 的 base64(约 1 KB) curl -sS http://127.0.0.1:18899/v1/chat/completions \ -H "Authorization: Bearer $KEY" \ -H "Content-Type: application/json" \ -d '{"model":"deepseek-v4.1-flash-free","messages":[{"role":"user","content":[{"type":"text","text":"颜色?"},{"type":"image_url","image_url":{"url":"data:image/png;base64,'"$( ... )"'"}}]}],"stream":false,"max_tokens":30}' 多发几次:约一半概率返回: 代码块 HTTP 502 (响应体为空,无 error 结构) 期望行为 至少满足一条: 透传可归类错误:上游若返回了可识别的错误(如 400 “model does not support images”),转发端口应按 forwardFailure() 的既有分类表透传为结构化错误(code + message),而不是折叠成裸 502。 构造可读错误:上游连错误体都没有时,转发端口自己构造一个:至少 {"error":{"message":"upstream rejected the image content (model may not support vision): …","type":"invalid_request_error"}},让客户端和组合降级逻辑有据可依。 组合降级增强(见发现③):在组合走链层面预筛 vision: false 的候选,避免把图片投给必然拒绝的模型。 修复建议 响应体为空的 502 建议至少带上转发端口自己的结构化 error;src/forward.js 的 failureReply() / openAiError() 已有能力,只是这个分支没走。 若上游 502 本身就无错误体(上游网关层故障),可在转发端口的 trace 里至少记录一次「upstream 502 with empty body」,供 /summary 或日志消费,方便用户定位是哪一层断了。 版本信息:dsh-our-free-model 2.5.7(插件端),DeepSeek Harness 桌面版,2026-10-21。
Activity