我真正开始觉得 Claude Code 好用,是放弃“把它当搜索引擎”之后。刚上手那阵子,我也习惯遇到问题就丢一句话过去:“帮我看看这个报错”“优化一下这段代码”“这里不太对,你改改”。听上去没什么毛病,但用过一段时间就会发现,它的输出时好时坏:有时候一个指令能帮我省半小时,有时候改出来的代码让我连夜回滚。
后来我把出过问题的那几轮对话翻出来逐条复盘,发现大多数翻车都不是工具本身不行,而是我用错了方法。这篇文章就把这几个月的真实经验整理成 8 条黄金法则,每条背后都有对应的“代价”案例。适合刚接触 Claude Code 的开发者,也适合已经用了一段时间、但总感觉效率忽高忽低的朋友。先说明一点:这不是官方文档式的最佳实践,也不是什么玄学技巧,就是我在真实项目里踩坑踩出来的协作规范。
1. 先搞懂 Claude Code 的底层脾气,再谈最佳实践
1.1 它不是搜索引擎,而是一个没有项目记忆的结对搭档
很多人对 Claude Code 的最大误解,是把它当成一个“什么都知道的问答机器人”。实际上,它更像一个能力很强、但没有项目记忆的新同事:你把它叫到工位旁边,它只能看到你当前贴在它面前的内容,以及上下文里讨论过的东西。它不会自己去翻你三个月前的架构文档,也不会自动记住你昨天在另一个会话里跟它确认过的命名规范。
这一点直接决定了所有黄金法则的走向。我见过很多同事抱怨“它怎么老改错地方”,一问之下,通常是只给了一句“帮我修一下那个 bug”。这句话里既没有文件路径,也没有报错信息,更没有“这个模块最近刚重构过”的背景。它对项目的理解全靠你提供的信息量,你给的上下文越像一份交接文档,它干出来的活就越像一个人真的在工位上思考过。
这也解释了为什么同一个问题,不同人用 Claude Code 得到的结果天差地别。不是运气问题,而是你给它的“输入包”质量差别太大。想让它输出高质量结果,第一步不是学更多技巧,而是意识到:任何它不知道的信息,你都得主动喂进去;任何你懒得交代的背景,最后都会变成它替你瞎猜的素材。
1.2 上下文是硬通货:你的每一次追问都在花掉“工作记忆”
还有一个经常被忽略的物理约束:上下文窗口。Claude Code 的工作记忆是有限的,每次对话都会消耗这个窗口,早期说的内容会被慢慢“挤”出去。你可以把它想象成一张白板,写满了就必须擦掉旧内容才能写新内容。当对话进行到后半程,你最初贴进去的那段报错、那份需求说明、那个目录结构,可能已经被它忘得差不多了。
这个机制解释了三个常见现象。第一,对话越长,它越容易“回答得一本正经但完全不记得最初的需求”;第二,你在一个会话里塞了太多无关杂事之后,它处理核心任务的能力会明显下降;第三,当你新开一个会话、把背景重新交代一遍之后,它的表现通常又恢复正常了。这不是它“状态不好”,而是它的工作记忆被消耗光了。
所以,你能不能用好 Claude Code,本质上取决于你会不会管理上下文空间。8 条黄金法则里有好几条都在围绕这件事打转:给足坐标是为了让信息花在刀刃上,一次只做一件事是为了不让杂音挤占记忆,会话冷却则是主动清空白板。理解了这一节,后面每一条法则就都有了逻辑支点。
2. 法则一至四:把任务需求翻译成 AI 高效识别的语言
2.1 法则一:给足“项目坐标”,杜绝大海捞针式提问
第一条法则听起来像废话,却是我见过翻车率最高的错误:提问时不给任何坐标。所谓坐标,至少包含三样东西:文件路径、具体现象、期望行为。如果你能再补充“这个文件的代码结构大概什么样”或者“最近这块代码有没有大改过”,效果会再上一个台阶。
我自己的标准模板是这样的:
在 src/services/user.ts 里,login 方法需要处理密码错误的情况。现在密码错误时后端返回 401,但前端拿到后直接进了 catch 分支,页面上没有提示信息。期望:401 时在表单下方显示“密码或账号错误”,其余错误仍然走原来的逻辑。相关代码片段我贴在下面:```ts // ...贴出关键代码片段
对比一下常见的提问方式:“登录报错了,帮我看看。”后者不是不能处理,但它需要大量来回追问才能锁定文件位置和问题细节,这些追问全部在消耗上下文窗口。而前者一次到位,它可以直接进入思考环节,产出可用的修改建议。
补充一个细节:贴代码片段时,不用把整个文件贴进去,截取与问题直接相关的十几行到几十行就够了。贴太多无关代码同样会挤占工作记忆,反而让它在细节里迷失重点。这条法则的本质是“用你的领域知识替它缩小搜索空间”,它知道得越精准,猜错的概率就越低。
2.2 法则二:一次只下一个任务,拒绝模糊的任务堆叠
我见过最典型的低效用法,是把三四个任务塞在一句话里,比如:“帮我优化一下登录逻辑,顺便把样式也调了,再看看接口性能有没有问题。”Claude Code 可以执行长任务,但面对这种多目标指令,它的注意力会变得分散:改了逻辑,又顺手改样式,中间还夹杂着性能分析,最后每一步都做得不够彻底,甚至互相干扰。
我现在的做法很明确:一次只让它做一件能被明确判定“完成还是没完成”的事。任务粒度怎么判断?你可以问自己一个问题:做完这件事之后,我能不能立刻写出一句验收描述?如果不能,说明任务太大,得拆。比如“优化登录逻辑”就不是一个合格任务,它缺乏验收标准;但“修复密码错误时前端无提示的问题”就是一个合格任务,因为你可以明确检验。
大功能一定要拆开做。我会在动手前先写一个任务清单,比如:
- 修复登录接口 401 时的前端提示
- 给登录表单的错误文案做个统一出口
- 顺手检查登录接口是否存在重复请求
然后按顺序逐条丢给它。每完成一条,检查一条,再开始下一条。这样做的另一个好处是:一旦中途出了问题,你能立刻知道是哪个任务的改动引起的,回退成本低得多,不会出现“改了三轮不知道是哪一轮搞坏的”的情况。
2.3 法则三:描述“验收标准”,而不是“实现方案”
这条法则我花了好几周才真正理解。早期我总喜欢替它设计实现方案,比如“你在这个函数里加个 if 判断,返回值改成对象”。结果是它确实照做了,但写出来的代码和旁边的模块风格完全不一致,或者在边界条件上漏洞百出。后来我才明白,我应该告诉它的不是“怎么实现”,而是“什么结果算完成”。
对比一下这两种说法:
- 错误示范:“帮我加个密码长度检查,8 位以下的直接 return 一个对象。”
- 正确示范:“当密码长度小于 8 位时,提交表单后页面显示‘密码长度不能少于 8 位’,并且不发请求。其他校验逻辑保持不变。”
第二种说法更啰嗦,但它给 AI 留出了实现自由:它可以自己决定是在前端校验、在提交函数里拦截,还是用表单库的规则体系。更重要的是,验收标准本身是一种“测试用例”,它能用这个标准来检查自己的输出是否达标,而不是机械地执行你指定的局部代码。
所以我会刻意训练自己:在发指令前,先在脑子里把验收标准写出来。如果你发现自己组织不出清晰的验收标准,那大概率不是你话术不行,而是你根本还没想清楚自己要什么。这时候不要急着开口,先把需求想明白再动手,比反复折腾 AI 高效得多。
2.4 法则四:删除和重构之前,强制 AI 先交一份“动刀计划”
这条法则专门用来防止 AI 的“热情过度”。Claude Code 在收到“删掉这段代码”或“重构这个模块”之类的指令时,有时候会超出你预期的范围,顺手改掉它认为“相关”但你没让它动的地方。这事儿我第一次遇到时挺崩溃的:我让它清理一个没用的旧接口,结果它把调用这个接口的三个文件里的相关逻辑也一并改了一遍,CI 直接红了一片。
后来我给自己定了一条铁律:涉及删除、重构、批量化改造之前,先让它输出一份“动刀计划”,包含改动范围、涉及文件、风险点和回滚方案。计划确认无误后,再让它执行。这个习惯在多人协作的代码库上尤其重要,因为你永远不知道某个看似无用的代码,是不是有哪个隐蔽入口还在引用。
我现在常用的话术长这样:
计划将 src/utils/format.ts 里的 dateFormat 相关函数迁移到 src/lib/date.ts,并在原位置保留 re-export 以兼容旧引用。请先列出:1. 需要迁移的所有函数名;2. 引用方有哪些文件;3. 这次迁移可能影响的行为变化;4. 你的回滚方案。确认后再执行。
别小看这一步。它相当于给 AI 装了一个刹车,让它从“闷头干活”模式切换到“带方案的干活”模式。执行效率看起来变慢了,但出错率下降得非常明显,尤其是重构这类高风险操作,省下来的返工时间远超那几分钟计划时间。
3. 法则五至八:管理输出质量,阻止代码悄悄失控
3.1 法则五:提交前反向走读 diff,先看删了什么
AI 生成的代码,你如果不看就提交,大概率会埋雷。这个“雷”不一定是语法错误,更多时候是“它删了你没意识到被删的代码”。所以我给自己立了一条规矩:任何 AI 参与改动的代码,提交前必须走读 diff,而且顺序要反过来——先看删了什么,再看加了多少。
“先看删了什么”这个习惯有用,是因为 AI 经常在“优化”的名义下做一些你以为它不会做的事。比如它会觉得某个变量“看起来没人用”就顺手删了,但真实情况是它没注意到这个变量在另一个分支里被引用了。这类问题在走读新增代码时几乎发现不了,因为新增的代码自己看起来往往是自洽的;只有盯着删除列表,你才会追问“为什么这段被删了”。
具体操作上,我用的是轻量级的 diff 命令(具体命令文本我在后面章节给)。走读的时候给自己提三个问题:
- 这些删除是我当初要求删除的吗?
- 新增的每一段代码,我能否向同事解释清楚它为什么在这里?
- 有没有哪次删除是我无法判断影响的?如果有,立刻回滚或补上测试验证。
任何一条答不上来,我就不会提交。不要嫌这个过程麻烦,AI 生成代码的速度很快,但库里的 bug 一旦上线,修复成本是提交前检查的十倍以上。走读 diff 不是对 AI 的不信任,而是对自己负责。
3.2 法则六:小步验证,禁止“大爆炸式重构”
“让 AI 重构整个模块”是很多人的终极浪漫:给它一个大任务,期待它一口气把遗留代码改得干干净净。实际上,这种大爆炸式重构的成功率极低,因为 Claude Code 对代码库的理解永远是局部性的,它看不到你整个系统的隐式依赖。模块越大,它越容易在一个局部优化得很漂亮,却在另一个看不见的角落踩断依赖。
我踩过最大的一个坑,就是让它重构过一整个认证模块,大约涉及十几个文件。它给出的代码风格统一、结构清晰,看起来非常专业。结果一跑测试,关联的权限系统、日志系统、甚至消息队列的消费者全部报错,最后花了一个周末才全部修回来。
从那以后,我的原则变成了:每一步改动都要能独立验证。先让它改一小部分,立刻运行相关测试或构建,确认没问题,再继续下一步。如果需要修改多个文件,我也会要求它分批次交付,每个批次之间保持功能可用。这套“小步快跑”的思路,和写代码时的“小提交”理念一模一样:改动的粒度越小,出问题的范围就越可控,AI 也越容易在稳定的基线上迭代出可靠结果。
3.3 法则七:任务切换即会话冷却,让 AI 的短期记忆清零
像前面说的,上下文窗口有限,而旧内容会污染新任务。所以,当完成一个独立任务、准备开始下一个任务时,我几乎一定会做一件事:新开一个会话,把新任务的背景从零交代一遍。这个习惯最初让我觉得有点浪费,毕竟刚才是同一个项目、同一段代码,为什么不能接着聊?
原因是:之前那个会话里充满了旧任务的痕迹——它当时的思考过程、你当时给的补充说明、中间几次偏离方向又拉回来的讨论。这些痕迹在新的上下文里就是噪声。你问它新问题,它的判断会不由自主地带有旧任务的偏向,甚至可能“以为”你还在讨论旧功能。新开会话等于给它按了重启键,让工作记忆回到一张干净的白板。
但是,直接新开会话又有个问题:项目背景信息不就丢了吗?我的做法是,维护一份极简的“项目备忘”文档,每次开会话前先花 30 秒扫一眼,把该交代的背景浓缩成一两句贴进去。这份备忘只记录稳定的、长期有效的信息,比如项目根目录结构、关键模块的位置、当前任务的验收标准等。短期信息我会在每条指令里带上,长期信息放在备忘里,避免每次重复交代。
3.4 法则八:用一份常量规范文件给 AI 装上“长期记忆”
说到项目备忘,这就是第八条法则的核心:给 Claude Code 建立一份“常驻记忆”文件,让它在会话一开始就能看到你项目里的长期约定。文件内容不强求很多,但一定要是你真正希望它每次都能遵守的规则。我的做法是在项目根目录放一个约定说明,里面写清楚项目结构、命令、编码规范,以及绝对不能碰的坑。
这份文件的价值不只是省打字。更重要的是,它能帮你约束 AI 的“默认行为”。比如我会在文件里明确写:所有新增函数必须写单元测试;禁止直接修改 src/core 目录下的文件;提交信息使用英文祈使句开头。这些规则如果每次重新交代,AI 很容易漏掉,但如果是常驻文件里第一条就写着,它每次启动工作前都会先读一遍,相当于给 AI 装了项目级的长期记忆。
文件内容怎么写,我建议从你自己的痛处出发:最想让 AI 记住的那个约定,写在最前面。不用追求大而全,先写五条以内、能落地、可验证的规则。等跑一段时间,你发现它老是犯某类错误,就把对应的规则补进去。这份文档是活的,它会随着你对项目理解的加深而生长。
4. 三个典型的“越用越乱”翻车现场复盘
4.1 翻车现场一:反复试探同一问题,撑爆上下文
有个项目我给一个临时功能做排查,第一次提问后它的诊断方向不太对。我不懂先停下来换思路,而是连续追了五六轮,每一轮都带着新的假设去问,前前后后贴了一大堆日志片段。结果对话到了后半程,它开始自相矛盾,先是说问题在 A 模块,后来又说是 B 模块,最后甚至建议重写整个服务。
复盘之后我意识到,问题出在我把上下文窗口耗光了。每一轮追问、试错、讨论,都在消耗工作记忆。到后面它已经没有足够空间容纳最初的报错信息和关键日志了,只能在越来越模糊的语境里“硬答”。它的回答看似严谨,实则是在信息残缺的状态下做了最不坏的猜测。
从那以后,我再遇到“第一轮方向不对”的情况,第一反应是停下来,而不是继续追问。冷静几秒,重新组织一下背景信息,把之前对话里确认过的有效结论提炼出来,丢进一个新会话里,重新开始。这个“冷静后重开”的周期通常只需要几分钟,比在乱麻一样的旧对话里继续缠斗高效得多。
4.2 翻车现场二:全盘接受 AI 重构建议,依赖链连环炸
那次重构刚开始时很顺利,Claude Code 给出的新代码结构清爽、命名规范,测试也能通过。我当时一高兴,就把它提出的十几个文件的改动全部接受了。结果两天后,另一个团队的同学跑过来问我:为什么某内部库的导出变了?我一脸懵,回头查才发现,AI 在“重构”过程中顺手调整了公共模块的导出结构,而这个公共模块是别的服务也在用的。
现在我会强调:AI 能看到的依赖范围,几乎不可能覆盖全仓库的真实依赖链。它擅长的是局部代码的语义优化,而不是跨模块、跨服务的依赖关系梳理。所以,接受建议之前必须自己核对引用方。尤其是涉及公共工具函数、配置文件、API 层这类被多处引用的代码,任何建议性调整都要一票否决、单独评估。重构这种活儿,主动权永远不能完全交给 AI。
4.3 翻车现场三:危险操作不设权限边界,批量替换误伤配置
最惊险的一次,是让它批量替换一个旧的配置变量名。它在代码库里做了全局替换,代码本身没问题,但连带着把几个配置文件里的同名变量也一并改了,而这些配置项是部署环境在用的。结果测试环境的配置解析直接失败,服务起不来。排查的时候我看到它弹出的修改清单里列了二十几个文件,当时忙着节省时间,扫了一眼就确认了。
从那以后,凡涉及全局替换、批量改动、删除文件之类的操作,我都要先让它列出全部改动清单,然后逐个人工确认影响范围,不确认就不放行。更稳妥的办法是把它能操作的“危险命令”彻底禁掉,尤其是那些不经过项目脚本就直接改全局配置的命令。别怕麻烦,在这种场景下,慢就是快。
下面汇总一下这三个现场对应的对策,方便你对照自查:
| 翻车场景 | 典型错误 | 根本原因 | 对策 |
|---|---|---|---|
| 反复追问导致前后矛盾 | 在旧会话里持续试错,有效信息被挤占 | 没有空余的工作记忆 | 及时重开会话,提炼有效结论重新喂入 |
| 全盘接受大规模重构 | 公共模块导出被擅自改动 | 对项目依赖链缺少全局感知 | 接受前核对引用方,一票否决公共代码调整 |
| 危险操作不设权限 | 全局替换误伤配置文件 | 没有对操作范围设边界 | 强制列出改动清单,人工确认后方可执行 |
5. 把八条法则串进一个工作日:我的实战节奏参考
5.1 开工前:先让 AI 出一份“项目体检报告”
每天早上开工之前,我会先让 Claude Code 读一遍项目的当前状态:跑一遍测试命令,扫一眼最近的改动文件,让它把可能存在的问题列一个优先级排序。这个动作看着花时间,其实很值,因为它能让我在一开始就抓到昨天遗留下来的问题,而不是等到下午才被 CI 打醒。
具体来说,我会给它这样一个指令:
请先运行 npm run test,如果测试失败,按“阻塞性问题、高风险问题、低风险问题”三个级别整理结果。然后扫描 git log 里最近 5 次提交的改动文件,列出与你刚才看到的测试结果相关的改动。最后用一句话概括:今天开工前需要优先处理什么?
这一步同时用到了前面说的法则一(给足坐标)和法则八(常驻规范文件里记录了测试命令和 git 信息)。一份干净的项目体检报告,能让我在喝第一口咖啡的时候就找准今天的主战场。
5.2 开发中:一个功能模块的标准协作流程
一个功能从需求到落地,我的协作节奏是固定的,每一步都对应着前文某条法则。
第一步,把需求写成验收标准清单,不急着讨论实现。第二步,把清单连同相关文件路径一起交给 AI,请它按清单逐项实现,但限定“一次只做清单里的第一项”。第三步,它在动手设计之前,先让它简要说明实现思路,我看完觉得没问题再让它写代码。
第四步,写完一部分后让它跑相关测试,确认通过再继续下一项。第五步,全部完成后,整份 diff 反向走读一遍,先看删除再看新增,改动全部能解释才提交。这五步串起来听起来流水账,但真正执行起来非常高效,因为每一步都避免了“事后返工”——AI 不会因为理解错了需求而白写几百行,我也不会因为漏了审查而事后补锅。
5.3 收工后:把今天的对话沉淀成明天的上下文
到了收工环节,我会多花最后五分钟做一件看起来不太起眼的事:把今天对话里确认过的结论、遇到的坑、以及处理方式,浓缩成几条摘要写进项目备忘文件。比如“今天确认了 format 函数的迁移不能动 re-export”“新增了 SMS 接口的 mock 配置”这类信息,明天新开会话时只要看一眼,就不用重新踩一遍今天的坑。
这一步对应的正是法则八的“长期记忆”思路。你每次让 AI 记住一点重要信息,它未来的行为就会越来越贴合你的项目习惯。对我来说,这个归档动作甚至比写代码本身更重要,因为它把今天踩出来的经验变成了项目资产。日子久了,这份备忘文件就是我个人的“人工智能协作黑历史簿”,坑踩得越多,它越值钱。
最后再分享一点个人体会吧。这 8 条法则不是什么高深理论,本质上是把“如何跟一个能力很强的实习生协作”的经验迁移到了 Claude Code 身上:给够背景、说清标准、约定边界、及时检查、沉淀经验。一开始执行起来可能觉得不太自然,尤其是走读 diff 和写计划这两步,会觉得“多此一举”。但只要坚持一两周,你会发现返工次数肉眼可见地往下掉,那种“AI 时灵时不灵”的玄学感也会慢慢消失,取而代之的是一条稳定、可控、效率越来越高的协作节奏。工具没有变,变的是你用它时的章法。