
重构电子面单模块时我干了一件蠢事——事后才意识到「AI代替不了人」系列此前已完结共11篇。整理稿件时发现还有一个跟主题高度相关的案例没有放进来——不是技术难题而是认知和执行之间的缝隙。AI全程参与了改造却没有发现这个缝隙。这个案例太适合作为系列的“番外篇”所以补上。这一篇不讲“AI做不到什么”而是讲“你和AI合作时容易漏掉什么”。旧系统里有一个定时任务每天凌晨自动去各电商平台刷新Token写完数据库就走。新系统里我加了一层缓存取号时先从缓存读读不到再查数据库速度明显快了。我是知道它们关系的。上游把Token领回来存进仓库下游的缓存负责加速分发。按理说上游每次领新Token之后应该通知缓存“兄弟你手里的旧货可以扔了”。但改造的时候我的注意力全放在了“缓存怎么设计、怎么高效读取”上。把“刷新后通知缓存”这件事给漏了。直到准备上线的全代码审查我重新把Token的整条链路串起来走了一遍刷新 → 存储 → 缓存 → 取号。走到第三步时我停住了——缓存货架上还贴着旧标签快递员继续拿旧Token根本不知道仓库里已经换了新的。而AI全程参与了这次改造。它严格按我们的指令执行代码修改没有主动问一句“刷新成功后缓存怎么办”它不是不想问是你没告诉它要问。一、三个角色一条流水线先搞清楚这三个东西各管什么事。后台定时刷新像个勤快的搬运工每天凌晨自动去各电商平台门口排队把新的Token领回来存进数据库仓库。一个平台没领到没关系记一笔继续跑下一家——绝不能因为一家没开门就收工后面几十家还等着。前台手动刷新像个被老板派去办事的员工用户在前台点一下“刷新Token”按钮他就跑去领Token。和后台那个搬运工干的活一模一样但脾气不一样——后台那个没领到就算了前台这个没领到会当场给老板打电话“这家没开门我没办成。”缓存查询像个快递员每次取号时先去货架上找Token。找到了直接用找不到再去仓库搬搬完顺手放货架上下次就不用再跑一趟仓库了。仓库里东西全、存得稳但去一趟太慢。货架就在手边东西少但拿起来飞快。快递员不可能每次取件都跑仓库所以先在货架上找——这就是缓存存在的意义。三者的关系是一条流水线后台定时刷新 / 前台手动刷新把Token搬进仓库 │ ▼ 数据库仓库 │ │ 缓存查询从货架上取Token ▼ 取号流程最终用上Token刷新在上游“生产”Token缓存在下游“分发”Token。我心里清楚这一点但改造的时候注意力全放在了“缓存怎么设计、怎么读”上把“刷新后怎么通知缓存”这件事给漏了。二、同样的活两种干法漏掉缓存同步让我开始反思我明明知道它们是上下游为什么改造时还是漏了后来我想明白了——改造时的注意力是有限的我把精力全放在了“缓存怎么设计”上就顾不上“刷新怎么通知缓存”。这让我想起改造中另一个对比——同样的刷新逻辑后台和前台的处理方式完全不同。不是代码不一样是场景不一样。后台和前台的核心流程一模一样查有哪些组织 → 拼签名 → 调接口 → 拿结果 → 更新数据库。唯一的区别在最后一步怎么处理失败。后台定时刷新一个组织没领到在本子上记一笔“这家今天没开门”然后继续跑下一家。绝不能因为一家没开门就回家睡觉——后面几十家还等着明天大家的Token全过期就是生产事故。前台手动刷新没领到就当场给老板打电话“这家没开门我没办成。”因为老板就站在旁边等着结果你不能假装办成了。同一个业务逻辑“记一笔继续跑”和“当场打电话”都是对的——取决于谁在调用。三、一个很容易被忽略的问题缓存什么时候更新新系统的缓存设计是每小时自动清空一次。也就是说Token刷新后最长要等一个小时缓存才能感知到新值。旧系统没有缓存层每次取号直接查数据库不存在这个问题。新架构加了缓存后这个问题才浮出水面。全代码审查时发现这个断点后我补上了方案刷新成功后主动通知缓存“兄弟你手里的旧货可以扔了”。补方案的时候我让AI写了那八处清理缓存的代码。它写得很快每一处的“保险”都包得很规范——try-catch包裹失败只记日志不抛异常。但它依然只是在执行我明确说出的规则。我没有告诉它“为什么要在这些位置加这些代码”它也就没有问“刷新和缓存之间还有没有其他遗漏”。怎么改有讲究。我的原则是只加不改。在刷新成功的分支里加一段清理缓存的逻辑。而且这段清理代码要加一道“保险”——万一清理缓存的时候出错了只记个日志绝不能让它把主流程带崩。就像你顺手扔个垃圾扔不出去就算了不能因为扔垃圾把正事耽误了。四个平台通道 × 两个刷新方法 八处要改的地方每处只加了不到十行代码。原有代码一字不动上线零风险。四、还有一个意外发现代码补完后我顺手梳理了一下缓存的“货架标签”规则想看看还有没有别的坑——结果还真发现了一个。同一个平台的普通模式和代发模式用的是同一个货架标签。两种模式的Token存在不同的格子里但标签一模一样。这就意味着先放了普通Token再放代发Token后放的那个会把前一个盖住——因为标签一样快递员根本不知道货架上有两份货。这个坑AI也没发现。因为它不知道“普通模式”和“代发模式”在业务上是两回事它只看到两个方法调用了同一个缓存标签。对它来说标签一样就是一样的东西——它理解不了“字段不同但标签相同”意味着什么。解决方案很简单给标签加一个模式后缀。普通模式PLAT_A_123_normal 代发模式PLAT_A_123_daifa老的标签不带后缀自动兼容完全不影响现有功能。一次改造同时解决了“缓存更新不及时”和“缓存标签冲突”两个问题。这种“顺手发现的隐患”在遗留系统里到处都是——不去动代码就永远不会发现。五、核心收获知道和做到之间有一条遗忘的缝隙。我清楚缓存和刷新是上下游但改造中还是漏了缓存同步这一步。经验再丰富的人注意力也有盲区。AI不会补全你没说出口的规则。你只告诉它“加缓存、加速读取”没告诉它“刷新后要清缓存”它就不会做。最小改动原则保护的是“不改旧代码”但保护不了“漏写新规则”。八处改造只加不删上线零风险——但如果你漏掉的规则没有被补充进来AI也不会帮你发现。改造过程中顺手发现的隐患往往比原本要解决的问题更有价值。缓存标签冲突如果不是这次梳理清楚迟早会变成线上故障。附新增缓存模块评审Checklist这次踩坑后我给自己定了一条规矩凡是新增缓存或中间件必须按这份清单逐项打勾才能在代码审查中放行。序号检查项这次踩的坑1读逻辑怎么处理缓存命中/未命中的流程是否完整✅ 这部分没漏2写/更新/删除数据之后缓存如何失效主动清除还是等TTL过期❌ 漏了这一步3有多少个入口会修改源数据是不是每个入口都处理了缓存失效❌ 四个平台×两个方法八处差点全漏4TTL兜底时间业务是否可以容忍不一致窗口如果TTL内数据变脏后果是什么⚠️ 1小时TTLToken过期后最多1小时才能感知5缓存Key是否完整带上所有业务隔离维度不同业务模式、不同组织的数据Key是否能区分❌ 普通和代发共用Key数据互相覆盖这份清单本身没有技术含量——它只是把“想清楚整条链路”拆成了五个必须回答的问题。但这恰恰是最容易被跳过的环节代码写得快链路想得少。AI可以帮你写缓存代码但这五个问题它一个都不会主动问。六、后续那个每天凌晨还在默默跑的上游刷新程序我让它继续跑着。它不是被替代了它只是找到了自己在流水线里的位置。AI也一样。我负责想清楚整条链路它负责把我想清楚的写到代码里——我找到的是“想”的位置它找到的是“做”的位置。但你没想清楚的地方代码里也不会自动长出来。所以那份Checklist才是这次踩坑留给我最值钱的东西——它不是什么高深的方法论只是把“想清楚”这个动作从靠记忆变成了一张必须逐项打勾的纸。你在工作中遇到过“明明知道该怎么做但改造过程中还是漏了一步”的情况吗最后是怎么发现的欢迎在评论区聊聊。推荐阅读第4篇 · AI不懂业务语义 → 为什么AI没发现缓存标签冲突因为它不理解“普通模式”和“代发模式”是两回事第8篇 · 五条血泪教训 → 本文的“只加不改”原则和Checklist正是从这五条教训中提炼出来的第10篇 · 我犯了六次错 → 知道该怎么做但还是漏了这不是第一次也不会是最后一次