M7 cost-per-case + p95
前两天落地了 outcome 四指标里的「准」(FPR,Day 162)和「好」(SAR 质量,Day 163)。
阶段: B17 · outcome 指标仪表盘 + A/B(Day 161-170) 标签: #cost-per-case #p95-latency #unit-economics #deepseek-v4
今日导引(由浅入深)
前两天落地了 outcome 四指标里的「准」(FPR,Day 162)和「好」(SAR 质量,Day 163)。
今天 Day 164 一次落地剩下两个硬数字——「贵」(cost-per-case)和「快」(p95)。
这两个合起来决定单位经济性:一套又准又好但每案件烧 $5、p95 要 60 秒的系统,在生产里没人用。
在 B1→B18 曲线上,这是把 AI 方案从「能跑」推到「算得清单位成本」的一步——AISA 面试 hiring manager 四问里的「成本」那一问,靠的就是这种可链接的真实成本数字。
最小可判定产出:把 cost+latency 采集接到 attributeMap,p95 复用 summarizeLatency,跑 20 案件出 cost-per-case 与 p95 两个数(需 key)。
1. 机理精读
cost-per-case 的公式与口径。
cost-per-case = (输入 token + 输出 token) × 单价 / 案件数。
三个口径必须钉死:
- 输入输出 token 分开记——多数模型输入输出单价不同;
- 单价用当周 OpenRouter 真实价,不能用过时 id 的旧单价;
- 分母是「案件数」不是「请求数」——一个案件可能跨多次 LLM 调用(证据汇集 + 类型学比对 + SAR 草稿),要全部累加。
本仓真实跑过的成本基线是 DeepSeek V4-Flash $0.0139/run,这是已测真值。
p95 为什么比均值重要。
时延分布通常右偏长尾:大多数请求很快,少数请求(长 prompt、重试、限流)很慢。
- 均值会被长尾轻微抬高但仍掩盖最坏体验;
- p95(第 95 分位) 直接报「95% 的请求都比这快」,反映的是尾部体验。
生产 SLO 几乎都按 p95/p99 定,不按均值定——因为用户感知的是最慢的那批请求,不是平均请求。
为什么 cost 和 p95 要放一起看。
两者是单位经济性的两个轴:cost 是「每案件花多少钱」,p95 是「每案件最坏要等多久」。
- 可以用更便宜的模型压 cost,但可能换来更高 p95(小模型重试多);
- 也可以并行化压 p95,但可能抬高 cost(重复调用)。
把两者并排进仪表盘,才能看清这种权衡,而不是只优化一个指标把另一个搞坏。
与相邻概念的边界。
今天的 p95 实现(summarizeLatency)是已 built+tested 的纯函数,输入时延样本就能出 p50/p95/p99;cost 的单条 run 真值($0.0139)也是已测的。
但「20 案件聚合的 cost-per-case 与 p95」需要真实跑一遍 eval:agent(需 key),属于 key-gated 外部动作——今天接好线、备好真值锚点,不臆造聚合数。
2. 推导 / 手算 / 代码走读
p95 实现 src/agent/eval/stats.ts 的 summarizeLatency 已 built + tested。走读:
-
summarizeLatency(samplesMs):- 先
[...samplesMs].sort((a,b)=>a-b); - 返回
{n, p50, p95, p99, mean},p50/p95/p99 都走percentile(sorted, p),mean 走mean(samplesMs); - 注释点明设计意图:「p95/p99 surface the tail that the mean hides.」
- 先
-
percentile(sorted, p):线性插值分位——idx = (p/100)×(len−1),lo=floor, hi=ceil,w=idx−lo;- 返回
sorted[lo]×(1−w) + sorted[hi]×w; - 空数组返回 NaN,单元素直接返回该元素。
-
cost 采集挂点
src/aml/observability/attributeMap.ts:- token 数走 semconv 属性
GEN_AI_ATTR.USAGE_INPUT_TOKENS/USAGE_OUTPUT_TOKENS(toSemconvAttributes里if (span.inputTokens !== undefined) attrs[...] = span.inputTokens); - 注意该文件当前不真正上报(注释明确「当前不真正上报——需后端 collector + 真实 LLM 调用元数据」),所以 cost 采集是把 token 字段接进来、乘单价,不是接 OTel collector。
- token 数走 semconv 属性
p95 手算:
时延样本 [120, 150, 180, 220, 300, 350, 400, 900](n=8,已排序)。
p95:
idx = 0.95 × 7 = 6.65lo=6, hi=7, w=0.65- p95 =
sorted[6]×0.35 + sorted[7]×0.65 = 400×0.35 + 900×0.65 = 140 + 585 = 725ms
对比 mean = (120+150+180+220+300+350+400+900)/8 = 2620/8 = 327.5 ms。
可见那个 900ms 的长尾把 p95 拉到 725,而均值 327 完全掩盖了 725 的尾部体验。这正是 p95 存在的理由。
cost-per-case 手算(口径示范,非真值):
若一个案件累计 input=1500、output=600 token,input 单价 $X/M、output 单价 $Y/M,则:
- 单案件 cost =
1500/1e6×X + 600/1e6×Y - 20 案件的 cost-per-case = 20 案件总 cost / 20
本仓已测的单条 run 真值是 $0.0139(V4-Flash)——可作为锚点校验聚合数量级是否合理。
3. 今日实战
- 把 cost + latency 采集加到
src/aml/observability/attributeMap.ts(接 token 字段 + 记录每步时延样本)。 - p95 直接复用
src/agent/eval/stats.ts的summarizeLatency(p50/p95/p99 已 built),不另写分位实现。 - cost 项用 token×当周 OpenRouter 单价(V4-Flash/Pro)/ 案件数算 cost-per-case。
- 跑 20 案件
pnpm eval:agent(需 key)出 cost-per-case 与 p95 两个数;用 $0.0139/run 校验数量级。
4. 今日实测 / 产出
stats.ts的summarizeLatency已 built + tested,可直接出 p50/p95/p99。- 真实成本已测:V4-Flash $0.0139/run。
- 20 案件聚合的 cost-per-case 与 p95(ms) = 待跑(需 key 跑 eval:agent),将产出 cost-per-case=$X.XX、p95=Yms;单条 run 成本 $0.0139 是已测真值。
- 不臆造 20 案件聚合数——仅有的真实成本数字是 $0.0139/run。
5. 常见误区 / 陷阱
- 用均值代替 p95 报时延:均值掩盖长尾(手算里 327 vs 725),生产 SLO 必须按 p95/p99。
- cost 分母用「请求数」而非「案件数」:一个案件多次 LLM 调用,必须全部累加再除以案件数。
- input/output 单价混用:两者单价通常不同,要分开乘。
- 把 $0.0139/run 当 cost-per-case:$0.0139 是单条 run 真值,cost-per-case 是跨多次调用的案件级聚合,二者不是一回事;后者需跑 eval 才有。
- 引旧模型 id 单价:legacy
deepseek-chat/-reasoner单价不能再用(见 SOTA 检查)。
6. 学习资源(每条带 YYYY-MM)
- OpenRouter pricing(2026-06)——DeepSeek V4-Pro / V4-Flash 当周单价,价格波动快需复查。
- OTel GenAI semantic conventions(2026-03)——
gen_ai.usage.input_tokens/output_tokens指标命名(仓内attributeMap.ts沿用)。 - 本仓代码:
src/agent/eval/stats.ts的summarizeLatency/percentile(p95 实现)、src/aml/observability/attributeMap.ts(token/cost 采集挂点)。 - DeepSeek-V4 模型卡 / 定价页(2026-06)——确认
deepseek-v4-pro/deepseek-v4-flashid 与单价。
SOTA检查 (2026-06 更新)
- 当前主流:DeepSeek V4 模型 id 为
deepseek-v4-pro/deepseek-v4-flash;p95/p99 + cost-per-case 是单位经济性的标准 outcome 度量,仍 SOTA。 - 过时黑名单:legacy
deepseek-chat/deepseek-reasoner于 2026-07-24 退役——成本模型里禁止再引旧 id 单价。 - 下次复查点:OpenRouter 2026-06 单价需执行当周复查(价格波动快);临近 2026-07-24 复查所有成本配置已切到 V4 id。
衔接
- 昨天:Day 163 — M7 SAR 质量量化(rubric 四维加权聚合)。
- 今天:cost-per-case(token×单价/案件数)+ p95(时延尾部),单条 run 真值 $0.0139,聚合数待 key 跑。
- 明天:Day 165 — 活仪表盘聚合(把 4 指标合成带 delta 的 snapshot JSON)。