让 AI 改一个老脚本,最典型的失败是它先动手、后看依赖——改完调用了三个不存在的函数。本文给一套「先读后改」的顺序:先读 3 个依赖文件、输出调用关系摘要、再动第 4 个文件。实测报错从 3 处降到 0。
一句话结论
改老代码的风险不在改的那几行,在你没告诉它的上下游。直接提需求,编辑器只看到当前文件,会按「看起来很合理」的方式改,结果调用了别处没有的辅助函数、或者传的参数个数不对。实测同一处改动:直接改,报错 3 处(2 处调用不存在的函数、1 处参数个数不符);先读后改,0 报错。多花的那 5 分钟在读文件,省下的是 12 分钟排错。关键是让它先输出一份「谁调用了我、我调用了谁」的摘要,确认无误后再动代码。
这篇解决什么问题
三种情况最常见。一是直接把需求丢过去,它改得很快,运行就报错,报错信息还指向别的文件。二是它新增了一个「更优雅」的辅助函数,但你项目里已有一个同功能的老函数,现在两套并存。三是改完能跑,可另一个调用这个函数的脚本悄悄坏了,两周后才发现。
根子是把 AI 编辑当成「改这一处」,而它是「改一个调用网络里的节点」:节点一动,上游和下游都会受影响。五步做完,得到一份调用关系摘要、一份改动计划、一处一提交的干净 diff,以及一份「反向依赖」检查清单。
开始前要准备什么
- 依赖文件清单:目标脚本 import 或 require 了哪些文件。手动列出来最可靠,让 AI 自己猜容易漏。
- 一条能跑的基线:改之前先跑一遍,确认当前是正常的。本来就坏的代码,改完出错分不清是谁的责任。
- 一份测试或验证方式:脚本级的跑一遍、或者至少准备一组输入输出对照。没有验证方式的改动等于凭感觉。
- 改动范围的书面描述:两处就写两处,不要写「优化一下」这种开放需求。范围越模糊,它越可能顺手重构。
具体怎么做
第一步:圈定范围,先写出上下游
动手前先手工画一张小图:我要改的函数,被谁调用、它又调用了谁。这一步用十分钟,但决定后面能不能一次改对。上游(调用方)决定你不能改函数签名;下游(被调用方)决定你不能想当然地假设返回值形状。
我要改一个 420 行的老脚本,只改两处逻辑:
1. ______(具体到函数名与行为)
2. ______请先不要改代码,只做两件事:
1. 根据我贴的代码,列出这两个函数的上下游:被哪些地方调用(行号)、内部又调用了哪些函数或模块;
2. 指出改动会波及哪些调用方——特别是「函数签名改动」会不会让某个调用点传的参数个数对不上。如果信息不足以判断,告诉我需要再看哪几个文件,不要猜。
第二步:让它读依赖,输出调用关系摘要
把 3 个依赖文件贴给它(或用编辑器的引用功能),要求它只输出摘要,不写代码。摘要要包含:每个文件提供的函数清单、目标脚本实际用了其中哪几个、有没有同名但签名不同的函数。这一步是全程最重要的一步。
这三个文件是目标脚本的依赖(共 1,100 行)。请只输出摘要,不要写任何代码:
1. 每个文件导出的函数与类,按功能分组列一遍;
2. 目标脚本实际用了其中哪几个(按调用位置标注行号);
3. 指出有没有「同名但参数不同」的函数——这类最容易在改动后静默出错;
4. 指出项目里是否已有与我要新增功能重复的现成函数(避免我引入第二套实现)。我的目标功能是:______。如果有现成实现,直接告诉我用哪个,不要新写。
第三步:先要一份改动计划,确认后再动手
计划写三样:改哪个文件的哪几行、每处改动的意图、会影响到谁。计划不对就改计划,别让它边改边想。这一步能把「顺手重构」挡在门外——实测直接改的那次,它顺手把两处没要求的代码也改了。
根据上面的调用关系摘要,请给出改动计划(仍然不要动代码):
1. 逐处列出:文件名、行号范围、改动前后的意图;
2. 每处改动的影响面:哪些调用方需要同步调整;
3. 明确列出「本次不改的部分」——把你觉得该顺手优化但不在范围内的项单独列出来,等我决定;
4. 指出这次改动里风险最高的一处,以及回退方式。我的原则是不引入新的辅助函数、不重构目录结构、不改函数名。如果做不到,说明原因。
第四步:一处一提交,让 diff 可读
两处改动分两次改、两次提交。合在一起改,出问题时看不出是哪一处引起的。每改完一处立刻跑一次基线验证——早发现比晚发现便宜。
按计划先改第一处,只改这一处。要求:
1. 给出改动的 diff,只包含这一处;
2. 说明这次改动是否需要同步修改调用方,如果需要,一并给出调用方的 diff;
3. 改完后我应该跑什么命令验证(给出具体命令,不要「自行测试」);
4. 如果改动后出现报错,先不要继续改,列出三个最可能的原因供我排查。第二处等我确认第一处通过后再动。
第五步:查反向依赖,改动才算完
最后一步最容易被跳过:谁调用了我改的函数。用全局搜索函数名找一遍,逐个确认调用点没坏。实测这一步发现了 1 个两周后才可能暴雷的调用——一个定时任务脚本在用同一个函数,参数顺序变了。
我已改完并跑通主流程。请帮我做反向依赖检查:
1. 给出一条能在项目里全局搜索「我改过的函数名」的命令(含要排除的目录,例如 node_modules、vendor、备份目录);
2. 列一份检查清单:每个调用点要确认什么(参数个数、参数顺序、返回值的处理方式);
3. 如果发现调用方仍在用旧签名,给出最小改动方案;
4. 给一句判断:这次改动是否影响了定时任务、外部接口这类「不常跑所以不容易发现」的入口。我改的函数是:______。
实测记录
口径:目标脚本 420 行,依赖 3 个文件共 1,100 行,改动 2 处(一个函数新增可选参数、一处判断逻辑从「等于」改「包含」)。
- 直接改:约 8 分钟改完,运行报错 3 处——2 处调用了项目里不存在的辅助函数(它按常见写法自己编的),1 处调用方仍传 2 个参数而函数已改成 3 个;排错 17 分钟,合计 25 分钟。
- 先读后改:读依赖与写摘要 7 分钟、改动 6 分钟、验证与反向依赖检查 5 分钟,合计 18 分钟,0 报错。
- 顺手重构:直接改那次它还改了 2 处没要求的代码(把一段重复逻辑抽成函数),这两处是后面排错的主要干扰源。先读后改时我在计划里明确「本次不改」,避免了。
- 反向依赖:全局搜索发现 1 个定时任务脚本也调用同一函数,参数顺序是旧版。它不常跑,如果没查,两周后才会报错。
- 补充测试:改动后有 1 处「包含」逻辑没有现成用例,补了 3 条断言,覆盖空值、多个匹配、无匹配。
最容易错的 3 个地方
第一,直接给需求让它改。编辑器只看得到当前文件,看不到别处有什么函数,于是自己造一个「名字合理」的——而项目里其实已有同功能的老函数。先读依赖并要求「有现成实现就用现成的」,能挡掉这一类。
第二,让它在同一次里顺手重构。它顺手把重复逻辑抽成函数、把变量改名,diff 一下变大三倍。这些改动本身没错,但混在一起就让排错成本翻倍。范围要在计划里写死。
第三,只跑主流程不查反向依赖。主流程通过就收工,是最常见的漏洞。同一个函数可能被定时任务、后台脚本、外部接口调用,它们不常跑,坏了很久才发现。全局搜一遍函数名的成本是两分钟。
可复用的东西
四步顺序:圈上下游 → 读依赖出摘要 → 写改动计划 → 一处一提交。顺序不能省,尤其第二步。
三条禁令:不引入新辅助函数、不重构目录、不改函数名。要破例先说明。
反向依赖检查:全局搜函数名,逐个确认参数个数、顺序、返回值处理。定时任务与后台脚本是重点。
一处一提交:两处改动分开提交,出问题时能定位到具体哪一处。
常见问题解答
为什么 AI 改代码总是调用不存在的函数
因为编辑器只看得到当前文件,不知道项目里已经有什么。它按「常见写法」造一个名字合理的辅助函数,运行就报错。解决办法是先让它读依赖文件并输出一份摘要,明确要求「项目里已有现成实现就用现成的,不要新写」。实测直接改出现 2 处调用不存在的函数,先读后改是 0 处。
改动之前需要准备什么
三样:依赖文件清单(手动列,别让它猜)、一条能跑的基线(改之前先跑通,否则出错分不清是谁的责任)、一份验证方式(脚本级跑一遍或一组输入输出对照)。另外改动范围要写成「两处、具体到函数名与行为」,不要写「优化一下」——范围越模糊,它越可能顺手重构。
为什么要先让它写改动计划
为了把「顺手重构」挡在门外。实测直接改那次,它顺带改了两处没要求的代码(抽公共函数),这两处成了后面排错的主要干扰源。先写计划能看清「改哪几行、影响谁、哪些不在范围内」,确认后再动手。计划里还要明确三条禁令:不引入新辅助函数、不重构目录、不改函数名。
改完跑通主流程就算完成了吗
不算,还差反向依赖检查——全局搜索你改的函数名,逐个确认调用点没坏。同一个函数可能被定时任务、后台脚本、外部接口调用,它们不常跑,坏了很久才发现。实测这一步发现一个定时任务脚本仍在用旧参数顺序,如果不查,两周后才会报错。查一遍的成本约两分钟。
本网站的部分内容可能来源于网络或用户投稿,仅供大家学习与参考,如有侵权,请联系客服: hhxmw778 进行删除处理。
本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
教程如引导您添加微信或有另外收费服务,请自行甄别!
如遇充值环节或绑定支付账户或输入支付密码之类的异常步骤,建议停止操作!本站不对操作项目的损失负责!
本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现任何资源有问题请向站长举报下架
(手机微信用户建议用默认浏览器打开,可体验完整功能)
