返回 AI 测试工程师强化支线
Phase 04 / AI Reliability & Safety 02

AI 应用性能、成本与可观测性教程

从“回答得出来”进阶到“高峰时仍可用、每一分钱可解释、任何版本回退可复现”,完成 AI 测试闭环的运行质量验收。

10 个章节客服 AI 贯穿案例性能 + FinOps + SRE
01

先把质量、速度和钱放进同一条请求链

贯穿案例

案例:电商售后客服 Copilot

客服输入“订单已签收 8 天,鞋子开胶,能否退款?”,系统先做安全检查,再检索售后政策与订单状态,调用模型生成带证据的建议,最后由规则决定自动回复还是转人工。目标不是单纯追求快,而是在正确、安全、可负担的前提下足够快。

一次请求的关键阶段

入口鉴权/排队
检索订单/政策
模型首字/生成
工具资格校验
出口门禁/人审

端到端预算拆解

阶段观测点示例预算失败信号
排队与限流queue_ms、rate_limit_wait_msP95 <= 150ms容量不足或租户不公平
检索retrieval_ms、top_k、cache_hitP95 <= 400ms索引慢或召回退化
模型首字provider_accept 到首个 TokenTTFT P95 <= 1.8s冷启动、排队或长输入
完整生成首字到最后一个 TokenP95 <= 3.5s输出过长或服务降速
端到端request_start 到业务结果P95 <= 5s任一阶段长尾叠加
预算是项目示例,不是行业通用阈值。先用真实业务峰值、客服可等待时间和人工兜底能力校准,再写入发布门禁。
02

分开测 TTFT、端到端与长尾

P50 / P95 / P99

延迟指标口径

指标计算边界回答的问题
TTFT首个响应 Token 时间 - 请求受理时间用户多久看到开始回答
生成耗时最后一个 Token 时间 - 首个 Token 时间流式输出是否拖沓
端到端延迟业务结果可用时间 - 请求进入时间检索、工具、模型合起来多慢
P5050% 请求不超过该值典型体验
P9595% 请求不超过该值大部分用户的坏体验上界
P9999% 请求不超过该值长尾、抖动和容量风险
从一次压测结果计算分位数
const sorted = latencyMs.toSorted((a, b) => a - b);
const percentile = (p: number) =>
  sorted[Math.ceil((p / 100) * sorted.length) - 1];

console.log({
  p50: percentile(50),
  p95: percentile(95),
  p99: percentile(99),
});
// 同时按模型、场景、缓存命中、是否调用工具分组,不能只看总分位数。

测量纪律

  • 预热后再记录稳定态,同时单独保留冷启动数据。
  • 流式请求必须记录首字和末字,不用服务端 200 时间冒充 TTFT。
  • 失败和超时也进入分母,否则延迟会因丢弃慢请求而虚假变好。
  • 每个分位数同时报告样本量、时间窗与成功率。
03

把 Token、检索和工具费用算到一次业务结果

可复核公式
单请求成本公式
C_request =
  T_input  / 1_000_000 * P_input  +
  T_cached / 1_000_000 * P_cached +
  T_output / 1_000_000 * P_output +
  C_retrieval + C_tools + C_retry

// T 是 Token 数,P 是每百万 Token 单价;币种与计费时间必须随报告保存。
// 不能只算主模型:重试、Embedding、重排、OCR 和外部工具都属于业务成本。

计算例:一次售后建议

假设未缓存输入 4,200 Token,输入单价 ¥0.50/百万;输出 850 Token,输出单价 ¥2.00/百万;检索与重排 ¥0.0004。则成本为 4,200 / 1,000,000 × 0.50 + 850 / 1,000,000 × 2.00 + 0.0004 = ¥0.0042/次。若每天 100,000 次且分布不变,日成本约 ¥420。以上价格只是演算值,测试时使用当前合同价。

成本指标与陷阱

指标计算防止的误判
单次 P50/P95 成本按每请求总成本取分位数平均值掩盖超长上下文
每成功任务成本总成本 / 成功且可用结果数便宜但大量失败
每租户日预算租户请求、重试、工具费求和头部租户挤占预算
质量调整成本总成本 / 人审接受结果数低质量输出看似便宜
Token 预算不是简单截断。必须先保护系统指令、证据与关键业务上下文,再压缩历史对话;截断后仍无足够证据时应请求澄清或转人工。
04

用到达率、并发和限流验证容量

不只看 QPS

负载模型

场景流量形态断言
基线1 用户顺序请求建立各阶段延迟与成本基准
阶梯负载每 5 分钟增加 10 并发找到 P95 超门与错误率拐点
突发30 秒内从 5 升到 100 并发队列有界,不发生雪崩重试
长稳目标峰值持续 2 小时连接、内存和限额无累积泄漏
租户竞争大租户突发 + 小租户稳定流量配额隔离,小租户不饿死
并发与吞吐的近似校验
// Little's Law:稳定系统中,并发量 L ≈ 到达率 λ × 平均停留时间 W
// 例:40 req/s × 3.0s ≈ 120 个在途请求
expectedInFlight = arrivalRatePerSec * meanE2eSeconds;

// 实测长期明显高于近似值时,检查排队、重试和下游阻塞。
// 平均数只用于容量估计;发布体验仍以 P95/P99 为准。

限流断言

  • 429/限流响应带可解释错误与退避提示,不返回半截正式答案。
  • 客户端采用带抖动的指数退避,并设置最大次数与总时限。
  • 重试沿用 request_id/idempotency_key,指标中区分原请求与尝试次数。
  • 排队达到上限后快速失败或转人工,不允许无界等待。
05

每条答案都能还原当时发生了什么

可观测字段
一次请求的最小观测事件
{
  "trace_id": "tr_7f31", "request_id": "req_0182", "tenant_id_hash": "t_91a",
  "scenario": "refund_after_delivery", "risk_level": "P0",
  "model": "provider/model", "model_version": "2026-07-15",
  "prompt_version": "refund-v12", "schema_version": "answer-v4",
  "index_version": "policy-2026-08-01", "retrieved_doc_ids": ["POL-17#3"],
  "input_tokens": 4200, "cached_tokens": 0, "output_tokens": 850,
  "queue_ms": 42, "retrieval_ms": 181, "ttft_ms": 932, "e2e_ms": 2940,
  "tool_calls": [{"name": "refund_eligibility", "status": "ok", "latency_ms": 87}],
  "estimated_cost": 0.0042, "currency": "CNY",
  "outcome": "human_review", "error_code": null, "retry_count": 0
}

三类信号如何配合

信号用途约束
Metrics趋势、分位数、错误率、预算消耗标签要有界,request_id 不做高基数标签
Traces拆解检索、模型、工具和队列耗时跨服务传播 trace_id
Logs错误上下文与审计证据敏感字段脱敏,不记录完整 Prompt/用户原文
Eval events质量分、引用、人工裁决和运行 trace 关联但权限隔离
可观测不等于“把所有内容打进日志”。订单号、手机号、用户原文和检索文档都要按最小必要原则脱敏、限权与设置保留期。
06

模型、Prompt 与索引都必须可版本化回归

漂移控制

三类版本漂移

变化可能表现对比方法阻断条件
模型版本质量、Token 或 TTFT 改变固定评估集做候选/基线 A/BP0 硬失败或质量显著回退
Prompt 版本工具选择、格式、拒答边界改变同模型同参数配对比较关键场景通过率低于基线
索引版本引用缺失、旧政策被召回锁定查询集测召回与答案证据现行政策召回失败或过期证据入答
Schema/解析器字段缺失、默认值污染契约测试 + 回放历史响应入库契约不兼容

漂移回归报告必须回答

  • 候选只改了什么,其他版本是否锁定?
  • 全量、P0、长上下文、工具调用四组指标分别如何变化?
  • 质量收益是否值得新增延迟与成本?
  • 线上灰度的停止条件、回退版本和负责人是什么?
07

建立覆盖质量、性能、成本与可靠性的矩阵

可执行组合

售后客服 AI 测试矩阵

维度取值主要指标重点断言
上下文长度短 / 典型 / P95 / 超限TTFT、成本、截断率关键证据不被截断
检索状态命中 / 空 / 慢 / 旧索引检索耗时、证据率空证据不编造政策
工具状态成功 / 429 / 超时 / 5xx成功率、重试、E2E副作用不重复
流量基线 / 阶梯 / 突发 / 长稳P95/P99、队列、429限流可控且租户隔离
风险咨询 / 金额 / 权限 / 隐私人审率、硬失败高风险不得静默降级
版本现网 / 候选模型、Prompt、索引质量、延迟、成本差量变化可归因可回退

最小实验设计

  1. 固定评估集、随机参数、计费表和基线版本。
  2. 先单变量比较,再做高风险组合;不要一次同时换模型、Prompt 和索引。
  3. 每个组合记录成功、失败、超时与人工接受结果。
  4. 对差量做业务解释,不能只凭总平均值宣布变好。
08

主动注入慢、错、限额与不可用

验证失败安全

失败注入清单

注入预期系统行为禁止行为
模型 TTFT 超时取消请求,展示可重试状态或转人工把未完成文本当正式答复
提供方 429按预算退避,达到上限后停止多个节点同时无界重试
检索超时/空结果说明证据不足,限制回答范围脱离证据编造退款政策
工具 5xx只重试幂等读操作;写操作先查状态重复创建退款或工单
成本计数缺失标记计费未知并告警按 0 成本放行预算门
旧索引误路由版本校验失败并回到稳定索引混用新旧政策生成答案
失败场景断言伪代码
given({ model: "timeout_after_first_token", retrieval: "ok" });
const result = await runCase("REFUND-017");

expect(result.publishable).toBe(false);
expect(result.state).toBe("HUMAN_REVIEW");
expect(result.partialAnswerStoredAsDraft).toBe(true);
expect(result.retryCount).toBeLessThanOrEqual(2);
expect(result.trace.errorCode).toBe("MODEL_TIMEOUT");
09

把预算门、发布门与分级降级写成策略

守住业务底线

发布门禁示例

候选标准失败动作
质量门P0 通过率 100%,总体质量不低于基线阻断发布,查看差异样本
延迟门TTFT P95 <= 1.8s;E2E P95 <= 5s;P99 <= 10s定位阶段长尾或回退版本
可靠性门成功率 >= 99.5%,错误预算未耗尽停止灰度扩量
成本门每成功任务 P95 <= ¥0.012,日预测不超预算压缩上下文或切换方案
漂移门模型/Prompt/索引均有版本与回退证据禁止不可归因变更上线

按风险降级,而不是一刀切

触发允许降级必须转人工/停止
预算接近上限低风险问答用小模型、缩短非关键历史资金与权限判断不因省钱绕过规则
检索不可用展示已有订单事实并说明限制政策结论、承诺与退款资格
模型超时保存草稿,允许客服手工回复禁止发布半截或无证据答案
高峰限流低优先级排队或异步通知紧急投诉和高风险请求进入人工通道
人工不是无限容量的“万能降级”。人审队列也要有 SLA、容量告警与超时处置;队列饱和时系统应明确停止自动承诺,而不是继续制造风险。
10

完成一次可复现的性能成本验收

练习与交付清单

练习

  1. 准备 30 条售后评估样本,标注风险、上下文长度、是否检索和是否调用工具。
  2. 记录基线的 TTFT、E2E P50/P95/P99、成功率和每成功任务成本。
  3. 执行阶梯、突发和长稳测试,验证限流、公平性与重试上限。
  4. 分别替换候选模型、Prompt、索引,输出质量/延迟/成本差量。
  5. 注入模型超时、429、检索空结果、工具 5xx 和成本字段缺失。
  6. 配置质量、延迟、可靠性、预算与漂移门,演练小模型、只读、排队和转人工。

数据与脚本

  • 分层负载数据
  • 固定评估集
  • 故障开关
  • 分位数计算

观测与报告

  • Trace 可串联
  • 版本可归因
  • 成本可复核
  • 隐私已脱敏

上线治理

  • 门禁有负责人
  • 灰度有停止线
  • 降级守边界
  • 回退已演练