Skip to content

fix(probe): 修正测速/能力实测的两类误判 - #100

Open
ghshhf wants to merge 1 commit into
LAGcomcom:masterfrom
ghshhf:fix/probe-verdicts
Open

ghshhf wants to merge 1 commit into
LAGcomcom:masterfrom
ghshhf:fix/probe-verdicts

Conversation

@ghshhf

@ghshhf ghshhf commented Oct 20, 2026

Copy link
Copy Markdown
Contributor

背景

基于仓库 open issues 中测速与能力对齐的讨论,以及自用中发现的「部分模型卡片永远测不出速度/能力」问题,修正探测路径两类误判。

改动

1. relay.ProbeModel(自定义供应商测速)

旧逻辑:只在读到 data: 帧时判定,若上游忽略 stream:true、以单个 JSON 对象(或 JSON 错误体 / HTML 代理页)应答,会一直读到 EOF 报「上游流在数据帧之前结束」,把可用模型判成未知,且该卡片永远没有首字延迟。

修复:累计所有非 data: 行,在流结束时裁决——

  • 合法 JSON(无 error 字段)→ 判为可用,detail 标注「非流式应答(上游未按 SSE 回帧)」;
  • JSON 错误体 → 走 ClassifyFailure;
  • HTML / 非 JSON → 走分类器(代理页会点名跳转点);
  • 首字节时间改为对首个到达的响应字节计时(SSE 注释帧不再影响)。

2. capsprobe.probeOneModality(能力实测)

ClassifyFailure 把 400/404/422 都归为 CodeServer+Unavailable,旧代码据此把 404(模型名/路由不存在) 写成「不支持该模态」并永久给多模态模型打纯文本标签——一个拼错的模型名就能把可用多模态模型降级。

修复:给 UpstreamError 新增 HTTPStatus 字段,ClassifyFailure 写入状态码;能力实测只在 HTTPStatus != 404 时才记 no,404 一律归 unknown 且不写标签。

测试

  • TestProbeModelPlainJSONAnswer / TestProbeModelNonStreamedJSONError / TestProbeModelNonStreamedHTMLPage
  • TestCapabilityProbeDoesNotTagOnModelNotFound
  • 原有 probe 测试全部保留并通过(go test ./internal/relay/ ./internal/gateway/)

未覆盖(需另行讨论)

  • 热点/订阅节点在中途掉线导致长流被掐:疑似与转发路径 providerStreamIdle=30s 或节点健康探测有关,需真实日志定性,本 PR 不动。

- relay.ProbeModel: 上游忽略 stream:true、以单个 JSON 对象(或 JSON 错误体 /
  HTML 页)应答时,旧逻辑读到 EOF 报「上游流在数据帧之前结束」、把可用模型判成
  未知。改为累计非 data 行:错误体走分类、合法 JSON 判为可用(非流式应答)、HTML
  页走分类器,首字节时间现对首个到达的响应字节计时。
- capsprobe.probeOneModality: ClassifyFailure 把 400/404/422 都归为
  CodeServer+Unavailable,旧代码据此把 404(模型名/路由不存在)写成「不支持该模态」
  并永久给多模态模型打纯文本标签。现新增 UpstreamError.HTTPStatus,404 一律判为
  unknown,不写能力标签。

新增测试:非流式 JSON 应答 / 非流式 JSON 错误 / 非流式 HTML 页 / 404 不写标签。

关联 open issues 中的测速与能力对齐讨论。
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant