《AI 渐进编程》之十六:程序通过以后,怎么把修复变成规则? 前面几篇我们已经把程序项目里最重要的几件事说清楚了prompt适合小任务Harness适合边界和验收state适合记住当前进展revision_log.md适合记录为什么这么改open_issues.md适合保存暂时不能解决的问题工作台适合把这些东西分开摆好完整循环适合把任务从开始跑到通过这一篇继续往下讲的是一个更长期的问题当程序任务已经验收通过以后系统应该怎么继续维护而不是停在“这次过了”上这本书把这个问题交给长期维护。因为程序项目不是修完一次就结束。很多时候今天通过的是一个具体 bug但明天还会遇到边界条件变化旧调用方行为不清楚新需求出现另一个模块开始受影响这次修复需要补更稳的验证所以真正重要的不是“这轮过了没有”而是过了以后系统怎么继续保持稳定。1. 为什么验收通过以后还不能直接结束因为程序项目里很多问题不是一次性消失的。还是用空购物车结算这个例子。这轮修好了以后表面上看已经结束了空购物车不能再直接进入结算正常购物车路径没有被破坏测试也通过了状态也回写了但紧接着就会冒出新的问题老版本调用方是不是还会传空购物车重试逻辑会不会重复触发结算统计埋点会不会受影响其他路径有没有类似的边界问题也就是说一个任务修完并不代表这个地方以后都不会再出问题。所以本书认为任务通过以后系统不应该只说“结束了”而是要进一步判断这个问题是彻底解决了还是只是暂时稳定了还是需要进入长期维护还是应该拆成新任务继续处理2. 稳定之后系统应该先看什么当一轮任务通过以后下一步不应该立刻乱加新需求而是先看三件事2.1 这个修复是不是足够稳比如空购物车路径已经有测试了正常购物车路径没有被破坏副作用没有扩大状态也记录完整了如果这些都稳定说明这次修改可以先保留。2.2 有没有重复出现的风险比如这个 bug 是不是同类问题的一种其他模块是不是也有类似边界以后是不是还会重新碰到如果会反复出现那就说明这不是一个单点 bug而是一个要升级成规则的问题。2.3 有没有必要把临时修复变成长期规则有些修复一开始只是临时挡住问题但后来发现它其实应该变成正式约束。比如空购物车不能进入结算重试请求必须幂等支付前必须检查购物车状态旧调用方行为要有兼容说明这些内容一旦稳定下来就不应该再只是“这次修了”而应该进入长期状态。3. 临时修复和长期维护有什么区别这个区别很重要。临时修复临时修复解决的是眼前问题。比如加一个空值判断补一个测试先挡住一个异常路径它的目标是让当前任务先通过。长期维护长期维护解决的是后续稳定性。比如把规则写入project_map.md把边界写进current_task.md把修复原因写进revision_log.md把仍然可能出现的问题写进open_issues.md把回归测试补完整它的目标是让下一轮不再重新踩同一个坑。所以临时修复关注“先过”长期维护关注“以后别再乱”。4. 购物车程序里的长期维护应该怎么做还是用空购物车结算修复来举例。如果这轮已经修好下一步可以做几件事4.1 固化验收规则把这次通过的判断写成稳定规则空购物车必须安全失败正常购物车必须继续通过支付接口不能被误调用修改范围不能越界这些规则以后就不是一次性检查而是项目的长期约束。4.2 补强回归测试如果这次是因为空购物车路径漏测才出问题那就应该把这个路径永久加入回归集。这样下一次改动时系统可以直接知道有没有破坏这个行为。4.3 记录兼容风险如果旧调用方行为还不确定就不要假装它不存在而是写进open_issues.md哪些调用方还要确认哪些边界需要后续验证哪些行为以后可能要升级这样系统就不会把“暂时没看到的问题”误当成“已经解决”。4.4 更新项目认知如果这次修复改变了项目对结算流程的理解那就把新的认知写回project_map.md。比如空购物车是明确禁止结算的状态checkout 前必须先检查购物车内容这个规则以后不能再被绕过这一步很重要。因为长期维护不只是修代码还包括更新项目认知。5. 什么时候一个修复应该升级成新任务不是每个修复都要变成新任务但有三种情况应该升级5.1 这个问题反复出现如果同类 bug 不止一次出现那就说明它不是一个局部失误而是一个系统性问题。这时就应该把它单独立成新任务。5.2 这个修复影响范围变大如果一开始只是修购物车后来发现结算、重试、支付、库存都受影响那这就已经不是单点修改了。系统应该把它拆开处理不要继续在一个任务里硬拖。5.3 这个修复需要新的长期规则如果修复之后系统明确知道以后必须遵守某条规则那这条规则就应该进入长期状态甚至写成独立任务去推广到其他模块。比如所有结算入口都要先检查购物车是否为空所有支付动作都要先验证有效性所有重试逻辑都要保证幂等这类内容已经超出一次修改就应该升级。6. 为什么不能让系统一直靠临时补丁因为临时补丁会把系统弄乱。问题一补丁越打越多如果每次出问题都只在局部加一层判断最后系统会变成一堆例外处理。问题二没有统一规则每个补丁都只处理一个局部现象久而久之系统会失去一致性。问题三下一轮不知道历史如果没有回写和升级下一轮还是要重新猜为什么这里会这样。所以程序项目不应该永远停留在“打补丁”阶段。它要学会把补丁吸收进长期规则里。7. 长期维护和四个状态文件是什么关系这四个文件要一起看。project_map.md记录长期稳定的项目认知。如果修复改变了项目的理解就要更新这里。current_task.md记录当前这一轮做什么。任务结束后要清理或替换。revision_log.md记录为什么这么改、改了什么、验证如何。这是这次修复的决策历史。open_issues.md记录还没解决、但不能忘的问题。如果新风险出现就写进去。所以长期维护不是另起炉灶而是让这四个状态文件一起完成“修复后的稳定化”。8. 一个最小的维护升级模板如果把这件事压缩成最小结构可以这样理解maintenance:stable:-empty-cart checkout blocked safely-normal checkout preservedpromote:-regression test added-boundary rule recordedfollow_up:-legacy caller behavior review-retry path coveragestate_update:-project_map.md updated-revision_log.md appended-open_issues.md refreshed这个模板的重点不是格式而是它表达了一个很清楚的事实通过不是结束通过之后要看稳定性稳定之后要决定哪些内容要升级成长期规则还没稳的内容要继续留在下一轮9. 长期维护为什么能让系统更稳因为它把“局部修好”变成了“项目认知的一部分”。如果没有长期维护系统每次都像从头修改完就忘通过就过下一次继续踩同一个坑但如果有长期维护系统就会逐步积累这些东西哪些问题已经出现过哪些边界已经确认过哪些规则不能再被绕过哪些风险需要单独跟踪这样下一轮就不是从零开始而是站在已经验证过的事实上继续推进。10. 本章小结这一章想讲清楚的核心是程序任务通过以后不应该马上结束而应该判断它是临时修复、稳定规则还是需要升级成新任务。以购物车程序为例长期维护的价值在于把这次通过变成长期规则把重复风险变成独立任务把临时补丁吸收进稳定状态把未决问题继续留给下一轮这就是程序项目真正开始变稳的地方。不是每次都改得更多而是每次都把已经确认的东西保留下来把还没确认的东西放到正确的位置。下一章我会继续讲当项目进入长期维护后Agent 怎么判断哪些地方该继续放松哪些地方必须继续收紧。