ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

不用先搭评估平台:三步把线上 trace 抽样变成一组能跑的不变量断言

不用先搭评估平台:三步把线上 trace 抽样变成一组能跑的不变量断言 周四下午的周会客服同学把一张截图投到屏幕上用户问『这单能不能改地址』Agent 回了三段很专业的条款其中一条根本不存在。你下意识去翻监控面板——错误率平的P99 没动最近一次发版是十一天前。上线前那份评测报告还挂在群里通过率很好看。没人指责谁。因为所有人的动作都对评测跑过了门禁放行了线上没报错。错的是那个没人怀疑过的分工——我们默认『评估』这一棒在上线前就跑完了上线后交给监控监控看的是有没有 500。而 Agent 的质量塌方常常不打断这条链。九月初 AWS 那篇挂在 Big Data Blog 上的技术实操正好说明为什么Amazon OpenSearch Service 官方把『观测并评估生产环境的 AI agent』写成了一篇 Technical How-to难度标到 Advanced 300——一个云厂商愿意用这个级别讲一件事通常意味着它认为这件事以后是日常工程不是前沿探索。两枚同向的一手信号第一枚2026-09-01AWS 官方 Big Data Blog 用 Agent Health 能力讲怎么在生产环境观测并评估 AI agent。第二枚2026-08-13据 Dynatrace 官方新闻稿Dynatrace 宣布以约 $915M 收购 AI 观测/评测厂商 Arize官方口径很直白——要把『上线前的实验与评测』和『上线后的生产观测』连成一条闭环。一家在自己文档里把『生产环境的评估』抬成技术实操一家花真金白银把评测公司买进来专门为了连这条线。两家没有互相抄作业但指向同一件事评估这件事的时间边界正在往后挪。标题里那半句『OpenAI 之外』要交代清楚免得被当成对比评测本文不替任何模型厂商下结论也不引它们的任何数字用这个说法只是标一个位置差别——过去把『怎么评模型』讲得最响的通常是模型厂商自己而这次开口的是卖搜索与运维平台的云厂商。这是一个值得注意的发言者变化不是一份成绩单。这对测试团队意味着我们那套『上线前评测一次、上线后只看可用性』的分工正在被行业当成一个过渡形态。下面这条回路就是把它落地的最小形状。维度上线前一次性评测上线后持续评估触发时机版本门禁、MR/发版前跑一轮按小时/按天滚动抽检跨版本长期跑数据来源人工整理的评测集、golden case线上真实 trace、真实用户问法与真实上下文判定形态一组分数 一条通过线属性不变量 抽样通过率 置信区间失败处置拦版本回炉不拦版本产出工单与回归新用例连续红才升级为什么监控一眼看不出来监控的判定单位是『请求有没有失败』。Agent 塌方的典型形态恰恰不是失败是成功的错误HTTP 200延迟正常回复通顺逻辑自洽只是引用了一条不存在的条款、多调了一个不该调的写操作工具、把三个人的订单金额算成了负数。这类问题在错误率曲线上是隐形的只有把它翻译成断言才看得见。所以持续评估不是『把评测集搬到线上跑』——线上没有标准答案可比。它是另一套东西断言落在输出属性上不落在字面答案上。同一问句今天答『可以改』明天答『未发货前可以改』都算对但『引用必须来自本次检索到的文档』『不得调用白名单外的工具』『金额为负就是错』『查不到依据就必须拒答』这四条跑一万次都得成立。这就是接口时代『生产日志采样→回放成回归用例』那套老招的新形态。骨架一个字没改改的是下面两层垫板被测对象从确定响应变成分布输出判定从 status code 变成一组属性断言加一个统计区间。第一步抽样别全采线上 trace 全量评估是最快死掉的做法——模型调用要钱评估本身也要钱。抽样策略得先按『会不会暴露问题』分层而不是按流量比例一刀切。# ce_sampler.py —— 线上 trace 抽样器可疑带全采正常带 head tail 混合 import random from collections import defaultdict LOW_CONF, COST_MULTIPLIER 0.6, 2.0 # 低置信阈值 / 成本越带倍数 def sample(traces, head_rate0.05, tail_per_route3, seed7): forced, normal [], [] for t in traces: over_cost t[cost_usd] t[route_cost_p99] * COST_MULTIPLIER if t[has_error] or t[confidence] LOW_CONF or over_cost: forced.append(t) # 错误带 / 低置信带 / 成本越带100% 入样 else: normal.append(t) head random.Random(seed).sample(normal, max(1, int(len(normal) * head_rate))) by_route defaultdict(list) for t in normal: by_route[t[route]].append(t) tail [x for g in by_route.values() # tail-based每条路由保留最贵的 N 条 for x in sorted(g, keylambda v: -v[cost_usd])[:tail_per_route]] out, seen [], set() for t in forced head tail: if t[trace_id] notin seen: seen.add(t[trace_id]); out.append(t) return out为什么这么分错误带和低置信带是全采的因为它们是问题的富矿采样率在这儿是纯浪费正常流量才需要 head-based无偏地量整体水位和 tail-based把长尾里最贵的调用钉住否则成本分布的右尾永远看不见混合。踩过的坑是把 head 比例调到 30% 求『稳』——抽样成本线性上涨水位却早就测平了真正缺的是尾部那几个罕见路由加钱不如加 tail 桶。第二步断言落在属性上# ce_asserts.py —— 对样本跑一组不变量断属性不断字面 ALLOWED_TOOLS {search, query_order, logistics} def check(trace, answer): answer: 结构化应答trace: 该次调用的原始记录含检索到的文档、工具调用序列 cited answer.get(citations, []) return { json_ok: isinstance(answer, dict), amount_nonneg: all(v 0for k, v in answer.items() if k.endswith(_amount)), grounded: all(c in trace[retrieved_ids] for c in cited), no_priv_tool: not set(trace[tool_calls]) - ALLOWED_TOOLS, refused_when_no_evidence: Trueif trace[retrieved_ids] else bool(answer.get(refusal)), } def is_pass(flags): return all(flags.values())五条断言里没有一条问『答案对不对』。它问的是证据链在不在grounded、权限边界破没破no_priv_tool、该拒的时候有没有硬编refused_when_no_evidence。这三类恰是监控完全看不见、而业务最在意的塌方方式。踩过的坑是把 grounded 写成『有 citations 字段就算过』——模型在检索为空时最爱凭空造两个像样的文档号必须比对回本次真实检索到的 ID 集合。线上可观测信号翻译成哪条不变量建议抽检频率落进回归的动作空检索却给了具体答案无依据必拒答每小时按路由分桶红样本原样入回归集标ce_no_evidencecitations 不在本次 retrieved_ids 内引用可溯源每小时按文档域聚成缺陷单同域连续红则进版本门禁工具调用序列出现白名单外操作越权工具调用 0全采属错误带立刻阻塞发布并新增一条跨工具回归用例单会话成本超本路由 P99 若干倍成本带宽断言每日 tail 桶反查是否重试/长上下文退化补一条长度边界用例同一问题模板下金额/数量字段出现负值数值域断言每小时进数据不变量用例集与接口契约用例并表第三步通过率必须带着区间出门# ce_gate.py —— 抽样通过率 bootstrap 置信区间 单条成本聚成一行门禁判定 import random def gate(flags, cost_per_sample, floor0.95, n_boot2000, alpha0.05, seed7): ifnot flags: returnN/A, N/A, 样本为空抽样链路或路由分桶先修好 rng random.Random(seed) boots sorted(sum(rng.choices(flags, klen(flags))) / len(flags) for _ in range(n_boot)) lo boots[max(0, int(len(boots) * alpha / 2))] hi boots[min(len(boots) - 1, int(len(boots) * (1 - alpha / 2)))] rate sum(flags) / len(flags) total_cost len(flags) * cost_per_sample if hi - lo 0.15: verdict f区间 {lo:.2f}–{hi:.2f} 宽到没有判定力先加样本再加结论 elif lo floor: verdict f绿置信下界 {lo:.3f} ≥ 线 {floor} elif rate floor: verdict f黄点估计 {rate:.3f} 达标但置信下界 {lo:.3f} 已破线看细分桶 else: verdict f红点估计 {rate:.3f}、下界 {lo:.3f} 双双低于 {floor}本轮红样本进回归 returnf{rate:.3f} [{lo:.3f}, {hi:.3f}], f${total_cost:.2f}, verdict if __name__ __main__: flags [1if i % 17else0for i in range(120)] # 演示样本约 93% 通过 print(gate(flags, cost_per_sample0.02))三个设计点。区间比点估计值钱120 条样本跑出 92%和 12000 条样本跑出 92%工程含义完全不同——前者可能只是运气后者才够你写进周报所以判定先看置信下界不看点估计。样本太少时最诚实的结论是『这条判定现在没资格下』把区间宽度当报警项而不是硬凑一个通过线。成本跟在同一行输出里持续评估最先死掉的不是准确率是账单——没人知道自己这轮抽检花了多少钱就没人会为它保预算。还有一处必须写进口径的坑这份抽样是有偏的。错误带全采意味着样本里失败被刻意富集gate打出来的通过率天然低于线上真实水位。这是特性不是缺陷——它是探测器不是报表。但你必须同时出两条曲线一条只用 head 桶算代表『线上整体怎么样』可以拿去和业务对表一条用全样本算代表『这轮抽到的问题密度』用来排工单优先级。把两条合成一条的 team第一次大促就会出现『监控说没事、评估说崩了』的僵局而两边都没说谎。评估也得分层确定性断言免费judge 才花钱上面五条不变量全是纯代码查 ID 集合、查工具白名单、查数值域跑一万条也不花一分钱模型预算。真正贵的是语义层判断——『这条回答是否真的解决了用户问题』『这段解释有没有误导』只能靠评审模型或人。正确的接法是分层第一层零成本的属性断言全量跑在抽样集上第二层评审模型只吃第一层的红样本与 head 桶里的固定比例。这么一改评估预算能砍掉大半而且是唯一能让持续评估长期跑下去的改法——因为它的成本随线上流量线性增长的那一档被切掉了留下的成本只和问题量相关。踩过的坑是第一层写太松属性断言漏过去的那批全落到昂贵的第二层预算立刻爆掉然后整个链路会在某个季度被静悄悄关掉。落进 CI这条回路闭合的动作抽样任务挂每日定时大促期提到每小时产出的红样本自动开一张工单附 trace_id、命中的是哪条不变量、该路由近七天通过率曲线。真正让闭环闭合的是下一步红样本进回归集并带上ce_前缀的标签下一次版本评测时这些线上真问法会和手写 golden case 一起跑。这样你的回归集不再是三年前设计、再也没长过的新陈代谢停滞集合而是每周从线上吸血的活集合。第二个必须守住的纪律是抽样口径不能随版本改动。head 比例、低置信阈值、tail 保留条数这三样一旦改了通过率曲线就断成两截——你分不清上周三那个台阶是模型退化了还是你把 tail_per_route 从 3 改成了 5。做法很朴素把这三个参数写进一个带版本号的配置文件和断言清单一起进仓库改一次提一次 MR并在曲线上打一条竖线标注口径变更。持续评估的价值全在『长期可比』这四个字上一次没人记录的调参就能让它前几个月的积累作废。这套打法哪里不成立三条边界。第一AWS 那篇是 Technical How-to 层级的官方实操不是基准报告——它讲的是能力可用不代表任何分数或行业水位本文也没引用它的任何指标结构。第二抽样的前提是 trace 里真的有 retrieved_ids 与工具调用序列这两类字段如果你的 agent 只留了问答文本grounded 与 no_priv_tool 这两条断言就是空转先把埋点补齐再谈持续评估。第三属性不变量守底线不守上限五条全绿仍然可能是一条糟糕的建议更值得警惕的是假绿——断言写得太机械时模型会稳定地『合规地胡说』所以每周得人工翻二十条绿样本校准清单本身这份校准记录也是评审模型可信度的唯一凭证。另外要坦白本文的抽样阈值、频率、区间宽度、成本量级全是示例设定接进去第一件事应该是按你真实流量重算一遍。结语本季度最小动作不用等一个评估平台。挑一个已经上线的 agent 场景把它的 trace 按今天这三段代码跑一遍——抽样、五条不变量、一行带区间的判定——一周后你会第一次拿到一个监控和评测报告都给不出的数字线上真实问法下这个 agent 的属性不变量通过率是多少区间有多宽。不报错的塌方只有断言能看见而断言要跑在哪条时间轴上行业已经给出答案——上线之后天天跑。
返回列表