<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.8.5">Jekyll</generator><link href="http://0.0.0.0/feed.xml" rel="self" type="application/atom+xml" /><link href="http://0.0.0.0/" rel="alternate" type="text/html" /><updated>2026-10-08T08:10:56+08:00</updated><id>http://0.0.0.0/feed.xml</id><title type="html">VF的部落格</title><subtitle>技术无止境,初心不忘...</subtitle><author><name>VF</name></author><entry><title type="html">第80篇：用 AI 做 Code Review——替你盯低级错误</title><link href="http://0.0.0.0/2026/10/07/ai-80-codereview/" rel="alternate" type="text/html" title="第80篇：用 AI 做 Code Review——替你盯低级错误" /><published>2026-10-07T10:00:00+08:00</published><updated>2026-10-07T10:00:00+08:00</updated><id>http://0.0.0.0/2026/10/07/ai-80-codereview</id><content type="html" xml:base="http://0.0.0.0/2026/10/07/ai-80-codereview/">&lt;blockquote&gt;
  &lt;p&gt;代码跑通了就敢提交？跑得通，只是及格线。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;上一篇给代码装了安全网——单元测试。测试好用，但有天然盲区：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;测试只查”结果对不对”，管不了”这么写行不行”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;举几个例子：数据库密码&lt;strong&gt;直接写代码里&lt;/strong&gt;——测试全绿，直到代码被人看到；用户输入搜索词&lt;strong&gt;原样拼进查询&lt;/strong&gt;——测试全绿，直到有人输入带引号的东西拖走整个库；报错时&lt;strong&gt;完整堆栈返回前端&lt;/strong&gt;——测试全绿，同时把目录结构、表名全告诉别人；循环里&lt;strong&gt;每转一圈查一次库&lt;/strong&gt;——测试全绿，上线 100 条数据就查 100 次。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;共同点：功能全对、测试全绿，但这些代码全都迟早出事。&lt;/strong&gt; 这类问题传统靠 &lt;strong&gt;Code Review（代码审查）&lt;/strong&gt;——提交前让更有经验的同事看一遍。&lt;strong&gt;可你要是没有那个同事呢？&lt;/strong&gt; 个人开发、小团队、外包、刚入行，绝大多数人根本没有”更有经验的同事”随时帮你看。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这一篇，教你怎么把 AI 变成那个同事。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一为什么直接说帮我-review得到全是废话&quot;&gt;一、为什么直接说”帮我 review”，得到全是废话&lt;/h2&gt;

&lt;p&gt;先做个实验。把代码丢给 AI 说”帮我 review 一下”，它八成给你：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“整体结构清晰，命名较规范。建议：1. 添加更多注释 2. 考虑增加错误处理 3. 变量命名更语义化 4. 考虑可扩展性……”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;看着像回事，实际一条没用。&lt;/strong&gt; 这些话对任何代码都成立，等于没说。你真正想知道的”我这段代码有没有要命的坑”，它一个字没提。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;你没告诉它「按什么标准看」，它只能给你放之四海皆准的空话。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;破法只有一个：给 AI 一张检查清单，逼它逐项过。&lt;/strong&gt; 像医院体检——你说”帮我看看身体”，医生只能”注意休息多喝水”；你递上 20 项体检单，他就得一项项出数值。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-07-ai-80-vague-vs-checklist.png&quot; alt=&quot;vague-vs-checklist&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二review-五关正安错洁快&quot;&gt;二、Review 五关：正、安、错、洁、快&lt;/h2&gt;

&lt;p&gt;那清单该有什么？把新手最容易踩、后果最严重的问题归成&lt;strong&gt;五个关卡&lt;/strong&gt;，口诀：&lt;strong&gt;正、安、错、洁、快&lt;/strong&gt;。&lt;strong&gt;注意顺序就是优先级，越靠前越致命。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第一关正正确性&quot;&gt;第一关：正（正确性）&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;功能是不是真的对？&lt;/strong&gt; 逻辑判断搞反（该”大于等于”写成”大于”）、边界漏了（正好等于阈值呢？）、算错（浮点直接比相等、金额用小数存）。&lt;strong&gt;这一关和上篇”四靶”一套东西，测试从外面验，review 从里面看。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第二关安安全&quot;&gt;第二关：安（安全）&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;最易被新手忽略，也是唯一”出事就没法挽回”的关卡。&lt;/strong&gt; 三大高发死法点名：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;① 密钥硬编码&lt;/strong&gt; 数据库密码、API 密钥、token 直接写代码。代码被人看到（同事、外包、公开仓库、截图发群）密钥就泄。&lt;strong&gt;正确做法：放配置文件或环境变量，确保那文件不被一起提交。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;② 用户输入直接拼进指令&lt;/strong&gt; 把用户填的内容原样拼进查询语句、系统命令、文件路径。&lt;strong&gt;用户填的不一定是”数据”也可能是”指令”&lt;/strong&gt;，这是绝大多数数据泄露源头。&lt;strong&gt;正确做法：用参数化传值，不是字符串拼接。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;③ 敏感信息进日志或返回前端&lt;/strong&gt; 把密码、身份证、手机号打进日志；把完整报错堆栈返前端。&lt;strong&gt;报错信息通常含文件路径、表名、框架版本——等于给别人画了张地图。&lt;/strong&gt; &lt;strong&gt;正确做法：详细报错记服务器日志，返前端的只有一句”操作失败，请稍后重试”。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第三关错异常处理&quot;&gt;第三关：错（异常处理）&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;顺利时都对，出问题呢？&lt;/strong&gt; 网络请求&lt;strong&gt;没设超时&lt;/strong&gt;（对方不响应就永远卡）、取可能不存在字段&lt;strong&gt;没判空&lt;/strong&gt;（直接崩）、除法&lt;strong&gt;没防除零&lt;/strong&gt;、捕获异常却&lt;strong&gt;什么都不做&lt;/strong&gt;（第 75 篇”假成功”，最阴险的 bug）。→ &lt;strong&gt;一句话：凡”跟外面打交道”的地方（网络、库、文件、第三方），都必须假设它会失败。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第四关洁整洁&quot;&gt;第四关：洁（整洁）&lt;/h3&gt;

&lt;p&gt;就是&lt;strong&gt;第 77 篇「重构六味」&lt;/strong&gt;：长、重、名、套、魔、杂。&lt;strong&gt;重要但不致命，排在安全和异常后面。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第五关快性能&quot;&gt;第五关：快（性能）&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;第 78 篇&lt;/strong&gt;内容，只盯几个”一眼看出”的：循环里查库（N+1，头号元凶）、循环里发网络请求、一次读海量数据进内存、能批却不批。&lt;strong&gt;性能排最后&lt;/strong&gt;，因为按”优化三问”，没测量前性能建议大多是猜的。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;五关速查表：&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;关&lt;/th&gt;
      &lt;th&gt;看什么&lt;/th&gt;
      &lt;th&gt;严重度&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;正&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;逻辑对不对、边界漏没漏&lt;/td&gt;
      &lt;td&gt;⚠️ 高&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;安&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;密钥硬编码、输入拼指令、敏感外泄&lt;/td&gt;
      &lt;td&gt;🔴 &lt;strong&gt;最高·不可逆&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;错&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;网络/空值/超时兜底、异常被吞&lt;/td&gt;
      &lt;td&gt;⚠️ 高&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;洁&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;长重名套魔杂（六味）&lt;/td&gt;
      &lt;td&gt;🟡 中&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;快&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;循环查库/发请求、能批没批&lt;/td&gt;
      &lt;td&gt;🟢 中低&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-07-ai-80-review-five-gates.png&quot; alt=&quot;review-five-gates&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三提示词怎么写四个关键技巧&quot;&gt;三、提示词怎么写：四个关键技巧&lt;/h2&gt;

&lt;p&gt;清单有了，还得会问。四招决定 AI 给干货还是废话。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;技巧一：禁止它夸你。&lt;/strong&gt; AI 改不掉先夸三句再说问题的毛病，夸完语气变软，”必须改”变成”可以考虑优化一下”，你一看就先不改了。&lt;strong&gt;直接堵死：&lt;/strong&gt;“不要评价优点，不要写总结性褒奖，只挑问题。”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;技巧二：要求按严重程度分级。&lt;/strong&gt; AI 一口气给 15 条全平铺，你分不清哪条”今天不改明天出事”哪条”改不改都行”。&lt;strong&gt;要求分三档：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;🔴 &lt;strong&gt;必须改&lt;/strong&gt;（安全漏洞、逻辑错、必崩空值）&lt;/li&gt;
  &lt;li&gt;🟡 &lt;strong&gt;建议改&lt;/strong&gt;（不立刻出事，但欠债）&lt;/li&gt;
  &lt;li&gt;🟢 &lt;strong&gt;可以不改&lt;/strong&gt;（纯风格）&lt;strong&gt;然后只处理红和黄，绿的直接跳过&lt;/strong&gt;，15 条变 4 条，人不慌。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;技巧三：每条必须给”四件套”。&lt;/strong&gt; 要求每条含：1. &lt;strong&gt;在哪&lt;/strong&gt;（第几行/哪个函数）2. &lt;strong&gt;什么问题&lt;/strong&gt;（一句话）3. &lt;strong&gt;为什么是问题&lt;/strong&gt;（&lt;strong&gt;会造成什么后果&lt;/strong&gt;，最关键）4. &lt;strong&gt;怎么改&lt;/strong&gt;（给改后代码）。&lt;strong&gt;第 3 条是过滤器——逼 AI 说清后果，一大半凑数假问题当场露馅。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;技巧四：允许它说”没问题”。&lt;/strong&gt; AI 有强烈”必须交作业”倾向，你让它挑毛病它就一定挑，哪怕代码很好也开始挑鸡毛蒜皮甚至编造。&lt;strong&gt;明确给退路：&lt;/strong&gt;“某一关确实没问题就写’本关无问题’，不要凑数硬找。”给了退路它反倒诚实。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四ai-说的不一定对三级过滤&quot;&gt;四、AI 说的不一定对：三级过滤&lt;/h2&gt;

&lt;p&gt;拿到结果&lt;strong&gt;别急着照单全改&lt;/strong&gt;。AI 的 review 结论分三类：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一类：真问题（改）。&lt;/strong&gt; 密钥硬编码、没判空、逻辑写反，占比约一半，直接改。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二类：AI 看错了（不用改）。&lt;/strong&gt; &lt;strong&gt;AI 只看到你贴的这一段，看不到项目其他部分。&lt;/strong&gt; 它可能说”这用户身份没校验”——可你在上层统一入口早校验过了，它不知道。&lt;strong&gt;识别法：你确定别处已处理，就是它上下文不全，回一句它会撤回。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第三类：风格之争（可不改）。&lt;/strong&gt; “建议改另一种写法”“建议提取独立函数”，没对错纯偏好，赶时间就跳过。&lt;/p&gt;

&lt;h3 id=&quot;一句话验伪让它举个会出事的场景&quot;&gt;一句话验伪：让它举个会出事的场景&lt;/h3&gt;

&lt;p&gt;怎么快速分辨？&lt;strong&gt;万能追问：&lt;/strong&gt;“这个问题在什么具体情况下会真的出事？给我能复现的场景：什么用户、什么操作、什么输入、最后什么后果。”&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;真问题&lt;/strong&gt; → 立刻说出：”用户搜索框输入带单引号内容时，查询被截断，攻击者可借此读整张用户表。”&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;假问题/凑数&lt;/strong&gt; → 开始打太极：”这主要提升可维护性和扩展性……”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;说不出具体场景的，基本都能放一放。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-07-ai-80-three-level-filter.png&quot; alt=&quot;three-level-filter&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五实战一段跑得通的代码被挑出了什么&quot;&gt;五、实战：一段”跑得通”的代码被挑出了什么&lt;/h2&gt;

&lt;p&gt;假设你写了”用户登录”逻辑，功能正常、测试过了。丢进五关一过：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🔴 必须改（3 条）&lt;/strong&gt;&lt;/p&gt;
&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;【安全·第 8 行】&lt;/strong&gt; 数据库连接密码直接写代码 → 后果：代码被看到密码就泄，传公开仓库几分钟被扫到 → 改法：移环境变量，代码只读变量名。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;【安全·第 22 行】&lt;/strong&gt; 用户名原样拼进查询 → 后果：输特殊字符可绕密码登录甚至读整张表 → 改法：参数化查询，用户名当”值”传不是”语句”。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;【异常·第 35 行】&lt;/strong&gt; 登录失败把完整错误返前端 → 后果：暴露表名、字段名、框架版本，给攻击者递地图 → 改法：详情写日志，前端统一”用户名或密码错误”。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;🟡 建议改（2 条）&lt;/strong&gt; 4. 【异常·15 行】调短信接口没设超时→对方挂了会卡住 5. 【整洁·全函数】一个函数干 5 件事→建议拆。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;🟢 可以不改（1 条）&lt;/strong&gt; 6. 变量 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;res&lt;/code&gt; 建议改名 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;loginResult&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;看到没——功能没毛病、测试全绿，但三个必须改里两个能直接致数据泄露。&lt;/strong&gt; 这就是 review 的价值：&lt;strong&gt;测试盯”对不对”，review 盯”稳不稳、安不安全”。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六提交前三分钟自查清单&quot;&gt;六、提交前三分钟自查清单&lt;/h2&gt;

&lt;p&gt;最后一张随身表，&lt;strong&gt;每次提交前花三分钟过一遍：&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;□ 代码里有没有写死的密码 / 密钥 / token？
□ 用户输入有没有被原样拼进查询语句或命令？
□ 报错信息会不会原样返回给前端？
□ 网络请求设超时了吗？
□ 可能为空的地方判空了吗？
□ 有没有 catch 了异常却什么都不做的地方？
□ 循环里有没有查数据库 / 发网络请求？
□ 有没有临时调试打印、注释掉的死代码、写死测试账号？
□ 单元测试跑过了吗？（上篇）
□ 这次改动，我能一句话说清改了什么、为什么改吗？
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;最后一条是隐藏考题。&lt;/strong&gt; 说不清自己改了什么，说明混进了不该混的东西——拆开分两次提交。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;提示词模板盒子&quot;&gt;提示词模板盒子&lt;/h2&gt;

&lt;h3 id=&quot;模板-1五关全量-review主力模板&quot;&gt;模板 1：五关全量 Review（主力模板）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;你现在的角色是一位严格的代码审查员，正在帮编程新手做提交前最后检查。

【要审查的代码】
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;（把完整代码贴在这里，不要贴片段）&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;
【这段代码是干什么的】
（两三句大白话说明业务用途、谁用、什么时候被调用）

【技术背景】
（什么类型项目、跑在哪、有没有暴露给外部用户）

【审查要求】
请严格按以下五关逐项审查，每关单独给结论：
第一关·正（正确性）：逻辑有无写反、边界有无遗漏、计算有无隐患
第二关·安（安全）：①密码/密钥/token有无硬编码 ②用户输入有无原样拼进查询/命令/路径 ③敏感信息（密码、身份证、手机号、完整堆栈）有无写进日志或返前端
第三关·错（异常）：网络有无超时、空值有无判空、有无捕获异常后啥都不做、外部调用失败有无兜底
第四关·洁（整洁）：过长、重复、命名、嵌套、魔法数字、职责过多
第五关·快（性能）：循环查库、循环发请求、能批却逐条、一次读海量数据

【输出格式】
按严重程度分三档，每档内按行号排序：
🔴 必须改（安全漏洞、逻辑错、必崩）  🟡 建议改（欠债）  🟢 可以不改（纯风格）
每一条必须含四要素：1.位置 2.问题（一句话） 3.后果（什么情况真出事、造成什么损失，不许写&quot;影响可维护性&quot;） 4.改法（给代码）

【严格约束】
- 不评价优点、不写褒奖，只挑问题
- 某关确实没问题就写&quot;本关无问题&quot;，不要凑数硬找
- 大白话解释，新手术语顺带解释一句
- 不确定处明确说&quot;我看不到上下文需你确认&quot;，不要猜
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板-2安全快查最快见效建议每次都跑--提交前三分钟&quot;&gt;模板 2：安全快查（最快见效，建议每次都跑 + 提交前三分钟）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;【A. 只查安全，其他不管】
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;（贴完整代码）&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;请只查这七项，逐项给结论（有问题指行号，没问题写&quot;未发现&quot;）：
1. 有无硬编码密码、密钥、token、连接字符串
2. 用户输入有无原样拼进数据库查询
3. 用户输入有无原样拼进系统命令或文件路径
4. 有无把完整报错堆栈/内部路径/表名返前端
5. 有无把密码、身份证、手机号写进日志
6. 有无该做权限校验却没做（能操作别人数据）
7. 有无用不安全老旧加密或伪随机
对每个发现说明：攻击者怎么利用（给可复现输入例子）、最坏后果、正确写法。
七项全无问题就明确答&quot;七项均未发现&quot;，别硬找别的。

【B. 提交前三分钟快查】
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;（贴代码）&lt;/p&gt;
&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;只回答下面 10 个是非题，格式「序号+是/否+若是指出行号」：
1. 有无写死密码/密钥/token  2. 用户输入有无原样拼进查询或命令
3. 报错会不会原样返前端  4. 网络请求漏设超时没
5. 有可能为空却没判空吗  6. 有无捕获异常啥都不做
7. 循环里查库或发请求没  8. 有无调试打印/死代码/写死测试账号
9. 有无本次改动外不小心带进的无关修改  10. 有无一眼可见逻辑错（判断反/边界漏）
最后一句话总结：这段代码现在能不能提交？不能只列必须先修那几条。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板-3验伪与纠偏判别-ai-结论真假--补上下文&quot;&gt;模板 3：验伪与纠偏（判别 AI 结论真假 + 补上下文）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;【A. 验伪追问——对每条可疑结论用】
你刚才提的这条问题：
【把 AI 那条结论原样贴过来】
请给我一个能真实复现的具体场景：
- 什么身份用户 / 做了什么操作 / 输入了什么 / 最终什么后果（具体到用户看到啥、数据变啥）
如果你说不出具体可复现场景，或只是&quot;理论上可能&quot;，请直接答：&quot;这条不是真实风险，可以忽略。&quot;
不要用&quot;提升可维护性&quot;&quot;增强健壮性&quot;&quot;符合最佳实践&quot;来搪塞。

【B. 上下文不全时的纠正】
你提的第 X 条问题（【贴那条】），我补充上下文：
【补充说明】这部分其实在别处已处理：（说明在哪层、怎么处理，最好贴那段代码）
请重新判断：1. 补了上下文这条还成立吗 2. 不成立请明确说&quot;这条撤回&quot; 3. 仍成立说明为什么现有处理不够、什么情况被绕过。
同时重新检查你其他结论，有没有同样因看不到全部代码而误判的。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;80-篇速查卡&quot;&gt;80 篇速查卡&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;记忆点&lt;/th&gt;
      &lt;th&gt;内容&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;为什么需要 review&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;测试盯”对不对”，review 盯”稳不稳、安不安全”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;AI 给废话的原因&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;你没给标准 → &lt;strong&gt;给清单，逼它逐项过&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;Review 五关&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;正&lt;/strong&gt;（正确）&lt;strong&gt;安&lt;/strong&gt;（安全）&lt;strong&gt;错&lt;/strong&gt;（异常）&lt;strong&gt;洁&lt;/strong&gt;（整洁）&lt;strong&gt;快&lt;/strong&gt;（性能）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;顺序即优先级&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;安全最致命不可逆，性能排最后&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;提示词四技巧&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;禁夸奖 / 分三档 / 每条四要素 / 允许说”没问题”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;四要素&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;在哪 + 什么问题 + &lt;strong&gt;会造成什么后果&lt;/strong&gt; + 怎么改&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;三级过滤&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;真问题（改）/ AI 看错了（补上下文）/ 风格之争（可跳过）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;一句话验伪&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;“给我一个会真出事的具体场景”&lt;/strong&gt; —— 说不出的都是凑数&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;新手三大死法&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;密钥硬编码 / 输入拼进指令 / 报错原样返前端&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;下篇预告&quot;&gt;下篇预告&lt;/h2&gt;

&lt;p&gt;现在代码有两道防线：&lt;strong&gt;测试&lt;/strong&gt;盯结果，&lt;strong&gt;review&lt;/strong&gt; 盯风险。但还有个问题没解决——&lt;strong&gt;三个月后你自己看不懂自己写的代码&lt;/strong&gt;。变量名取对了、逻辑没毛病，却想不起”当初为什么这么写”。代码能说清”做了什么”，说不清”为什么”。下一篇《第 81 篇：用 AI 生成注释与文档》讲注释该写什么、不该写什么（剧透：&lt;strong&gt;写”为什么”不写”是什么”&lt;/strong&gt;）。下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">代码跑通了就敢提交？跑得通，只是及格线。</summary></entry><entry><title type="html">第79篇：用 AI 写单元测试——覆盖率不再头疼</title><link href="http://0.0.0.0/2026/10/06/ai-79-unittest/" rel="alternate" type="text/html" title="第79篇：用 AI 写单元测试——覆盖率不再头疼" /><published>2026-10-06T10:00:00+08:00</published><updated>2026-10-06T10:00:00+08:00</updated><id>http://0.0.0.0/2026/10/06/ai-79-unittest</id><content type="html" xml:base="http://0.0.0.0/2026/10/06/ai-79-unittest/">&lt;blockquote&gt;
  &lt;p&gt;改了一行，不知道会崩哪儿。这种恐惧，能治。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;上上篇讲重构时，我留了样东西叫&lt;strong&gt;「行为快照表」&lt;/strong&gt;——改代码前先把”这段功能现在的表现”手工记一遍：输入什么、出来什么。改完照表跑，对上就安全。&lt;/p&gt;

&lt;p&gt;那张表好用，但致命缺点是&lt;strong&gt;它是手工的&lt;/strong&gt;。三个功能点跑一遍五分钟，三十个功能点跑一小时，于是你就不跑了。不跑等于没安全网。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这一篇就一句话：把那张手工快照表，变成一行命令就能全跑完的代码。&lt;/strong&gt; 这东西叫&lt;strong&gt;单元测试&lt;/strong&gt;。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一先说人话单元测试到底是个啥&quot;&gt;一、先说人话：单元测试到底是个啥&lt;/h2&gt;

&lt;p&gt;别被”测试”吓到，它跟”测试工程师”两码事。最土的比喻：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;手工验证，是把整台机器开起来看它转不转。&lt;/strong&gt;
&lt;strong&gt;单元测试，是把每个零件单独拿出来，通上电，看它响不响。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;“单元”就是&lt;strong&gt;一个函数、一个方法、一小块独立逻辑&lt;/strong&gt;。你写一小段代码专门调用它，检查”我给它 3 和 5，它是不是返回 8？”是就打勾，不是就报红。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;一个最小的单元测试，本质只有三句话：&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;准备&lt;/strong&gt;：输入是什么&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;执行&lt;/strong&gt;：调用它&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;断言&lt;/strong&gt;：结果应该等于什么&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;第三步”断言”是灵魂——你写死在代码里那句&lt;strong&gt;“它必须等于这个”&lt;/strong&gt;。以后谁改代码，结果不等于这个，机器当场报警。&lt;strong&gt;这就是它比手工表强的地方：机器帮你看、帮你对，一秒能对完几百条。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-06-ai-79-manual-vs-unit.png&quot; alt=&quot;manual-vs-unit&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二该测什么记住四靶正边错空&quot;&gt;二、该测什么？记住「四靶」：正、边、错、空&lt;/h2&gt;

&lt;p&gt;小白写测试最大问题不是不会写，是&lt;strong&gt;不知道该测哪些情况&lt;/strong&gt;。写完一个就觉得”测过了”，结果线上还炸，因为你只测了最顺的那种。&lt;/p&gt;

&lt;p&gt;归成&lt;strong&gt;四个靶子&lt;/strong&gt;，口诀：&lt;strong&gt;正、边、错、空&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;靶一：正（正常情况）&lt;/strong&gt; 最典型最顺的那一种，用户按你想的那样用。算折扣原价 100 打 8 折 → 80；手机号 13812345678 → 通过。&lt;strong&gt;这一靶最容易想到，也最没价值，只能证明”能用”不能证明”可靠”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;靶二：边（边界值）&lt;/strong&gt; &lt;strong&gt;刚好卡在临界线上的数，线上事故八成出在这。&lt;/strong&gt; 满 100 减 20，那&lt;strong&gt;正好 100&lt;/strong&gt; 呢？库存”大于 0 才能买”，&lt;strong&gt;正好 0&lt;/strong&gt;、&lt;strong&gt;负数&lt;/strong&gt;呢？分页每页 10 条，&lt;strong&gt;正好 10/11/第一页/最后一页&lt;/strong&gt;呢？→ &lt;strong&gt;记一条：代码里出现「大于」「小于」「至少」「最多」，那个数字本身就是必测靶。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;靶三：错（错误输入）&lt;/strong&gt; 用户会乱输，接口会返垃圾，必然的。手机号栏输汉字、金额栏输负数、日期输”2026-13-45”。&lt;strong&gt;你要测的不是”它能不能处理”，而是”出错时是不是优雅报错，而不是整个崩掉”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;靶四：空（空值）&lt;/strong&gt; &lt;strong&gt;新手漏得最多，也是线上崩溃第一元凶。&lt;/strong&gt; 空字符串 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;&quot;&lt;/code&gt;、空数组 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;[]&lt;/code&gt;（列表一条数据没有，页面白屏？）、null/None（数据库那字段本来就是空）、用户没填/接口没返。&lt;strong&gt;很多”莫名其妙崩溃”追到底，就是某处是空的，代码默认它一定有值。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;四靶速记表：&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;靶&lt;/th&gt;
      &lt;th&gt;测什么&lt;/th&gt;
      &lt;th&gt;一句话&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;正&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;最典型正常输入&lt;/td&gt;
      &lt;td&gt;证明”能用”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;边&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;临界值：0、1、正好、最大、最小&lt;/td&gt;
      &lt;td&gt;事故高发区&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;错&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;非法输入：类型错、格式错、负数&lt;/td&gt;
      &lt;td&gt;看它报错还是崩溃&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;空&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;空串、空数组、null、没填&lt;/td&gt;
      &lt;td&gt;崩溃第一元凶&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;务实标准：一个函数，四靶各写一条，四条就够用。&lt;/strong&gt; 别一上来想写二十条。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-06-ai-79-test-four-targets.png&quot; alt=&quot;test-four-targets&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三让-ai-写测试四步法框说生补&quot;&gt;三、让 AI 写测试：四步法「框、说、生、补」&lt;/h2&gt;

&lt;p&gt;流程压成&lt;strong&gt;四步&lt;/strong&gt;，口诀：&lt;strong&gt;框、说、生、补&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;第一步框先定测试框架&quot;&gt;第一步：框——先定测试框架&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;新手第一个坑。&lt;/strong&gt; 直接说”帮我写单元测试”，AI 随便挑个框架给你写，复制过去一跑满屏报错——&lt;strong&gt;你项目根本没装那个框架&lt;/strong&gt;。正确做法：&lt;strong&gt;先问 AI 你该用什么。&lt;/strong&gt; 把项目依赖清单文件（记录”用了哪些工具”的文件）整份贴给 AI，问清三件事：① 已装测试框架吗、装哪个？② 没装推荐哪个、安装命令？③ 测试文件放哪、文件名怎么起。&lt;strong&gt;问清这三件少走一半弯路。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第二步说说清它应该做什么别让-ai-猜&quot;&gt;第二步：说——说清”它应该做什么”，别让 AI 猜&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;全篇最重要的一句话：千万不要只把代码丢给 AI 说”帮我写测试”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;因为 AI 会&lt;strong&gt;照着你的代码写测试&lt;/strong&gt;。代码有 bug，AI 就把 bug 当”正确答案”写进断言。比如”满 100 减 20”你写错了写成”大于 100 才减”，AI 一看写出测试：”输入 100 应该不减。”测试绿了，可 bug 被永久固化，还有测试给它背书。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;破法：先用大白话描述函数「应该」做什么，让 AI 按描述写，不是按代码写。&lt;/strong&gt; 对比：&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;❌ 差：「这是我的代码，帮我写测试。」&lt;/li&gt;
  &lt;li&gt;✅ 好：「业务规则：订单原价满 100（含 100）减 20，不满不减，负数直接报错。请按这规则写测试。写完后对照我贴的代码，告诉我代码和规则有没有对不上。」&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;后半句是白送的 bug 检测器&lt;/strong&gt;，让 AI 拿”规则”和”代码”对一遍，常能当场抓问题。&lt;/p&gt;

&lt;h3 id=&quot;第三步生生成然后一定要跑起来&quot;&gt;第三步：生——生成，然后一定要跑起来&lt;/h3&gt;

&lt;p&gt;AI 给测试代码后，&lt;strong&gt;别看，直接跑。&lt;/strong&gt; 新手常卡在这三类报错：① 找不到文件（引入被测代码的路径不对）② 框架没装（命令不认识）③ 配置缺失（需要配置文件）。&lt;strong&gt;这三类全不用自己解决——把报错原文（整段别转述）贴回给 AI，加一句：”我按你给的代码跑，报了这个错，这是完整报错，请告诉我原因和具体改哪个文件哪行。”&lt;/strong&gt; 这是第 71 篇老规矩：报错贴原文。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;跑起来看到第一排绿勾，你才算真入门。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第四步补看覆盖率找洞补测&quot;&gt;第四步：补——看覆盖率，找洞，补测&lt;/h3&gt;

&lt;p&gt;跑通后让 AI 教你开&lt;strong&gt;覆盖率报告&lt;/strong&gt;：绿色行 = 被测到过，红色行 = 一次没跑到。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-06-ai-79-ai-test-four-steps.png&quot; alt=&quot;ai-test-four-steps&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四覆盖率别追高要找洞&quot;&gt;四、覆盖率：别追高，要找洞&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;覆盖率是新手最容易被骗的数字。&lt;/strong&gt; 先把话说死：&lt;strong&gt;覆盖率高 ≠ 代码没问题。&lt;/strong&gt; 它只统计”这行被跑过”，&lt;strong&gt;完全不管你有没有检查结果对不对。&lt;/strong&gt; 极端例子：写个测试把所有函数调一遍，一个断言不写，覆盖率 100%，但啥也没测——从不检查结果，返回什么都说通过。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;正确用法：不是追高，是找洞。&lt;/strong&gt; 打开报告&lt;strong&gt;只看红色&lt;/strong&gt;，对每块红的问自己：”这段代码从来没被测过，我慌不慌？”慌（支付金额、权限、扣库存）→ 立刻补；不慌（打印日志、界面颜色）→ 放着。&lt;strong&gt;这才是覆盖率真正的用法：一张藏宝图，标出你没走过的路，挑重要的走。&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;代码类型&lt;/th&gt;
      &lt;th&gt;建议覆盖率&lt;/th&gt;
      &lt;th&gt;理由&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;核心业务逻辑&lt;/strong&gt;（钱、权限、库存）&lt;/td&gt;
      &lt;td&gt;80% 以上&lt;/td&gt;
      &lt;td&gt;出事代价最大&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;工具函数&lt;/strong&gt;（格式化、校验）&lt;/td&gt;
      &lt;td&gt;60%~80%&lt;/td&gt;
      &lt;td&gt;好测，顺手测&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;界面胶水代码&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;不强求&lt;/td&gt;
      &lt;td&gt;测起来贵收益低&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;第三方库代码&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;0%&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;那是人家的事&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;为凑数字写假测试，是纯粹自我欺骗。&lt;/strong&gt; 数字好看了，安全网还是破的。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五ai-写测试的三个坑提前告诉你&quot;&gt;五、AI 写测试的三个坑，提前告诉你&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;坑一：AI 把 bug 当正确答案。&lt;/strong&gt; 上面说过，&lt;strong&gt;破法就是先说规则再让它写&lt;/strong&gt;，最重要的一条。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;坑二：AI 爱写”测了个寂寞”的测试。&lt;/strong&gt; 它把所有外部依赖都换成假的（术语 mock），假到最后&lt;strong&gt;测的全是自己造的假数据，真实逻辑一行没跑到&lt;/strong&gt;。&lt;strong&gt;破法加一句约束：&lt;/strong&gt;“尽量少用 mock，只有网络请求、数据库、文件读写、当前时间这四类才允许替换成假的，其余用真实调用。”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;坑三：AI 造的测试数据太”干净”。&lt;/strong&gt; 它特爱用”张三”“test@test.com”“123”，全是标准格式一个坑踩不到。&lt;strong&gt;破法点名要脏数据：&lt;/strong&gt;“测试数据要贴近真实：含中文、空格、超长字符串、特殊符号、emoji、前后带空格的输入。”&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六一条铁律测试红了先怀疑代码&quot;&gt;六、一条铁律：测试红了，先怀疑代码&lt;/h2&gt;

&lt;p&gt;这条单独说，因为它决定这套东西&lt;strong&gt;有没有用&lt;/strong&gt;。你常会遇到：改了点代码一跑，&lt;strong&gt;红了&lt;/strong&gt;。新手第一反应：”这个测试挡我路了，我把它改改让它过。”&lt;strong&gt;打住。&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;测试红了，永远先怀疑代码，最后才怀疑测试。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;测试红是好事，说明&lt;strong&gt;安全网起作用了&lt;/strong&gt;，刚拦下你没意识到的行为变更。把断言改成新结果，等于&lt;strong&gt;看到火警响了把警报器电池抠掉&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;正确顺序：① 看它红在哪（期望值 vs 实际值）② 问：这变化是我故意的吗？③ 不是故意 → 恭喜抓到 bug，&lt;strong&gt;改代码&lt;/strong&gt; ④ 是故意（需求真改了）→ 才改测试，&lt;strong&gt;并在提交说明写清为什么改&lt;/strong&gt;。&lt;strong&gt;这一条记住了，这篇文章就没白读。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-06-ai-79-test-red-fix.png&quot; alt=&quot;test-red-fix&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;七完整走一遍从零到绿灯&quot;&gt;七、完整走一遍：从零到绿灯&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;贴依赖清单&lt;/strong&gt;，问 AI 用什么框架、装什么、文件放哪&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;装好框架&lt;/strong&gt;，让 AI 写个”1+1=2”级最简单测试，&lt;strong&gt;先确保能跑起来&lt;/strong&gt;（省掉后面 80% 抓狂）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;挑最核心的函数&lt;/strong&gt;（管钱、管权限那个）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;用大白话写它应该做什么&lt;/strong&gt;（业务规则）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;让 AI 按规则 + 四靶写测试&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;跑，报错就贴原文回问&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;绿了看覆盖率，挑红色重要的补&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;以后每次改代码，先跑一遍测试&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;第 8 条才是全部价值所在。&lt;/strong&gt; 前七步一次性投入，第八步是你此后每天的收益。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;提示词模板盒子&quot;&gt;提示词模板盒子&lt;/h2&gt;

&lt;h3 id=&quot;模板-1按业务规则写测试核心最重要&quot;&gt;模板 1：按业务规则写测试（核心，最重要）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;请帮我为下面这个函数写单元测试。

【第一部分：这个函数应该做什么（业务规则）】
用大白话一条条列：
1. ……
2. ……
3. 出现 XX 情况时，应该报错，不能返回错误结果

【第二部分：当前代码实现】
（完整贴代码，不要贴片段）

【第三部分：要求】
1. 测试框架用：XXX
2. 严格按【业务规则】写测试，不要照代码现有行为写
3. 每个规则至少覆盖四类：正（典型正常）/ 边（临界值0、1、正好、最大、最小）/ 错（类型错、格式错、负数）/ 空（空串、空数组、null、字段缺失）
4. 尽量少用 mock，只有网络/数据库/文件/当前时间才允许替换成假
5. 测试数据要贴近真实：含中文、空格、超长串、特殊符号、前后带空格
6. 每条测试上用中文注释写清&quot;测什么、为什么测&quot;
7. 给完整可运行测试文件，不要片段

【第四部分：额外任务】
写完对照【业务规则】和【代码】，告诉我代码有没有和规则对不上，逐条列：规则说啥/代码做啥/造成啥后果。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板-2环境搭建与排错定框架--跑不起来用&quot;&gt;模板 2：环境搭建与排错（定框架 + 跑不起来用）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;【A. 确定框架（第一步必用）】
我是编程新手，想加单元测试，不知从哪开始。下面是我项目依赖清单文件内容：
【把依赖清单完整内容贴这里】
请大白话告诉我四件事：1. 已装测试框架吗、装哪个 2. 没装推荐哪个（新手易上手）、完整安装命令 3. 测试文件放哪、文件名怎么起 4. 装完用什么命令跑。
最后给个最简单&quot;能跑通就行&quot;的示例测试文件（比如测加法函数），我先确认环境通再写真的。

【B. 测试跑不起来（排错专用）】
我按你给的测试代码运行，报错了。
【我执行的命令】（原样贴）
【完整报错信息】（一个字没改全贴）
【我的项目目录结构】（测试文件和被测代码分别在哪）
请告诉我：1. 报错原因（大白话）2. 具体改哪个文件哪行、改成什么 3. 一次只给一处修改，我改完跑一遍再回来。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板-3找洞与验伪覆盖率--测试红了用&quot;&gt;模板 3：找洞与验伪（覆盖率 + 测试红了用）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;【A. 看覆盖率报告找洞】
我跑出覆盖率报告，下面是没被测到的代码行：
【未覆盖代码】（贴报告标红那段）
请做三件事：1. 逐段说明这段代码干啥、啥情况被执行到 2. 按&quot;出事后果严重程度&quot;排成【必须补】【建议补】【可以不管】三档（涉及金额/权限/删除/库存一律必须补）3. 对【必须补】直接给可运行测试代码。
我不追求数字好看，只想补真危险的地方，别为凑数建议给日志/常量/赋值写测试。

【B. 测试失败了，帮我判断】
我改了代码，一条测试红了。请判断该改代码还是改测试。
【失败的测试】（贴）【报错内容】（期望值和实际值那部分必贴全）【我这次改了什么】（大白话）
请回答：1. 这条测试原本保护什么行为 2. 我改动是&quot;不小心破坏原行为&quot;还是&quot;需求真变了&quot; 3. 前者告诉我校哪、怎么改回 4. 后者告诉我测试怎么更新，并写一句提交说明讲清为什么变。
请不要默认&quot;改测试让它通过&quot;是正确答案。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;79-篇速查卡&quot;&gt;79 篇速查卡&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;记忆点&lt;/th&gt;
      &lt;th&gt;内容&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;单元测试是什么&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;用代码写的行为快照表，一行命令全跑完&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;测试三句话&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;准备 → 执行 → &lt;strong&gt;断言&lt;/strong&gt;（断言是灵魂）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;测试四靶&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;正&lt;/strong&gt;（正常）&lt;strong&gt;边&lt;/strong&gt;（临界）&lt;strong&gt;错&lt;/strong&gt;（非法）&lt;strong&gt;空&lt;/strong&gt;（空值）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;AI 写测试四步&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;框&lt;/strong&gt;（定框架）&lt;strong&gt;说&lt;/strong&gt;（说规则）&lt;strong&gt;生&lt;/strong&gt;（生成跑通）&lt;strong&gt;补&lt;/strong&gt;（覆盖率找洞）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;最大的坑&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;只贴代码让 AI 写 → bug 被当正确答案固化&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;覆盖率用法&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;不追高，&lt;strong&gt;只用来找洞&lt;/strong&gt;；红的里挑重要的补&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;铁律&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;测试红了，&lt;strong&gt;先怀疑代码，最后才怀疑测试&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;下篇预告&quot;&gt;下篇预告&lt;/h2&gt;

&lt;p&gt;测试是&lt;strong&gt;机器帮你盯”结果对不对”&lt;/strong&gt;。但有一大类问题机器盯不到：密钥写代码里、用户输入原样拼查询、循环里一遍遍查库、错误信息把内部结构吐给前端——这些代码全跑通、测试全绿，可迟早出事。这类本靠有经验同事帮你看，可你没有那个同事呢？下一篇《第 80 篇：用 AI 做 Code Review》教你把 AI 变成那个同事。下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">改了一行，不知道会崩哪儿。这种恐惧，能治。</summary></entry><entry><title type="html">第78篇：用 AI 做代码优化（性能/可读性）——双管齐下</title><link href="http://0.0.0.0/2026/10/05/ai-78-optimize/" rel="alternate" type="text/html" title="第78篇：用 AI 做代码优化（性能/可读性）——双管齐下" /><published>2026-10-05T10:00:00+08:00</published><updated>2026-10-05T10:00:00+08:00</updated><id>http://0.0.0.0/2026/10/05/ai-78-optimize</id><content type="html" xml:base="http://0.0.0.0/2026/10/05/ai-78-optimize/">&lt;blockquote&gt;
  &lt;p&gt;页面转圈五秒，用户已经关了。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;上一篇我们把代码”擦干净”了，但没让它变快一分一毫。&lt;/p&gt;

&lt;p&gt;这一篇要处理的，是所有人都会遇到的另一个难题：&lt;strong&gt;代码不光要好读，还得跑得动。&lt;/strong&gt; 而这两件事经常打架——你会发现一个残酷规律：&lt;strong&gt;让代码变快的手段，多半会让它变难懂。&lt;/strong&gt; 加缓存、批量、并发，每样都在往代码里塞额外复杂度。&lt;/p&gt;

&lt;p&gt;所以”优化”和重构完全不同：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;重构是”只赚不赔”，优化是”有得有失”。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;重构改完更好懂、功能没变、没有代价。优化改完更快了，但&lt;strong&gt;总要付出点什么&lt;/strong&gt;——可读性、内存、或多一个可能出错的环节。&lt;strong&gt;既然是买卖，就得先算账。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一优化三问值位价&quot;&gt;一、优化三问：值、位、价&lt;/h2&gt;

&lt;p&gt;动手之前先问自己三句话，口诀&lt;strong&gt;“值、位、价”&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;第一问值不值得改值&quot;&gt;第一问：值不值得改？（值）&lt;/h3&gt;

&lt;p&gt;这一问能砍掉八成无效优化。问自己：&lt;strong&gt;现在这个速度，真的有人在抱怨吗？&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;后台页面加载 1.2 秒 —— &lt;strong&gt;不用改&lt;/strong&gt;，没人骂你。&lt;/li&gt;
  &lt;li&gt;点提交转圈 6 秒 —— &lt;strong&gt;必须改&lt;/strong&gt;，已经在流失用户。&lt;/li&gt;
  &lt;li&gt;一年跑一次的报表脚本跑 10 分钟 —— &lt;strong&gt;不用改&lt;/strong&gt;，花两小时优化一年只省 9 分钟。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;很土但好用的尺子：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;场景&lt;/th&gt;
      &lt;th&gt;用户感受&lt;/th&gt;
      &lt;th&gt;该不该改&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;100 毫秒内&lt;/td&gt;
      &lt;td&gt;感觉”瞬间”&lt;/td&gt;
      &lt;td&gt;别碰&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;100ms - 1 秒&lt;/td&gt;
      &lt;td&gt;感觉”流畅”&lt;/td&gt;
      &lt;td&gt;一般不用&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;1 - 3 秒&lt;/td&gt;
      &lt;td&gt;开始”有点慢”&lt;/td&gt;
      &lt;td&gt;看情况&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3 - 10 秒&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;明显不耐烦&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;该改&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;10 秒以上&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;以为坏了直接关&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;立刻改&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;过早优化是新手最大的时间黑洞。&lt;/strong&gt; 你花一下午把 0.3 秒优化到 0.2 秒，用户完全无感，代码却多了一层没人懂的逻辑。&lt;/p&gt;

&lt;h3 id=&quot;第二问改哪一处位&quot;&gt;第二问：改哪一处？（位）&lt;/h3&gt;

&lt;p&gt;回到第 73 篇铁律：&lt;strong&gt;先测量，再优化。&lt;/strong&gt; 绝大多数程序耗时符合规律：&lt;strong&gt;80% 的时间花在 20% 的代码上。&lt;/strong&gt; 你随手挑一段优化，大概率优化了一段本来就不慢的东西。&lt;/p&gt;

&lt;p&gt;顺序永远是：先测（整个流程几秒）→ 再拆（几秒分别花在哪）→ 锁定（占比最大的那段）→ &lt;strong&gt;只改它，其他不动&lt;/strong&gt;。&lt;strong&gt;没有测量数据就优化，等于蒙眼开枪。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第三问代价是什么价&quot;&gt;第三问：代价是什么？（价）&lt;/h3&gt;

&lt;p&gt;最容易被跳过、也最要命的一问。任何优化都有代价，常见四种：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;可读性&lt;/strong&gt;（代码变绕）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;内存&lt;/strong&gt;（用空间换时间，缓存多了爆内存）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;一致性&lt;/strong&gt;（加了缓存数据可能旧）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;复杂度&lt;/strong&gt;（多一个可能出错的环节）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;让 AI 优化时，一定要逼它把代价说出来。&lt;/strong&gt; 它默认只吹”性能提升 80%”，不会主动告诉你”但数据可能延迟 5 分钟”。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-05-ai-78-optimize-three-questions.png&quot; alt=&quot;optimize-three-questions&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二提速四招少缓批延&quot;&gt;二、提速四招：少、缓、批、延&lt;/h2&gt;

&lt;p&gt;真要改的时候，小白只需认识四类手段，口诀&lt;strong&gt;“少、缓、批、延”&lt;/strong&gt;。&lt;strong&gt;这四招覆盖日常九成性能问题。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一招：少（少做点事）&lt;/strong&gt; 最朴素也最有效：本来做十次改做一次。比如计算结果在循环里被反复算一千遍，算一遍存起来就行；从数据库查一万条回来在代码里筛五条——为什么不让数据库直接给那五条？&lt;strong&gt;代价：几乎没有，永远优先用。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二招：缓（算过的存起来）&lt;/strong&gt; 同样问题第二次直接给上次答案。城市列表、商品分类、汇率一天不变，每次查库纯浪费。&lt;strong&gt;代价：数据可能是旧的。&lt;/strong&gt; 用缓存前先问：”这个数据过期 5 分钟会出事吗？”城市列表没事，&lt;strong&gt;账户余额过期 5 分钟出大事。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第三招：批（一次一批，别一次一条）&lt;/strong&gt; 数据库操作上效果最猛，常快十倍以上。要存 1000 条却循环一条条存 1000 次，光”打招呼”就耗掉大部分时间，打包一次送过去直接起飞。&lt;strong&gt;代价：一批里一条出错，整批怎么办？要提前想清。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第四招：延（不急的放后面）&lt;/strong&gt; 用户等的马上做，不急的挪后面。点”提交订单”依次做了存订单→扣库存→&lt;strong&gt;发短信→发邮件→写日志&lt;/strong&gt;——用户等的只是”存没存上”，后面三件他不在乎。挪后台慢慢做，等待时间砍掉一大半。&lt;strong&gt;代价：多一个”后台那步失败了怎么办”的问题。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-05-ai-78-four-speedups.png&quot; alt=&quot;four-speedups&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三性能和可读性打架时听谁的&quot;&gt;三、性能和可读性打架时，听谁的？&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;先给结论：99% 情况下，可读性优先。&lt;/strong&gt; 依据很硬：&lt;strong&gt;你 99% 的代码根本不在瓶颈上&lt;/strong&gt;，那部分写得再”高效”对整体速度影响近零，但变难懂的代价你每天承受。&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;情况&lt;/th&gt;
      &lt;th&gt;选谁&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;没测量，凭感觉慢&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;可读性&lt;/strong&gt;（先去测量）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;测过，这段不是瓶颈&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;可读性&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;测过是瓶颈，但优化只省 50 毫秒&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;可读性&lt;/strong&gt;（不值得）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;测过是瓶颈，从 6 秒降到 1 秒&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;性能&lt;/strong&gt;，但必须补注释&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;是瓶颈，且优化后没变难懂（”少”常见）&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;两个都要&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;真要为速度牺牲可读性，你有义务留三样东西，否则三个月后这段代码成没人敢碰的雷区：&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;一段”为什么”注释&lt;/strong&gt;——不要写”这里做了缓存”（代码看得出），要写清背景：哪天排查发现首页每次查全量分类表、单次 800ms、占首页 70%、分类日均变 0-1 次、允许 10 分钟延迟。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;一组数字&lt;/strong&gt;——”优化前 6.2 秒，优化后 1.1 秒”，写进注释，是后人判断”这段还值不值得留”的唯一依据。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;一句”什么情况可删掉”&lt;/strong&gt;——比如”分类降到 50 条内，这缓存可直接删”。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;没有这三样，你留的不是优化，是定时炸弹。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四实战完整的一次优化对话&quot;&gt;四、实战：完整的一次优化对话&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;场景&lt;/strong&gt;：用户点”导出订单”，转圈 12 秒。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一步：先量（别跳过）。&lt;/strong&gt; 第一句话不该是”帮我优化”，而是”帮我测量”。让 AI 加计时点跑一次，看 12 秒花在哪：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;查询订单数据      1.1 秒
循环处理每条订单  9.8 秒   ← 元凶
生成文件          0.7 秒
写入响应          0.4 秒
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;优化的目标只有一个——那 9.8 秒。&lt;/strong&gt; 剩下三段加起来才 2.2 秒，优化到 0 也只省两秒。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二步：让 AI 给方案，但要它列代价。&lt;/strong&gt; 关键：&lt;strong&gt;不要直接要代码，先要方案对比表。&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;方案&lt;/th&gt;
      &lt;th&gt;手段&lt;/th&gt;
      &lt;th&gt;预估效果&lt;/th&gt;
      &lt;th&gt;可读性代价&lt;/th&gt;
      &lt;th&gt;风险&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;A&lt;/td&gt;
      &lt;td&gt;循环里每条查用户名→改一次批量查&lt;/td&gt;
      &lt;td&gt;9.8s→1.5s&lt;/td&gt;
      &lt;td&gt;低&lt;/td&gt;
      &lt;td&gt;低&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;B&lt;/td&gt;
      &lt;td&gt;加多线程并发&lt;/td&gt;
      &lt;td&gt;9.8s→3s&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;高&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;中（并发问题）&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;C&lt;/td&gt;
      &lt;td&gt;结果整体缓存 10 分钟&lt;/td&gt;
      &lt;td&gt;二次→0.1s&lt;/td&gt;
      &lt;td&gt;中&lt;/td&gt;
      &lt;td&gt;中（数据延迟）&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;选择很明显：方案 A&lt;/strong&gt;——效果最好、代价最低、风险最小，用的正是”批”。循环里查库是新手最常见性能杀手，行话叫 &lt;strong&gt;N+1 查询&lt;/strong&gt;。&lt;strong&gt;方案 B 那种”加多线程”听着高级，但并发引入的 Bug 比它解决的性能问题更麻烦，能不用就不用。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第三步：只改这一处，改完再量。&lt;/strong&gt; 从 12 秒降到 3.7 秒。这时停下问第一问：”还值得继续改吗？”3.7 秒已从”以为坏了”变成”有点慢但能接受”，再抠收益递减、风险递增。&lt;strong&gt;优化最容易上瘾，见好就收是一种能力。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-05-ai-78-optimize-flow.png&quot; alt=&quot;optimize-flow&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五三个新手最容易踩的优化陷阱&quot;&gt;五、三个新手最容易踩的优化陷阱&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;陷阱一：相信 AI 报的”提升百分比”。&lt;/strong&gt; 它很自信说”提升 80%”，&lt;strong&gt;那是它猜的&lt;/strong&gt;——没跑过你代码、不知数据量、不知配置。&lt;strong&gt;唯一可信的数字是你自己跑出来的，改完必须重测。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;陷阱二：一次改五处。&lt;/strong&gt; 和重构同理，但优化更危险——&lt;strong&gt;你分不清是哪一处带来提升&lt;/strong&gt;。万一某处其实让程序变慢，被另一处提升掩盖，根本发现不了。&lt;strong&gt;一次改一处，改完就量。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;陷阱三：优化了功能，忘了验证正确性。&lt;/strong&gt; 最惨的一种：代码从 12 秒变 1 秒，但导出数据错了。性能优化常动数据处理逻辑——批量可能漏数据、缓存给旧数据、并发乱序。&lt;strong&gt;第 77 篇那张”行为快照表”，优化场景同样必须做，而且要更严格：优化后的正确性验证，比重构还重要。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六一张随身判断表&quot;&gt;六、一张随身判断表&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;□ 用户真的抱怨了吗？没有 → 停，别改
□ 慢到几秒？3 秒以内 → 大概率不用改
□ 我测量过了吗？没有 → 先去测，别猜
□ 最慢那段占比多少？不到 50% → 改它收益有限
□ 能用&quot;少&quot;解决吗？能 → 优先，代价最低
□ 要用&quot;缓&quot;吗？数据旧了会出事吗？
□ 要用&quot;批&quot;吗？一条失败整批怎么办？
□ 要用&quot;延&quot;吗？后台失败了谁来管？
□ 改完可读性变差了吗？变差 → 补三样：为什么/数字/何时可删
□ 改完我重新测了吗？
□ 改完验证数据还是对的吗？（比性能更重要）
□ 现在速度够用了吗？够了 → 停手
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;提示词模板盒子&quot;&gt;提示词模板盒子&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;模板一：先测量（永远的第一步）&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;下面这段代码执行很慢，用户点击后要等约 __ 秒。

【本轮只做一件事：帮我测量，不要优化】
1. 在关键节点插入耗时统计，把流程拆成若干段，分别打印每段耗时
2. 告诉我应该重点关注哪几段
3. 给我完整文件（含插入的计时代码）
4. 告诉我：测完怎么读这些数字，什么占比才算&quot;这就是瓶颈&quot;

【代码】
（在此粘贴完整文件）
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;模板二：方案对比（要表格，不要代码）&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我已经测量过了，耗时分布如下：
（贴出各段耗时）
最慢的是【____】这一段，占总耗时约 __%。

【本轮要求 · 重要】
1. 只针对最慢这段给方案，其他部分一律不讨论
2. 不要给我代码，先给【方案对比表】，至少 3 个方案，含：
   方案 | 具体手段 | 预估效果 | 可读性代价（低/中/高） | 引入的新风险 | 实现难度
3. 明确标出你推荐哪个，以及为什么
4. 特别说明：哪些方案会改变数据正确性/一致性/实时性
5. 若属&quot;用空间换时间&quot;，说明大概多占多少内存

【我的情况】
数据量大约：____   使用人数：____   技术水平：新手，优先好理解、风险低的方案
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;模板三：执行与验收（带正确性护栏）&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我选择方案【__】，请帮我实现。

【铁律】
1. 只改这一处，其他任何地方不要动
2. 性能可提升，但【数据正确性绝对不能变】——同样输入必须得到完全一样输出
3. 若优化让代码变难懂，必须补注释说明：为什么这么写（原来慢在哪多慢）、优化前后耗时数字、什么情况可删这优化
4. 若引入缓存，明确告诉我：缓存多久过期、数据变更时怎么失效

【交付要求】
1. 完整文件，不要片段
2. 末尾用表格列出：改了哪几行 | 改成什么 | 为什么
3. 单独列出：改完我必须重点测哪几种情况（尤其易错边界）

【验收】这是优化前【A】和优化后【B】，请严格检查：
1. 【正确性】所有输入下输出是否一致？特别查空数据/单条/超大量/特殊字符
2. 【遗漏】A 里哪些判断/异常处理在 B 里被省略了
3. 【新风险】B 引入了哪些 A 没有的失败可能（缓存不一致/批量部分失败/并发冲突）
4. 【可读性】给 B 可读性 1-10 打分，说明比 A 差在哪
5. 一句话结论：这次优化&quot;划算&quot;还是&quot;不划算&quot;
【A】（粘贴）【B】（粘贴）
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;下篇预告&quot;&gt;下篇预告&lt;/h2&gt;

&lt;p&gt;两把刀到手：第 77 篇重构（擦干净，只赚不赔）、第 78 篇优化（跑得快，有得有失）。但都共一个前提——&lt;strong&gt;你得知道”改完到底有没有改坏”&lt;/strong&gt;。手工快照表太累还爱偷懒。下一篇《第 79 篇：用 AI 写单元测试》讲怎么让机器自动盯。下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">页面转圈五秒，用户已经关了。</summary></entry><entry><title type="html">第77篇：用 AI 重构烂代码——可读性直线上升</title><link href="http://0.0.0.0/2026/10/04/ai-77-refactor/" rel="alternate" type="text/html" title="第77篇：用 AI 重构烂代码——可读性直线上升" /><published>2026-10-04T10:00:00+08:00</published><updated>2026-10-04T10:00:00+08:00</updated><id>http://0.0.0.0/2026/10/04/ai-77-refactor</id><content type="html" xml:base="http://0.0.0.0/2026/10/04/ai-77-refactor/">&lt;blockquote&gt;
  &lt;p&gt;代码能跑，但一个月后你自己都看不懂。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这就是所有人都会撞上的那堵墙。&lt;/p&gt;

&lt;p&gt;前面十几篇我们一直在解决”&lt;strong&gt;能不能跑&lt;/strong&gt;“：写出来、跑起来、修好 Bug。从这一篇开始换赛道，解决”&lt;strong&gt;跑得好不好看&lt;/strong&gt;“。&lt;/p&gt;

&lt;p&gt;你可能会想：能跑就行呗，好看有什么用？我给你算笔账。&lt;/p&gt;

&lt;p&gt;一段乱七八糟的代码，今天写完能跑。三周后要加功能，你盯了二十分钟才想起来”这个变量是干嘛的”。改完一测，另外三个地方坏了——因为你根本不知道这段代码还被谁用着。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;代码不是写给电脑看的，电脑什么烂代码都能跑。代码是写给三周后的你自己看的。&lt;/strong&gt; 而”三周后的你”，记忆力大概等于一个陌生人。&lt;/p&gt;

&lt;p&gt;这一篇，教你把 AI 变成专门帮你”擦桌子”的助手。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一先说清楚什么叫重构&quot;&gt;一、先说清楚：什么叫重构&lt;/h2&gt;

&lt;p&gt;这个词听着唬人，其实一句话就能说明白：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;重构 = 只改样子，不改行为。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;改之前输入 1 得到 2；改之后输入 1 还得得到 2。&lt;strong&gt;功能一模一样，只是更好读了。&lt;/strong&gt; 这句话是本篇的地基，务必记牢。新手用 AI 重构翻车，&lt;strong&gt;九成踩在这一句上&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;典型翻车现场：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;小白：（把整个文件甩给 AI）帮我重构一下这段代码。
AI：好的！我帮你重构了。（顺手合并三个功能，删掉两个”看起来没用”的判断，还改了接口返回格式）
小白：（一测）……怎么全崩了？&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;AI 不知道哪些代码”看起来没用但其实很重要”。&lt;/strong&gt; 那个奇怪的 if，可能是三个月前为某个客户特殊情况加的。你不说，AI 就当垃圾清掉。所以重构&lt;strong&gt;主导权必须在你手上，AI 只是那把刀。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-04-ai-77-refactor-vs-rewrite.png&quot; alt=&quot;refactor-vs-rewrite&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二烂代码的六种味道先学会闻&quot;&gt;二、烂代码的六种味道：先学会”闻”&lt;/h2&gt;

&lt;p&gt;程序员圈有个说法叫 &lt;strong&gt;Code Smell（代码坏味道）&lt;/strong&gt;：不一定有 Bug，但闻着不对劲，早晚出事。记六种就够了，口诀&lt;strong&gt;长、重、名、套、魔、杂&lt;/strong&gt;，叫&lt;strong&gt;重构六味&lt;/strong&gt;：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一味：长（函数太长）&lt;/strong&gt; 一个函数拉到两百行，滚轮滚半天。判断标准很土但好用：&lt;strong&gt;一屏放不下，就是太长了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二味：重（重复代码）&lt;/strong&gt; 同一段逻辑复制粘贴出现三次以上。改的时候必须记得改三个地方——&lt;strong&gt;你一定会忘掉一个。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第三味：名（命名瞎起）&lt;/strong&gt; 满屏 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;a&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;b&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;tmp&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;data1&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;flag&lt;/code&gt;。写的时候知道，三周后不知道。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第四味：套（嵌套太深）&lt;/strong&gt; if 里套 if，if 里再套 for——&lt;strong&gt;缩进快顶到屏幕右边了。&lt;/strong&gt; 超过三层就该警觉。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第五味：魔（魔法数字）&lt;/strong&gt; 代码里突然冒出 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;7&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.85&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;3600&lt;/code&gt;。从哪来的？代表什么？没人知道，包括三周后的你。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第六味：杂（一个函数干太多事）&lt;/strong&gt; 一个”保存订单”函数，又查库存、又算优惠、又发短信、又写日志。&lt;strong&gt;名字说它干一件，实际干了四件。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-04-ai-77-six-code-smells.png&quot; alt=&quot;six-code-smells&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三重构四步法锁闻拆验&quot;&gt;三、重构四步法：锁、闻、拆、验&lt;/h2&gt;

&lt;p&gt;整套流程四步，口诀&lt;strong&gt;“锁闻拆验”&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;第一步锁锁定行为基线&quot;&gt;第一步：锁（锁定行为基线）&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;这是最重要、也最容易被跳过的一步。&lt;/strong&gt; 动任何一行之前，先回答：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;改完之后，我怎么证明”没改坏”？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;答不上来，就不要开始。最实用的做法是做一张&lt;strong&gt;“行为快照表”&lt;/strong&gt;：把这段代码目前的几组”输入 → 输出”记下来。比如算运费的函数，实际跑几次记下来：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;输入：重量 0.5kg、地址 本市    → 输出：6 元
输入：重量 3kg、地址 外省      → 输出：18 元
输入：重量 0（异常）           → 输出：报错&quot;重量不能为0&quot;
输入：地址 为空（异常）        → 输出：默认按外省算，22 元
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;最后两条异常必须记&lt;/strong&gt;——AI 重构时最爱”顺手优化”的就是这些奇怪的边界处理。另外动手前做件五秒钟的事：&lt;strong&gt;把原文件复制一份改名 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;xxx_备份.txt&lt;/code&gt; 存着&lt;/strong&gt;，它救过无数人。&lt;/p&gt;

&lt;h3 id=&quot;第二步闻让-ai-先体检不许动手&quot;&gt;第二步：闻（让 AI 先体检，不许动手）&lt;/h3&gt;

&lt;p&gt;很多人一上来就说”帮我重构”，这是错的。&lt;strong&gt;第一轮，只让 AI 诊断，明确禁止它给代码。&lt;/strong&gt; 你要先知道这段代码有几个问题、哪个最严重，然后自己决定改哪个。诊断时让 AI 按六味对号入座，并&lt;strong&gt;按严重程度排序&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;第三步拆一次只改一味&quot;&gt;第三步：拆（一次只改一味）&lt;/h3&gt;

&lt;p&gt;看到 AI 列出六个问题，新手本能是”都改了吧”。&lt;strong&gt;千万别。&lt;/strong&gt; 一次改六处，出问题你根本不知道是哪处引起的。&lt;strong&gt;一次只改一味，改完立刻验，验过再改下一味。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;顺序建议&lt;strong&gt;从最安全的改起&lt;/strong&gt;：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;优先级&lt;/th&gt;
      &lt;th&gt;改什么&lt;/th&gt;
      &lt;th&gt;风险&lt;/th&gt;
      &lt;th&gt;收益&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;1&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;名&lt;/strong&gt;（改命名）&lt;/td&gt;
      &lt;td&gt;极低&lt;/td&gt;
      &lt;td&gt;立竿见影&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;2&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;魔&lt;/strong&gt;（数字变常量）&lt;/td&gt;
      &lt;td&gt;极低&lt;/td&gt;
      &lt;td&gt;高&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;3&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;重&lt;/strong&gt;（合并重复）&lt;/td&gt;
      &lt;td&gt;中&lt;/td&gt;
      &lt;td&gt;高&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;4&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;长 / 杂&lt;/strong&gt;（拆函数）&lt;/td&gt;
      &lt;td&gt;中&lt;/td&gt;
      &lt;td&gt;高&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;5&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;套&lt;/strong&gt;（减少嵌套）&lt;/td&gt;
      &lt;td&gt;中高&lt;/td&gt;
      &lt;td&gt;中&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;先改成命名和魔法数字&lt;/strong&gt;——几乎不可能改坏，读起来立刻不一样，先尝甜头建信心。拆函数放后面，因为它动结构、风险更高。&lt;/p&gt;

&lt;h3 id=&quot;第四步验每改一次就验一次&quot;&gt;第四步：验（每改一次就验一次）&lt;/h3&gt;

&lt;p&gt;拿出第一步那张快照表，&lt;strong&gt;四组全跑一遍&lt;/strong&gt;，尤其那两条异常——它们最容易被”顺手删掉”。一致 → 通过，进下一味；不一致 → &lt;strong&gt;立刻回退备份&lt;/strong&gt;，别试图”再改改就好了”。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-04-ai-77-refactor-four-steps.png&quot; alt=&quot;refactor-four-steps&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四实战演练一段六味俱全的代码&quot;&gt;四、实战演练：一段”六味俱全”的代码&lt;/h2&gt;

&lt;p&gt;假设你手上有段处理订单的代码（&lt;strong&gt;语言不重要&lt;/strong&gt;）：两百行函数叫 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handle&lt;/code&gt;，普通用户折扣写死 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.95&lt;/code&gt;、会员 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.85&lt;/code&gt;，if 套 if 套 if 判断四层库存和地区，三段几乎一样的”算运费”只是数字不同，最后又发短信又写日志。&lt;strong&gt;六味占全了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一轮，你说：&lt;/strong&gt;“只诊断，不要给代码。按六味列出问题并排序。” AI 会给体检报告：杂（严重）、魔（严重，0.95/0.85/3/7 含义不明）、重（中等）、名（中等）、套（中等）、长（中等）。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二轮，你只说一句：&lt;/strong&gt;“先只改【魔】这一项，把四个数字提成有名字的常量，其他一律不动，给完整文件。” 改完跑快照表，四组一致 → 通过。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第三轮：&lt;/strong&gt;“再只改【名】……” &lt;strong&gt;这个节奏才对。&lt;/strong&gt; 看着慢，但每一步都安全、随时能停。而”一次全改”看着快，一出事你要花三倍时间找哪儿坏的。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五四个必须知道的坑&quot;&gt;五、四个必须知道的坑&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;坑一：让 AI “顺便优化一下”。&lt;/strong&gt; 最危险的六个字。你说重构它只改结构；加一句”顺便优化”，它可能改了业务逻辑。&lt;strong&gt;重构时明确禁止 AI 改变任何功能，写进提示词。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;坑二：只给片段。&lt;/strong&gt; 你只贴那个 200 行函数，没贴调用它的地方。AI 把函数名从 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;handle&lt;/code&gt; 改成 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;processOrder&lt;/code&gt;——&lt;strong&gt;所有调用处全报错&lt;/strong&gt;，因为它不知道谁在调。→ &lt;strong&gt;改函数名前，先问”这函数在哪被调用”，或自己全局搜一下。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;坑三：接受”看起来更简洁”的改动。&lt;/strong&gt; AI 特喜欢把五行压成一行，看着酷但&lt;strong&gt;读起来更费劲&lt;/strong&gt;。&lt;strong&gt;重构目标是”更好懂”不是”更短”&lt;/strong&gt;，改完你自己读着更吃力，就是失败。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;坑四：没有快照表就开始改。&lt;/strong&gt; 头号死因，再强调一次：&lt;strong&gt;没有验收标准的重构，不叫重构，叫赌博。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-04-ai-77-refactor-pitfalls.png&quot; alt=&quot;refactor-pitfalls&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六什么时候不该重构&quot;&gt;六、什么时候不该重构&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;三种情况别碰：&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;马上要上线&lt;/strong&gt;——上线前一天动结构等于找刺激；&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;半年内不会再碰&lt;/strong&gt;——重构是投资，要看回报；&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;完全看不懂在干嘛&lt;/strong&gt;——先回第 69、74 篇让 AI 讲清楚，看不懂就改，坏了自己都不知坏哪。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;三种情况值得改：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;你&lt;strong&gt;每周都要打开&lt;/strong&gt;这个文件&lt;/li&gt;
  &lt;li&gt;你&lt;strong&gt;准备在这加新功能&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;最近&lt;strong&gt;连着出过两次 Bug&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;重构最佳时机，是”你正要在这儿加东西”的前一刻——先扫地，再搬家具。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;提示词模板盒子&quot;&gt;提示词模板盒子&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;模板一：代码体检（第一轮必用，只诊断不给码）&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;你是一位注重可维护性的资深工程师。

下面是我项目里的一段代码，我想改善它的可读性。

【本轮要求 · 重要】
1. 只做诊断，不要给我任何修改后的代码
2. 按以下六类&quot;坏味道&quot;对号入座：
   - 长：函数过长   - 重：重复代码   - 名：命名不清
   - 套：嵌套过深   - 魔：魔法数字   - 杂：单个函数职责过多
3. 按【严重程度】排序，每条注明：位置（第几行）| 具体问题 | 为什么是问题 | 预估改动风险（低/中/高）
4. 最后单独告诉我：你建议我第一个改哪一项，为什么

【代码】
（在此粘贴完整文件，不要只贴片段）
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;模板二：单点重构（一次只改一味）&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;接着上面的诊断。

【本轮只做一件事】
只修改【____】这一项问题，其他任何地方一律不动。

【铁律】
1. 严禁改变任何功能行为——输入什么，输出必须和原来完全一致
2. 严禁删除任何看起来&quot;没用&quot;的判断或分支（那可能是特殊业务处理）
3. 严禁&quot;顺便优化&quot;任何其他内容
4. 目标是更好懂，不是更短。不要为简洁牺牲可读性

【交付要求】
1. 给我完整文件，不要片段
2. 末尾用表格列出：改了哪几行 | 改成什么 | 为什么
3. 如果改动可能影响文件之外（如函数改名影响调用方），请明确警告我检查哪些位置
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;模板三：基线与验收（动手前建快照 + 改完对比）&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;下面这段代码，我准备重构它。

【第一部分 · 动手前：建立行为基线】
1. 列出所有输入参数及取值范围
2. 帮我设计 5 组测试用例，必须包含：2 组正常、2 组边界/异常（空值、0、超大值）、1 组最容易忽略的特殊分支
3. 每组写清：输入 | 预期输出
4. 指出有没有&quot;看起来没用、但可能是特殊业务处理&quot;的分支，单独标出提醒我别删

【第二部分 · 改完后：行为对比检查】
这是重构前的【A】和重构后的【B】。
1. 逐项确认 B 相对 A 有无任何功能行为变化
2. 特别检查：A 里哪个判断分支/异常处理/边界，在 B 里被弱化或删掉了
3. 有没有变量/函数被改名？有则列出提醒我检查调用方
4. 一句话结论：这是&quot;安全重构&quot;，还是实际已变成&quot;重写&quot;

【A - 重构前】
（粘贴）
【B - 重构后】
（粘贴）
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;下篇预告&quot;&gt;下篇预告&lt;/h2&gt;

&lt;p&gt;这一篇我们只做了一件事：&lt;strong&gt;让代码变好读，一个字功能都没改。&lt;/strong&gt; 可现实里代码不光要好读，还得跑得快——而这俩常打架。下一篇《第 78 篇：用 AI 做代码优化》讲”优化三问”与”提速四招”。下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">代码能跑，但一个月后你自己都看不懂。</summary></entry><entry><title type="html">第76篇：调试类小结——把排错思路彻底沉淀下来</title><link href="http://0.0.0.0/2026/10/03/ai-76-debug-summary/" rel="alternate" type="text/html" title="第76篇：调试类小结——把排错思路彻底沉淀下来" /><published>2026-10-03T10:00:00+08:00</published><updated>2026-10-03T10:00:00+08:00</updated><id>http://0.0.0.0/2026/10/03/ai-76-debug-summary</id><content type="html" xml:base="http://0.0.0.0/2026/10/03/ai-76-debug-summary/">&lt;blockquote&gt;
  &lt;p&gt;招式学了七篇，现在把它们收成一套。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;从第 69 篇到第 75 篇，我们一路走过来：读不懂代码怎么办、框架原理怎么问、报错怎么贴、没报错怎么查、慢在哪怎么找、老项目怎么接、真实 Bug 怎么走完全程。&lt;/p&gt;

&lt;p&gt;七篇，七套打法。&lt;/p&gt;

&lt;p&gt;但如果你现在遇到一个新问题，脑子里第一反应还是&lt;strong&gt;“我该用哪一招？”&lt;/strong&gt;——那说明这些招式还是散的。&lt;/p&gt;

&lt;p&gt;这一篇的任务就是把它们&lt;strong&gt;收成一套&lt;/strong&gt;，交给你三样东西：&lt;strong&gt;一张决策树、一套母版、一份误区清单&lt;/strong&gt;。看完这篇，”代码理解与调试”这个小节就结课了。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一先把七篇摆在一张地图上&quot;&gt;一、先把七篇摆在一张地图上&lt;/h2&gt;

&lt;p&gt;很多人学完一堆技巧记不住，是因为&lt;strong&gt;脑子里没有位置感&lt;/strong&gt;。先看这张地图——七篇其实只解决三类问题：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一类：我看不懂（理解型）&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;篇目&lt;/th&gt;
      &lt;th&gt;解决什么&lt;/th&gt;
      &lt;th&gt;核心打法&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;69&lt;/td&gt;
      &lt;td&gt;一段代码读不懂&lt;/td&gt;
      &lt;td&gt;让 AI &lt;strong&gt;逐行翻译成中文&lt;/strong&gt;，先问干什么再问怎么做&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;70&lt;/td&gt;
      &lt;td&gt;用了库但不懂原理&lt;/td&gt;
      &lt;td&gt;让 AI 用&lt;strong&gt;生活类比&lt;/strong&gt;讲清楚，再问”什么时候会坑我”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;74&lt;/td&gt;
      &lt;td&gt;接手祖传老项目&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;剥洋葱五层&lt;/strong&gt;：入口→地图→主线→数据→细节&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;第二类：它不对劲（故障型）&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;篇目&lt;/th&gt;
      &lt;th&gt;解决什么&lt;/th&gt;
      &lt;th&gt;核心打法&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;71&lt;/td&gt;
      &lt;td&gt;有红字报错&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;报错贴原文&lt;/strong&gt;，一个字都不转述&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;72&lt;/td&gt;
      &lt;td&gt;没报错但结果不对&lt;/td&gt;
      &lt;td&gt;说清&lt;strong&gt;“期望什么 / 实际什么”&lt;/strong&gt;，让 AI 逆推&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;75&lt;/td&gt;
      &lt;td&gt;完整一次实战&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;排错八步&lt;/strong&gt;：现界差证，设修归盘&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;第三类：它太慢（性能型）&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;篇目&lt;/th&gt;
      &lt;th&gt;解决什么&lt;/th&gt;
      &lt;th&gt;核心打法&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;73&lt;/td&gt;
      &lt;td&gt;卡、慢、转圈&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;先测量再优化&lt;/strong&gt;，性能四件套：作量时标&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;理解型问”这是什么”，故障型问”哪里错了”，性能型问”慢在哪里”。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;三类问题，三种提问方式。选错类型，怎么问都问不出结果。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-03-ai-76-seven-articles-map.png&quot; alt=&quot;seven-articles-map&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二排错总决策树遇到问题先问自己三句话&quot;&gt;二、排错总决策树：遇到问题先问自己三句话&lt;/h2&gt;

&lt;p&gt;遇到问题别急着打字，&lt;strong&gt;先花十秒问自己三句话&lt;/strong&gt;，你就知道该走哪条路。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一句：屏幕上有没有红字 / 报错？&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;有&lt;/strong&gt; → 走【报错线】：完整复制报错原文 + 完整代码文件，直接问 AI。&lt;strong&gt;这是最省事的一条路&lt;/strong&gt;，报错本身就是最强线索。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;没有&lt;/strong&gt; → 进入第二句。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;第二句：是”结果不对”，还是”能用但很慢”？&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;结果不对&lt;/strong&gt;（数据没保存、数字不对、点了没反应）→ 走【逻辑线】：说清&lt;strong&gt;“我期望什么、实际得到什么、用的什么输入”&lt;/strong&gt;，让 AI 逆推。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;能用但很慢&lt;/strong&gt; → 走【性能线】：&lt;strong&gt;先测量，找出最慢的那一段&lt;/strong&gt;再优化。&lt;strong&gt;没测量就优化 = 瞎猜。&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;第三句（前两句都不适用时）：我是不是压根没看懂这段代码？&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;是&lt;/strong&gt; → 走【理解线】：先让 AI 逐行讲清楚，&lt;strong&gt;看懂了再谈修&lt;/strong&gt;。&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;再补一句判断偶发问题的：&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;如果问题”有时有、有时没有”&lt;/strong&gt; → 不管属于哪条线，&lt;strong&gt;先做差异法&lt;/strong&gt;：找一个必成功的例子和一个必失败的例子，逐字段对比，&lt;strong&gt;先把那个条件变量抓出来。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-03-ai-76-debug-decision-tree.png&quot; alt=&quot;debug-decision-tree&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三万能排错提示词母版五件套&quot;&gt;三、万能排错提示词母版：五件套&lt;/h2&gt;

&lt;p&gt;前面七篇给了几十个提示词模板，其实&lt;strong&gt;它们全都长一个样&lt;/strong&gt;。骨架就五段，我叫它&lt;strong&gt;排错五件套&lt;/strong&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;象 · 证 · 境 · 试 · 要&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;段&lt;/th&gt;
      &lt;th&gt;全称&lt;/th&gt;
      &lt;th&gt;写什么&lt;/th&gt;
      &lt;th&gt;常见错误&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;象&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;现象&lt;/td&gt;
      &lt;td&gt;期望什么 / 实际什么&lt;/td&gt;
      &lt;td&gt;只说”报错了”“不好使”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;证&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;证据&lt;/td&gt;
      &lt;td&gt;报错原文、日志、代码&lt;strong&gt;完整文件&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;转述、截断、只贴片段&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;境&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;环境&lt;/td&gt;
      &lt;td&gt;什么系统、什么工具、什么条件下必现&lt;/td&gt;
      &lt;td&gt;完全不提&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;试&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;试过&lt;/td&gt;
      &lt;td&gt;我已经排除了什么&lt;/td&gt;
      &lt;td&gt;让 AI 重复走你走过的死路&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;要&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;要什么&lt;/td&gt;
      &lt;td&gt;要解释？要清单？要改好的代码？&lt;/td&gt;
      &lt;td&gt;不说，然后嫌它答非所问&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;把这个骨架背下来，你就不需要背模板了。&lt;/strong&gt; 完整母版见文末模板盒子。&lt;/p&gt;

&lt;p&gt;同样一个问题：只说”报错了，帮我看看” → AI 给你一段通用建议，八成不对症；五件套齐全 → AI 基本一次命中。&lt;strong&gt;你多花两分钟组织信息，能省下两小时来回试错。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四新手八大误区踩一个白干半天&quot;&gt;四、新手八大误区（踩一个白干半天）&lt;/h2&gt;

&lt;p&gt;这七篇里反复强调的坑，集中列在这儿：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;误区一：不复现就开始改。&lt;/strong&gt; 听用户说两句就动手，改了半天发现人家根本没点提交按钮。→ &lt;strong&gt;自己亲眼看到 Bug 发生，才算立案。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;误区二：转述报错。&lt;/strong&gt; “它说什么找不到之类的。” → &lt;strong&gt;报错原文每个字符都是线索，全选、复制、原样贴。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;误区三：只贴片段。&lt;/strong&gt; 贴出错那三行，AI 看不到上下文只能猜。→ &lt;strong&gt;贴完整文件。多贴几十行不花钱，猜错一次浪费半小时。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;误区四：一次问五个问题。&lt;/strong&gt; “顺便优化下性能，再美化界面。” → &lt;strong&gt;AI 会给你大杂烩，还可能顺手改坏好的地方。一次一个问题。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;误区五：让 AI 直接给代码，跳过解释。&lt;/strong&gt; 它给了你贴上去好了，但不知道为什么好，下次还犯。→ &lt;strong&gt;先要解释，再要代码。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;误区六：AI 说什么信什么。&lt;/strong&gt; 它会非常自信地编造不存在的函数名、配置项。→ &lt;strong&gt;它说的是假设不是结论，每一条都要验证。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;误区七：改完只测那一个场景。&lt;/strong&gt; 修好失败那条就上线，结果把原来好的搞坏。→ &lt;strong&gt;三条必测：原来坏的、原来好的、极端的。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;误区八：修完就完，不复盘。&lt;/strong&gt; → &lt;strong&gt;多问一句”同类问题项目里还有几个”，往往一次扫掉三五个雷。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-03-ai-76-eight-mistakes.png&quot; alt=&quot;eight-mistakes&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五关于-ai-排错三条底线必须记住&quot;&gt;五、关于 AI 排错，三条底线必须记住&lt;/h2&gt;

&lt;p&gt;这三条比任何技巧都重要。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一条：AI 只知道你给它的那一屏。&lt;/strong&gt; 它看不到你没贴的文件、数据库里的真实数据、服务器上的配置、你昨天改了什么。&lt;strong&gt;所以它答得不对，很多时候不是它笨，是你给的信息不够。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二条：AI 不会说”我不知道”。&lt;/strong&gt; 你问它不确定的问题，它大概率编一个听起来很合理的答案——语气笃定、格式工整、就是不对。→ &lt;strong&gt;凡是它说的”因为 XX 导致 YY”，你都要能自己验证一遍。验不了的，别信。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第三条：最终按下确认键的人是你。&lt;/strong&gt; AI 可以给方案，但&lt;strong&gt;它不承担后果&lt;/strong&gt;。数据删了是你删的，线上崩了是你的锅。所以规矩要成肌肉记忆：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;改动前先备份&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;删改数据前，先只查不改试一遍&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;一次只改一处，改完立刻验证&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六一张随身自查表&quot;&gt;六、一张随身自查表&lt;/h2&gt;

&lt;p&gt;把这张表存手机里，遇到问题照着走：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;□ 我亲眼看到问题发生了吗？（没有 → 先复现）
□ 我能找到&quot;必失败&quot;和&quot;必成功&quot;两个例子吗？（偶发问题必做）
□ 这属于哪一类：看不懂 / 不对劲 / 太慢？
□ 数据断在哪一段：浏览器 / 网络 / 后端 / 数据库？
□ 我贴的是报错原文，还是我的转述？
□ 我贴的是完整文件，还是片段？
□ 我说清楚&quot;期望什么、实际什么&quot;了吗？
□ 我告诉 AI 我已经试过什么了吗？
□ 我要的是解释，还是代码？我说清楚了吗？
□ AI 给的原因，我验证过了吗？
□ 改动前我备份了吗？
□ 改完我测了三条吗（原来坏的 / 原来好的 / 极端的）？
□ 我问过&quot;同类问题还有几个&quot;吗？
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;十三个框全打勾，你就不是新手了。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;七这个小节最后想说的&quot;&gt;七、这个小节最后想说的&lt;/h2&gt;

&lt;p&gt;很多人以为，会用 AI 写代码是本事。其实&lt;strong&gt;真正的分水岭是——生成出来的东西不对劲时，你能不能救回来。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这七篇讲的所有东西，本质上只有一件事：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;AI 是一个知识极其渊博、但眼睛看不见的顾问。它的能力上限，取决于你描述现场的能力。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;而”准确描述一个问题”，恰恰不需要任何代码基础。&lt;/strong&gt; 一个完全不懂编程的人，认真练这七篇的方法，排错能力可以超过很多写了三年代码但从不整理思路的人。&lt;/p&gt;

&lt;p&gt;工具是新的，方法是老的：&lt;strong&gt;看清现场、缩小范围、逐个验证、留下记录。&lt;/strong&gt; 祝你以后每个 Bug 都死得明明白白。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;-提示词模板盒子&quot;&gt;📦 提示词模板盒子&lt;/h2&gt;

&lt;h3 id=&quot;模板一万能排错五件套象证境试要&quot;&gt;模板一：万能排错五件套（象证境试要）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我遇到一个问题，需要你帮我定位。

【现象】
我期望：[正确应该是什么样]
实际发生：[实际是什么样]
偶发情况：[什么条件下必现，什么条件下正常]

【证据】
报错/日志原文（完整粘贴，未做任何修改）：
[粘贴，前后各多贴几行]

相关代码（完整文件，不是片段）：
[粘贴]

【环境】
系统：[Windows / Mac]
工具：[你用的 AI 工具]
触发条件/数据规模：[比如：数据超过 200 条时必现]

【我已经试过】
1. [试过什么，结果如何]
2. [排除了什么可能]

【我要什么】
1. 用大白话解释这是什么问题
2. 按可能性排序，列出 3 个最可能的原因
3. 每个原因告诉我怎么快速验证
4. 先解释和列清单，暂时不要给我改好的代码

我是新手，不熟悉专业术语，请一步步说清楚。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板二分流器不知道怎么问的时候先问这个&quot;&gt;模板二：分流器（不知道怎么问的时候先问这个）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我遇到一个问题，但我不确定该从哪查起。

【我看到的现象】
[尽可能具体地描述，包括你点了什么、看到什么]

请你先不要给我解决方案，先帮我判断：
1. 这属于哪一类问题：代码理解 / 功能出错 / 性能太慢 / 环境配置
2. 我接下来应该收集哪些信息给你？请列一份&quot;取证清单&quot;，
   每一条写清楚我具体该点哪里、看什么
3. 这些信息里，哪一条最关键，我先弄哪个

我完全是新手，请把操作步骤写细一点。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板三校验与收尾验真伪--安全护栏--复盘&quot;&gt;模板三：校验与收尾（验真伪 + 安全护栏 + 复盘）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;【A. 结论校验——怀疑 AI 在编时用】
你刚才说问题的原因是：[复述它的结论]。在我照做之前，请自己复核：
1. 这个结论依据的是我提供的哪几行内容？请指出来
2. 如果我提供的信息不足以支撑这个结论，请直接说&quot;信息不够&quot;
3. 你提到的函数/配置/参数，是否确实存在于我贴的代码里？逐个核对，不存在的请明确指出
4. 除了这个原因，还有没有别的可能被你忽略

【B. 安全护栏——让 AI 改动前必加的一段】
在你给出任何修改之前，请遵守：
1. 只改我指定的地方，其他一律不动，不要顺手优化、不要改格式
2. 输出完整文件，不要给片段
3. 单独列出：改了哪几行、每行改了什么、为什么
4. 如果改动可能影响其他功能，必须提前警告我
5. 涉及删除数据的操作，先给我一条&quot;只查不改&quot;的版本让我试跑

【C. 复盘器——修完必问的一句】
我刚修好一个问题，本质是：[一句话概括类型]。
请帮我扫一遍项目里其他相关文件：
1. 还有哪些地方存在同样或变种的问题？逐个指出位置
2. 按危险程度排序
3. 给我一条简单的自查规则，以后怎么避免这类问题
先列清单，不要改代码。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;-速查卡调试全套口诀&quot;&gt;🔖 速查卡：调试全套口诀&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;【分类】三类问题
  看不懂 → 问&quot;这是什么&quot;
  不对劲 → 问&quot;哪里错了&quot;
  太慢了 → 问&quot;慢在哪里&quot;

【提问】五件套：象 证 境 试 要
  象 = 期望什么 / 实际什么
  证 = 报错原文 + 完整文件
  境 = 系统 / 工具 / 触发条件
  试 = 我已经排除了什么
  要 = 要解释还是要代码

【流程】八步：现界差证，设修归盘
  复现 → 划界 → 差异 → 取证 → 假设 → 修复 → 回归 → 复盘

【底线】三条
  1. AI 只知道你给它的那一屏
  2. AI 不会说&quot;我不知道&quot;，它会编
  3. 按确认键的人是你，改前先备份
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;-下篇预告&quot;&gt;👉 下篇预告&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;第 77 篇：用 AI 重构烂代码——可读性直线上升。&lt;/strong&gt; 调试篇结课，下一篇进入「重构与质量」：代码能跑却一团糟怎么办，&lt;strong&gt;重构不是重写&lt;/strong&gt;，让 AI 安全重构的三步法。下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">招式学了七篇，现在把它们收成一套。</summary></entry><entry><title type="html">第75篇：调试实战——一个真实 Bug 的全流程还原</title><link href="http://0.0.0.0/2026/10/02/ai-75-debug-case/" rel="alternate" type="text/html" title="第75篇：调试实战——一个真实 Bug 的全流程还原" /><published>2026-10-02T10:00:00+08:00</published><updated>2026-10-02T10:00:00+08:00</updated><id>http://0.0.0.0/2026/10/02/ai-75-debug-case</id><content type="html" xml:base="http://0.0.0.0/2026/10/02/ai-75-debug-case/">&lt;blockquote&gt;
  &lt;p&gt;报名表单显示”提交成功”，后台却只收到一半人。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;前面四篇，我们把排错的各个招式拆开讲了：贴报错、找逻辑错、查性能、读老代码。这一篇不教新招式，而是&lt;strong&gt;从头到尾还原一个真实的 Bug&lt;/strong&gt;——让你看清楚一个问题从”完全懵”到”彻底解决”，中间到底发生了什么。&lt;/p&gt;

&lt;p&gt;因为很多人的问题不是不会某一招，而是——&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;手上有一堆锤子，但不知道先抡哪个。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;咱们开始。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一事故现场&quot;&gt;一、事故现场&lt;/h2&gt;

&lt;p&gt;背景：你用 AI 工具做了一个小站，功能很简单——&lt;strong&gt;一个活动报名表单&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;用户填四个框：姓名、手机号、公司、备注。点提交，页面弹出”报名成功”，后台管理页能看到报名名单。上线三天一切正常，&lt;strong&gt;第四天&lt;/strong&gt;活动负责人找过来，脸不太好看：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“有人跟我说他报名了，可名单里没有他。你查一下。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;你打开后台名单，数了数：&lt;strong&gt;87 条&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;活动群里的人数：&lt;strong&gt;112 人&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;你心里咯噔一下。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这就是最难受的一类 Bug：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;页面&lt;strong&gt;没有报错&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;用户&lt;strong&gt;看到的是成功&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;数据&lt;strong&gt;确实丢了&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;而且&lt;strong&gt;不是全丢，是丢了一部分&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;新手这时候最常见的反应是两种，&lt;strong&gt;两种都是错的&lt;/strong&gt;：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;“是不是服务器不稳定？”&lt;/strong&gt; —— 把锅甩给玄学，然后什么都不做。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;直接打开代码，从提交那一段开始一行行看。&lt;/strong&gt; —— 大海捞针，看两小时也看不出来。&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-02-ai-75-accident-site.png&quot; alt=&quot;accident-site&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二第一步复现把听说变成我看到了&quot;&gt;二、第一步：复现——把”听说”变成”我看到了”&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;排错的第一步永远不是改代码，而是：你自己让 Bug 再发生一次。&lt;/strong&gt; 为什么？因为你亲眼看到之前，手上的信息全是二手的：用户说”我提交了”可能没点按钮，说”显示成功”可能记错了，你以为丢的 25 条也可能有人压根没报名。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;没复现之前，你连”有没有 Bug”都不确定，改什么？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;复现要抓三个要素：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;要素&lt;/th&gt;
      &lt;th&gt;你要问清楚的&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;谁&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;什么设备、什么浏览器、什么账号&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;做了什么&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;具体点了什么，填了什么&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;看到了什么&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;屏幕上原话是什么，最好要截图&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;于是你去群里问了一句：”哪几位报名后没在名单里的，麻烦举个手，告诉我你填的内容。”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;三个人回复了。你拿到三份填写内容。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;你自己照着填了一遍第一个人的内容——&lt;strong&gt;提交成功，名单里出现了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;咦？没复现出来。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这时候千万别放弃。&lt;/strong&gt; 换第二个人的内容，再填一遍——&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;页面显示”报名成功”，名单里没有。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;复现了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这一刻你赢了一半——手里有了两个宝贝：&lt;strong&gt;一个必然失败的例子&lt;/strong&gt;、&lt;strong&gt;一个必然成功的例子&lt;/strong&gt;。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三第二步差异法偶发不是玄学&quot;&gt;三、第二步：差异法——偶发不是玄学&lt;/h2&gt;

&lt;p&gt;只有一部分人丢单，说明&lt;strong&gt;不是所有情况都出问题&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;那必然存在一个&lt;strong&gt;条件变量&lt;/strong&gt;：满足它就挂，不满足就好。&lt;/p&gt;

&lt;p&gt;找它的方法叫&lt;strong&gt;差异法&lt;/strong&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;把”成功的那次”和”失败的那次”摆在一起，一栏一栏比，看差在哪。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;你把两份填写内容并排贴出来：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;字段&lt;/th&gt;
      &lt;th&gt;成功的那个&lt;/th&gt;
      &lt;th&gt;失败的那个&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;姓名&lt;/td&gt;
      &lt;td&gt;张伟&lt;/td&gt;
      &lt;td&gt;李娜&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;手机号&lt;/td&gt;
      &lt;td&gt;138xxxx&lt;/td&gt;
      &lt;td&gt;139xxxx&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;公司&lt;/td&gt;
      &lt;td&gt;甲科技&lt;/td&gt;
      &lt;td&gt;乙传媒&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;备注&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;无&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;一大段话，写了他为什么想参加，200 多字&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;看到没有——备注字段的长度差了几十倍，这就是最可疑的条件变量。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;把这份对比丢给 AI，它能帮范围收得更窄。&lt;strong&gt;注意：别问”为什么丢数据”，要问”这两组差异可能触发什么问题”。&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我的表单有偶发丢数据的问题。同样的代码，有的提交成功并入库，有的
显示成功但库里没有。

我找到了一组对照：
【成功的一次】姓名：张伟 / 手机：138xxxxxxxx / 公司：甲科技 / 备注：（空）
【失败的一次】姓名：李娜 / 手机：139xxxxxxxx / 公司：乙传媒 / 备注：（约240字的中文长文本）

请你：
1. 指出这两组数据最值得怀疑的差异点（按可疑程度排序）
2. 针对最可疑的那一点，列出 3~5 个可能的技术原因
3. 每个原因给我一个&quot;我怎么快速验证它是不是真凶&quot;的动作
4. 先不要改代码

我是新手，请用大白话解释。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;AI 给了你一串可能：字段长度限制、编码问题、数据库字段类型太短、校验规则拦截、请求体大小限制……&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;注意：这些都还只是猜测。下一步是验证，不是相信。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-02-ai-75-diff-method.png&quot; alt=&quot;diff-method&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四第三步划界判断到底在哪一段断的&quot;&gt;四、第三步：划界——判断到底在哪一段断的&lt;/h2&gt;

&lt;p&gt;一个表单提交，数据要走&lt;strong&gt;四段路&lt;/strong&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;浏览器 → 网络请求 → 后端处理 → 数据库写入&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;你现在的任务不是找出哪行代码错了，而是先确定：数据是在哪一段路上掉的。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这一步叫&lt;strong&gt;四段划界法&lt;/strong&gt;，做法很朴素——&lt;strong&gt;每一段路口都装个”摄像头”&lt;/strong&gt;：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第 1 段：浏览器有没有把数据组装对？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;按 &lt;strong&gt;F12&lt;/strong&gt; 打开开发者工具（Windows 按 F12，Mac 按 Command+Option+I），切到 &lt;strong&gt;Network（网络）&lt;/strong&gt; 标签，然后提交那份会失败的内容。&lt;/p&gt;

&lt;p&gt;你会看到列表里多出一条请求。点进去看 &lt;strong&gt;Payload / 请求负载&lt;/strong&gt;，那里显示的就是浏览器&lt;strong&gt;实际发出去&lt;/strong&gt;的内容。&lt;/p&gt;

&lt;p&gt;结果：&lt;strong&gt;四个字段都在，备注那 240 字也完整。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;第 1 段没问题，排除前端组装。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第 2 段：请求有没有到后端？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;同一个面板里看这条请求的 &lt;strong&gt;Status（状态码）&lt;/strong&gt;：&lt;/p&gt;

&lt;p&gt;显示 &lt;strong&gt;200&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;通了，第 2 段没问题。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第 3 段：后端处理有没有出错？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这一段看不见，需要&lt;strong&gt;日志&lt;/strong&gt;。翻到刚才那个时间点的后端输出——&lt;strong&gt;居然有一行红字&lt;/strong&gt;，服务没挂还在跑。&lt;/p&gt;

&lt;p&gt;→ &lt;strong&gt;抓到了。问题在第 3 段。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第 4 段：数据库&lt;/strong&gt;——不用查了，第 3 段就断了，压根没走到第 4 段。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这一步的价值：范围缩小了 90%。&lt;/strong&gt; 你原本要在几百行代码里找，现在锁定在”后端保存那一小段”里找。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-02-ai-75-four-segments.png&quot; alt=&quot;four-segments&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五第四步取证把真凭实据交给-ai&quot;&gt;五、第四步：取证——把真凭实据交给 AI&lt;/h2&gt;

&lt;p&gt;现在你有日志了。&lt;strong&gt;这时候才轮到把东西贴给 AI。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;记住前面第 71 篇讲过的铁律：&lt;strong&gt;报错贴原文，一个字都别转述。&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我的表单提交接口出现问题：接口返回 200 和&quot;成功&quot;，但数据没有写进
数据库。后端日志里有一段异常，但服务没有崩溃。

【后端日志原文】
[把那一段红字完整粘贴，包含前后各几行]

【接口对应的完整代码文件】
[粘贴整个文件，不要只贴片段]

【触发条件】
备注字段填约 240 字时必现；备注为空时正常。

请你回答：
1. 这段日志说的是什么问题（用大白话）
2. 为什么出了异常，接口还会返回成功给前端
3. 定位到具体是哪一行引发的
4. 先解释，暂时不要给我改好的代码

我是新手，请一步步说清楚。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;AI 的回答让你恍然大悟，真相有两层：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一层：为什么数据会丢？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;保存前有一段校验：&lt;strong&gt;备注不能超过 200 字&lt;/strong&gt;，超了就抛异常——李娜写了 240 字，被拦下。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二层（更关键）：为什么页面还显示成功？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;代码里有一段”&lt;strong&gt;捕获异常但什么也不做&lt;/strong&gt;“的写法——出错了，它把错误吞掉，然后&lt;strong&gt;继续往下走&lt;/strong&gt;，最后照常返回了”成功”。&lt;/p&gt;

&lt;p&gt;用大白话说就是：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;快递员把包裹弄丢了，但还是给你发了”已签收”的短信。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这就是&lt;strong&gt;假成功&lt;/strong&gt;——&lt;strong&gt;页面上的”成功”，只代表”程序跑完了”，不代表”事情办成了”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-02-ai-75-fake-success.png&quot; alt=&quot;fake-success&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六第五步修只改一处别顺手重写&quot;&gt;六、第五步：修——只改一处，别顺手重写&lt;/h2&gt;

&lt;p&gt;到这一步，很多人会犯一个错：让 AI “帮我把这个文件优化一下”。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;千万别。&lt;/strong&gt; 你现在只搞明白了一个问题，一次只解决一个。&lt;/p&gt;

&lt;p&gt;而且这次的修法要&lt;strong&gt;分两层&lt;/strong&gt;，因为&lt;strong&gt;真凶其实有两个&lt;/strong&gt;：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;表面凶手&lt;/strong&gt;：备注超 200 字被拦&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;幕后黑手&lt;/strong&gt;：异常被吞掉，导致失败伪装成成功&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;只修表面凶手（把 200 放宽到 1000）是治标&lt;/strong&gt;——下次换个别的原因失败，你照样收到”成功”、照样丢单。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;两个都要修：&lt;/strong&gt;&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;现在我明白问题了，请帮我修，但请严格遵守：

1. 只修下面这两处，其他代码一律不要动，不要顺手优化、不要改格式
   （a）备注字段的长度上限，从 200 放宽到 1000
   （b）不要再静默吞掉异常：出错时必须记录日志，并且给前端返回失败，
       不能再返回成功

2. 返回给前端的失败提示要写给普通用户看，比如&quot;备注最多 1000 字&quot;，
   不要把技术错误原文丢给用户

3. 输出改动后的完整文件，不要给片段

4. 在文件外面单独告诉我：你一共改了哪几行、每行改了什么、
   为什么这么改

我是新手，请顺便说明我改完之后应该怎么验证。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;这段提示词里有四个”新手保命条款”：&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;只改这两处，其他别动&lt;/strong&gt; —— 防止 AI 顺手重写导致新 Bug&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;输出完整文件&lt;/strong&gt; —— 防止你不知道片段该贴在哪&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;列出改了哪几行&lt;/strong&gt; —— 让你看得懂它动了什么&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;告诉我怎么验证&lt;/strong&gt; —— 修完不是终点&lt;/li&gt;
&lt;/ul&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;七第六步回归验证三条必测&quot;&gt;七、第六步：回归验证——三条必测&lt;/h2&gt;

&lt;p&gt;改完立刻测，而且&lt;strong&gt;必须测三条，一条都不能少&lt;/strong&gt;：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;测什么&lt;/th&gt;
      &lt;th&gt;期望结果&lt;/th&gt;
      &lt;th&gt;为什么必测&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;原来失败的那条&lt;/strong&gt;（240 字备注）&lt;/td&gt;
      &lt;td&gt;提交成功，&lt;strong&gt;名单里能查到&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;证明问题真的修好了&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;原来成功的那条&lt;/strong&gt;（备注为空）&lt;/td&gt;
      &lt;td&gt;依然成功&lt;/td&gt;
      &lt;td&gt;证明&lt;strong&gt;没有修坏别的&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;一条极端的&lt;/strong&gt;（备注 1200 字）&lt;/td&gt;
      &lt;td&gt;提交&lt;strong&gt;失败&lt;/strong&gt;，页面提示”备注最多 1000 字”&lt;/td&gt;
      &lt;td&gt;证明&lt;strong&gt;失败时会明确报错&lt;/strong&gt;，不再假成功&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;第三条最重要。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;因为它验证的不是这一个 Bug，而是”以后再出问题，你能不能第一时间发现”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;三条全过，才算修完。&lt;/p&gt;

&lt;p&gt;然后你回群里补一句：”报过名但不在名单里的朋友，麻烦重新提交一次。”&lt;/p&gt;

&lt;p&gt;——&lt;strong&gt;87 条变成了 110 条。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-02-ai-75-regression-three-tests.png&quot; alt=&quot;regression-three-tests&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;八第七步复盘让这次经验值钱&quot;&gt;八、第七步：复盘——让这次经验值钱&lt;/h2&gt;

&lt;p&gt;Bug 修完，还剩最后一件事，也是最多人跳过的一件事：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;问一句：同样的坑，项目里还有几个？&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我刚修好一个问题：某处校验失败抛出异常，但异常被静默吞掉，
导致接口仍然返回成功，数据其实没保存。

【项目里其他几个接口的代码】
[粘贴其他接口文件]

请你帮我检查：
1. 还有哪些地方存在&quot;吞掉异常后照常返回成功&quot;的写法？逐个指出行号
2. 还有哪些地方&quot;前端提示成功&quot;和&quot;实际结果&quot;可能不一致？
3. 按危险程度排序，告诉我哪个最该先改
4. 给我一条简单的自查规则，以后写代码时怎么避免这类问题

先列清单，不要改代码。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;AI 一查——&lt;strong&gt;另外两个接口也有同样的写法。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;你顺手把它们也修了。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这就是复盘的价值：修一个 Bug 只值一次，找到这类 Bug 的规律值一辈子。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;九把这次流程压成八个字&quot;&gt;九、把这次流程压成八个字&lt;/h2&gt;

&lt;p&gt;回头看整个过程，其实是固定的八步：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;复现 → 划界 → 差异 → 取证 → 假设 → 修复 → 回归 → 复盘&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;口诀记法：&lt;strong&gt;现界差证，设修归盘。&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;步骤&lt;/th&gt;
      &lt;th&gt;一句话&lt;/th&gt;
      &lt;th&gt;最容易被跳过的&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;复现&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;自己看到才算数&lt;/td&gt;
      &lt;td&gt;⭐ 最常被跳过&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;划界&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;先定位在哪一段断&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;差异&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;成功和失败差在哪&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;取证&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;拿日志，别拿猜想&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;假设&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;让 AI 列清单，你来验&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;修复&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;只改一处，完整文件&lt;/td&gt;
      &lt;td&gt; &lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;回归&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;三条必测&lt;/td&gt;
      &lt;td&gt;⭐ 第二常被跳过&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;复盘&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;同类问题还有几个&lt;/td&gt;
      &lt;td&gt;⭐ 最常被跳过&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;新手和熟手的差距，八成不在第六步”修复”，而在第一步和最后两步。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;十这一篇最该记住的三句话&quot;&gt;十、这一篇最该记住的三句话&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;第一句：没复现之前，你查的是传说，不是 Bug。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二句：先划界，再看代码。范围没缩小之前看代码，等于大海捞针。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第三句：页面上的”成功”，只代表程序跑完了，不代表事情办成了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;最后再补一条心态上的：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug 不丢人，查不出来也不丢人。丢人的是每次都从零开始瞎撞。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;你今天走完这八步，下次再遇到”数据莫名丢了”“偶尔才出错”这类问题，会发现&lt;strong&gt;流程一模一样&lt;/strong&gt;。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;-提示词模板盒子&quot;&gt;📦 提示词模板盒子&lt;/h2&gt;

&lt;h3 id=&quot;模板一对照找条件变量偶发问题必用&quot;&gt;模板一：对照找条件变量（偶发问题必用）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我遇到一个偶发问题：同样的操作，有时候正常，有时候不正常。

【现象】
正常时：[描述]
不正常时：[描述]

【我找到的一组对照】
成功的一次输入：[逐字段列出]
失败的一次输入：[逐字段列出]

请你：
1. 按可疑程度排序，指出这两组数据最值得怀疑的差异点
2. 针对最可疑的那一点，列出 3~5 个可能的技术原因
3. 每个原因给我一个&quot;怎么快速验证它是不是真凶&quot;的动作
4. 先不要改代码

我是新手，请用大白话解释。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板二四段划界判断在哪一段断的&quot;&gt;模板二：四段划界（判断在哪一段断的）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我的功能出问题了：[描述现象]。

我想先确定数据是在哪一段丢的，一共四段：
浏览器 → 网络请求 → 后端处理 → 数据库

请你针对我这个功能，给我一份逐段排查指引：
1. 每一段我具体该看哪里（说清楚点哪个菜单、看哪个字段）
2. 每一段&quot;正常&quot;应该长什么样，&quot;异常&quot;长什么样
3. 按从易到难排序，我先查哪一段最省事

我完全没用过开发者工具，请把点击步骤写细一点。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板三取证提问拿到日志后&quot;&gt;模板三：取证提问（拿到日志后）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我的功能出现问题：[一句话现象]。

【日志/报错原文】
[完整粘贴，前后各多贴几行，不要转述、不要截断]

【相关的完整代码文件】
[粘贴整个文件]

【触发条件】
[什么情况下必现，什么情况下正常]

请你回答：
1. 这段日志说的是什么问题（大白话）
2. 为什么会出现&quot;表面成功、实际失败&quot;（如适用）
3. 定位到具体是哪一行引发的
4. 先解释，暂时不要给我改好的代码

我是新手，请一步步说清楚。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;外科手术式修复&lt;/strong&gt;：让 AI 只改指定几处、输出完整文件、列出改了哪几行；并要求出错时记录日志、向用户返回失败而非静默吞掉（原模板四）。
▸ &lt;strong&gt;回归验证清单&lt;/strong&gt;：改完让 AI 列三类验证——原来失败的、原来正常的、极端的，每条写清操作与期望（原模板五）。
▸ &lt;strong&gt;复盘扫雷&lt;/strong&gt;：修好后让 AI 在其它文件里找同类问题、按危险排序，并给一条自查规则（原模板六）。&lt;/p&gt;

&lt;h2 id=&quot;-速查卡排错八步&quot;&gt;🔖 速查卡：排错八步&lt;/h2&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. 复现 —— 自己看到才算数，拿到&quot;必失败&quot;和&quot;必成功&quot;两个例子
2. 划界 —— 浏览器 / 网络 / 后端 / 数据库，先确定断在哪一段
3. 差异 —— 成功与失败逐字段对比，找出那个条件变量
4. 取证 —— 贴日志原文 + 完整文件，不转述、不截断
5. 假设 —— 让 AI 列可能性清单，你负责逐个验证
6. 修复 —— 只改一处，输出完整文件，要它列出改了哪几行
7. 回归 —— 三条必测：修好的 / 原本好的 / 极端的
8. 复盘 —— 同类问题还有几个，顺手一起扫掉
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;-下篇预告&quot;&gt;👉 下篇预告&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;第 76 篇《调试类小结——把排错思路彻底沉淀下来》。&lt;/strong&gt; 下一篇把 71~75 这五篇收口，交给你三样东西：一张排错总决策树、一套万能排错提示词母版、一份新手八大误区清单。&lt;strong&gt;看完那篇，你手上就有一套完整的”AI 排错工具箱”了。&lt;/strong&gt; 我们下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">报名表单显示”提交成功”，后台却只收到一半人。</summary></entry><entry><title type="html">第74篇：用 AI 理解遗留老代码——接手祖传项目不慌</title><link href="http://0.0.0.0/2026/10/01/ai-74-legacy-code/" rel="alternate" type="text/html" title="第74篇：用 AI 理解遗留老代码——接手祖传项目不慌" /><published>2026-10-01T10:00:00+08:00</published><updated>2026-10-01T10:00:00+08:00</updated><id>http://0.0.0.0/2026/10/01/ai-74-legacy-code</id><content type="html" xml:base="http://0.0.0.0/2026/10/01/ai-74-legacy-code/">&lt;blockquote&gt;
  &lt;p&gt;代码不是你写的，写的人已经离职了。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;前面几篇讲的都是”你自己写的代码”。&lt;/p&gt;

&lt;p&gt;这一篇讲一个更让人头皮发麻的场景：&lt;/p&gt;

&lt;p&gt;老板拍拍你肩膀：”这个项目以后你负责。”&lt;/p&gt;

&lt;p&gt;你打开文件夹，看到：&lt;strong&gt;几十个文件夹，几千行代码，没有文档，注释寥寥无几，最后一次提交是两年前。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;写这段代码的人，已经不在公司了。&lt;/p&gt;

&lt;p&gt;你随手点开一个文件，看了三分钟，脑子里只有三个问题：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;它到底从哪儿开始跑的？&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;这段是干嘛的？&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;我改这一行，会不会炸掉别的地方？&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;这就是俗称的”&lt;strong&gt;祖传代码&lt;/strong&gt;“。&lt;/p&gt;

&lt;p&gt;好消息是：&lt;strong&gt;这恰恰是 AI 最能帮上忙的场景之一。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;坏消息是：&lt;strong&gt;如果你用错方法，AI 会把你带进更深的坑。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这一篇，把接手老项目的完整打法讲清楚。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一先纠正一个致命误区&quot;&gt;一、先纠正一个致命误区&lt;/h2&gt;

&lt;p&gt;新手接手老项目，第一反应通常是：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;从第一个文件开始，一个一个读过去。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;这是最慢、也最容易放弃的方式。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;几千行代码，你按文件顺序读，读到第三个文件就晕了——因为&lt;strong&gt;你不知道这些东西之间是什么关系&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;还有一种更常见的错误：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;把整个项目一股脑丢给 AI，问一句”这项目是干嘛的？”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;AI 会给你一段听起来很专业、但基本没用的概述。&lt;/strong&gt; 而且大部分工具根本装不下你整个项目。&lt;/p&gt;

&lt;p&gt;这里有一条必须刻在脑子里的原则：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;AI 只知道你给它的那一屏。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;它看不到你没贴的文件，看不到数据库里的数据，看不到服务器上的配置。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;你贴什么，它答什么。你贴得没头没尾，它就编得有头有尾。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;所以理解老项目，不是”把活丢给 AI”，而是&lt;strong&gt;你带路，AI 解说&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-01-ai-74-two-reads.png&quot; alt=&quot;two-reads&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二剥洋葱五层法接手老项目的正确顺序&quot;&gt;二、剥洋葱五层法：接手老项目的正确顺序&lt;/h2&gt;

&lt;p&gt;记住这个顺序：&lt;strong&gt;入口 → 地图 → 主线 → 数据 → 细节&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;每一层没搞清楚之前，不要进下一层。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第一层找入口程序从哪儿开始跑&quot;&gt;第一层：找入口——程序从哪儿开始跑&lt;/h3&gt;

&lt;p&gt;这是&lt;strong&gt;唯一正确的起点&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;任何项目都有一个”第一行被执行的代码”。可能叫 main、app、index、server，也可能藏在某个启动脚本里。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;找不到入口，后面全是瞎逛。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;如果你自己找不到，就把&lt;strong&gt;项目根目录的文件列表&lt;/strong&gt;贴给 AI，让它告诉你入口最可能是哪个。&lt;/p&gt;

&lt;p&gt;文件名清单怎么拿？在项目文件夹里截个图、或者把文件名手动列一列都行。&lt;strong&gt;这一步不需要贴任何代码。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第二层画地图项目分成哪几大块&quot;&gt;第二层：画地图——项目分成哪几大块&lt;/h3&gt;

&lt;p&gt;拿到入口后，别急着往下钻。&lt;/p&gt;

&lt;p&gt;先搞清楚&lt;strong&gt;这个项目一共分几大块，每块干什么&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;通常一个项目会有这么几类文件夹，名字千奇百怪，但角色就这几种：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;页面 / 界面&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;业务逻辑&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;数据存取&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;工具函数&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;配置&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;把目录结构贴给 AI，让它帮你给每个文件夹标注”这块大概是干什么的”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这一步的产出，应该是一张你自己能画出来的草图。&lt;strong&gt;画不出来，说明还没懂。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第三层走主线追一个完整功能从头走到尾&quot;&gt;第三层：走主线——追一个完整功能，从头走到尾&lt;/h3&gt;

&lt;p&gt;这是&lt;strong&gt;最关键的一层&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;不要试图理解所有功能。&lt;strong&gt;挑一个最核心的功能，把它从头到尾走一遍。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;比如”用户下单”，从头到尾走一遍是这样的：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;点击”提交订单”按钮&lt;/li&gt;
  &lt;li&gt;请求发到哪（哪个接口）&lt;/li&gt;
  &lt;li&gt;哪个函数接住了这个请求&lt;/li&gt;
  &lt;li&gt;它又调用了谁（下游逻辑）&lt;/li&gt;
  &lt;li&gt;数据最终存到哪（哪张表）&lt;/li&gt;
  &lt;li&gt;给用户返回了什么&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;走通一条主线，你对这个项目的理解就超过 60% 了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;因为其他功能，大概率是&lt;strong&gt;同一套路的复制&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;第四层看数据数据从哪来到哪去&quot;&gt;第四层：看数据——数据从哪来，到哪去&lt;/h3&gt;

&lt;p&gt;老项目最容易搞错的地方，往往不在逻辑，而在数据。&lt;/p&gt;

&lt;p&gt;搞清楚三件事：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;数据存在哪&lt;/strong&gt;（哪几张表 / 哪些文件）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;谁在写&lt;/strong&gt;（哪个功能在往里写）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;谁在读&lt;/strong&gt;（谁在依赖这份数据）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;特别留意那些”被很多地方读、但只有一个地方写”的数据&lt;/strong&gt;——那通常是整个项目的命脉，改它风险最高。&lt;/p&gt;

&lt;h3 id=&quot;第五层抠细节到这一步才开始逐行读&quot;&gt;第五层：抠细节——到这一步才开始逐行读&lt;/h3&gt;

&lt;p&gt;前四层都清楚了，你再回头看具体某个函数的实现，会发现&lt;strong&gt;读起来轻松得多&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;顺序反过来，就是灾难。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-01-ai-74-onion-five-layers.png&quot; alt=&quot;onion-five-layers&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三让-ai-解说的正确姿势三个要求&quot;&gt;三、让 AI 解说的正确姿势：三个要求&lt;/h2&gt;

&lt;p&gt;贴代码给 AI 让它解释，大部分人只会说一句”这段代码是干嘛的？”&lt;/p&gt;

&lt;p&gt;得到的回答通常是&lt;strong&gt;逐行翻译&lt;/strong&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“这一行定义了一个变量，这一行是一个循环，循环里判断了……”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;你自己都能看出来，这不叫理解。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;要让 AI 说人话，加上这三个要求：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;要求一：先说”它在整体里干什么”，再说”它怎么做的”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;先要一句话的职责概括，再要实现细节。&lt;strong&gt;顺序不能反。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;要求二：用大白话打比方，不要用术语堆砌&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;明确告诉它：”假设我完全不懂这个技术栈，请用生活化的比方解释。”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;要求三：主动指出可疑和过时的地方&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;老代码里一定有坑。让 AI 顺便标出：&lt;strong&gt;哪里写法过时、哪里可能有隐患、哪里的命名和实际功能对不上。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;第三点尤其值钱。因为它会引出下面这个话题——&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四老代码四大坑ai-也会被骗&quot;&gt;四、老代码四大坑：AI 也会被骗&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;AI 读老代码时会犯的错，和人一模一样：它相信代码表面的样子。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这四个坑，你得心里有数：&lt;/p&gt;

&lt;h3 id=&quot;坑一名字骗人&quot;&gt;坑一：名字骗人&lt;/h3&gt;

&lt;p&gt;一个函数叫 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;checkUser&lt;/code&gt;，你以为它只是”检查用户”，结果它顺手改了数据库、发了短信、还写了日志。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;老项目里，函数名和实际功能对不上，是常态而不是意外。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;AI 看到这个名字，也会顺着名字理解。&lt;strong&gt;所以永远别只看名字，要看它实际做了什么。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;坑二注释过期&quot;&gt;坑二：注释过期&lt;/h3&gt;

&lt;p&gt;注释写着”此处返回全部订单”，代码早就改成”只返回未支付订单”了。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;注释是两年前的，代码是上个月的。&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;代码不会骗人，注释会。&lt;/strong&gt; 两者冲突时，永远信代码。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;坑三同一段逻辑抄了好几份&quot;&gt;坑三：同一段逻辑抄了好几份&lt;/h3&gt;

&lt;p&gt;老项目里经常有三四个长得几乎一样的函数，只有细微差别。&lt;/p&gt;

&lt;p&gt;你改了其中一个，以为修好了。&lt;strong&gt;结果线上跑的是另一个。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;所以改之前，一定要搜一下：这段逻辑是不是还有别的副本。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;坑四藏起来的调用&quot;&gt;坑四：藏起来的调用&lt;/h3&gt;

&lt;p&gt;最阴险的一类。&lt;/p&gt;

&lt;p&gt;你以为这个函数没人用了，准备删掉。结果它被好几处地方用着：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;一个&lt;strong&gt;定时任务&lt;/strong&gt;在调用它&lt;/li&gt;
  &lt;li&gt;一个&lt;strong&gt;配置文件&lt;/strong&gt;里写着它的名字&lt;/li&gt;
  &lt;li&gt;某个&lt;strong&gt;几乎没人访问的老页面&lt;/strong&gt;也在用&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;这类调用，AI 完全看不到&lt;/strong&gt;——因为你没贴给它。&lt;/p&gt;

&lt;p&gt;删之前，先全项目搜一遍这个名字。&lt;strong&gt;搜索框，是老项目里最重要的工具。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-01-ai-74-four-traps.png&quot; alt=&quot;four-traps&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五动手改之前必做三查&quot;&gt;五、动手改之前，必做”三查”&lt;/h2&gt;

&lt;p&gt;理解只是第一步。&lt;strong&gt;真正的考验是：你要改它。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;老项目改动的黄金法则是：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;不懂全部，也能安全改动。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;怎么做到？改之前，做完这三查。&lt;/p&gt;

&lt;h3 id=&quot;查一查引用这东西被谁用着&quot;&gt;查一：查引用——这东西被谁用着&lt;/h3&gt;

&lt;p&gt;要改的这个函数、这个变量、这张表，&lt;strong&gt;全项目搜一遍它的名字&lt;/strong&gt;，看看有多少处在用。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;只有 1 处用 → 风险低，可以放心改&lt;/li&gt;
  &lt;li&gt;有 10 处用 → &lt;strong&gt;要小心了&lt;/strong&gt;，你改的是公共部件&lt;/li&gt;
  &lt;li&gt;搜出来一堆，还有配置文件里的 → &lt;strong&gt;先别动，去问人&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;这一步是纯手工的，AI 帮不了你&lt;/strong&gt;，因为它看不到你没贴的文件。&lt;strong&gt;但它是最重要的一步。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;查二查影响改了会波及什么&quot;&gt;查二：查影响——改了会波及什么&lt;/h3&gt;

&lt;p&gt;把这段代码 + 所有调用它的地方，一起贴给 AI，问它：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;“如果我把这里改成 XX，会有哪些地方受影响？有没有我没注意到的连带后果？”&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;注意：&lt;strong&gt;必须把调用方也贴上&lt;/strong&gt;。只贴被改的那段，AI 只能猜。&lt;/p&gt;

&lt;h3 id=&quot;查三查退路出事了怎么退回去&quot;&gt;查三：查退路——出事了怎么退回去&lt;/h3&gt;

&lt;p&gt;改之前，&lt;strong&gt;把原始代码整段复制一份存起来&lt;/strong&gt;，或者用版本管理工具提交一次。&lt;/p&gt;

&lt;p&gt;老项目最怕的不是改错，&lt;strong&gt;是改错了还回不去。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-10-01-ai-74-three-checks.png&quot; alt=&quot;three-checks&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六边读边攒给项目补一份说明书&quot;&gt;六、边读边攒：给项目补一份说明书&lt;/h2&gt;

&lt;p&gt;这是&lt;strong&gt;最容易被跳过、但回报最高&lt;/strong&gt;的一件事。&lt;/p&gt;

&lt;p&gt;你花了两天搞懂的东西，&lt;strong&gt;三周后会忘掉一大半&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;所以从第一天开始，就建一个文件，边读边记。不用写得多正式，记这五样就够：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;入口在哪个文件&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;各文件夹分别是干什么的&lt;/strong&gt;（一句话一个）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;主流程走一遍是怎样的&lt;/strong&gt;（用箭头连起来那种）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;数据存在哪几个地方&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;踩过的坑 / 反直觉的地方&lt;/strong&gt;（这条最值钱）&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;第 5 条尤其重要。&lt;/strong&gt; 那些”看着像 A，其实是 B”的地方，正是你未来最容易再次踩进去的。&lt;/p&gt;

&lt;p&gt;下次再问 AI 任何关于这个项目的问题，都可以把这份笔记贴在前面当背景——&lt;strong&gt;AI 立刻从”外人”，变成”看过说明书的同事”&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;回答质量的差别，大到你会后悔没早点开始记。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;提示词模板盒子&quot;&gt;提示词模板盒子&lt;/h2&gt;

&lt;p&gt;以下模板可直接复制使用，方括号内替换成你自己的内容。&lt;/p&gt;

&lt;h3 id=&quot;模板一找入口第一步不贴代码&quot;&gt;模板一：找入口（第一步，不贴代码）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我接手了一个别人写的老项目，现在完全不知道从哪儿开始看。

下面是这个项目根目录的文件和文件夹清单：
[粘贴文件名列表]

请你告诉我：
1. 程序的入口最可能是哪个文件？为什么？给出第一、第二可能
2. 这几个文件夹分别大概承担什么角色（一句话一个）
3. 我应该按什么顺序打开这些文件，才最快搞懂这个项目
4. 有哪些文件是我暂时可以完全不用管的

我是新手，请用大白话说，不要用架构术语。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板二项目地图第二层&quot;&gt;模板二：项目地图（第二层）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;这是我接手项目的目录结构：
[粘贴目录树]

请帮我做一张&quot;项目地图&quot;：
1. 把这些文件夹归类成几大块（例如：界面层、业务层、数据层、工具、配置）
2. 每一块用一句话说明它负责什么
3. 用文字画出这几大块之间的调用关系（谁调谁，用箭头表示）
4. 指出哪一块是这个项目的&quot;核心&quot;，也就是我必须先搞懂的

请输出成我能直接抄进笔记的格式。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;追一条主线&lt;/strong&gt;：把相关代码段按序贴给 AI，让它讲清执行过程、指出断层、用箭头图总结（原模板四）。
▸ &lt;strong&gt;生成项目笔记&lt;/strong&gt;：让 AI 整理入门笔记（入口/目录/主流程/数据/坑点），直接存文件（原模板六）。&lt;/p&gt;

&lt;h3 id=&quot;模板三解说一段陌生代码最常用&quot;&gt;模板三：解说一段陌生代码（最常用）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;下面这段代码是我接手的老项目里的，我完全不知道它在干什么。

请按以下顺序回答，不要打乱：
1. 【一句话职责】这段代码在整个系统里负责什么（一句话，说人话）
2. 【打个比方】用一个生活中的例子来类比它做的事
3. 【分段说明】把它切成几个逻辑段落，每段说明在干什么（不要逐行翻译）
4. 【输入输出】它需要什么、产出什么
5. 【依赖】它调用了哪些外部东西（其他函数、数据库、接口、配置）
6. 【可疑之处】哪里写法过时、哪里可能有隐患、哪里的命名和实际功能对不上

前提：假设我完全不熟悉这个技术栈，请避免术语堆砌。

代码如下：
[粘贴代码]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;改动前影响评估&lt;/strong&gt;：把要改代码+调用方贴给 AI，评估影响与风险，并要求它指明风险（原模板五）。&lt;/p&gt;

&lt;h3 id=&quot;速查卡接手老项目五句口诀&quot;&gt;速查卡：接手老项目五句口诀&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. 剥洋葱   —— 入口 → 地图 → 主线 → 数据 → 细节，顺序不能乱
2. 走主线   —— 追通一个功能，理解度立刻过半
3. 信代码   —— 名字会骗人，注释会过期，只有代码不说谎
4. 先三查   —— 查引用、查影响、查退路，缺一不改
5. 边读边记 —— 笔记贴给 AI，它就从外人变成同事
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;最后&quot;&gt;最后&lt;/h2&gt;

&lt;p&gt;这一篇的核心，压缩成一句话：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;接手老项目的本事，不是”全都读懂”，而是”没全懂也能安全动手”。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;没有人能完全读懂一个几千行的祖传项目，&lt;strong&gt;老手也不能。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;老手和新手的区别只在于：&lt;strong&gt;老手知道哪些必须搞清楚，哪些可以先放着。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;入口必须清楚，主线必须走通，改动前必须三查。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;其余的，用到再说。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;下篇预告&quot;&gt;下篇预告&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;第75篇《调试实战——一个真实 Bug 全流程》。&lt;/strong&gt; 前面四篇拆开讲招式，下一篇串起来打一遍：还原一个真实场景——用户反馈”报表少了几条数据”，没报错、数据大、代码是别人写的，全程记录每一步贴了什么、信哪条。包括走错的两步弯路。&lt;strong&gt;看十篇方法论，不如走一遍。&lt;/strong&gt; 我们下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">代码不是你写的，写的人已经离职了。</summary></entry><entry><title type="html">第73篇：用 AI 做性能瓶颈分析——慢在哪，它告诉你</title><link href="http://0.0.0.0/2026/09/30/ai-73-perf/" rel="alternate" type="text/html" title="第73篇：用 AI 做性能瓶颈分析——慢在哪，它告诉你" /><published>2026-09-30T10:00:00+08:00</published><updated>2026-09-30T10:00:00+08:00</updated><id>http://0.0.0.0/2026/09/30/ai-73-perf</id><content type="html" xml:base="http://0.0.0.0/2026/09/30/ai-73-perf/">&lt;blockquote&gt;
  &lt;p&gt;能跑，结果也对，就是慢得让人想砸键盘。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;前两篇讲”错”，这一篇讲”慢”。&lt;/p&gt;

&lt;p&gt;这两件事完全不是一回事。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Bug 是有答案的&lt;/strong&gt;：要么报错了，要么结果不对，改完一验证，对了就是对了。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;慢没有答案。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;页面点一下转圈五秒，导出一个表要等半分钟，数据一多就整个卡死——它不报错，它也没算错，它只是&lt;strong&gt;让你等&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;更难受的是：你连”多快才算正常”都说不上来。&lt;/p&gt;

&lt;p&gt;于是很多新手的操作是这样的：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;觉得这段循环可能有点慢 → 改了 → 好像还是那么慢 → 又觉得那个查询有问题 → 再改 → 更慢了&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;改了一下午，快了 0.2 秒，还顺手改出两个新 bug。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这一篇我们把打法讲清楚。核心就一句：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;先测量，再优化。凭感觉调性能，八成越调越慢。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一新手最大的坑跳过测量直接动手&quot;&gt;一、新手最大的坑：跳过测量，直接动手&lt;/h2&gt;

&lt;p&gt;先说一个真实到扎心的规律：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;你觉得慢的那段代码，十有八九不是真正慢的那段。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;人对”哪里慢”的直觉极其不准。看起来很复杂的一段计算，可能只花了 3 毫秒；看起来平平无奇的一行取数据，可能花了 4 秒。&lt;/p&gt;

&lt;p&gt;而 AI 呢？&lt;strong&gt;你不给它数据，它比你更爱猜。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;你把 200 行代码丢过去说”这段有点慢，帮我优化”，AI 一定会给你一堆看起来很专业的建议：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;“可以考虑使用缓存”&lt;/li&gt;
  &lt;li&gt;“建议改成异步处理”&lt;/li&gt;
  &lt;li&gt;“这里可以用更高效的数据结构”&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;每一条听起来都对。&lt;strong&gt;每一条都可能跟你的实际瓶颈毫无关系。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;因为 AI 在做的事，和你一样——&lt;strong&gt;猜。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;所以性能优化的第一步，从来不是”问 AI 怎么优化”，而是：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;先让 AI 教你怎么量，量出数字，再拿数字问它。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-30-ai-73-two-paths.png&quot; alt=&quot;two-paths&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二不用专业工具三招量出耗时&quot;&gt;二、不用专业工具，三招量出耗时&lt;/h2&gt;

&lt;p&gt;一提”性能分析”，很多教程立刻上性能剖析器、火焰图、监控平台。&lt;/p&gt;

&lt;p&gt;对小白来说那太远了。&lt;strong&gt;先用最土的三招就够，土归土，管用。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第-1-招整体计时先确认到底有多慢&quot;&gt;第 1 招：整体计时——先确认到底有多慢&lt;/h3&gt;

&lt;p&gt;在这段功能&lt;strong&gt;开始前&lt;/strong&gt;和&lt;strong&gt;结束后&lt;/strong&gt;各记一个时间，相减打印出来。&lt;/p&gt;

&lt;p&gt;这一步的意义是：&lt;strong&gt;把”感觉慢”变成”3.8 秒”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;数字一出来，讨论才有基础。&lt;/p&gt;

&lt;h3 id=&quot;第-2-招分段计时把大块切成小块&quot;&gt;第 2 招：分段计时——把大块切成小块&lt;/h3&gt;

&lt;p&gt;这是最关键的一招。&lt;/p&gt;

&lt;p&gt;把整个流程拆成 3~5 段（比如：取数据 / 处理数据 / 生成结果 / 返回），&lt;strong&gt;每段都记一次耗时&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;跑一次，你会看到类似这样的结果：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;阶段&lt;/th&gt;
      &lt;th&gt;耗时&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;取数据&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;3.6 秒&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;处理数据&lt;/td&gt;
      &lt;td&gt;0.1 秒&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;生成结果&lt;/td&gt;
      &lt;td&gt;0.08 秒&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;返回&lt;/td&gt;
      &lt;td&gt;0.02 秒&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;答案瞬间就有了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;你之前盯着看了半天的”处理数据”那段复杂逻辑，只占 0.1 秒。真正的问题在取数据。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这一张表，比你问 AI 十遍都有用。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第-3-招改数据量看它是不是越多越慢&quot;&gt;第 3 招：改数据量——看它是不是”越多越慢”&lt;/h3&gt;

&lt;p&gt;同一个功能，分别用 10 条、100 条、1000 条数据各跑一次，记下耗时。&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;10 条 0.1 秒，100 条 1 秒，1000 条 10 秒 → &lt;strong&gt;和数据量成正比，属于正常，但有优化空间&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;10 条 0.1 秒，100 条 10 秒，1000 条直接卡死 → &lt;strong&gt;危险信号&lt;/strong&gt;，说明数据一多耗时暴涨，多半是”循环里套查询”或”循环里套循环”&lt;/li&gt;
  &lt;li&gt;10 条 3 秒，1000 条也 3 秒 → 慢的不是数据处理，是某个&lt;strong&gt;固定开销&lt;/strong&gt;（比如某次网络请求、某个初始化）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;这三种情况的解法完全不同。分不清就乱改，必然白干。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-30-ai-73-timing-bottleneck.png&quot; alt=&quot;timing-bottleneck&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三性能四件套作量时标&quot;&gt;三、性能四件套：作、量、时、标&lt;/h2&gt;

&lt;p&gt;有了数字，才轮到 AI 上场。&lt;/p&gt;

&lt;p&gt;问性能问题，和问 bug 一样，要给&lt;strong&gt;四样东西&lt;/strong&gt;。这一套记住：&lt;strong&gt;作、量、时、标&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1）作——是哪个操作慢&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;不要说”我系统慢”。要说”点击『导出报表』按钮之后慢”。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;具体到一个用户动作。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2）量——数据规模多大&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;“表里有 5 万条记录，这次导出筛出 2000 条。”&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;数据量是性能问题的第一上下文。&lt;/strong&gt; 不给数据量，AI 给的建议全是空话。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3）时——实测耗时，最好是分段的&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;把你第 2 招量出来的那张表直接贴给它。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4）标——你的目标是多快&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;“希望 3 秒内出来” 和 “希望 100 毫秒内出来”，是&lt;strong&gt;两个量级的方案&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;前者可能加个索引就行，后者可能要上缓存、改架构。&lt;strong&gt;不说目标，AI 容易给你一个杀鸡用牛刀的方案。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;把这四样凑齐，AI 的回答质量会立刻从”正确的废话”变成”能落地的建议”。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四新手性能问题的四大元凶&quot;&gt;四、新手性能问题的四大元凶&lt;/h2&gt;

&lt;p&gt;看了大量新手代码之后，你会发现慢的原因高度集中。&lt;strong&gt;记住这四个，覆盖八成情况。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;元凶一在循环里查数据库头号杀手&quot;&gt;元凶一：在循环里查数据库（头号杀手）&lt;/h3&gt;

&lt;p&gt;这是&lt;strong&gt;最常见、也是最致命&lt;/strong&gt;的一个。&lt;/p&gt;

&lt;p&gt;代码逻辑通常长这样：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;先查出 100 个订单 → 然后对每个订单，再去查一次它的客户信息&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;看起来很自然对吧？但实际发生的事情是：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1 次查询 + 100 次查询 = 101 次数据库往返。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;每次往返哪怕只要 30 毫秒，101 次就是 3 秒多。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这就是那个反直觉的事实：真正拖慢你的不是代码，是它问了数据库一百遍。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;正确做法是&lt;strong&gt;一次性把 100 个客户全查出来&lt;/strong&gt;，再在内存里对应上。101 次变 2 次，3 秒变 60 毫秒。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;你不需要会写这个优化，你只需要知道去问 AI：「我这段是不是在循环里查数据库？能不能改成批量查询？」&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;元凶二一次性把全部数据拿出来&quot;&gt;元凶二：一次性把全部数据拿出来&lt;/h3&gt;

&lt;p&gt;“查询所有订单” —— 表里有 50 万条，你全拿了出来，然后在代码里筛出 20 条显示。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;该让数据库干的活，你搬到内存里干了。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;三个关键词：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;加筛选条件&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;加分页&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;只取需要的字段&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;元凶三重复计算同一个东西&quot;&gt;元凶三：重复计算同一个东西&lt;/h3&gt;

&lt;p&gt;同一个结果，在一次流程里算了 5 遍；同一份配置，每次调用都重新读一次文件。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;算过的东西存下来复用&lt;/strong&gt;，这就是缓存最朴素的含义。&lt;/p&gt;

&lt;h3 id=&quot;元凶四前端一次性渲染太多东西&quot;&gt;元凶四：前端一次性渲染太多东西&lt;/h3&gt;

&lt;p&gt;一次往页面上塞 5000 行表格、几十张没压缩的大图，浏览器直接卡住。&lt;/p&gt;

&lt;p&gt;解法：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;分页&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;懒加载&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;图片压缩&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-30-ai-73-four-culprits.png&quot; alt=&quot;four-culprits&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五让-ai-改的时候守住三条线&quot;&gt;五、让 AI 改的时候，守住三条线&lt;/h2&gt;

&lt;p&gt;拿到 AI 的优化建议后，&lt;strong&gt;别一口气全改了。&lt;/strong&gt; 性能优化最容易的翻车方式，就是”快了，但结果不对了”。&lt;/p&gt;

&lt;p&gt;三条线，每次都守住：&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第一条：一次只改一处，改完立刻测。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;同时改三处，快了你不知道是哪处起的作用，慢了你也不知道该退哪一步。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二条：改之前留副本。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;原来的代码整段复制到一个备份文件里。优化改坏的概率，比你想的高。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第三条：改完必须核对结果一致。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这是&lt;strong&gt;最容易被忽略、后果最严重&lt;/strong&gt;的一条。&lt;/p&gt;

&lt;p&gt;优化的前提是”结果不变，只是更快”。而很多优化写法（尤其是批量查询、加缓存）&lt;strong&gt;极容易悄悄改变结果&lt;/strong&gt;：少了几条数据、顺序变了、拿到的是旧数据。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;所以每次优化后，必须拿同一份输入跑一遍，逐条对比新旧结果。&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;快了但结果错了，比慢着但对着糟糕得多。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六一个完整的实战节奏&quot;&gt;六、一个完整的实战节奏&lt;/h2&gt;

&lt;p&gt;把上面的东西串起来，一次完整的性能优化长这样：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;描述现象&lt;/strong&gt; —— 点导出按钮，等 8 秒&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;整体计时&lt;/strong&gt; —— 确认是 7.9 秒，不是错觉&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;分段计时&lt;/strong&gt; —— 取数据 7.5 秒，其余加起来 0.4 秒&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;变数据量再测&lt;/strong&gt; —— 100 条 0.8 秒，1000 条 7.5 秒，成正比且偏慢&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;凑齐四件套问 AI&lt;/strong&gt; —— 作、量、时、标一次说清&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;AI 判断&lt;/strong&gt; —— 循环里逐条查客户信息，典型 N+1&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;只改这一处&lt;/strong&gt; —— 改成批量查询，留好备份&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;复测&lt;/strong&gt; —— 7.9 秒 → 0.6 秒&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;对结果&lt;/strong&gt; —— 导出条数、内容、顺序与优化前完全一致 ✔&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;九步走完，比瞎改一下午强一百倍。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;注意第 9 步不能省。&lt;strong&gt;没对过结果的优化，不算完成。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;提示词模板盒子&quot;&gt;提示词模板盒子&lt;/h2&gt;

&lt;p&gt;以下模板可直接复制使用，把方括号里的内容替换成你自己的情况。&lt;/p&gt;

&lt;h3 id=&quot;模板一让-ai-教你加计时第一步永远是这个&quot;&gt;模板一：让 AI 教你加计时（第一步永远是这个）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我要给下面这段代码做性能分析，但我不知道慢在哪。

请你帮我做两件事：
1. 把这段流程拆成 3~5 个阶段，在每个阶段前后加上计时代码，
   运行后能打印出每段各花了多少毫秒。
2. 计时代码请加得明显一点（加注释标出来），方便我之后删掉。

要求：
- 只加计时，不要改动任何原有逻辑
- 给我完整文件，不要片段
- 最后告诉我：运行后我应该重点关注哪几个数字

代码如下：
[粘贴你的代码]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;数据量增长测试解读&lt;/strong&gt;：把 10/100/1000 条各跑一次的耗时贴给 AI，让它判断是”成正比 / 暴涨 / 几乎不变”，并指出下一步先查哪段（原模板四）。&lt;/p&gt;

&lt;h3 id=&quot;模板二性能四件套正式提问核心模板&quot;&gt;模板二：性能四件套——正式提问（核心模板）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我有一个性能问题，信息如下：

【作】慢的操作：[例如：点击&quot;导出订单报表&quot;按钮]
【量】数据规模：[例如：订单表 5 万条，本次筛出 2000 条]
【时】实测耗时（分段）：
  - 取数据：3.6 秒
  - 处理数据：0.1 秒
  - 生成文件：0.08 秒
  - 总计：3.8 秒
【标】目标：希望总耗时降到 1 秒以内

相关代码如下：
[粘贴最慢那一段的代码]

请你：
1. 先判断瓶颈最可能出在哪一行或哪几行，说明理由
2. 给出优化方案，按&quot;见效大小&quot;排序，并标出每个方案的风险
3. 先只给我改动最小、见效最大的那一个方案的完整代码
4. 告诉我改完之后，我应该怎么验证&quot;结果没变，只是变快了&quot;

不要一次给我多个方案的代码，我要一个一个改。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;优化后安全核对&lt;/strong&gt;：改完让 AI 列一份可勾选清单——对比哪几项确认”结果没变”，以及这种优化最易在什么边界悄悄出错（原模板五）。&lt;/p&gt;

&lt;h3 id=&quot;模板三排查循环里查数据库头号元凶专用&quot;&gt;模板三：排查”循环里查数据库”（头号元凶专用）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;请检查下面这段代码，是否存在&quot;在循环里反复查询数据库&quot;的问题
（也就是常说的 N+1 查询）。

请按以下格式回答：
1. 有没有：是 / 否
2. 如果有，指出是哪一个循环、循环里的哪一行在查询
3. 按当前数据量估算：总共会产生多少次数据库查询
4. 改成批量查询后，查询次数会变成多少
5. 给出改造后的完整代码

特别注意：改造后必须保证返回的数据条数、内容、顺序
与原来完全一致。如果有可能不一致，请提前告诉我。

代码如下：
[粘贴你的代码]
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;速查卡性能优化五句口诀&quot;&gt;速查卡：性能优化五句口诀&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;1. 先量再改  —— 没有数字，不要动代码
2. 分段计时  —— 一张耗时表，胜过十次猜
3. 四件套    —— 作（什么操作）、量（多少数据）、时（多久）、标（目标）
4. 一次一处  —— 改完立刻测，别批量改
5. 必对结果  —— 快了但错了，比慢着更糟
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;最后&quot;&gt;最后&lt;/h2&gt;

&lt;p&gt;这一篇的核心，压缩成一句话：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;性能问题里，”数字”就是你的报错。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Bug 有红字告诉你出事了，性能没有。&lt;strong&gt;那个数字，就是你自己造出来的红字。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;没有它，你和 AI 都在猜；有了它，路径只剩一条。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;先测量，再优化。&lt;/strong&gt; 记住这五个字，你已经甩开一半的人了。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;下篇预告&quot;&gt;下篇预告&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;第74篇《用 AI 理解遗留老代码——接手祖传项目不慌》。&lt;/strong&gt; 代码不是你写的、写的人离职了、没文档没注释几千行起步。下一篇讲：按什么顺序读（九成人一上来就开错文件）、怎么让 AI 画”项目地图”、以及动手前先查清”这一行被谁用着”。&lt;strong&gt;不懂全部，也能安全改动。&lt;/strong&gt; 我们下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">能跑，结果也对，就是慢得让人想砸键盘。</summary></entry><entry><title type="html">第72篇：让 AI 定位逻辑错误——没有红字，也能查出来</title><link href="http://0.0.0.0/2026/09/29/ai-72-logic-bug/" rel="alternate" type="text/html" title="第72篇：让 AI 定位逻辑错误——没有红字，也能查出来" /><published>2026-09-29T10:00:00+08:00</published><updated>2026-09-29T10:00:00+08:00</updated><id>http://0.0.0.0/2026/09/29/ai-72-logic-bug</id><content type="html" xml:base="http://0.0.0.0/2026/09/29/ai-72-logic-bug/">&lt;blockquote&gt;
  &lt;p&gt;一个错都不报，结果就是不对。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;上一篇讲的是”有红字”的 bug。&lt;/p&gt;

&lt;p&gt;那一类其实是&lt;strong&gt;幸运&lt;/strong&gt;的——程序已经明确告诉你出事了，还顺手指了地方。&lt;/p&gt;

&lt;p&gt;这一篇讲的是另一类，也是真正吃时间的那一类：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;程序跑得好好的，没有任何报错。
&lt;strong&gt;但结果就是不对。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;统计出来的总数少了三条。
排序排完，第一名跑到了中间。
明明该显示 10 条，页面上只有 7 条。
金额算出来永远差那么几分钱。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;没有红字，没有提示，你连从哪一行看起都不知道。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;很多新手到这一步就卡死了，反复把整段代码丢给 AI，问一句：”帮我看看哪里有问题？”&lt;/p&gt;

&lt;p&gt;然后 AI 开始&lt;strong&gt;一本正经地瞎猜&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;这一篇，我们就把这类问题的正确打法讲透。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一先理解为什么-ai-对逻辑错更容易翻车&quot;&gt;一、先理解：为什么 AI 对逻辑错更容易翻车&lt;/h2&gt;

&lt;p&gt;上一篇里，AI 表现得像个老手。这一篇，它经常表现得像个新手。&lt;/p&gt;

&lt;p&gt;原因很简单：&lt;strong&gt;信息量差太多了。&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;报错型 bug&lt;/th&gt;
      &lt;th&gt;逻辑型 bug&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;有没有明确信号&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;有&lt;/strong&gt;，报错类型 + 消息&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;没有&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;出错位置&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;给了&lt;/strong&gt;，精确到行&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;不知道&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;出错时的值&lt;/td&gt;
      &lt;td&gt;常常直接给出&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;完全没有&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;AI 拿到什么&lt;/td&gt;
      &lt;td&gt;一份证词&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;一段”看起来都对”的代码&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;关键在最后一行。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;逻辑错的代码，从语法上看&lt;strong&gt;每一行都是对的&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;你把它丢给 AI 说”这里有 bug”，AI 只能做一件事：&lt;strong&gt;从常见错误清单里挑几个像的，说给你听。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;要让 AI 靠谱，你必须把它缺的那部分信息补上。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-29-ai-72-two-bug-types.png&quot; alt=&quot;two-bug-types&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二逻辑错四件套入期实码&quot;&gt;二、逻辑错四件套：入、期、实、码&lt;/h2&gt;

&lt;p&gt;上一篇的报错四件套是「错、码、做、境」。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这一篇换一套：「入、期、实、码」。&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;件&lt;/th&gt;
      &lt;th&gt;内容&lt;/th&gt;
      &lt;th&gt;一句话&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;入&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;输入数据&lt;/td&gt;
      &lt;td&gt;你喂进去的&lt;strong&gt;具体&lt;/strong&gt;内容&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;期&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;期望输出&lt;/td&gt;
      &lt;td&gt;你认为&lt;strong&gt;应该&lt;/strong&gt;得到什么&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;实&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;实际输出&lt;/td&gt;
      &lt;td&gt;它&lt;strong&gt;实际&lt;/strong&gt;给了你什么&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;码&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;相关代码&lt;/td&gt;
      &lt;td&gt;处理这段数据的代码&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;核心逻辑：既然没有报错，那唯一的线索就是「期望和实际的差异」。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这个差异越具体，AI 越能顺着差异倒推。&lt;/p&gt;

&lt;h3 id=&quot;入和实必须是具体的值不能是描述&quot;&gt;「入」和「实」必须是具体的值，不能是描述&lt;/h3&gt;

&lt;p&gt;这是最多人做错的地方。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;❌ “我传了一些订单数据进去，结果统计不对。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这句话对 AI 来说约等于什么都没说。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;✅ “我传了 5 条订单，金额分别是 12.5、8.0、30.25、0、-5。
期望总额是 45.75，实际得到 50.75。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;看到区别了吗？&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;第二种写法里，那个 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;-5&lt;/code&gt; 和 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0&lt;/code&gt;，一眼就能让 AI 想到”是不是负数/零值被过滤掉了”。&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;划重点：给样例胜过描述十句&lt;/strong&gt;——在调试这里比写代码时更重要。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;期要说清楚为什么应该是这样&quot;&gt;「期」要说清楚”为什么应该是这样”&lt;/h3&gt;

&lt;p&gt;有时候不是代码错了，是&lt;strong&gt;你以为的规则和实际规则不一样&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;所以除了写期望值，最好补一句依据：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“期望是 45.75，因为按业务规则，负数订单（退款）也要算进总额。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;这一句能帮 AI 判断：到底是代码写错了，还是需求本来就有歧义。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-29-ai-72-logic-four-parts.png&quot; alt=&quot;logic-four-parts&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三最该学的一招二分法定位&quot;&gt;三、最该学的一招：二分法定位&lt;/h2&gt;

&lt;p&gt;如果只让我教新手一个调试技巧，我会教这个。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;它不需要任何工具，不需要懂调试器，笨但极其有效。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;思路&quot;&gt;思路&lt;/h3&gt;

&lt;p&gt;假设你的处理流程有 10 步，结果在第 10 步不对。&lt;/p&gt;

&lt;p&gt;问题在哪一步？你不知道。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;那就先看第 5 步。&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;如果第 5 步的结果&lt;strong&gt;已经不对了&lt;/strong&gt; → 问题在前 5 步，后 5 步不用看了&lt;/li&gt;
  &lt;li&gt;如果第 5 步的结果&lt;strong&gt;是对的&lt;/strong&gt; → 问题在后 5 步&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;一次操作，排查范围砍掉一半。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;再来一次，砍成四分之一。&lt;strong&gt;四五轮之内，你能把范围缩到具体某一行。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;怎么看中间结果&quot;&gt;怎么”看”中间结果？&lt;/h3&gt;

&lt;p&gt;最简单的办法：&lt;strong&gt;打印出来。&lt;/strong&gt; 这事儿不用你自己写，&lt;strong&gt;直接让 AI 帮你加&lt;/strong&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“请在这段代码的每个关键步骤后面加一行打印，
把当时的变量值和步骤名打出来，给我完整代码。
我运行后会把打印结果贴给你。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;然后你运行，&lt;strong&gt;把打印出来的那一坨复制回去&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这个来回，就是新手能做的最高效的调试动作。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;为什么这招对-ai-特别有效&quot;&gt;为什么这招对 AI 特别有效&lt;/h3&gt;

&lt;p&gt;因为它把”猜”变成了”看”。&lt;/p&gt;

&lt;p&gt;AI 拿到中间打印结果之后，它面对的就不再是一段”看起来都对的代码”，而是&lt;strong&gt;一组带具体值的现场数据&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这时候它就从”猜谜”切换回了”破案”模式。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-29-ai-72-binary-search.png&quot; alt=&quot;binary-search&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四别问哪里错了要让-ai逐行推演&quot;&gt;四、别问”哪里错了”，要让 AI”逐行推演”&lt;/h2&gt;

&lt;p&gt;这是个提问方式上的大坑。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;❌ “这段代码哪里有问题？”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这句话在&lt;strong&gt;暗示 AI”这里有问题”&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;AI 为了满足你，会努力找一个问题出来——&lt;strong&gt;哪怕代码其实是对的&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;换个问法，效果完全不同：&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;✅ “请假设你是计算机，逐行执行这段代码。
输入是【具体数据】。
每执行一行，写出这一行执行后所有关键变量的值。
最后告诉我程序输出是什么。
&lt;strong&gt;先不要看我的期望值，也不要试图找 bug，就老老实实推演。&lt;/strong&gt;”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这叫「&lt;strong&gt;代码走读&lt;/strong&gt;」，或者说”手工模拟执行”。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;它的妙处在于：你没有让 AI 找 bug，你让它算一遍。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;算完之后，你再对比：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“你推演出的结果是 50.75，我期望的是 45.75。
现在请指出：是哪一步导致了这个差异？”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;这时候 AI 给的答案，准确率会高一大截。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;因为它是&lt;strong&gt;从自己的推演里找矛盾&lt;/strong&gt;，而不是凭印象猜。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五常见逻辑错清单让-ai-照着查一遍&quot;&gt;五、常见逻辑错清单：让 AI 照着查一遍&lt;/h2&gt;

&lt;p&gt;有一些逻辑错误特别高频，几乎每个新手都会踩。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;你可以直接让 AI 拿这张清单去对照检查。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;-差一位边界问题&quot;&gt;① 差一位（边界问题）&lt;/h3&gt;

&lt;p&gt;循环少跑一次或多跑一次；取列表最后一个元素时算错位置。&lt;/p&gt;

&lt;p&gt;典型表现：&lt;strong&gt;结果永远少一条 / 多一条&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;-小数比较&quot;&gt;② 小数比较&lt;/h3&gt;

&lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.1 + 0.2&lt;/code&gt; 在计算机里不等于 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;0.3&lt;/code&gt;。这不是 bug，是浮点数的天性。&lt;/p&gt;

&lt;p&gt;典型表现：&lt;strong&gt;金额差几分钱 / 判断相等永远不成立&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;-复制还是引用&quot;&gt;③ 复制还是引用&lt;/h3&gt;

&lt;p&gt;你以为复制了一份数据去改，其实改的是原来那份。&lt;/p&gt;

&lt;p&gt;典型表现：&lt;strong&gt;改了 A，B 也跟着变了&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;-异步顺序&quot;&gt;④ 异步顺序&lt;/h3&gt;

&lt;p&gt;网络请求还没回来，你就去用它的结果了。&lt;/p&gt;

&lt;p&gt;典型表现：&lt;strong&gt;第一次是空的，刷新一下就好了&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;-条件判断顺序&quot;&gt;⑤ 条件判断顺序&lt;/h3&gt;

&lt;p&gt;多个 if 条件的顺序写反了，某些数据被前面的条件先截走了。&lt;/p&gt;

&lt;p&gt;典型表现：&lt;strong&gt;大部分对，少数特定数据不对&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;-类型隐式转换&quot;&gt;⑥ 类型隐式转换&lt;/h3&gt;

&lt;p&gt;字符串 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;&quot;10&quot;&lt;/code&gt; 和数字 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;10&lt;/code&gt; 在有些语言里能直接比较，结果可能出乎意料。&lt;/p&gt;

&lt;p&gt;典型表现：&lt;strong&gt;排序结果诡异（比如 10 排在 9 前面）&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;-空值与零值被一起过滤&quot;&gt;⑦ 空值与零值被一起过滤&lt;/h3&gt;

&lt;p&gt;代码里写了”如果没有值就跳过”，结果把&lt;strong&gt;真实的 0 也当成”没有值”跳过了&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;典型表现：&lt;strong&gt;总数偏少，且缺的都是 0 或空字符串&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;-时区与编码&quot;&gt;⑧ 时区与编码&lt;/h3&gt;

&lt;p&gt;时间差 8 小时；中文变成乱码。&lt;/p&gt;

&lt;p&gt;典型表现：&lt;strong&gt;日期对不上 / 中文显示成问号或方块&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-29-ai-72-eight-logic-bugs.png&quot; alt=&quot;eight-logic-bugs&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;用法很简单：&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“请按以下 8 类常见逻辑错误，逐条检查这段代码，
明确说明每一条’有 / 没有 / 不适用’，不要跳过。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六终极验证让-ai-写测试用例来抓这个-bug&quot;&gt;六、终极验证：让 AI 写测试用例来”抓”这个 bug&lt;/h2&gt;

&lt;p&gt;修完之后，怎么确认真的好了？&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;跑一次看起来正常，不算数。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;更靠谱的做法：&lt;strong&gt;让 AI 写一组测试数据，专门去踩容易出问题的地方。&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“请针对这个函数，设计 8 组测试输入，要求覆盖：
正常情况、空数据、只有一条、最大值、负数、零、
重复数据、以及格式不规范的数据。
每组给出输入和正确答案。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;然后你把这 8 组挨个跑一遍。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;这一步经常能顺手抓出另外两三个你还不知道的 bug。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;而且这组数据可以留下来——&lt;strong&gt;以后每次改这段代码，重跑一遍就知道有没有改坏。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;七把整个流程串起来&quot;&gt;七、把整个流程串起来&lt;/h2&gt;

&lt;p&gt;新手遇到”不报错但结果不对”，按这个顺序走：&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;步&lt;/th&gt;
      &lt;th&gt;动作&lt;/th&gt;
      &lt;th&gt;目的&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;①&lt;/td&gt;
      &lt;td&gt;凑齐&lt;strong&gt;入、期、实、码&lt;/strong&gt;四件套&lt;/td&gt;
      &lt;td&gt;给足信息&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;②&lt;/td&gt;
      &lt;td&gt;先对&lt;strong&gt;八类高频错&lt;/strong&gt;照一遍现象&lt;/td&gt;
      &lt;td&gt;碰运气，命中就省事&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;③&lt;/td&gt;
      &lt;td&gt;让 AI &lt;strong&gt;加打印&lt;/strong&gt;，运行，贴回结果&lt;/td&gt;
      &lt;td&gt;把”猜”变成”看”&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;④&lt;/td&gt;
      &lt;td&gt;按&lt;strong&gt;二分法&lt;/strong&gt;缩小范围&lt;/td&gt;
      &lt;td&gt;定位到具体几行&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;⑤&lt;/td&gt;
      &lt;td&gt;让 AI &lt;strong&gt;逐行推演&lt;/strong&gt;（先别提期望值）&lt;/td&gt;
      &lt;td&gt;拿到中立判断&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;⑥&lt;/td&gt;
      &lt;td&gt;对比推演结果与期望，问差异出在哪一步&lt;/td&gt;
      &lt;td&gt;锁定根因&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;⑦&lt;/td&gt;
      &lt;td&gt;让 AI &lt;strong&gt;写测试用例&lt;/strong&gt;验证&lt;/td&gt;
      &lt;td&gt;确认真修好了&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;大部分逻辑 bug，走不到第五步就解决了。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;提示词模板盒子&quot;&gt;提示词模板盒子&lt;/h2&gt;

&lt;p&gt;以下模板可直接复制使用，把【】里的内容换成你自己的。&lt;/p&gt;

&lt;h3 id=&quot;模板-72-1逻辑错四件套万能主模板&quot;&gt;模板 72-1：逻辑错四件套（万能主模板）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我的程序没有任何报错，但运行结果不对，需要你帮我定位。

【① 入 —— 输入数据】
（给出具体的值，不要用&quot;一些数据&quot;这种描述）

【② 期 —— 我期望的输出】
期望结果：
为什么应该是这样：（说明业务规则或计算依据）

【③ 实 —— 实际的输出】
实际结果：
差异在哪：（例如&quot;总数少了 3 条&quot;&quot;金额多了 5.00&quot;）

【④ 码 —— 相关代码】
（粘贴处理这段数据的完整代码）

补充：什么情况下结果是对的：（如果有）

请按顺序回答：
1. 你判断问题最可能出在哪一段？为什么
2. 我该怎么验证你的判断（要具体到我该做什么）
3. 确认后给出修改的完整代码

我是编程新手，请用大白话解释。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;八类高频错筛查&lt;/strong&gt;：让 AI 按 8 类常见逻辑错逐条回答”有 / 没有 / 不适用”，对”有”的指明行号与改法（原 72-5）。
▸ &lt;strong&gt;规则歧义排查&lt;/strong&gt;：附上你理解的规则，让 AI 对比代码实际执行的规则，指出不一致处（原 72-7）。&lt;/p&gt;

&lt;h3 id=&quot;模板-72-2加打印做二分定位&quot;&gt;模板 72-2：加打印做二分定位&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;这段代码的最终结果不对，但中间过程我看不到。

请给我一份&quot;带日志版&quot;的完整代码：
- 在每个关键步骤后面加一行打印
- 打印内容包括：步骤编号、步骤在干什么、当时关键变量的值
- 如果处理的是列表，请同时打印它的长度
- 打印格式要清晰，便于我复制回来给你看

不要改动原有逻辑，只加打印。

原代码：
【粘贴】
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;生成测试用例&lt;/strong&gt;：让 AI 设计覆盖正常 / 空 / 边界 / 异常的输入组，改完挨个验证（原 72-6）。&lt;/p&gt;

&lt;h3 id=&quot;模板-72-3逐行推演中立问法防附和&quot;&gt;模板 72-3：逐行推演（中立问法，防附和）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;请你扮演一台计算机，逐行执行下面这段代码。

输入数据是：【具体的值】

要求：
- 一行一行来，不要跳步
- 每执行一行，写出这一行执行后所有关键变量的当前值
- 遇到循环，至少完整展示前两轮和最后一轮
- 最后给出程序的最终输出

重要：现在不要试图寻找 bug，也不要评价代码好坏，
就老老实实按代码写的逻辑推演一遍。

代码：
【粘贴】
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;对比差异找根因&lt;/strong&gt;：把推演结果与期望值并排，追问差异从第几步产生、是代码错还是理解偏差（原 72-4）。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;速查两类-bug两套四件套&quot;&gt;速查：两类 bug，两套四件套&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt; &lt;/th&gt;
      &lt;th&gt;报错型（第71篇）&lt;/th&gt;
      &lt;th&gt;逻辑型（本篇）&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;四件套&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;错、码、做、境&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;入、期、实、码&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;核心线索&lt;/td&gt;
      &lt;td&gt;报错原文 + 栈&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;期望与实际的差异&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;关键动作&lt;/td&gt;
      &lt;td&gt;找栈里自己的文件名&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;加打印 + 二分法&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;最大的坑&lt;/td&gt;
      &lt;td&gt;红字消失≠修好&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;AI 顺着你说”是的这里有问题”&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;验收标准&lt;/td&gt;
      &lt;td&gt;说得清值为什么变成那样&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;测试用例全部通过&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;最后&quot;&gt;最后&lt;/h2&gt;

&lt;p&gt;这一篇的核心，也压缩成一句话：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;没有报错的时候，”期望和实际的差”就是你的报错。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;把这个差描述得越具体，AI 越派得上用场。&lt;/p&gt;

&lt;p&gt;而当你连差异都描述不清楚的时候——&lt;strong&gt;先别急着问 AI，先加两行打印。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;看见了，才谈得上分析。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;下篇预告&quot;&gt;下篇预告&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;第73篇《用 AI 做性能瓶颈分析——慢在哪，它告诉你》。&lt;/strong&gt; 能跑、结果也对，就是慢——比 bug 更无从下手。下一篇讲先量再改、性能四大元凶，以及反直觉真相：拖慢你的往往不是代码，是它问了数据库一百遍。我们下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">一个错都不报，结果就是不对。</summary></entry><entry><title type="html">第71篇：Bug 调试——把报错贴给 AI，错误栈这样喂最有效</title><link href="http://0.0.0.0/2026/09/28/ai-71-debug-error/" rel="alternate" type="text/html" title="第71篇：Bug 调试——把报错贴给 AI，错误栈这样喂最有效" /><published>2026-09-28T10:00:00+08:00</published><updated>2026-09-28T10:00:00+08:00</updated><id>http://0.0.0.0/2026/09/28/ai-71-debug-error</id><content type="html" xml:base="http://0.0.0.0/2026/09/28/ai-71-debug-error/">&lt;blockquote&gt;
  &lt;p&gt;一屏红字，你只复制了第一行。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;前两篇讲的是「读懂」，从这一篇开始讲「修好」。&lt;/p&gt;

&lt;p&gt;先说一个几乎所有新手都干过的动作：&lt;/p&gt;

&lt;p&gt;程序跑挂了，屏幕上刷出一大片红字。你眯着眼睛看了两秒，鼠标一划，&lt;strong&gt;复制了最上面那一行&lt;/strong&gt;，丢给 AI，问：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“这个错怎么解决？”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;然后 AI 给了你一个答案。你照着改，&lt;strong&gt;红字消失了&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;三天后，同一个地方，换了个姿势又炸了。&lt;/p&gt;

&lt;p&gt;这就是”贴报错”最大的陷阱：&lt;strong&gt;你以为你在修 bug，其实你只是在让红字消失。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;这一篇就讲三件事：一屏红字里哪几行是宝贝、哪几行是噪音；只贴报错为什么常拿不到正解、还差哪几样东西；以及怎么判断 AI 给的是&lt;strong&gt;真修好&lt;/strong&gt;还是&lt;strong&gt;假修好&lt;/strong&gt;。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;一先破个误区错误信息不是报警是证词&quot;&gt;一、先破个误区：错误信息不是”报警”，是”证词”&lt;/h2&gt;

&lt;p&gt;很多人对报错的心理是：这玩意儿是来骂我的。&lt;/p&gt;

&lt;p&gt;所以看到红字，第一反应是躲——赶紧让它消失。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;换个视角：错误信息是程序留给你的一份证词。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;它老老实实交代了三件事：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;发生了什么类型的问题&lt;/strong&gt;（是找不到东西？还是类型不对？还是权限不够？）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;是在哪一行、哪个文件出的事&lt;/strong&gt;&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;出事的时候，那些变量是什么值&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;这三件事，就是破案的全部线索。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;你把证词只念了第一句就合上，当然破不了案。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-28-ai-71-error-three-layers.png&quot; alt=&quot;error-three-layers&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;二错误栈怎么读三步定位法&quot;&gt;二、错误栈怎么读：三步定位法&lt;/h2&gt;

&lt;p&gt;所谓「错误栈」（也叫堆栈、调用栈、traceback），就是那一大坨看起来像天书的东西。&lt;/p&gt;

&lt;p&gt;它其实是一张&lt;strong&gt;路径图&lt;/strong&gt;：程序从哪儿出发，一路调用了谁，最后在哪儿摔倒了。&lt;/p&gt;

&lt;p&gt;新手觉得它可怕，是因为里面&lt;strong&gt;大部分文件名你根本没见过&lt;/strong&gt;——那些都是库和框架内部的文件。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;记住三步，就能读懂九成的错误栈。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第一步找错误类型--错误消息这一行&quot;&gt;第一步：找”错误类型 + 错误消息”这一行&lt;/h3&gt;

&lt;p&gt;这是整段报错的核心。&lt;/p&gt;

&lt;p&gt;不同语言位置不一样：&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;Python&lt;/strong&gt;：在&lt;strong&gt;最后一行&lt;/strong&gt;（比如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;KeyError: 'user_id'&lt;/code&gt;）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;JavaScript / Node&lt;/strong&gt;：通常在&lt;strong&gt;第一行&lt;/strong&gt;（比如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;TypeError: Cannot read properties of undefined&lt;/code&gt;）&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Java / C#&lt;/strong&gt;：在&lt;strong&gt;第一行&lt;/strong&gt;（比如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;NullPointerException&lt;/code&gt;）&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;这一行告诉你”是什么错”。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第二步从栈里找出你自己的文件名&quot;&gt;第二步：从栈里找出你自己的文件名&lt;/h3&gt;

&lt;p&gt;这一步是&lt;strong&gt;最关键的&lt;/strong&gt;，也是最多人漏掉的。&lt;/p&gt;

&lt;p&gt;那一大坨路径里，绝大部分长这样：&lt;/p&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;at node_modules/xxx/lib/index.js:412
at /usr/lib/python3.11/site-packages/yyy/core.py:88
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;strong&gt;凡是路径里带 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;node_modules&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;site-packages&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vendor&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dist&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;lib&lt;/code&gt; 这些字眼的，基本都不是你的代码。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;你要找的是&lt;strong&gt;带着你自己项目文件名的那一行&lt;/strong&gt;——比如 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;app.py&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;main.js&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;UserService.java&lt;/code&gt;。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;那一行，才是你真正要看的地方。&lt;/strong&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;小技巧：&lt;/strong&gt; 如果栈里出现了好几行你自己的文件，取&lt;strong&gt;离错误最近的那一行&lt;/strong&gt;（Python 看最下面那个，JS 看最上面那个）。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;第三步看错误消息里的具体值&quot;&gt;第三步：看错误消息里的”具体值”&lt;/h3&gt;

&lt;p&gt;好的报错会把出事时的实际值写出来：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;KeyError: 'user_id'&lt;/code&gt; —— 说明它去找一个叫 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;user_id&lt;/code&gt; 的东西，没找着
&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Cannot read properties of undefined (reading 'name')&lt;/code&gt; —— 说明某个东西是空的，你还想从它身上拿 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;name&lt;/code&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;这一步回答的是”为什么”。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-28-ai-71-stack-three-steps.png&quot; alt=&quot;stack-three-steps&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;三贴报错四件套错码做境&quot;&gt;三、贴报错四件套：错、码、做、境&lt;/h2&gt;

&lt;p&gt;现在到了最实用的部分。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;只贴报错，AI 的回答准确率大概只有五成。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;你要给它四样东西，我把它叫「贴报错四件套」：&lt;/strong&gt;&lt;/p&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;件&lt;/th&gt;
      &lt;th&gt;内容&lt;/th&gt;
      &lt;th&gt;一句话&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;错&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;完整报错原文&lt;/td&gt;
      &lt;td&gt;从头到尾，&lt;strong&gt;别截断，别转述&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;码&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;出错那段代码&lt;/td&gt;
      &lt;td&gt;报错指到的那一行&lt;strong&gt;及其上下文&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;做&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;你做了什么才触发的&lt;/td&gt;
      &lt;td&gt;点了什么、传了什么参数&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;&lt;strong&gt;境&lt;/strong&gt;&lt;/td&gt;
      &lt;td&gt;环境信息&lt;/td&gt;
      &lt;td&gt;语言版本、框架版本、怎么运行的&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;p&gt;&lt;strong&gt;逐个说清楚为什么。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;错完整原文不要转述&quot;&gt;「错」：完整原文，不要转述&lt;/h3&gt;

&lt;p&gt;最要命的一个坏习惯是&lt;strong&gt;用自己的话描述报错&lt;/strong&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;❌ “它说什么找不到什么东西”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI 收到这句话，只能靠猜。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;✅ 直接把整段红字，&lt;strong&gt;从第一个字符复制到最后一个字符&lt;/strong&gt;，原封不动贴进去。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;&lt;strong&gt;你觉得看不懂的那部分，恰恰可能是 AI 最需要的部分。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;码贴出错那一行的前后文&quot;&gt;「码」：贴出错那一行的前后文&lt;/h3&gt;

&lt;p&gt;只贴报错指到的那一行是不够的。&lt;/p&gt;

&lt;p&gt;那一行是&lt;strong&gt;结果&lt;/strong&gt;，原因往往在它上面几行。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;建议贴出错行前后各 10～20 行&lt;/strong&gt;，或者干脆把整个函数贴进去。&lt;/p&gt;

&lt;p&gt;如果这段代码依赖别的地方传过来的数据，&lt;strong&gt;把数据长什么样也说一句&lt;/strong&gt;。&lt;/p&gt;

&lt;h3 id=&quot;做复现动作&quot;&gt;「做」：复现动作&lt;/h3&gt;

&lt;p&gt;这一条最容易被忽略，但价值极高。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“我在页面上点了’提交’按钮，表单里手机号那一栏是空的，然后就报了这个错。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这一句话，直接把排查范围从”整个项目”缩小到”表单提交 + 空值处理”。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;很多时候，AI 靠这一句就能直接猜中根因。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;境环境信息&quot;&gt;「境」：环境信息&lt;/h3&gt;

&lt;p&gt;同样一行代码，在不同版本下的行为可能完全不同。&lt;/p&gt;

&lt;p&gt;至少说清楚：&lt;strong&gt;什么语言、什么框架、大概什么版本、在哪儿跑的（本地/服务器/浏览器）&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-28-ai-71-report-four-parts.png&quot; alt=&quot;report-four-parts&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;四最大的坑红字消失--问题解决&quot;&gt;四、最大的坑：红字消失 ≠ 问题解决&lt;/h2&gt;

&lt;p&gt;AI 有一个很强的倾向：&lt;strong&gt;它会优先给你”能让报错消失”的方案&lt;/strong&gt;，而不一定是”能让问题不再发生”的方案。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;下面这三种改法，都是典型的”假修好”：&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;假修好一把错误吞掉&quot;&gt;假修好一：把错误吞掉&lt;/h3&gt;

&lt;p&gt;给你套一层 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;try / catch&lt;/code&gt;（或者 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;try / except&lt;/code&gt;），把报错捂住不让它冒出来。&lt;/p&gt;

&lt;p&gt;红字确实没了。&lt;strong&gt;但那段逻辑其实根本没跑成功&lt;/strong&gt;，只是你看不见了。&lt;/p&gt;

&lt;p&gt;后果是：数据没存进去，你还以为存了。&lt;/p&gt;

&lt;h3 id=&quot;假修好二加个判空绕过去&quot;&gt;假修好二：加个判空绕过去&lt;/h3&gt;

&lt;p&gt;比如报错是”某个值是空的”，AI 给你加一句”如果为空就跳过”。&lt;/p&gt;

&lt;p&gt;问题是：&lt;strong&gt;它为什么会是空的？&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;如果它本来就允许为空，那这么改是对的；
如果它本该有值却没有，那真正的 bug 在&lt;strong&gt;更上游&lt;/strong&gt;——你只是把症状挡住了。&lt;/p&gt;

&lt;h3 id=&quot;假修好三强行转类型&quot;&gt;假修好三：强行转类型&lt;/h3&gt;

&lt;p&gt;报错说类型不对，AI 给你强制转一下。&lt;/p&gt;

&lt;p&gt;这跟上面同理：&lt;strong&gt;类型为什么会不对？&lt;/strong&gt; 这才是要问的。&lt;/p&gt;

&lt;hr /&gt;

&lt;p&gt;&lt;strong&gt;所以，AI 给完修改方案后，你必须追问三句话。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;我把它叫「&lt;strong&gt;修完必问三句&lt;/strong&gt;」：&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;这个错的根本原因是什么？&lt;/strong&gt; 请从触发到报错，按顺序讲一遍。&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;你这个改法是治标还是治本？&lt;/strong&gt; 如果是治标，治本该怎么改？&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;项目里还有没有别的地方，可能犯同样的错？&lt;/strong&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;第三句尤其值钱。&lt;strong&gt;一个 bug 出现的地方，往往不止一处。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/images/posts/2026-09-28-ai-71-fake-vs-real.png&quot; alt=&quot;fake-vs-real&quot; /&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;五按错误类型分档问法不一样&quot;&gt;五、按错误类型分档，问法不一样&lt;/h2&gt;

&lt;p&gt;不是所有报错都要走完整套流程。&lt;strong&gt;先分个档，省时间。&lt;/strong&gt;&lt;/p&gt;

&lt;h3 id=&quot;第一档一眼错30-秒解决&quot;&gt;第一档：一眼错（30 秒解决）&lt;/h3&gt;

&lt;p&gt;拼写错了、少个括号、变量名写错、忘了导入。&lt;/p&gt;

&lt;p&gt;这类错误消息通常很直白，&lt;strong&gt;AI 几乎不会答错&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;直接贴报错 + 那一行代码就够了，不用四件套。&lt;/p&gt;

&lt;h3 id=&quot;第二档环境错最烦人的一档&quot;&gt;第二档：环境错（最烦人的一档）&lt;/h3&gt;

&lt;p&gt;装不上、跑不起来、版本冲突、路径找不到。&lt;/p&gt;

&lt;p&gt;这一档的特点是：&lt;strong&gt;代码本身没问题，问题在外面。&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;贴的时候一定要重点给「境」：&lt;strong&gt;操作系统、语言版本、安装命令、完整的安装日志&lt;/strong&gt;。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;提示：这一档特别容易踩到”网上抄的方案是别人环境下的”。让 AI 明确告诉你&lt;strong&gt;每条命令是干什么的&lt;/strong&gt;，别闭眼执行。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;第三档隐蔽错要走完整流程&quot;&gt;第三档：隐蔽错（要走完整流程）&lt;/h3&gt;

&lt;p&gt;程序跑得好好的，某个特定条件下才炸。&lt;/p&gt;

&lt;p&gt;这一档必须上四件套，&lt;strong&gt;而且「做」这一项最关键&lt;/strong&gt;——你要说清楚&lt;strong&gt;什么情况下会出、什么情况下不出&lt;/strong&gt;。&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“输入正常数据没问题，一旦名字里带空格就报错。”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;这一句话的价值，超过一百行代码。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;六还有一招让-ai-教你自己看&quot;&gt;六、还有一招：让 AI 教你自己看&lt;/h2&gt;

&lt;p&gt;如果你想真的进步，而不是每次都当伸手党，&lt;strong&gt;加一句话就行&lt;/strong&gt;：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;“修改之后，请再告诉我：以后遇到同类报错，我自己该怎么一眼看出问题在哪？”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;AI 会给你一套”识别特征”。&lt;/p&gt;

&lt;p&gt;积累十几条，&lt;strong&gt;你会发现大部分报错你自己扫一眼就知道原因了&lt;/strong&gt;。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;提示词模板盒子&quot;&gt;提示词模板盒子&lt;/h2&gt;

&lt;p&gt;以下模板可直接复制使用，把【】里的内容换成你自己的。&lt;/p&gt;

&lt;h3 id=&quot;模板-71-1贴报错四件套万能主模板&quot;&gt;模板 71-1：贴报错四件套（万能主模板）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;我遇到一个报错，需要你帮我定位并修复。

【① 错 —— 完整报错原文】
（从头到尾原封不动粘贴，不要删改、不要转述）

【② 码 —— 出错的代码】
（报错指向的那一行，及前后各 15 行；能贴整个函数更好）

【③ 做 —— 我是怎么触发的】
我做了：（例如：在页面点了&quot;提交&quot;按钮）
当时的输入是：（例如：手机号那栏是空的）
什么情况下不会出现：（例如：填了手机号就正常）

【④ 境 —— 环境信息】
语言/框架：  版本：  运行方式：（本地/服务器/浏览器）  操作系统：

请按以下顺序回答：
1. 这个报错的中文意思是什么（大白话）
2. 根本原因是什么，从触发到报错完整讲一遍
3. 给出修改后的完整代码，标出改动了哪几处
4. 说明这是治标还是治本

我是编程新手，请不要用没解释过的术语。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;环境类报错&lt;/strong&gt;：在「④ 境」里重点给操作系统、语言版本、安装命令和&lt;strong&gt;完整安装日志&lt;/strong&gt;，并让 AI 说明每条命令是干什么的、别闭眼执行（原模板 71-4）。
▸ &lt;strong&gt;偶发 bug（时好时坏）&lt;/strong&gt;：在「③ 做」里写清”什么情况下会出现、什么情况下不会、多久出现一次”，附上报错原文和相关代码，让 AI 按可能性列原因并给验证动作（原模板 71-5）。&lt;/p&gt;

&lt;h3 id=&quot;模板-71-2读懂错误栈看不懂那一坨时用&quot;&gt;模板 71-2：读懂错误栈（看不懂那一坨时用）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;下面是一段报错的完整堆栈信息，我看不懂。

请帮我拆解：
① 错误类型和错误消息是哪一行？中文意思是什么？
② 这一坨里，哪几行是我自己的代码，哪几行是库/框架内部的？分别列出来。
③ 我应该重点看哪一行？为什么？
④ 从这段信息能推测出，出事时哪个变量是什么值？

报错原文：
【粘贴完整报错】
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;模板-71-3修完必问三句防假修好&quot;&gt;模板 71-3：修完必问三句（防假修好）&lt;/h3&gt;

&lt;div class=&quot;language-plaintext highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;关于你刚才给的修改方案，我要确认三件事：

① 这个 bug 的根本原因到底是什么？
   请从&quot;用户做了什么&quot;开始，一步步讲到&quot;为什么会报错&quot;。

② 你的改法是治标还是治本？
   如果只是让报错不再出现、但根因还在，请明说，
   并告诉我治本应该怎么改。

③ 我的项目里，还有没有别的地方可能犯同样的错？
   请告诉我该用什么关键词去搜索排查。
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;▸ &lt;strong&gt;顺便学会自己看&lt;/strong&gt;：修好后加一句——”以后遇到同类报错，我自己该怎么一眼看出问题在哪？”让 AI 给你一套识别特征，抄进笔记（原模板 71-6）。&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;速查一屏红字先看这三处&quot;&gt;速查：一屏红字，先看这三处&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;步&lt;/th&gt;
      &lt;th&gt;看什么&lt;/th&gt;
      &lt;th&gt;回答什么&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;①&lt;/td&gt;
      &lt;td&gt;错误类型 + 消息（Python 看最后一行，JS/Java 看第一行）&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;是什么错&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;②&lt;/td&gt;
      &lt;td&gt;栈里带&lt;strong&gt;你自己文件名&lt;/strong&gt;的那一行&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;错在哪&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;③&lt;/td&gt;
      &lt;td&gt;消息里出现的具体值 / 变量名&lt;/td&gt;
      &lt;td&gt;&lt;strong&gt;为什么&lt;/strong&gt;&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;blockquote&gt;
  &lt;p&gt;路径里带 &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;node_modules&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;site-packages&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;vendor&lt;/code&gt;、&lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;dist&lt;/code&gt; 的，一律先跳过。&lt;/p&gt;
&lt;/blockquote&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;速查三档报错投入不一样&quot;&gt;速查：三档报错，投入不一样&lt;/h2&gt;

&lt;table&gt;
  &lt;thead&gt;
    &lt;tr&gt;
      &lt;th&gt;档&lt;/th&gt;
      &lt;th&gt;典型表现&lt;/th&gt;
      &lt;th&gt;该怎么贴&lt;/th&gt;
    &lt;/tr&gt;
  &lt;/thead&gt;
  &lt;tbody&gt;
    &lt;tr&gt;
      &lt;td&gt;一眼错&lt;/td&gt;
      &lt;td&gt;拼写、括号、忘导入&lt;/td&gt;
      &lt;td&gt;报错 + 那一行，30 秒搞定&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;环境错&lt;/td&gt;
      &lt;td&gt;装不上、跑不起、版本冲突&lt;/td&gt;
      &lt;td&gt;重点给&lt;strong&gt;「境」&lt;/strong&gt;+ 完整安装日志&lt;/td&gt;
    &lt;/tr&gt;
    &lt;tr&gt;
      &lt;td&gt;隐蔽错&lt;/td&gt;
      &lt;td&gt;平时正常，特定条件才炸&lt;/td&gt;
      &lt;td&gt;上&lt;strong&gt;全套四件套&lt;/strong&gt;，重点写「做」&lt;/td&gt;
    &lt;/tr&gt;
  &lt;/tbody&gt;
&lt;/table&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;最后&quot;&gt;最后&lt;/h2&gt;

&lt;p&gt;这一篇的核心，压缩成一句话：&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;红字消失，不代表 bug 修好了。&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;判断标准只有一条——&lt;strong&gt;你能不能说清”它原本为什么会变成那个值”&lt;/strong&gt;。&lt;/p&gt;

&lt;p&gt;说得清，是真修好；说不清，只是把问题往后拖了几天。&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;而要说得清，前提是你给了 AI 足够的证词：错、码、做、境。&lt;/strong&gt;&lt;/p&gt;

&lt;hr /&gt;

&lt;h2 id=&quot;下篇预告&quot;&gt;下篇预告&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;第72篇《让 AI 定位逻辑错误——没有红字也能查》。&lt;/strong&gt; 下一篇讲更难的：程序跑得欢、结果却不对，一个红字都没有——不报错的 bug，才是真正吃时间的那一类。我们下篇见。&lt;/p&gt;</content><author><name>VF</name></author><summary type="html">一屏红字，你只复制了第一行。</summary></entry></feed>