外层模型卡片与分组详情成功率不一致,应该怎么排查?

同一个模型,外层卡片显示 83%,点进分组详情却看到 98%、100% 和 0%。这里的数字只是便于说明口径差异的确定性样例,并非线上实测数据。它们不一定说明数据错了,也不应该直接把详情页数字复制到外层。

真正需要确认的是:两层页面是否在回答同一个问题。外层可能展示分组健康度,详情可能展示真实请求成功率;外层可能读取 24 小时摘要,详情可能读取实时窗口。只要口径不同,数字就必然不同。

下面给出一套从数据源到 UI 的完整排查顺序。

第一步:给每个数字写出完整定义

不要只记录"成功率 83%",而要把指标写成一个可复算合同:

text 复制代码
指标名称:模型分组健康度
统计对象:有请求样本的可用分组
时间窗口:最近 24 小时
聚合方法:每个分组先映射健康档位,再等权汇总
更新时间:客户端将查询结果视为新鲜数据 60 秒,服务端按时间桶聚合

详情页如果是另一套定义,也要完整写出:

text 复制代码
指标名称:分组真实请求成功率
统计对象:该分组内所有有效请求
时间窗口:最近 24 小时
聚合方法:成功请求数 / 请求总数

这一步经常能直接发现:看起来相同的"成功率",其实一个是健康摘要,一个是按请求数计算的业务指标。

第二步:核对服务端的两条聚合链

当前工程里,模型总体成功率先合并请求计数,再用成功数除以请求数。这是按真实请求量加权的结果:

go 复制代码
successRate := float64(total.successCount) / float64(total.requestCount) * 100

同时,服务端还会保留每个分组的独立成功率,避免高流量路线完全覆盖低流量路线的风险信号:

go 复制代码
for _, group := range groups {
	rates = append(rates, math.Round(successRate(groupTotals[group])*100)/100)
}

如果外层卡片使用 group_success_rates,详情页使用单个分组的 success_rate,两者本来就不是同一个字段。排查时先看接口响应,而不是先怀疑 CSS 或四舍五入。

第三步:检查前端是否做了二次转换

很多不一致来自前端把百分比再次映射成档位。例如当前逻辑中,90% 及以上映射成 6 格,70% 到 90% 映射成 4 格,低于 70% 映射成 2 格,然后再对各分组格数取平均。

ts 复制代码
const averageBars =
  validRates.reduce((total, rate) => total + getSuccessRateBarCount(rate), 0) /
  validRates.length

const displayRate = (averageBars / 6) * 100

这类数字应叫"健康度"或"状态评分"。如果 UI 仍写"成功率",用户自然会拿它与详情页真实百分比比较。

修复方向是明确标签:

  • 总体请求成功率:按所有请求计算;
  • 分组健康度:各分组等权反映风险;
  • 分组成功率:详情页单个分组的真实请求比例。

第四步:逐项排除窗口、缓存和过滤差异

如果两边理论上应该一致,再检查下面五项。

时间窗口

外层 24 小时、详情 1 小时,是最常见原因。还要检查窗口起点是滑动时间还是整点桶,以及服务器和浏览器是否使用同一时区。

历史数据补位

有些摘要在当前窗口没有数据时,会读取最近一条历史记录;详情页可能只展示当前窗口。此时外层应标记"历史",不能让用户误认为是实时状态。

缓存更新时间

服务端摘要、React Query 缓存和详情请求可能有不同的更新时间。记录接口返回时间、页面请求时间和缓存失效时间,避免拿一分钟前的卡片与刚刷新的详情比较。

请求过滤

一边排除取消请求,另一边保留;一边只统计已启用通道,另一边含已停用分组,都会改变分母。过滤条件应该进入指标合同和测试用例。

重试与去重

用户一次调用触发三次上游尝试时,模型卡片可能按最终用户请求统计,分组详情可能按每次尝试统计。应同时保存 request_idattempt,明确哪一层去重。

第五步:用一组可手算数据做回归

不要用随机大数据验证聚合。准备三组确定样本:

分组 请求数 成功数 成功率
A 100 100 100%
B 10 5 50%
C 0 0 暂无数据

应该明确得到:

  • 总体请求成功率为 105 / 110 = 95.45%
  • 分组成功率列表为 [100, 50]
  • C 不进入有效分组汇总;
  • 如果健康度采用档位映射,结果必须以"健康度"展示,不冒充 95.45%。

这组样本适合同时保护后端聚合、接口 JSON 和前端格式化逻辑。

产品页怎么改才不误导

最小改法通常包括四项:

  1. 外层卡片把"成功率"改成"分组健康度";
  2. 悬浮说明写清等权或请求量加权;
  3. 详情页显示请求数,避免只有百分比没有分母;
  4. 历史补位、无样本和实时数据使用不同状态。

如果需要对照模型的近期公开状态,可查看 FishAI 模型状态页。这类入口应放在读者需要继续核验的位置,而不是在文末堆叠品牌和网址。

结论

外层卡片与分组详情不一致时,排查顺序应是:指标定义 → 服务端字段 → 前端二次转换 → 时间窗口 → 缓存与过滤 → 确定样本回归

数字不同不一定是 bug,但同名指标采用不同算法一定是产品问题。把"真实请求成功率"和"分组健康度"分开,既保留总体体验,也不会放过低流量分组的风险。

相关推荐
GreenTea1 小时前
vLLM 与 SGLang KV Cache 底层实现机制深度调研报告
前端·后端·算法
天天喝旺仔1 小时前
Go 并发编程:Goroutine 与 Channel 实战
云原生·性能优化·架构·go
几何心凉4 小时前
没有万能模型:我用 AiiOnly Token Plan,把多款大模型的长处拼进同一个项目
前端
kyriewen4 小时前
Claude Code 的额度今天缩水了17%——官方公告上写的是"永久提高25%"
前端·ai编程·claude
雪芽蓝域zzs5 小时前
vue解构平铺VS对象包裹
前端·javascript·vue.js
风骏时光牛马6 小时前
从零到实战,完整AI学习路线
前端
星辰徐哥6 小时前
本地视频预览别只自己看:把Remotion动效项目发给客户远程验收
docker·ai·node.js·html·音视频·react·remotion
三十而立洋6 小时前
深入理解 Monorepo:子包安装依赖
前端·前端工程化
IT_陈寒6 小时前
Java Stream处理大集合,我的内存怎么就炸了
前端·人工智能·后端