老项目做 vibe coding 改造,别先开写:先把边界、契约和验收跑通
老项目做 vibe coding 改造别先开写先把边界、契约和验收跑通摘要老项目改造最容易被 vibe coding 带偏看到一个现象就让 AI 写一个补丁短期很快长期却容易把历史行为、隐藏约束和回归风险搅在一起。本文不讨论某个具体兼容项目而是整理一套更通用的方法先做边界发现再把旧行为写成契约用可逆变更控制风险最后用证据链和确定性规则验收。这篇适合谁看这篇主要写给正在用 AI 辅助改造老项目的开发者、技术负责人和工具链建设者。你面对的项目可能是一个多年运行的后台页面也可能是一套无人敢大改的业务流程、一个缺少测试的前端工程或者一段依赖历史环境的脚本。它们的共同点不是技术栈旧而是很多行为已经变成了业务约定却没有被写进文档和测试。所以这篇不会展开某个具体适配细节而是回答一个更通用的问题当 AI 能很快给出代码时我们怎样避免把老项目改得更不可控我的结论是老项目 vibe coding 不能以“写代码”为起点而要以四个交付物为起点。边界地图 - 行为契约 - 可逆变更记录 - 证据验收清单代码只是这四件事之后的结果。一开始最容易误判老项目不是代码仓库而是历史行为集合新项目里需求通常可以从产品说明、接口文档、设计稿和测试用例里推出来。老项目不一样。很多真正重要的规则藏在这些地方某个字段为什么能为空某个按钮为什么要先弹确认某个列表为什么默认只查最近一段时间某个失败提示为什么不能换文案某个导入流程为什么允许部分成功某个页面为什么必须保留一个看似多余的隐藏字段某个旧接口为什么返回字符串而不是标准 JSON某个用户习惯为什么已经依赖了一个“历史缺陷”。AI 不知道这些背景。它看到的是当前代码、当前错误、当前提示词所以它很容易给出“局部合理”的改法。例如你告诉 AI这个保存按钮点了没有反应请帮我修复。AI 可能会补事件绑定、改提交逻辑、重构表单校验、增加 loading 状态。每一段代码单独看都可能合理但它没有回答三个更关键的问题保存按钮原来在什么条件下允许点击失败时应该保持旧提示还是可以换成新提示这个页面有没有被其他入口复用老项目改造的风险不在于 AI 写错一行代码而在于我们没有先定义“什么叫没改坏”。通用方法先产出四个交付物我现在做老项目改造会先要求自己把问题压成四个小文档。它们不需要复杂但必须能被复核。交付物解决什么问题最小内容边界地图防止不知道影响范围就开改入口、页面族、接口、数据对象、用户角色、外部依赖行为契约防止把历史行为当成可随意优化的代码触发条件、输入、输出、副作用、异常分支、不得改变项可逆变更记录防止补丁越改越散、难以回退变更点、原因、开关、回滚方式、关联证据证据验收清单防止 AI 或人工凭感觉判断成功观测点、命令、截图、日志、断言、人工确认项这四个交付物的作用是把“边写边试”变成“有边界地探索”。vibe coding 仍然可以很快但快的是生成候选方案而不是跳过判断。第一步边界发现不要让 AI 在未知范围里补丁扩散老项目里一个现象经常横跨多个边界。比如一个“提交失败”可能涉及页面按钮状态前端校验规则表单字段序列化老接口参数名后端兼容分支权限或角色判断缓存和历史数据用户原有操作习惯。如果只盯着报错点很容易把补丁写在最方便的位置却不是最应该的位置。我会先做一张边界地图边界要问的问题记录示例入口边界用户从哪里进入是否有多个入口list - edit、dashboard - quickEdit页面边界同一组件是否被多个页面复用edit.html、copy.html共用表单数据边界哪些字段是展示字段哪些字段会提交displayName展示entityId提交接口边界接口是否容忍旧参数、空值、字符串编码status可空type只能是旧枚举权限边界不同角色看到的按钮和流程是否不同普通用户只读维护用户可编辑环境边界行为是否依赖浏览器、插件、缓存或配置本地正常测试环境缓存旧资源习惯边界用户是否依赖某个历史表现失败后保留已输入内容边界地图不追求完整设计它只回答一个问题这次修改最远可能影响到哪里如果这个问题答不出来先不要让 AI 扩写代码。第二步把旧行为写成行为契约老项目改造里“优化”是一个危险词。很多看起来可以优化的地方可能早就被用户、数据、接口或脚本依赖了。我们要先把旧行为写成契约明确哪些可以改哪些不能改。一个行为契约可以很轻量contract:legacy-form-savescope:page_family:/example/order/*entry:edit-formtrigger:action:click save buttonpreconditions:-required fields have values-user has edit permissioninput:visible_fields:-displayName-amounthidden_fields:-entityId-versionexpected_behavior:success:-submit legacy parameter names unchanged-show success message-keep redirect target unchangedfailure:-keep user input on page-show original validation category-do not retry automaticallymust_not_change:-submitted field names-empty-value compatibility-permission branch-failure message categoryevidence:-request payload snapshot-response status-page state after success-page state after failure这个契约不需要一次写完。它可以随着排查逐步补齐。但只要写出来AI 的任务就变了它不再是“请帮我修一下”而是“请在不破坏这些契约的前提下给出最小变更”。提示词会变得更具体请根据下面的行为契约分析修复方案。 要求 1. 不改变 must_not_change 中的任何行为 2. 优先给出最小改动 3. 标出每个改动需要哪条证据验证 4. 如果证据不足先列出需要补充的观测点不要直接写代码。这比直接贴一段报错让 AI 猜要稳定得多。第三步变更必须可逆不能只看当前页面修好了没有老项目里最怕“补丁堆叠”。今天为一个页面加一个兜底明天为另一个入口加一个特判后天再补一段兼容逻辑。单看每次都不大合在一起就会变成没人敢删的逻辑。所以我建议每个改动都写进可逆变更记录变更为什么改限制范围如何关闭验收证据保留旧参数名接口仍按旧字段读取仅/example/order/*配置开关legacyParamModefalse请求 payload 对比增加空值兼容历史数据存在空枚举仅编辑页保存删除兼容分支或关闭开关空值样本保存成功延迟初始化组件旧脚本加载顺序不稳定仅指定页面族恢复同步初始化初始化日志和页面截图可逆不一定等于每个改动都要做功能开关。它至少要回答这个改动在哪里生效为什么不能全局生效如果误伤怎么快速退回哪条证据证明它确实需要存在。如果一个改动说不清这些内容它就不适合在老项目里扩散。第四步AI 负责推理和生成PASS/FAIL 由证据规则决定vibe coding 最大的价值是把探索速度拉起来。你可以让 AI 帮你从日志里找异常分支对比新旧请求参数推断可能断点生成最小补丁补一组回归用例把现场现象整理成检查清单。但 AI 不应该替你决定“通过”。老项目验收至少要分成三层层级AI 可以做什么不能交给 AI 的判断证据收集整理日志、截图、请求、响应、页面状态不能仅凭描述判断现场已通过规则匹配对照契约指出缺失证据和风险不能把推测当成验收结论PASS/FAIL生成检查表、解释失败原因最终结果必须由断言、命令、截图或人工确认项落地一个更稳的验收格式是检查项保存失败后保留用户输入 证据来源浏览器截图 表单字段快照 通过规则失败提示出现后displayName、amount、entityId 保持原值 AI 角色对比快照并指出差异 最终结论由测试记录人勾选 PASS/FAIL这里 AI 可以辅助观察但不能绕过规则。什么时候应该停止写代码先补观测能力老项目改造中有几种情况不适合继续让 AI 写补丁。信号继续写代码的风险应该先补什么失败现象不稳定每次修复都可能修到假问题版本标记、环境标记、复现步骤无法确认旧行为可能把历史契约改没旧版本截图、请求样本、用户确认项不知道改动是否生效会把部署问题误判成代码问题构建版本、加载日志、资源校验同类问题反复出现会形成散落特判问题分类表、共享适配层、回归矩阵修好 A 后破坏 B说明边界没有圈住影响范围表、相邻场景测试这些时候最有效的下一步往往不是继续补代码而是增加观测点页面显示当前构建版本关键流程输出结构化日志请求和响应可以脱敏导出重要字段有前后快照回归清单能标记已验证、待复验、禁止重复修每个补丁能对应到一个契约和一条证据。观测能力看起来不像功能但它能减少大量假成功和假失败。一个通用的老项目改造流程下面这套流程适合多数老项目 vibe coding 改造。1. 记录现象 - 用户动作 - 当前结果 - 期望结果 - 是否稳定复现 2. 画边界 - 入口 - 页面或模块 - 数据对象 - 接口 - 权限 - 环境 3. 写契约 - 触发条件 - 输入输出 - 副作用 - 异常分支 - 不得改变项 4. 让 AI 分析 - 先找断点 - 再给最小改动 - 标出风险 - 不足证据先补证据 5. 小步修改 - 限定范围 - 保留回滚方式 - 记录变更原因 6. 证据验收 - 正向路径 - 失败路径 - 相邻路径 - 旧行为保持 7. 沉淀规则 - 更新契约 - 更新清单 - 更新回归矩阵这套流程的重点不是多写文档而是让每次 AI 生成的代码都有约束、有边界、有验收。一个可直接复用的提示词下面这段可以在老项目改造时直接使用。你现在是老项目改造审查员。 请不要先写代码先基于我提供的现象、代码片段、日志和截图完成以下分析 1. 这次问题涉及哪些边界 - 入口边界 - 页面或模块边界 - 数据边界 - 接口边界 - 权限边界 - 环境边界 - 用户习惯边界 2. 旧行为契约是什么 - 触发条件 - 输入 - 输出 - 副作用 - 异常分支 - 不得改变项 3. 当前证据能支持哪个判断 - 已确认事实 - 合理推断 - 仍缺失的证据 4. 如果要修改请给出最小变更方案 - 改动点 - 限制范围 - 回滚方式 - 可能误伤的相邻场景 5. 最后输出验收清单 - 正向路径 - 失败路径 - 相邻路径 - 旧行为保持 - PASS/FAIL 由什么证据决定 如果证据不足请先列出需要补充的观测点不要直接生成补丁。这段提示词的核心是把 AI 从“代码生成器”拉回到“证据和约束的协作者”。最后的检查清单每次老项目改造前我会用下面这份清单做自查是否知道这次修改的最远影响范围是否记录了入口、页面、数据、接口、权限、环境边界是否把旧行为写成了可复核契约是否明确了哪些行为不能改是否让 AI 先分析证据而不是直接写补丁是否把 AI 的推断和已确认事实分开是否让每个改动都有范围、原因和回滚方式是否至少验证了正向路径、失败路径和相邻路径是否确认加载的是新版本而不是旧资源或缓存是否有一条确定性规则决定 PASS/FAIL是否把新的经验沉淀回契约、清单或回归矩阵。老项目做 vibe coding不是不能快。真正的问题是如果没有边界、契约和证据AI 会把“写得快”变成“返工也快”。把这三件事补上以后AI 才更像一个可靠的改造助手而不是一个不断制造局部补丁的自动补全工具。