给Agent压测,别瞎造请求,回放线上日志当样本

📅 2026/6/30 3:17:55
给Agent压测,别瞎造请求,回放线上日志当样本
压测 Agent 这事我一开始拿一句你好循环打几千遍跑出来 QPS 漂亮得很结果真上线被真实流量打趴了。问题出在样本——真实用户的问题长短不一、有的触发工具有的不触发、有的命中缓存有的不命中用一句固定问候压压的是个假场景。后来我改成回放线上日志压测结果才跟生产对得上。为什么固定样本测不准Agent 的耗时和成本跟问题本身强相关短问题模型生成快长问题带长文档的 RAG慢好几倍触发工具调用的请求要多走一次模型推理 工具往返延迟翻倍重复问题可能命中缓存毫秒返回混进样本会把平均延迟拉得虚低。你拿单一样本压要么全是快的、要么全是慢的压出来的数字没法指导容量规划。做法脱敏后回放真实流量把线上一段时间的请求日志捞出来脱敏手机号、姓名这些必须抹掉做成压测样本池按真实比例回放。import json, random, asyncio, time # 1. 从日志导出样本已脱敏保留问题文本和它当时的特征 samples [json.loads(l) for l in open(traffic_sample.jsonl)] # 每条形如 {msg: 怎么退货, hit_tool: false, tokens: 120} async def replay(concurrency50, duration60): sem asyncio.Semaphore(concurrency) latencies, errors [], 0 end time.time() duration async def one(): nonlocal errors async with sem: s random.choice(samples) # 按真实分布抽 t0 time.time() try: await call_agent(s[msg]) latencies.append(time.time() - t0) except Exception: errors 1 tasks [] while time.time() end: tasks.append(asyncio.create_task(one())) await asyncio.sleep(1 / concurrency) await asyncio.gather(*tasks) report(latencies, errors)我盯的几个指标别只看平均延迟平均会骗人。我看这几个P95 / P99 延迟长尾才是用户体验崩的地方。平均 1.2 秒很好看P99 到了 8 秒就有一批用户在干等。首 token 延迟流式输出场景用户最在意的是多久开始出字不是全部跑完。错误率随并发的变化曲线从 10 并发加到 100看错误率在哪个点开始陡升那就是你的容量上限附近。token 消耗速率顺手能估出满负载下一小时烧多少 token、多少钱做预算。一个反直觉的发现我压到一定并发瓶颈居然不在模型 API而在我自己代码里——RAG 检索那段没做连接池并发一高数据库连接被占满请求全堵在检索这步。要不是用真实样本带 RAG 的请求回放纯打问候语根本暴露不出来这个瓶颈。压测的价值一半在数字一半在逼出这种藏着的坑。说点不好的回放线上日志最大的麻烦是脱敏得认真做别把用户隐私当压测样本到处传——这条是底线。另外回放是过去的流量遇上大促这种没发生过的峰值历史样本里没有还得人工构造极端样本补充。压测能测出现在扛不扛得住已知流量测不出没见过的流量别指望它替你预言未来。模型推理走的讯飞星辰MaaS 现成 API压测时按真实样本打过去它的限流和延迟表现直接反映到我的指标里我不用自己维护一套推理算力再单独压模型层省一大块。你们压 Agent 是造样本还是回放真实流量P99 卡在哪一步最多评论区聊聊。