面试官坏笑:“你用 AI 编程半年了,那怎么保证 Claude Code 写出来的代码是对的?”我:“直接用 Claude Opus 4.8!”
本文是转载我是留个档。完整文章请看https://mp.weixin.qq.com/s/NCzHo4SxcuYOueyq2Q-2NQ你好我是小 G。上个周末我通过文字消息分享了一些 Vibe Coding 的小技巧不少 G 友反馈说分享的经验非常有用甚至要把我的建议做成一个 skill。还有一些朋友非常想要详细版。Vibe Coding 技巧分享读者评论Vibe Coding 技巧分享读者评论于是我爆肝了一篇前后反复优化完善很多遍把我这几年所有积累的 AI 编程经验都总结分享了出来真心希望对你有帮助。正文开始之前想问问大家你还记得自己第一次 Vibe Coding 的感觉吗我反正是特别上头24 年第一次接触 Cursor真是惊为天人。那种感觉就像小时候刚接触游戏一样但比游戏还爽一些。每天最开心的事情就是 Vibe Coding看着代码一行一行被自动写出来。就感觉自己一天做的事情比过去一周还要多。那段时间是真的游戏都不想碰了就想着 AI 能帮我多干点活。但爽完之后翻车情况也越来越多经常会遇到一些莫名其妙的问题。这让我意识到单纯凭感觉去 Vibe Coding 是不太可行的。下面这些是小 G 这几年用 AI 编码踩出来的一些经验。不花哨但都挺管用。概览图片先把 Git 准备好如果只选一个最重要的 Vibe Coding 技巧小 G 会选 Git。原因很简单AI 写错一行代码不可怕可怕的是它一口气改了 20 个文件等你发现方向不对已经不知道哪一块该留、哪一块该扔。Git 不是写完代码之后再补的仪式它应该站在 AI 动手之前。让 Agent 改代码前先看工作区git status --short如果当前目录里已经有改动先弄清楚这些改动是谁的、要不要保留。多人协作或多 Agent 并行时这一步尤其重要。不要让 AI 回滚它没写的东西也不要把别人的半成品混进自己的任务里。确认干净后再给当前任务单独开分支git switch -c feat/order-export任务很小也建议开分支。主分支上裸跑 Vibe Coding心理负担会越来越大分支隔离之后AI 就算写歪了也只是当前任务分支的问题。AI 改完后别急着看它的总结先看仓库自己怎么说git diff --statgit diffgit diff --stat 看影响面git diff 看细节。确认没问题之后再分块暂存和提交git add -pgit commit -m “feat: add order export”一个提交只做一件事。能分块提交就分块提交后面 Review、回滚、定位问题都会轻很多。AI 说“我只改了导出逻辑”不如 diff 可信。改坏了也尽量用可控回滚丢弃某个未提交文件的修改git restore path/to/file撤销已经暂存的文件git restore --staged path/to/file已经提交并推送过优先生成反向提交git revertgit reset --hard 不是什么禁术但别随手交给 Agent。除非当前分支就是一次性实验分支否则它很容易把没保存好的改动一起抹掉。并行任务可以用 git worktree 隔离git worktree add …/project-order-export -b feat/order-exportgit worktree add …/project-refactor-user -b feat/refactor-user一个 Agent 一个目录、一个分支、一个任务。这样它们即使乱改也只会乱在自己的工作区里。Claude Code Git WorktreeClaude Code Git Worktree开工前先把范围写窄你需要让 AI 做什么尽量说得具体一些不要让它自己猜。以订单场景为例你说一句帮我实现导出订单功能。这句话太宽泛了AI 不知道每次导出几条导出什么格式导出哪些字段字段顺序是怎样的。信息没给够它就会自己猜。猜出来的结果能跑但未必是你想要的。不如在开工前花几分钟写轻量 Spec通常比后面返工便宜得多目标实现订单导出接口支持按时间范围导出 CSV。约束单次最多导出 5000 条时间范围不能超过 31 天只能导出当前租户的数据查询必须走 order_tenant_time_idx导出失败要记录失败原因不能只返回 unknown error验收正常导出 CSV字段顺序为 order_no、amount、status、created_at超过 5000 条返回明确错误越权租户数据不能被导出单元测试覆盖无数据、越权、超过条数、超过时间范围 4 种情况这份东西不用写得像方案评审文档。Spec Coding 四步流水线Spec Coding 四步流水线小任务写清楚目标、约束和验收就够了中等任务再补接口格式、错误码、表结构大一点的需求再拆成 requirements.md、design.md、tasks.md。没必要一上来就把流程拉满不然你会先被文档劝退。关于 Spec Coding 的详细介绍可以参考我写的这篇质量非常高Spec Coding 规范驱动编程实战从 Vibe Coding 到 AI 代码规范。还有一招比抽象规范更管用给 AI 看项目里写得好的代码。先阅读 UserController、UserService、UserRepository 和对应测试。参考它们的分层方式、异常处理、返回体包装、日志风格和测试写法。然后实现 OrderExportController。不要引入新的响应格式。不要新增全局异常处理器。不要绕过现有权限校验逻辑。“代码要优雅、可维护、符合最佳实践”这种话放在 Prompt 里看着很认真实际约束力很弱。模型更擅长模仿具体样板。你让它看一段项目里真正合格的代码它反而更容易写出同一套风格。把项目坑点写进规则文件长期项目可以把这些规则放到 AI 工具能稳定读取的位置。比如Claude CodeCLAUDE.mdCodexAGENTS.mdCursorProject Rules、.cursor/rules/*.mdc也可以配合 AGENTS.mdGitHub Copilot / VS Code.github/copilot-instructions.md千万别写成项目说明书应该写 Claude 容易猜错、代码里读不出来、团队又必须遵守的规则。重点放技术栈版本、常用命令、架构取舍、团队约定和项目坑点别塞空话、默认行为和大段文档。判断标准很简单这行删掉后Claude 会不会更容易犯错多智能股票分析项目中的 CLAUDE.md 和 AGENTS.md多智能股票分析项目中的 CLAUDE.md 和 AGENTS.md每次 AI 犯了重复错误也别只在聊天里训它一句。聊天记录会散规则文件会跟着仓库走。你把坑补进规则里下一次它才更可能绕过去。善用 Skill把套路沉淀下来规则文件和 Skill 解决的问题不太一样。规则文件更适合放这个项目一直要遵守什么比如技术栈版本、启动命令、目录结构、错误码格式、哪些文件不能碰。Skill 更适合放遇到某类任务时应该怎么做。比如做代码审查、写测试、改前端页面、网页调研、写技术文章这些任务每次流程都差不多就没必要每次都在聊天里重新提醒一遍。小 G 之前写过两篇相关的文章Agent Skills 是什么和 Prompt、MCP 到底差在哪 和 AI 编程必备 Skills 推荐。简单说Skill 就是一份能被 Agent 按需加载的任务说明。它不是插件也不是 MCP 工具本身而是把某类任务的流程、约束、检查项和踩坑经验写进 SKILL.md。。Agent 执行链路Agent 执行链路比如这些事情就很适合沉淀成 Skill写功能前走 TDD先写失败测试再写实现。做代码审查时固定检查安全、事务、性能、边界条件和项目约定。写前端页面时固定检查响应式、hover 状态、可访问性和设计系统。做网页调研时固定选择搜索、抓取、浏览器自动化这些工具的顺序。写技术文章时固定检查事实来源、引用、标题层级和 AI 味。为什么要用 Skill 因为这些流程每次靠聊天提醒都很烦。你今天提醒它先写测试明天换个会话它又忘了你这次让它 Review 权限风险下次它可能只看命名和格式。Skill 的价值就在这里把重复提醒变成可复用的工作手册。不过Skill 也别写成 README。README 是给人看的可以讲背景、原理和安装说明Skill 是给 Agent 执行任务时看的重点是什么时候用、按什么顺序做、哪些情况别做、失败了怎么兜底。正文越长越容易占上下文。写 Skill 时可以问自己一句这段话会不会直接影响 Agent 下一步怎么做不会就别塞进去。Anthropic 的建议是SKILL.md 正文最好控制在 500 行以内如果超过这个长度就把细节拆到单独文件里通过渐进式披露的方式让 Agent 按需读取。SKILL.md 正文最好控制在 500 行以内SKILL.md 正文最好控制在 500 行以内现成 Skill 也可以直接用比如 Superpowers 把 TDD、Code Review、Spec-Driven、Git Worktree、子 Agent 协作这些流程封装好了。我在 AI 编程必备 Skills 推荐TDD、代码审查与网页自动化实战这篇文章中有详细推荐。但第三方 Skill 不要拿来就跑。SKILL.md 也是指令里面如果带了危险命令、奇怪脚本、过宽权限Agent 会照着做。装之前至少看一眼正文、scripts/ 和 references/确认它没有越权操作。贵模型别拿来搬砖不要什么事都丢给最贵的模型。这就像请了一个资深架构师结果天天让他改字段名、补 getter、调 CSS钱花了价值没用出来。反过来也一样为了省钱把系统设计、安全边界、复杂重构全交给便宜模型硬扛最后返工成本可能更高。小 G 更常用的是“贵模型把方向定清楚便宜模型去干活最后再让贵模型验一遍”。第一步让 Claude Opus 4.6 / Opus 4.7 这类顶级模型读需求和代码库。只让它做方案、列风险、拆任务不让它急着写代码。第二步方案确认后把一个个 Task 丢给 DeepSeek V4-Pro / GLM5.1 或同级低价模型。让它按任务编码、补测试、跑命令做完之后给出 diff 摘要。第三步把 git diff 交回 Claude Opus 4.6 / Opus 4.7。这次只让它 ReviewBug、越权风险、事务边界、性能问题、测试缺口。代码审计也可以这么干。先让便宜模型扫一遍项目把疑似问题列出来再让强模型复核这些问题到底成不成立。直接让高价模型全量扫当然也不是不行就是钱烧得快收益未必成比例。DeepSeek V4 Benchmark 数据DeepSeek V4 Benchmark 数据别听它说修好了看证据AI 最爱说“已修复”“已优化”“没问题”。听听就行别直接信。小 G 更愿意看三样东西测试、命令输出、diff。比如你让它修一个订单导出 Bug不要只问“修好了吗”。可以直接这样要求先不要改实现。先根据 Spec 补测试覆盖正常路径、参数非法、权限不足、无数据、并发重复请求。测试一开始应该失败。我确认测试合理之后你再改实现直到测试通过。这个做法有点像 TDD但不用搞得很教条。重点是别让 AI 一边改代码、一边补一个永远会通过的测试。先让测试失败再让实现通过心里会踏实很多。不想完整 TDD至少也要让它列清楚验收项新增接口有权限校验错误返回符合统一格式数据库查询命中指定索引空值、越界、重复请求都有测试日志不打印 token、password、api key所有测试通过还要让它贴运行过的命令和结果mvn testnpm testgo test ./…pnpm lint没跑就写“未运行”并说明原因。比如依赖没装、数据库没起、测试环境缺配置都可以接受最怕的是它没跑但写一句“已验证”糊弄过去。性能优化更不能只听它说。它说“速度提升明显”你就让它把证据贴出来优化前后的 SQL、EXPLAIN、测试数据量、P95/P99 或接口耗时。没有真实压测结果就只写预期收益和待验证项别让它编数字。上下文别越堆越乱小 G 之前写过一篇 Context Engineering里面有个观点放到 Vibe Coding 里也很适用上下文窗口大不等于效果好——窗口能装更多东西但模型能不能稳定找到重点是另一回事。上下文为什么会失效上下文为什么会失效一个会话里先写登录再改支付再重构缓存最后又问为什么测试挂了模型迟早把旧约束、失败尝试和废弃方案混在一起。你以为自己给了它完整历史它拿到的可能是一堆噪声。Vibe Coding 里上下文要管三件事。第一别把仓库一股脑塞进去。 当前任务只需要 Spec、相关文件、报错日志、验收命令和少量参考实现。其他内容先用路径、文件名、目录结构挂着等需要时再让 Agent 去读。Claude Code 分析大仓库时也是这种思路先用搜索和目录定位再逐步读具体文件而不是上来吞全量代码。第二长任务要及时压缩。 Claude Code 可以用 /compact 压缩上下文用 /clear 清空上下文详细用法参考 Claude Code 核心命令详解[1]Codex 或其他 Agent 也有类似的摘要、压缩、重开机制。压缩是为了保留重点如架构决策、已改文件、未解决问题、失败命令和下一步任务丢掉重复对话和已经消化过的工具输出。第三关键进展要落到文件里。 比如让 Agent 在长任务中维护一份 NOTES.md 或任务 handoff记录已完成修改了哪些文件哪些测试已经跑过哪些问题已经确认不是 Bug剩余任务还没修的失败用例还没确认的边界场景下一个 Agent 需要先读哪些文件这样就算开新会话也不用重新解释半天。聊天记录会变长、变乱、变旧结构化笔记反而更稳定。小 G 的习惯是一个会话只处理一个任务超过两次纠正还不对就开新会话新会话只带当前 Spec、相关文件、失败日志、验收命令和上一轮 handoff。对多数编码任务来说3000 到 8000 tokens 的高质量上下文通常比几十万 tokens 的杂乱对话更可靠。上下文包可以写得很朴素当前任务实现订单导出接口。必读文件src/main/java/…/UserController.javasrc/main/java/…/OrderRepository.javadocs/spec/order-export.md禁止修改数据库已有字段名全局异常格式登录鉴权逻辑验收命令mvn testmvn -DtestOrderExportServiceTest test文档也可以当上下文用。AI 改了多个模块后让它补一份变更说明新增了什么接口改了哪些表或索引关键业务规则是什么如何验证如何回滚。这样就可以下次继续开发时能直接喂给 AI。历史包袱多的项目里哪个字段不能改、哪个接口兼容老客户端、哪个枚举值被外部系统写死这些口口相传的规则都该进文档。多 Agent 先串行再并行多 Agent 分工协作的玩法确实很香但真心不建议大家上来就尝试多 Agent 并行例如一个写代码一个补测试一个做 Review一个写文档很容易把项目搞乱。你刚开始就串行着跑就好了Plan Agent 只读代码输出方案和任务拆分Code Agent 只负责一个 Task不碰其他任务Test Agent 补测试并运行验证Review Agent 只看 diff找问题不直接大改。一定不要一上来就让多个 Agent 同时改代码让们在同一个 feature 分支上按顺序提交git commit -m “[plan] add order export design”git commit -m “[code] implement order export api”git commit -m “[test] add order export tests”git commit -m “[review] fix tenant permission check”等流程跑顺以后也比较熟练之后再考虑 worktree 并行、Agent View[2] 这类玩法。多 Agent 并行会话多 Agent 并行会话Claude Code Agent ViewClaude Code Agent View并行最怕的不是 Git 冲突那种至少能看到。真正麻烦的是不冲突——两个 Agent 同时改同一个公共 DTO一个为了导出加字段一个为了查询删字段合并时看起来没问题但接口语义、序列化结果、前端依赖可能已经变了。所以多 Agent 不能靠运气要靠任务边界、分支隔离和验收项管住。哪些文件能改、哪些模块不能碰、改完要跑哪些测试、哪些 diff 必须人工看都要提前写清楚。subagent 适合做专项任务这里也可以顺手提一下 subagent。以 Claude Code 为例subagent 可以理解成一个“专门干某类活的小助手”。它有自己的上下文、系统提示词和工具权限适合处理边界比较清楚的任务比如代码审查、测试补齐、日志分析、文档整理。官方文档里也提到subagent 可以在独立上下文中运行减少主会话的上下文压力并且可以为不同任务配置不同的工具访问权限。Claude Code Sub-Agent让主对话保持干净Claude Code Sub-Agent让主对话保持干净它和前面说的多 Agent 并行不是一回事。多 Agent 更偏协作方式subagent 更偏任务委派。比如主会话正在实现订单导出功能你可以把“检查这次 diff 有没有权限绕过风险”交给 Review subagent把“根据当前代码补单元测试”交给 Test subagent。它们各自做完后把结论返回给主会话。但 subagent 也别滥用。任务太小、边界不清、代码还在剧烈变化时拆出去反而容易增加沟通成本。比较稳的用法是主 Agent 负责整体上下文和决策subagent 负责局部、明确、可验收的任务。权限控制很重要AI Coding 不能只靠 Prompt 里写一句“请你谨慎一点别做危险操作”。Claude Code 这类工具已经不只是回答问题了它会读文件、改代码、执行命令也可能通过 MCP 调内部工具或外部服务。风险自然也不再只是代码写错更严重的问题可能误删文件、改坏配置、跑错迁移、推送到远程甚至碰到密钥、证书、生产配置这类敏感信息。所以权限要提前收住。.env.production、密钥、证书这类文件默认就不应该让 AI 读取或修改删除文件、数据库迁移、推送远程、改 CI 配置这类操作必须人工确认登录、支付、权限、上传、Webhook 这类模块改完要单独做安全 Review。Claude Code 官方其实也提供了对应的权限机制。比如可以用 /permissions 查看和管理工具权限权限规则里可以配置 allow、ask、deny分别表示允许执行、执行前询问、直接拒绝。像 git diff、跑单测这类低风险命令可以放得宽一点git push、删除文件、读取 .env、访问 secrets/** 这类操作就应该放到 ask 或 deny 里。如果只是配置权限规则还不放心可以继续加 Hooks 和 Sandbox。Hooks 可以在工具调用前后执行自定义检查比如拦截危险命令、检查是否改了敏感路径、在提交前跑格式化和测试Sandbox 则更偏执行环境隔离用来限制 Bash 命令能访问的文件系统和网络范围。举个例子假设 Claude Code 准备执行rm -rf /tmp/buildPreToolUse Hook 会先拿到这次 Bash 调用判断它是不是危险命令如果命中规则就返回 denyClaude Code 会取消这次工具调用并把拒绝原因反馈给 Claude。下面这张图展示了整个过程图源 Claude Code 官方文档对 Hooks 的介绍。Claude Code PreToolUse HookClaude Code PreToolUse Hook更稳的做法是把这些规则固化到工程里哪些命令可以自动执行哪些命令必须人工确认哪些路径禁止读取或修改哪些 MCP 工具不能随便调用哪些 CI 任务必须人工审批哪些测试不过就不能合并。这里还有一个容易忽略的点权限规则不是万能的。比如你只拦了 rm *不代表一定拦得住 /bin/rm、find -delete 这类变体。所以高风险操作不能只靠一条命令黑名单兜底最好结合路径限制、Hooks、Sandbox、CI 和人工 Review 一起管。工程上的谨慎肯定不能写在 Prompt 里要落到命令、脚本、权限、测试、CI 和审批流程里。分享下我常用的一套流程日常写需求时小 G 一般按这个节奏走新建分支先确认工作区是干净的。写一份轻量 Spec把目标、约束、验收标准说清楚。看看有没有合适的 Skill比如 TDD、Code Review、前端设计、网页调研。先让顶级模型出方案只讨论方案不急着写代码。方案确认后再让低价模型按 Task 一步步实现。每完成一个 Task就跑测试、看 diff然后小步提交。当前 diff 稳住后再让顶级模型做一次 Review。修掉 Review 里合理的问题再跑一遍测试。合并前人工看关键 diff。涉及数据、权限、支付、定时任务这类改动时再补一下文档、回滚方案或者灰度说明。这个流程比“一句话生成代码”慢一点。但慢的这点时间通常会在后面赚回来。至少能少很多返工、回滚和线上排雷。短期原型可以大胆 Vibe先把东西跑起来再说但只要代码要长期维护还是得回到工程流程里。GitHub Flow 本身也是围绕分支、Pull Request、Review 和合并来组织协作不是让人直接往主分支怼代码。Codex 这类工具也支持通过 AGENTS.md 放项目级规则让 AI 按仓库里的约定做事而不是每次都靠聊天临时提醒。Spec Coding 规范驱动编程实战从 Vibe Coding AI 编程必备 Skills 推荐到 AI 代码规范说白了AI 写代码越快Git、测试、Review、Spec 这些老东西越不能丢。以前它们是为了约束人现在还得顺手约束 AI。参考资料[1]Claude Code 核心命令详解: https://javaguide.cn/ai-coding/claudecode-commands.html[2]Agent View: https://javaguide.cn/ai-coding/practices/claudecode-agentview.html