照着做就行,但理解为什么这么做更重要

上一篇讲了怎么把一条指令写清楚,这一篇把那些原则落到每天真实会遇到的几类任务里。不是给你一张"任务类型对应模板"的大表——那样你背一百个模板也没用——而是把每类任务背后的思路讲透,让你自己能组合出合适的 Prompt。

修 Bug:先定位,再加失败测试,最后动手

Bug 修复最容易翻车的时刻,是你还没搞清原因就让 Agent 开始改代码。它会按症状猜一个最像的原因、顺手改几处"相关"的地方,跑个似是而非的验证就交差。等你回头看 diff,已经分不清哪些是修 bug、哪些是它顺手"优化"的,测试也可能只是绕开了现象而没触及根因。

所以一个可靠的 bug 修复流程应当被显式地写进 Prompt:先让它告诉你根因在哪个文件哪一行,再写一个能复现这个 bug 的失败测试,然后修复,最后跑一次完整测试套件确认没有连带破坏。禁止它顺手重构其他代码——这条必须明说,因为 Agent 对"看着别扭就顺手改掉"有天然偏好。

一个拿来就能用的骨架:

修复 bug:订单页刷新后购物车偶尔变空

复现:
1. 加一个商品到购物车
2. 访问 /cart
3. F5 刷新 3-5 次

报错:无报错,数据直接丢失

背景:购物车状态用 Zustand + persist 中间件存 localStorage

步骤:
1. 读 stores/cart.ts 分析可能的根因,先告诉我
2. 加一个能复现该现象的失败测试
3. 修复,让测试由红变绿
4. 跑 pnpm test 确认没有破坏其他用例
5. 不要修改其他无关代码

这个结构里最反直觉的一条是"先加失败测试"。它的价值不是测试本身,而是逼你(和 Agent)把现象转化成一个可验证的断言——很多看似诡异的 bug 在写复现用例的时候就水落石出了。

加功能和重构:都要先进 Plan Mode,分阶段推进

新功能和重构在 Claude Code 里的处理节奏很像:先 Shift+Tab 进 Plan Mode 让它出方案,你审完再执行。它们的共同特征是"决策点多"——数据结构怎么设、API 契约长什么样、旧代码动到哪一层、测试怎么不破——一口气写完,中间任何一个决策拐弯都可能让后面全部白做。

新功能的推进通常分四段:先只设计数据模型和 API 契约不写实现、确认后写后端和校验、然后写前端和页面、最后串起来联调。每段收尾处 Agent 停下来等你反馈,这比它一口气跑二十分钟回来全错要划算太多。

重构则有一条必须守住的黄金规则:现有测试必须通过。如果项目根本没测试,第一步不是重构,而是让它写 3 到 5 个覆盖主要行为的测试先——这就是经典的 characterization test 做法,Claude Code 尤其擅长。测试跑通之后再开工,并要求一次只做一类变更、每动完一个模块跑一次测试。否则重构途中出问题你会完全无从定位是哪一步引入的。

一个典型的重构指令会这样写:

[先 Shift+Tab 进 Plan Mode]

把 components/orders 下的 class 组件改成 hooks。

范围:components/orders/*.tsx
要求:
- 外部行为不变(API 调用、props、UI 都不动)
- 现有测试必须全部通过
- 一次只处理一个组件,改完就跑 pnpm test
- 先列所有要改的文件和改法,我确认后再开始

写测试:防止"假测试"的一句咒语

让 Agent 补测试是它最擅长、也最容易敷衍的任务。典型的敷衍长这样:expect(result).toBeDefined()expect(fn).not.toThrow()——看着一屏绿,实际上几乎什么都没验证。这种断言在任何 bug 面前都不会失败,属于测试噪声。

解法是把标准写死到 Prompt 里:"测试必须断言具体的值、具体的字段形状、具体的错误类型,不允许只测'没抛错'或'不为 undefined'"。顺带要求它先列出打算覆盖哪些场景——正常路径、边界值(空、null、超长、负数)、异常路径——等你点头后再动手。场景清单这一步可以砍掉大量之后返工的时间。

框架选择交给现状:让它先翻一眼 tests/ 目录,按现有文件的风格仿写。每个项目的测试习惯都不一样,强行指定反而会写出跟项目格格不入的风格。

读代码、审代码、写文档:Agent 被低估的三件事

接手一个陌生项目时,与其啃 README,不如直接问:"给我一页纸的架构总览——模块职责、数据流、核心抽象(哪些函数改动会牵动一大片)、看起来奇怪但八成有历史原因的地方、以及我该从哪个文件开始读。" 这个提示相当于让 Agent 替你做一次项目考古,效率是人工翻代码的十倍不止。

代码 Review 也是同一类任务的变体。让它看 git diff main...HEAD,重点问有没有明显 bug、漏掉的边界情况、和项目其他部分的风格一致性,以及是否有更简单的写法。有一条要明确:"只指出具体问题,不要给'可以考虑加注释'这种模糊建议"——否则它会用一堆不痛不痒的评论填满响应。

补文档则要反过来约束它别改代码:"只给导出函数加 JSDoc,包含一句话用途、参数、返回值、一个示例,代码逻辑一行都不要动。" 没有这条约束,它大概率会顺手"优化"几处实现。

交给它走完 Git 流程

修完 bug 或写完功能后的收尾工作——分组、写 commit、开 PR——是 Agent 最熟悉的流水线活之一。一条命令可以打包:

我改完了。请:
1. git status 看当前状态
2. 按主题把改动分成独立 commit(每个 commit 单一意图)
3. 写 commit message,用项目一贯的中文 + conventional commits 风格(参考最近几条提交)
4. gh pr create 开 PR,标题简洁、正文说明动机和测试情况

它会实际调用 gh CLI 把 PR 开出来。这个阶段唯一要提醒的是:push 之前让它先 git log 看一下当前分支和 main 的差距,避免误推到错误分支——这也是为什么上一篇强调永远不要让它自动执行 push --forcereset --hard

一劳永逸:放进 CLAUDE.md 的安全网

上面每个场景里反复出现的几条约束——不要顺手改无关代码、破坏性 Git 操作要先问、不清楚就问不要猜——其实不该每次都写在 Prompt 里。把它们写进项目根目录的 CLAUDE.md,每次会话自动生效:

## 给 Claude Code 的规则
- 改多个文件或删除文件前,先列出计划让我确认
- 破坏性 Git 操作(push --force、reset --hard、branch -D)一律不要自动执行
- 不要通过修改测试来让它通过
- 不清楚的地方先问,不要猜
- 每个任务完成后主动跑一次 lint 和 test
- 回复用中文

有了这层安全网,日常 Prompt 就可以写得更松——焦点放在任务本身,约束交给配置文件。

下一篇讲 Claude Code 的几样进阶武器:Slash Commands、Hooks、Subagents、MCP。它们让这套工作流从"每次手写 Prompt"升级到"把常用动作变成一个命令或一个协议"。

参考资料

版权声明: 如无特别声明,本文版权归 sshipanoo 所有,转载请注明本文链接。

(采用 CC BY-NC-SA 4.0 许可协议进行授权)

本文标题:日常工作流:Bug 修复、新功能、重构、测试

本文链接:https://www.sshipanoo.com/blog/ai/claude-code/08-日常工作流/

本文最后一次更新为 天前,文章中的某些内容可能已过时!