风眼洪涝维度改造复盘:单因子分级会在最危险时段给出最低档
一句话:当分级依据只覆盖一条致灾路径,遇到走另一条路径的极端个例时,它不是”不够准”,而是给出反向信号——风眼按风力推档,美莎克减弱成热带低压后档位回落到四档最低的蓝色,而那正是伤亡最集中的 26 小时。
事实记录(不可修改区)
- 项目:风眼 · Typhoon Eye(
E:\typhoon-eye),台风实况与分级应急预案单页站。双发布面:GitHub Pages + B 站 Toy(slugYliUzbE5TOqySu4G/ id8980525008896) - 起因:2026-08-21 QQ 群里群友称”7 月初的美莎克台风在广西正面登陆”,并把”风眼上查不到实况数据”当作佐证之一转发。作者要求核查
- 核查结论(外部事实):
- 美莎克 = 2026 年第 10 号台风,国际编号 2610,强热带风暴级,全程未升格为台风级
- 两次登陆均不在广西:7-03 18:20 前后登陆海南陵水黎族自治县椰林镇(23 m/s);7-04 20:30 前后二次登陆越南广宁省芒街市(10 级 / 28 m/s)。芒街紧贴中越边境,台风在越南一侧登陆后随即进入广西
- 登陆后结构不散反而在陆上重建眼区,眼区经广西东兴入境,在广西内陆滞留 26 小时;南宁 24 小时最大雨量 713.3 mm
- 伤亡通报:7-07 全区 6 人遇难 11 失联 / 37.5 万人受灾 → 7-09 全区累计 39 死 9 失联 → 8-21 新华社:南宁贵港两地 16 县 165 万人受灾,遇难 159 人、失联 10 人,其中六蓝、云表等水库溃坝洪灾遇难 107 人、失联 7 人
- 官方定性:弱级强灾
- “风眼查不到美莎克”的真实原因:本仓库首次提交 2026-07-10 08:05,首份
data/typhoon.json落盘 08:38,而美莎克 7-07 停编——差三天,它从未进入过这个系统。且风眼从设计上只渲染在编台风,海神/红霞/鲸鱼/浪卡同样查不到轨迹。与数据可得性无关(官方路径系统公开可查) - 代码缺陷(改版前
assets/app.jssuggestLevel,共 7 行):if (!t || !t.nearCoast) return "blue"→w>=14 orange→w>=10 yellow→blue。唯一输入是windLevel。代入美莎克:登陆时 10 级→黄;减弱为热带低压后 <10 级→蓝(四档最低);7-07 停编后typhoons为空→页面显示”风平浪静” - 改造(v0.8,commit
dd831ce):scripts/fetch-typhoon.mjs接入第四个源中央气象台预警发布平台(www.nmc.cn/rest/findAlarm),抓暴雨/台风/山洪灾害/山洪风险/地质灾害五类在效预警;alertid前 6 位即行政区划代码,免抓详情页即可聚合到省- 关联规则(台风↔省份,不涉用户位置):该省已发台风预警(多台风并存按最近者归属,上限 1500 km)∪ 省中心距实况点或预报路径 ≤450 km
- 档位改为
max(风力档, 洪涝档);洪涝档更高时页面显式标注”台风等级只反映风速,不代表致灾程度” - 停编后保留最长 7 天影响持续期,其间影响省份仍有洪涝预警在效则维持风险姿态,不回落”风平浪静”
- 预警抓取设 60 s 总预算且可降级为
ok:false;两个数据工作流的校验步骤同步覆盖新字段
- 实测验证(2026-08-21 当日真实数据):北部湾 0021 号热带低压(未命名,7 级)——旧逻辑=蓝色;海南(101 km)/广西(301 km)/广东(365 km)三省均挂暴雨橙色预警 → 新逻辑=橙色,抬升两档
- 上线:Pages 已部署并核验;手动触发数据工作流跑通,CI 新校验输出
validated 2 active typhoon(s), 164 alert(s), 0 in aftermath;B 站 Toy 提交审核status: auditing,后由作者确认发布完成;复盘专栏发到 Toy 开发者小站「晒晒 Toy」分区,勾选了 AI 辅助创作声明 - 数据来源:
git log、新华社 8-21 通报、中国天气网气象分析师叶梦龙分析、维基百科登陆记录、横州公安通报、toy mylist --json、gh run日志、浏览器 DOM 实测
错在哪(设计事实)
不是阈值调错了,是分级依据只覆盖了一条致灾路径。
台风等级(热带低压→热带风暴→…→超强台风)是按近中心最大风速定义的。风眼把它直接当成”危险程度”的代理,于是:
| 致灾路径 | 风眼是否感知 |
|---|---|
| 大风(吹倒/吹飞) | ✅ windLevel |
| 风暴潮 | ⚠️ 间接(nearCoast) |
| 暴雨内涝 | ❌ 数据模型里没有雨 |
| 山洪/滑坡 | ❌ |
| 水库溃坝 | ❌ |
美莎克走的是后三条。而后三条恰恰在台风减弱时才充分发展(残涡滞留、水汽持续输送),于是出现反向关系:致灾能力上升的同时,风力档位在下降。
这比”少了个功能”严重:一个只报风的系统,在纯降雨型台风面前不是沉默,是主动给出安全信号。
结果分析
- 符合预期:五个场景全部通过(正常台风 / 影响持续期 / 真·风平浪静 / 旧 schema 缓存 / 预警源抓取失败);当日真实个例抬档两级;暗色主题与 CSS 令牌正常;旧 schema 下雨情区块自动隐藏,向后兼容
- 未验证部分(诚实边界):
- 影响持续期从未经历真实停编——只用构造数据测过,
recentlyEnded的识别逻辑(比对上一版 JSON 中消失的台风)要等下一次真实停编才算跑通 - 450 km / 1500 km 两个阈值是拍的,没有依据校准;省中心点关联对新疆、内蒙这类大省很粗糙(本场景多为华南沿海省份,影响有限)
- 省级
floodLevel取全省最高档——省内可能只有个别区县发布,页面口径已注明,但仍是偏保守的放大 - Toy 侧最终发布状态是作者人工确认的,不是我抓到的页面内容(Chrome 扩展在点击发布的瞬间断连,我停在了
auditing)。与2026-07-30_风眼九段线问题地图事故复盘_v1同一处复验缺口第二次出现:这类平台的线上态目前没有可自动化的核验手段
- 影响持续期从未经历真实停编——只用构造数据测过,
方法论沉淀
⚠️ 单因子分级会在最危险时段给出最低档(首次发现)
核心:分级/评分系统若只取一个代理指标,遇到走其他致灾路径的个例时会反向失效——不是不够灵敏,是自信地报安全。风眼按风力推档,而美莎克的伤亡全部来自水;风力档位在残涡滞留阶段回落到蓝色,恰是死亡最集中的 26 小时。
来源:美莎克(2610)“弱级强灾”,官方定性;代入改版前 suggestLevel 得到的档位序列 黄→蓝→风平浪静。
操作规则:
- 给任何分级系统列一张致灾路径 × 是否被感知的表(见上文),空格就是盲区;
- 多路径系统取
max(各路径档位),不要用单一指标推导; - 当次要路径档位高于主指标档位时,必须在界面上说破这件事,而不是静默取高——否则用户会拿主指标(台风等级)自行推翻你的建议;
- 迁移场景:健康风险评分、告警分级、风控评分、内容审核置信度——凡”用一个易测量代理去表达一个多因致的风险”都适用。
⚠️ 数据源的生命周期短于业务风险的生命周期(首次发现)
核心:上游数据源的对象生命周期,往往按它自己的业务定义,而不是按你的。台风”编号”只存在 6 天(停编即从官方 JSON 消失),但这场灾害的伤亡数字是停编 45 天后才核定的(39 → 159)。系统跟着数据源的生命周期归零,于是在灾后重建期显示”风平浪静,风来之前都是准备的好时候”。
来源:7-07 停编 → 8-21 新华社定案,中间六周页面持续显示无台风态。
操作规则:
- 接入外部源时明确问一句:“这个对象消失,是它的风险结束了,还是只是它在上游的记账周期结束了?”
- 两者不一致时自建一段”余波窗口”,由真实风险信号(此处=影响省份仍有洪涝预警在效)而非源对象存在与否来决定退出;
- 余波期的文案要与常态区分,不要复用”一切正常”那套话术。
⚠️ 混合行尾会让多行锚点替换静默失败,而常用命令查不出来(首次发现)
核心:E:\typhoon-eye 全部源文件为 CRLF / LF 混合(仓库既有状态,无 .gitattributes)。用 \n 拼接的多行锚点做字符串替换必然 miss,单行锚点却正常命中——症状极像”锚点写错了”,实际是行尾不匹配。更坑的是 Git Bash 的 grep -c $'\r'、awk '/\r$/'、cat -A、wc -l 都会静默剥掉 CR,查不出问题;只有 node -e 'JSON.stringify(...)' 或 file 看得见(实测 app.js 有 943 个 CR)。
来源:本轮连续 3 次多行锚点替换失败,先后怀疑过锚点抄错、heredoc 转义、patcher 逻辑,最后靠 node 打印原始字节定位。
操作规则:
- 改这类仓库,锚点替换要么只用单行锚点,要么让匹配对行尾不敏感(先按原样找,找不到再按全 CRLF 变体找);
- 不要为此做全库行尾规范化——那会把真实改动淹没在噪声里;git 本身配了 autocrlf,提交时会归一;
- 排查行尾问题一律用 node/python 看原始字节,别信 Git Bash 的文本工具;
- 附带一坑:本机 bash heredoc 即使用
<<'EOF'引号形式也观察到会把\\折成\,所以 patcher 脚本里避免写正则转义(用双变体字符串匹配代替)。
⚠️ 自曝局限比被人发现更有利(首次发现)
核心:“风眼查不到美莎克”被当成了传闻的佐证。真实原因(仓库比台风晚建三天 + 只渲染在编台风)平淡且对作者不利,但由作者自己讲清楚,比等别人发现要好得多——它同时解决了传闻和信任两件事。本轮把这条写进了 README、PLAN.md 和对外专栏的最后一节,并顺势承诺了”做一个能查历史台风的版本”。
操作规则:工具的已知局限写在自己的文档里,并在对外稿里主动点名;别等它变成别人手里的证据。与打磨不等于校验律_v1互补:那条讲”看起来精致会虚假抬高信任”,这条讲”主动示弱能换回真实信任”。
顺带修掉的既有隐患
#tyKicker 内含 #tyCode / #tyEnName 两个 span,而”风平浪静”分支直接 tyKicker.textContent = "西北太平洋" 会把这两个子节点连根删除,此后任何 $("tyCode") 返回 null。原代码没暴露是因为无台风分支之后不再引用它们;本轮新增”影响持续期”分支需要读 code/enName,一写就崩。已改为重建结构(setKickerStorm),顺带修掉”无台风态 → 有台风态”切换时的潜在崩溃。
教训:textContent 赋值是破坏性的,凡容器内嵌有 id 的子元素,一律重建而非直接赋值。
关联文档
- 同项目前作:2026-07-30_风眼九段线问题地图事故复盘_v1 —— 同一个站,上一次也是群友先发现;两次的复验缺口(Toy 线上态无法自动核验)是同一个
- 同族反直觉律:打磨不等于校验律_v1 —— 精细打磨不产生内容正确性证据;本档的”单因子分级”正是被反复维护却从未被问过”它覆盖全部致灾路径了吗”
- 本轮查证方法沉淀:混合真伪的证据链_最弱一环会拖垮最强一环_v1
- 发布面清算:B站Toy同步事故复盘_版本指纹与外部cron兜底_v1 —— 本轮同样踩到”Toy 包构建早于数据提交,内嵌快照是旧 schema”,手动重建工作流解决
- 对外版(裸路径,不进图谱):
08_对外分发/台风工具在美莎克面前显示风平浪静_单因子分级的教训_公开版.md—— 2026-08-21 首发 B 站 Toy 开发者小站「晒晒 Toy」分区 - 区索引:09_平台工程索引