Agent 上线前的冒烟走查:一份可勾选的清单
功能说通了不等于能上线。这份走查清单覆盖流式输出、超时、配额、回滚与灰度五个最容易翻车的面。
本文是站点的工程样例文:用来跑通全链路(目录、表格、代码块、MDX 组件),正式内容会陆续替换。清单本身是我真实使用的走查框架,欢迎按自己的业务裁剪。
把一个带 LLM 的功能推到生产前,我会做一轮固定的冒烟走查。它不验证功能对不对——那属于集成测试的事——它验证的是故障来临时系统的行为是否可预期。下面按五个面展开,每一条都可以直接勾选。
一、流式输出:断在中间怎么办#
流式响应最典型的翻车不是慢,是断。用户侧的表现是回答停在一半,转圈,然后没有然后。
走查两条:
- 断开网络 5 秒再恢复,前端是否能继续渲染或给出明确提示;
- 服务端对中断的请求是否记了日志(没有日志的故障等于没发生过)。
// 前端:流中断后的兜底提示,比无限 loading 好得多
stream.on('error', (err) => {
appendNotice('回答中断了,点这里重试上一问。');
telemetry.count('stream.broken', { reason: err.name });
});
二、超时与重试:别让默认值替你做决定#
HTTP 客户端的默认超时通常远大于用户的耐心。走查时确认三件事:
| 项 | 走查点 | 通过标准 |
|---|---|---|
| 连接超时 | 网关到模型服务的超时值 | 显式配置,且小于用户可感知阈值 |
| 重试策略 | 哪些错误重试、重试几次 | 只重试幂等错误,指数退避 |
| 兜底文案 | 全部失败后用户看到什么 | 有道歉、有出路,不是裸报错 |
坑位:重试放大故障
重试写得不对,等于给故障乘了一个系数。429(限流)和 5xx 要区分对待:前者退避更久,后者看情况。无脑重试三次的代码,在配额耗尽当天会把十分钟的服务中断变成三十分钟。
三、配额与降级:今天额度用完了,站还是站着的#
LLM 服务按 token 计费,配额是会真的用完的。走查两个问题:
- 配额耗尽的错误,用户看到的是「服务暂不可用」还是一段 stack trace;
- 有没有一条不依赖模型的降级路径(缓存答案、排队、换模型),哪怕很粗糙。
为什么降级路径要粗糙也要有#
降级路径的意义不在体验,在止损节奏。有它,你能在故障期间从容排查;没有它,你会在压力下做草率决定。
四、回滚:上一版随时能回去#
上线前问一句:回滚到上一版需要几步、几分钟?
- 构建产物是否留了上一个版本;
- 配置(提示词、模型参数)是否纳入版本管理;
- 回滚后数据兼容吗(新版本写过的记录,旧版本读得懂吗)。
# 产物目录按时间戳保留,回滚 = 切一次软链
ls -1 /opt/app/releases/
# 2026-09-20T1015 2026-09-20T0930
ln -sfn /opt/app/releases/2026-09-20T0930 /opt/app/current
五、灰度:先让 5% 的真相进场#
全量上线等于把所有用户当成测试环境。走查确认:
- 流量能否按比例切分(网关层或配置层);
- 灰度期间的关键指标有没有看板:错误率、延迟 P95、成本;
- 出问题后一键切回 100% 旧版的操作路径,写在值班文档里,不是写在某个人脑子里。
小结#
这五个面——流、超时、配额、回滚、灰度——共同回答一个问题:故障发生时,系统是按你设计的剧本走,还是即兴发挥。 冒烟走查就是上线前最后一遍对剧本。
分享给朋友
点右上角 ⋯ →「转发给朋友」或「分享到朋友圈」,即可把本文发给微信好友。