上个月有一天早上,手机震了七条异常告警。一条一条翻完,全是活动期间的正常波动。四十几分钟搭进去了,没有一条是真的问题。
我坐在那愣了一下。不是愣白花了四十几分钟--是愣我居然对这种白花时间的事毫无感觉了。可能是习惯了吧。
───────────────────────
我可能三个月没认真看告警了
最早连告警都没有。每天早上泡杯咖啡,打开面板,从DAU翻到客单价再到各条线的转化率,头从到尾一遍。四十几个指标,天天翻。翻完大概四十分钟,记几行笔记。
后来写了个3-Sigma脚本。
python
df['mu'] = df['metric_value'].rolling(30).mean()df['sigma'] = df['metric_value'].rolling(30).std()df['is_anomaly'] = (df['metric_value'] > df['mu'] + 3*df['sigma']) | (df['metric_value'] < df['mu'] - 3*df['sigma'])
拉三十天均值标准差,偏三个sigma就亮灯。每天早上七八条推送,跑了有大半年。
我是到了第三个月才注意到一件事:我不看告警了。不是刻意的——连续好几天每条点进去都是虚惊之后,手指自动就划过去了。扫一眼飞书卡片、大脑判断"又是那堆东西"、继续干别的事。
后来翻了一下那个季度的记录。推送了四百多条告警,我认真翻了的不超过四十条。剩下三百六十条,它的作用不是帮我发现问题——是让我大脑学会了一个新技能:自动过滤。
比没有告警还要命。没有至少你知道自己得去看。
─────────────────────────
不是脚本的问题
双十一那天运营砸了几万拉新。订单飙了四成,客单价跌不少。脚本把五个主指标全标红了。
一条一条翻。全是活动效应。快一个小时搭进去了。
不是3-Sigma错了。正常数据往三个标准差外跑,它就该亮。

问题是它没有"今天有活动"这个上下文。对支付流水这种全年平稳的指标,八九成准确。订单量这种每周有波峰波谷的,活动期准确率直接掉到接近零。
我加了一层IQR。
python
q1, q3 = df['metric_value'].quantile(0.25), df['metric_value'].quantile(0.75)iqr = q3 - q1df['iqr_anomaly'] = (df['metric_value'] < q1 - 1.5*iqr) | (df['metric_value'] > q3 + 1.5*iqr)df['final'] = df['is_anomaly'] & df['iqr_anomaly']
1.5那个阈值是试出来的。1.0太紧什么都标,2.0太松漏了两条真异常。1.5卡在中间,没什么科学道理。
阈值 | 结果 | 规律 |
1.0倍IQR | 太紧,日常波动都报 | 用得最窄的IQR,小波也抓 |
1.5倍IQR | 刚好,筛掉日常留异常 | 标准的统计拐点 |
2.0倍IQR | 太松,真异常也漏了 | 只有极端值才亮,迟钝 |
双筛之后推送从七八条降到大概十来条——可几十个指标,十来条也够呛。里面真正需要看的,三四条。
花十几分钟翻完,找三四条,投入产出还行,但逼近底线了。
───────────────────────
prompt写越细,它越瞎
刚好那阵子在试AI写SQL,顺手把第二道筛扔给AI了。
第一版我列了六个判断条件——活动期排除、连续三天下行才报、突破历史极值、排除周末、同比超20%,还留了个"..."。以为覆盖得挺全。跑了一个多礼拜发现有个指标连掉了三天,不报。翻回去查——小促当天,"排除活动期间"卡住了。规则不管规模,看到"活动"俩字直接跳。
后来全删了,留下三条:波动幅度有没有超出历史范围、连着好几天了没有、跟去年同期对不对得上。
text
统计粗筛后的异常列表 + 近七天趋势 + 近三十天分布→ AI判:真变化 / 周期波动 / 可忽略推出来大概三到四条的样子

三比六好使。不是AI更聪明——是你不给它那么多条件之后,它终于不用当条件过滤器了。
推出来的跟我手动翻的,差不太多。但它比我看得快——我翻十几条十来分钟,它两三秒。那个差距不是省的判断时间,是省了翻的动作。
国庆节翻过一回大的。日活从两百八掉到一百九,叮叮了好几天。我翻了又翻——跌是跌,同环比都难看,拆开看也看不出结构问题。第三天晚上躺着才反应过来:国庆,放假了。我在对着面板看了快一周,完全没想过日期这回事。
后来加了一份假期日历和活动日历。到日子自动切同比。
───────────────────────
扔进OpenClaw之后,有些事比我想的有意思
今年年初把整套逻辑迁到OpenClaw上。定时任务+飞书推送自带的,之前写的cron跟webhook全扔了。主要是把逻辑从代码里拆成了yaml:
yaml
rules:- name: weekend_normalcondition: day_of_week in ['saturday', 'sunday']action: use_yoy- name: holiday_specialcondition: date in holiday_calendaraction: use_yoy- name: promotion_knowncondition: promotion_calendar has current_weekaction: skip
拆完之后有个完全没想到的好处:改规则不用开IDE。打开yaml加一行,保存就生效。活动日历运营那边能自己改,不用找我。
迁移前 | 迁移后 |
改一条规则:开IDE→改代码→跑测试→部署,约20分钟 | 改yaml加一行,不到一分钟 |
假期规则漏加了懒得改("算了下次再说") | 日历文件运营维护,到日子自动生效 |
规则嵌在Python里,运营看不到 | yaml放共享目录,谁都能看懂 |

迁移完有个事让我挺意外的——它居然记得上周的判断。有个指标连着三个周一早上红灯。周末基数低、周一跳升,周期性的。前两次手查确认了。到第四周,推送自己备注了"连续四周周期性波动,不用管了"。OpenClaw本地有持久记忆。
现在每天推一两条,偶尔没有。统计那层拿3-Sigma加IQR双筛扫四十个指标,不判断,只标"偏离正常范围"。AI那层拿结果,配着趋势跟分布看是不是真有问题。业务规则那层管周末假期活动期——不在prompt里在yaml里,硬过滤。
也不是就没毛病了。最头大的是基线——每季度得重拉一遍。Q1日活日均三百万,Q2掉到两百六,拿Q1的基准套Q2数据,正常波动标红。反过来Q4拿Q1基准,该红的平了。

基线不重拉,该警不警不该警瞎警。统计方法有个前提假设——数据分布不变。业务变了,方法没变。
───────────────────────
每天花大概一两分钟,扫一眼卡片。哪天推送没了,我还真得去翻一下。不是怕漏了异常——是分不清到底是没事,还是检测自己挂了。那种不知道,比收到一堆告警还让人不舒服。
夜雨聆风