文章目录
- 四大原则:感觉驱动不等于无章法
- 意图优先:先描述效果而非实现方式
- 快速迭代:拥抱"生成→测试→修正"循环
- 信任但验证:关键逻辑必查
- 上下文经营:持续维护给 AI 的背景信息
- 为什么 Agent 不是聊天框:LLM Loop 机制
- 对话式 AI 与 Agent 的本质区别
- Agent 与 Chatbot 对比
- LLM Loop 的四个环节
- Agent 的自我纠错机制
- Plan-Act-Observe-Reflect 循环示例
- 官方推荐工作流:Explore→Plan→Implement→Commit
- 四阶段详解
- 为什么必须分阶段:一个反面场景
- 完整示例:用官方工作流搭一个 Express Hello World
- 三种变体工作流:测试驱动、UI 驱动、文档驱动
- 测试驱动变体:后端与逻辑代码的首选
- UI 驱动变体:前端与界面的视觉验证
- 文档驱动变体:大型功能的规范先行
- 验证手段是最高杠杆建议
- 上下文管理:被新手严重低估的核心技能
- 为什么对话越长 AI 反而越笨
- /context 与 /compact:监控与压缩
- /clear 与 /compact 的使用时机
- CLAUDE.md:持久上下文的正确用法
- Git 即存档系统:Vibe Coding 的安全网
- 黄金法则:大修改前先 commit
- 完整的存档-回退-再存档流程
四大原则:感觉驱动不等于无章法
Vibe Coding(感觉驱动编程)这个词由 Andrej Karpathy 在 2025 年初的一条推文中带火,核心理念是:开发者不再逐行敲打语法,而是用自然语言描述想要的效果,把"写代码"这件事交给 AI,自己只专注于意图表达与结果验收。听起来像是在"凭感觉"做事,但真正高效的 Vibe Coding 并不是漫无目的地许愿,而是一套有章可循的协作方法。脱离原则的"感觉驱动"只会让 AI 在错误的轨道上狂奔,产出一堆看似能跑却埋满隐患的代码。以下四条原则,构成了 Vibe Coding 可重复、可把控的底层心法。
从传统编码到 Vibe Coding,开发者的角色发生了一次质变:过去你是代码的生产者,注意力集中在语法和实现细节上;现在你是意图的表达者和结果的验收者,注意力转移到需求拆解、约束定义和质量把关上。这个转变并不轻松——它要求你具备更强的系统思维和判断力,因为你要审核的不再是自己一行行写出来的代码,而是 AI 在几分钟内生成的一大片代码。能否快速读懂、判断对错、给出有效反馈,成为新的核心竞争力。四条原则正是围绕这个新角色展开的:把意图讲清楚、把节奏控起来、把关键处盯住、把背景养好。
意图优先:先描述效果而非实现方式
所谓意图优先,指的是在向 AI 下达任务时,要把"想要达成什么效果"讲清楚、把不可妥协的约束钉死,而不是抛一个模糊的功能名让 AI 自由发挥。AI 强于补全细节、弱于猜测心智,你给的意图越具体,它返工的次数就越少。这里的关键区分不是"要不要写实现细节",而是"有没有把契约讲明白"——你可以指定用哪个库、复用哪段既有代码,但这些是约束而非逐行指令。
看一组正反例对比就明白差距在哪。
差的写法只给了一个功能名,所有设计决策都甩给了 AI:
帮我做一个登录功能AI 拿到这句话,只能靠猜:用什么密码哈希?返回什么凭证?查哪张表?一旦猜错,后面全是返工。
好的写法把效果和约束都钉死了,AI 只需填充骨架:
在 /api/auth/ 下创建登录 API:POST /api/auth/login, 接受 {email, password},用 bcrypt 验证密码, 成功返回 JWT,复用项目已有的 prisma client 查 User 表其中 bcrypt 是一种密码哈希库(把明文密码变成不可逆的散列值,防止数据库泄露后密码被还原),JWT(JSON Web Token)是一种无状态令牌(服务端签发后客户端每次请求带上即可,无需在服务端存 session),prisma client 是项目里已初始化的数据库访问层。这段 Prompt 没有写一行实现代码,却把路由、入参、安全方案、数据来源全部锁定,AI 几乎没有歧义空间。意图优先的本质,是用最小篇幅传递最大确定性。
新手常踩两个坑。一个是把意图优先误解为"什么都别管细节",结果 Prompt 写得比反面例子还模糊,AI 只能照着最通用的模板生成一坨谁都能写的代码。另一个是走向另一个极端,把每一步实现都写死,Prompt 长到像在口述代码,既费时又限制了 AI 发挥它擅长的样板代码生成。正确的度在中间:钉死影响正确性的关键决策(用哪个库、走哪条数据流、复用哪段代码),放手让 AI 处理不影响正确性的样板(import 语句、目录结构、错误处理的样板写法)。判断一条细节该不该写进 Prompt,看它是否影响最终结果的正确性——影响就写,不影响就留给 AI。
快速迭代:拥抱"生成→测试→修正"循环
传统开发的心智模型是"想清楚再写,一次写对",因为手写代码的成本高、改动的心理负担重。Vibe Coding 把生成代码的边际成本压到了接近零,于是最优策略反转过来:不要追求一次完美,而是尽快生成一个能跑的版本,用真实运行结果去校准方向。生成、测试、修正,这三步会循环很多次,每一次循环都让产品更接近目标。
一个典型场景是做表单校验。第一轮让 AI 生成基础校验逻辑,跑一下发现邮箱格式没拦住;第二轮贴上报错让 AI 补正则;第三轮发现空字符串没处理,再让它加一条规则。每一轮只解决一个具体问题,远比一开始就写一份十全十美的需求文档更高效。拥抱迭代意味着接受"前几版一定不完美",把验收标准拆成一个个可验证的小目标,让 AI 逐个击破。这种工作方式的前提是每次迭代都有明确的反馈信号,否则循环就失去了方向。
迭代的速度取决于反馈环的短促程度。反馈环越短——从生成到验证的间隔越小——单位时间内的循环次数越多,收敛越快。这正是 Agent 比聊天框高效的根本原因:聊天框的反馈环要经过"复制代码到编辑器、装依赖、运行、看报错、再把报错描述回给 AI"一长串人工中转,一个循环可能耗掉几分钟;Agent 自己跑命令、读结果,一个循环只要几秒。把反馈环压到最短,是快速迭代的工程前提。落到操作上,意味着要给 AI 配好能立刻跑的测试、能立刻看的截图、能立刻验证的命令,让它不必等你人工反馈就能自己转起来。
信任但验证:关键逻辑必查
AI 生成的代码大多数时候是对的,但"大多数时候"在涉及数据库迁移、身份认证、支付扣款这类不可逆操作时远远不够。一句 SQL 把DELETE写成没带WHERE,一次密码比对用错了常量时间函数,一个支付回调没做幂等校验——这些错误藏得深、复现难、后果重。"信任但验证"是 Vibe Coding 的黄金法则:相信 AI 的能力以获得速度,但关键逻辑必须逐行过目。
验证的力度应该与风险成正比。展示层文案写错一个字,让 AI 自己改就行;涉及金钱和数据安全的代码,开发者要亲自读一遍逻辑、跑一遍边界用例。一个实用判断标准是问自己一句:这段代码如果出错,回滚成本有多高?成本高的地方,就是必须人工验证的地方。把 AI 当成一个手脚快但偶尔粗心的初级工程师来用——常规活儿放手交给他,签字盖章的环节你亲自来。
举一个隐蔽错误的例子。AI 生成一段修改用户密码的接口,逻辑看着完整:校验旧密码、更新新密码、返回成功。但它可能用了普通的字符串比较来校验旧密码,而非常量时间比较——这会引入时序侧信道(攻击者通过比较耗时的长短逐字节猜出密码)。这种漏洞测试覆盖不到、运行也不报错,只有懂安全的人 review 时才抓得出来。关键逻辑必查,查的就是这类"能跑但有害"的隐患。验证手段能拦住显性错误,隐性隐患靠的是人对业务和安全的理解,这是 Agent 替代不了的环节。
上下文经营:持续维护给 AI 的背景信息
这是四条原则里最被低估的一条。AI 的输出质量直接取决于它掌握的背景信息量,而背景信息不会自动保鲜——项目演进、约定变更、历史决策,都需要开发者主动喂给 AI。很多人抱怨"AI 越用越笨",根因往往是上下文被无关内容稀释、被错误尝试污染,而非模型本身变差。上下文经营就是把这些信息当作一项资产来维护:哪些写进 CLAUDE.md 长期生效,哪些只在当前任务临时说明,哪些该及时清理掉,都要有意识地去管。
一个反面例子是,开发者在对话里零零散散提了一堆要求,中间夹着几次失败的尝试和跑偏的讨论,最后让 AI"按刚才说的做"。AI 早就被冗余信息淹没,抓不住重点。正例是任务开始前先用一两句话交代清楚背景与约束,过程中及时清理跑偏的分支,关键约定沉淀到 CLAUDE.md(项目根目录的特殊指令文件,每次对话自动加载)里固化下来。上下文经营的具体手法会在后文展开,这里只需记住一条:你给 AI 的背景信息质量,决定了它回馈你的代码质量。
上下文经营和另外三条原则是相互支撑的。意图优先要求你把约束讲清楚,这些约束就是高质量上下文;快速迭代依赖短反馈环,而反馈环的产物(测试结果、报错信息)需要及时清理避免污染;信任但验证关注的是关键逻辑,而判断哪些是关键逻辑本身依赖你对项目背景的掌握。把上下文当成一次性的输入是常见误区——它是活的,需要随任务推进不断修剪、补充、归档。
为什么 Agent 不是聊天框:LLM Loop 机制
理解 Vibe Coding 的前提,是搞清楚你面对的到底是一个聊天机器人,还是一个能自主干活的 Agent(智能体)。这两者外表相似——都是用自然语言交互——但底层运行机制截然不同,工作方式也天差地别。把 Agent 当聊天框用,是新手最容易踩的坑,也是效率上不去的头号原因。
对话式 AI 与 Agent 的本质区别
对话式 AI(如网页版的 ChatGPT、Claude.ai)的交互模式是:你问一个问题,它生成一段文字回答,对话结束,主动权始终在人手里。它只能产出文本——代码片段、解释、建议,但无法触碰你的文件系统,不能运行命令,不能验证自己说的是否真的能跑。你拿到一段代码后,还得自己复制到编辑器、自己装依赖、自己跑、自己排错,AI 与真实环境之间隔着一堵玻璃墙。
Agent(如 Claude Code)的模式完全不同:你给一个目标,AI 自己把目标拆成若干步骤,依次调用工具——读文件、写文件、运行 shell 命令、搜索代码库,每一步都观察执行结果,再决定下一步做什么,如此循环直到目标完成或需要你介入。主动权被交给了 AI,它不再是被动回答问题的百科全书,而是能动手干活的执行者。最关键的差异在于反馈闭环:对话式 AI 写完代码就结束了对错与否它不知道;Agent 写完代码会自己跑一遍,报错了会读错误信息、调整方案再试。这个自闭环,是 Vibe Coding 能够"忘记代码"的技术保障。
Agent 与 Chatbot 对比
| 维度 | 对话式 AI(Chatbot) | Agent(Claude Code) |
|---|---|---|
| 交互行为 | 一问一答,单轮为主 | 给目标,多轮自主推进 |
| 能力边界 | 只能生成文本 | 读写文件、运行命令、搜索代码 |
| 主动性 | 被动等待提问 | 主动拆解、调用工具、自我纠错 |
| 记忆范围 | 单次对话窗口内 | 会话内循环 + CLAUDE.md 持久记忆 |
| 比喻 | 一个只能口头指导你的顾问 | 一个能自己上手干活的实习生 |
最后那行比喻最能说明问题:顾问说得再好听,活儿还得你亲手干;实习生虽然需要你把关方向,但脏活累活他能自己上手,干错了还会自己改。
这个区别决定了你该怎么和它们协作。面对聊天框,你得把它的输出当成"草稿"——它给的代码要自己拷出来、自己跑、自己改,它不参与验证环节,对错全靠你兜底。面对 Agent,你把它当成"能动手的搭档"——给目标、给约束、给验证手段,然后放手让它跑,只在关键节点介入。很多新手把 Agent 当聊天框用,每生成一段代码就停下来人工检查、人工跑,等于亲手把 Agent 的自闭环拆掉了,效率反而不如直接用聊天框。让 Agent 发挥价值的前提,是给它完整的自主空间和配套的验证手段,而不是把它降级成一个只会输出文本的问答机器。
LLM Loop 的四个环节
Agent 之所以能自主运转,靠的是一套叫 LLM Loop(大模型循环)的机制。每一轮循环包含四个环节:思考、行动、观察、判断是否完成。思考环节里,模型分析当前状态、规划下一步该做什么;行动环节里,模型调用某个工具(读文件、跑命令等)产生实际效果;观察环节里,模型读取工具返回的结果(文件内容、命令输出、报错信息);判断环节里,模型决定是继续循环还是已经达成目标可以交付。这四个环节紧密咬合,构成 Agent 的心跳。
这四个环节里,观察环节是 Agent 区别于纯文本生成的关键。一个只生成文本的模型,它的输出是"最终答案",对错只能靠人判断;而 Agent 每次行动后都观察工具的返回——文件是否写入成功、命令的 stdout 和 stderr、测试的通过情况——这些观察构成了一条事实链,让模型的下一步决策建立在真实结果而非臆测之上。观察环节质量越高(工具返回的信息越准确、越完整),Agent 的决策就越靠谱。这也是为什么给 Agent 配的命令最好有清晰的退出码和结构化输出:模糊的输出会让观察失真,进而带偏后续所有决策。
和聊天框"答完即止"不同,Loop 是持续运转的。模型不会在生成第一段代码后就停下,而是会接着把代码写进文件、运行测试、看结果、有问题就改,直到任务真正完成。这意味着你给一个目标,Agent 可能自主跑上几十轮循环,期间无需你逐句指挥。理解了 Loop,就理解了为什么 Agent 能承担"端到端完成一个功能"这种复杂任务——它不是一次性生成,而是在持续试错中逼近目标。
Agent 的自我纠错机制
Loop 机制里最值钱的一环是自我纠错。当 Agent 执行某条命令报错时,它不会卡住等你救场,而是把错误信息读进来,分析原因,调整方案,换个写法再试。比如它跑测试发现某个用例失败,会去读失败的断言、定位到对应代码、修改逻辑、重跑测试,直到通过。这种"看到错误→理解错误→修正错误"的能力,让 Agent 在没有人工介入的情况下也能逐步收敛到正确结果。
自我纠错的边界在于:它修的是"能被工具结果暴露的错误"。测试失败、编译报错、命令异常退出,这些有明确信号的错误 Agent 能自己兜住;但逻辑上"看似正确实则错误"的隐患——比如一个永远返回 true 的权限校验——没有信号暴露,Agent 就察觉不到。这正是"信任但验证"原则要补的缺口:Agent 能消灭显性错误,隐性错误仍需人来兜底。
Plan-Act-Observe-Reflect 循环示例
把上面的机制落到一个具体任务上,完整的循环长这样。假设你给 Agent 一个目标:“帮我做个番茄钟”。下面是它内部运转的文字流程图:
[目标] 帮我做个番茄钟 │ ▼ [思考/Plan] 拆解:需要倒计时逻辑 + 开始/暂停按钮 + 时间到提醒 决定先读项目结构,确认技术栈 │ ▼ [行动/Act] 调用工具:读 package.json,ls 当前目录 │ ▼ [观察/Observe] 得知项目是 Vite + React,已有组件目录 src/components │ ▼ [反思/Reflect] 计划可行,技术栈明确,开始实现番茄钟组件 判断:完成?否 → 回到思考 │ ▼ [思考/Plan] 创建 src/components/PomodoroTimer.jsx,写倒计时与按钮 │ ▼ [行动/Act] 写文件,然后运行 npm run dev 启动开发服务器 │ ▼ [观察/Observe] 控制台报错:Timer 组件未导入 useState │ ▼ [反思/Reflect] 发现漏了 import,这是显性错误,自己能修 判断:完成?否 → 回到思考 │ ▼ [思考/Plan] 补上 useState 导入,重新验证 │ ▼ [行动/Act] 修改文件,重跑构建 │ ▼ [观察/Observe] 构建通过,页面渲染正常,倒计时工作 │ ▼ [反思/Reflect] 功能符合目标 判断:完成?是 → 交付结果整个过程中,那次"报错→读错误→补 import→重跑"就是自我纠错在起作用。如果换成聊天框,模型生成第一版代码就结束了,能不能跑、报不报错它一概不管,你得自己复制粘贴、自己装依赖、自己排错。Agent 把这套"生成→验证→修正"的循环内化了,这才是 Vibe Coding 敢说"忘记代码"的底气所在——不是你不用管代码了,而是 Agent 替你管了跑通和纠错这层。
官方推荐工作流:Explore→Plan→Implement→Commit
Anthropic 在官方博文《Claude Code: Best practices for agentic coding》(2025 年 4 月发布,内容后续整合进 code.claude.com 官方文档)里给出了一套核心工作流,把 Agent 编码拆成四个阶段:Explore(探索)、Plan(规划)、Implement(实施)、Commit(提交)。这套流程的精髓在于用 Plan Mode(规划模式,Agent 在此模式下只读不写)把"搞清楚要做什么"和"动手去做"分开,避免 Agent 在没弄明白问题时就闷头改代码。下文涉及的具体能力与界面以官方文档为准,核对时间 2026 年 5 月。
四阶段详解
| 阶段 | 你做什么 | AI 做什么 | 推荐模式 |
|---|---|---|---|
| Explore 探索 | 提出问题、指方向 | 读文件、grep 搜索、跟引用链路,只读不改 | Plan Mode |
| Plan 规划 | 审核方案、补充约束 | 出详细实现方案、评估边界情况 | Plan Mode |
| Implement 实施 | 监督执行、必要时纠偏 | 按方案写代码、跑测试、修错误 | Normal / Auto-Accept |
| Commit 提交 | 确认提交信息 | 生成描述性 commit message,开 PR | Normal |
Explore 阶段的目的让 Agent 先摸清代码库现状:相关文件在哪、现有模式是什么、有哪些依赖可复用。Plan 阶段让 Agent 基于探索结果产出一个具体方案,列出要改哪些文件、按什么顺序、边界情况怎么处理,你审核通过后再进入实施。Implement 阶段才真正动手写代码,并立即用测试或运行结果验证。Commit 阶段让 Agent 生成规范的提交信息,把成果固化到版本库。官方文档提示,可以用快捷键在文本编辑器里直接编辑 Agent 给出的计划,再让它按修订后的方案执行。
Explore 阶段常用手段是让 Agent 主动跑搜索命令摸清代码脉络。比如要改一个认证模块,可以让 Agent 先 grep 所有引用了authenticate的文件,再顺着调用链读下去,搞清楚现有认证是怎么接入的、有没有可复用的中间件。这一步的产出不是代码,而是"地图"——Agent 对代码库建立认知后,Plan 阶段才能给出贴合现状的方案。跳过 Explore 直接规划,Agent 只能基于猜测出方案,结果往往是方案看着合理、落地处处碰壁。
为什么必须分阶段:一个反面场景
不分阶段直接让 Agent 动手的代价,用一个真实场景说明。某开发者对一个在线表格项目说了一句"加个软删除功能"(软删除指不真正删除记录,而是打一个deleted_at标记,查询时过滤掉)。Agent 拿到这个模糊指令,没有先探索就开干:它给所有数据表加了deleted_at字段,改了全局查询过滤器自动排除已删除记录,又顺手"优化"了三个相关接口的返回结构。15 分钟后,全局过滤器把一个本该显示历史归档数据的接口也过滤空了,另外两个接口因为返回结构变了导致前端报错。14 个文件被改动,3 个接口被破坏,开发者只能手工一个个回退。
问题的根源不是 Agent 能力不行,而是它在不了解全局影响的情况下就动了手。如果在 Implement 之前先走 Explore 和 Plan,Agent 会先发现"这个项目有全局查询过滤器""历史归档接口依赖未过滤的原始数据"这些约束,方案里就会提前规避冲突。分阶段的本质,是用 5 分钟的规划换 30 分钟的返工免除。官方文档也指出,Plan Mode 对"改动跨多个文件、对要改的代码不熟悉、方案不确定"的场景最有价值;如果是改个错别字这种一句话能说清的 diff,直接做即可,不必强行走完整流程。
判断要不要走 Plan Mode,可以问自己三个问题:这次改动会碰几个文件?我对要改的代码熟不熟?方案有没有不确定的地方?三个里有一个答案是"不乐观",就值得花几分钟规划。Plan Mode 的开销主要在等待 Agent 读代码、出方案的时间,通常几分钟;而跳过规划直接动手导致返工的时间,动辄半小时起步。这笔账怎么算都划算——何况 Plan 阶段产出的方案本身就是一份变更记录,后面 Commit 时还能复用来写提交信息,投入产出比很高。
完整示例:用官方工作流搭一个 Express Hello World
把四阶段落到一个可运行的最小项目上。目标是用 Node.js 的 Express 框架搭一个返回 JSON 的 Hello World 接口。
先创建项目目录并启动 Claude Code:
$mkdirhello-api&&cdhello-api&&claude进入 Plan Mode(按对应快捷键切换,以官方文档说明为准),先做探索和规划。给 Agent 的 Prompt 把意图和约束讲清楚:
请帮我初始化 Node.js Express 项目: 1. npm init 创建 package.json 2. 安装 express 3. 创建 app.js 实现 GET /hello 返回 {message:'Hello AI Coding!'} 4. 端口 3000Agent 在 Plan 阶段会确认:当前是空目录,需要从零初始化;技术栈选 Express;入口文件命名 app.js;监听 3000 端口。方案明确、无歧义,切出 Plan Mode 进入实施。Agent 依次执行初始化、安装依赖、生成代码。最终产出的app.js如下:
constexpress=require('express');constapp=express();app.use(express.json());app.get('/hello',(req,res)=>{res.json({message:'Hello AI Coding!'});});app.listen(3000,()=>{console.log('Server running on http://localhost:3000');});Agent 写完文件后会自行启动服务验证。终端里的执行过程与输出大致如下:
$npminit-yWrote to /home/user/hello-api/package.json:... $npminstallexpress added1packagein2s $nodeapp.js Server running on http://localhost:3000另开一个终端验证接口(Agent 也会自己跑这条命令确认结果):
$curlhttp://localhost:3000/hello{"message":"Hello AI Coding!"}返回结果与预期完全一致,Agent 判定任务完成,进入 Commit 阶段生成提交信息:
$gitadd.&&gitcommit-m"init express project with GET /hello endpoint"[main(root-commit)a1b2c3d]init express project with GET /hello endpoint2files changed,18insertions(+)create mode100644app.js create mode100644package.json这个例子虽然简单,却完整走过了四阶段:探索确认空目录与技术栈、规划敲定文件结构与端口、实施生成代码并自验证、提交固化成果。项目越大,这套流程省下的返工时间越多。
三种变体工作流:测试驱动、UI 驱动、文档驱动
官方四阶段工作流是骨架,针对不同类型的任务可以演化出变体。Anthropic 官方文档列举了三种典型变体:探索-计划-编码-提交(即基础四阶段)、写测试-提交-编码-迭代-提交(测试驱动)、写代码-截图-迭代(UI 驱动)。再加上适合大型功能的文档驱动变体,基本覆盖了日常开发的全部场景。选对变体,等于给 Agent 配上最合适的反馈信号。
测试驱动变体:后端与逻辑代码的首选
测试驱动变体适用于后端接口、算法逻辑、业务规则这类"对错可以用断言判定"的代码。流程是:先让 Agent 写一组失败的测试,提交这组测试,再让 Agent 写实现代码让测试通过,反复迭代直到全部通过,最后提交。核心思路是用测试充当验证手段——测试红了说明还没实现完,测试绿了说明功能达标,反馈信号清晰且自动化。
以一个邮箱校验函数为例。先让 Agent 写测试:
// validateEmail.test.jsconst{validateEmail}=require('./validateEmail');test('合法邮箱返回 true',()=>{expect(validateEmail('user@example.com')).toBe(true);});test('缺少域名返回 false',()=>{expect(validateEmail('user@.com')).toBe(false);});test('空字符串返回 false',()=>{expect(validateEmail('')).toBe(false);});此时实现文件还不存在,跑测试必然失败:
$ npx jest validateEmail FAIL ./validateEmail.test.js ✕ 合法邮箱返回true(1ms)● 合法邮箱返回true→ Cannotfindmodule'./validateEmail'红色信号明确了"缺什么"。让 Agent 写实现:
// validateEmail.jsfunctionvalidateEmail(email){if(!email)returnfalse;return/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email);}module.exports={validateEmail};再跑测试,全部通过:
$ npx jest validateEmail PASS ./validateEmail.test.js ✓ 合法邮箱返回true(2ms)✓ 缺少域名返回false✓ 空字符串返回false(1ms)Tests:3passed,3total测试驱动变体的妙处在于:测试本身就是需求文档,Agent 每次改动都能立刻知道是否破坏了既有行为。这对涉及复杂业务规则的后端代码尤其重要。
测试驱动变体还有一个隐性收益:它天然产出了回归测试网。每写一个功能就配一组测试,后续改动时 Agent 重跑全套测试,立刻知道有没有破坏既有行为。随着功能增多,这张测试网越织越密,Agent 的"信任但验证"成本越来越低——因为验证已经自动化了。对没有现成测试体系的遗留项目,可以反过来用 Vibe Coding 补测试:让 Agent 读现有代码、推断行为、生成覆盖用例,把测试网从无到有建起来。
UI 驱动变体:前端与界面的视觉验证
UI 驱动变体适用于前端页面、组件样式这类"对错靠眼睛看"的代码。这类任务没有简单的断言能判定成败,按钮偏了 2 像素、配色和设计稿不一致,测试框架抓不出来。解法是用截图对比当反馈信号:让 Agent 写完代码后自己截图,和设计稿或参考图比对,列出差异再修。Anthropic 官方提供了 Chrome 扩展,能让 Claude 自己打开浏览器、渲染页面、截图比对,形成视觉层面的自闭环。
这类任务的 Prompt 范式是:
[粘贴设计稿截图] 按这个设计实现页面。 完成后截图,和原图对比,列出差异并修复。Agent 收到后会先实现一版,然后用浏览器扩展截图,把截图和设计稿做视觉对比,识别出"间距偏大"“按钮圆角不符”"主色偏暗"等差异,逐条修正后再截图比对,循环到视觉一致。没有这套视觉验证,前端任务的反馈就只能靠你肉眼盯——每个像素级的偏差都得你指出,Agent 才知道改。视觉自闭环把你也从反馈环里解放出来。
UI 驱动变体对设计还原度的提升非常显著。传统流程里,设计师交付设计稿后,前端按自己的理解实现,最后设计师 review 时往往发现一堆偏差,来回沟通成本很高。让 Agent 自己截图比对,等于把设计师的验收环节前置到了开发过程中——Agent 在实现时就持续向设计稿对齐,而不是等做完再返工。对于响应式适配,还可以让 Agent 分别截桌面端和移动端的图,逐一比对,覆盖人工容易漏掉的断点。
文档驱动变体:大型功能的规范先行
文档驱动变体适用于跨多个模块、周期较长的大型功能。这类任务如果直接让 Agent 写代码,很容易写到一半发现方向偏了、各模块约定不一致。解法是先写一份 PRD(产品需求文档)或 SPEC(技术规范),把数据结构、接口契约、模块划分、边界情况定死,再让 Agent 严格按规范实现。规范文档在此充当"可引用的源头真相",Agent 实现过程中随时参照,保证各部分一致性。
文档驱动和 CLAUDE.md 的区别在于粒度:CLAUDE.md 是项目级的长期约定,PRD 是功能级的临时规范,任务完成后归档。一个团队做支付模块时,先在 PRD 里定好订单状态机、回调幂等策略、金额精度规则,再让 Agent 按这份文档分模块实现,比让它"自由发挥"靠谱得多。
文档驱动变体的另一层价值在于跨会话的连续性。大型功能往往一次对话做不完,中途要 /clear 或换天继续。如果没有规范文档,新会话里 Agent 对之前的设计一无所知,只能重新摸索;有了文档,Agent 每次开工先读规范,立刻接上之前的上下文,各模块实现保持一致。规范文档在此充当了"跨会话的记忆外挂",把易失的对话上下文固化为持久文件。这也是为什么大型项目尤其值得在前期投入写规范——它省的不是一次对话的时间,而是整个功能周期里反复对齐的成本。
验证手段是最高杠杆建议
Anthropic 官方把"Give Claude a way to verify its work"(给 Claude 一种验证自己工作的手段)称为"你能做的唯一最高杠杆的事"。原因很直接:没有验证手段,你就是唯一的反馈环,Agent 每犯一个错都得你介入指出,效率被人为拖慢;有了验证手段,Agent 能自己发现错误、自己修正,你只在关键节点把关即可。测试、截图、预期输出、lint 检查,任何能把"对错"变成机器可判别信号的东西,都算验证手段。
| 变体 | 适用场景 | 验证手段 | 典型流程 |
|---|---|---|---|
| 测试驱动 | 后端、逻辑、算法 | 单元测试断言 | 写测试→提交→编码→迭代→提交 |
| UI 驱动 | 前端、界面、样式 | 截图视觉对比 | 写代码→截图→对比→迭代 |
| 文档驱动 | 大型功能、跨模块 | 规范文档一致性 | 写 PRD→按规范实现→对照验收 |
| 基础四阶段 | 通用、中等复杂度 | 运行结果/测试 | Explore→Plan→Implement→Commit |
选型决策遵循一个原则:哪种验证信号最贴合任务的对错判定,就用哪种变体。逻辑代码用断言,界面代码用截图,大型功能用文档,通用场景用基础四阶段。信号越贴合,Agent 自闭环的能力越强,你需要介入的次数越少。
上下文管理:被新手严重低估的核心技能
官方文档把上下文窗口称为"最重要的资源",并明确指出:大多数最佳实践都源于一个约束——上下文窗口填得很快,填满后性能会退化。这条警告是理解一切上下文操作的钥匙。上下文窗口(模型一次能处理的全部文本量,包含对话历史、读入的文件、命令输出,单位是 token 即词元)容量有限,塞得越满,模型越容易"忘记"早期指令、犯更多错误。Claude 的上下文窗口在 20 万 token 量级(具体数值请以官方文档为准,核对时间 2026 年 5 月)。
为什么对话越长 AI 反而越笨
上下文退化有三个主要来源。其一是无关片段增多:随着对话推进,早期探索读入的文件、中间跑偏的讨论、冗长的命令输出都堆在窗口里,真正相关的信息被稀释。其二是早期指令被挤出:窗口接近满时,最先被"遗忘"的往往是任务开头定下的关键约束,导致 Agent 偏离最初的方向。其三是失败尝试污染后续:一段报错的代码、一次跑偏的方案如果留在上下文里,Agent 后续可能反复受其干扰,绕不出来。
这三股力量叠加,表现为一个反直觉的现象:聊得越久,AI 的输出质量不升反降。新手常误以为是模型变笨了,其实是上下文被垃圾信息淹没。解法不是换模型,而是主动管理上下文的进出——该留的留、该清的清、该压缩的压缩。
除了 /clear 和 /compact,官方还推荐用 subagent(子智能体)来隔离消耗上下文的调查工作。当某个子任务需要读大量文件或跑大量命令——比如全库搜索某个模式、分析一段复杂日志——与其让这些冗长输出塞满主对话,不如派一个子智能体去干,它只把结论带回主对话,过程留在自己的上下文里。这相当于把上下文预算分账管理:主对话只保留决策相关的精炼信息,脏活累活的中间产物隔离在子任务里。合理使用 subagent,能让主对话的上下文寿命成倍延长。
/context 与 /compact:监控与压缩
Claude Code 提供/context命令查看当前上下文占用情况,能看到各类内容分别占了多少比例。一个实用的经验阈值是:当占用超过 60% 时,就该考虑用/compact压缩了。/compact会把当前对话历史压缩成摘要,保留关键信息、丢弃冗余细节,腾出空间继续工作。压缩不是无损失的,它丢掉的是细节和过程,留下的是结论和约定,所以要在"还没满到影响质量"时主动压,而不是等到塞爆了才救火。
/clear 与 /compact 的使用时机
/clear和/compact都能释放上下文,但适用场景不同,选错了要么丢信息、要么白忙活。
| 操作 | 作用 | 适用时机 | 副作用 |
|---|---|---|---|
| /clear | 完全清空对话历史 | 一个任务彻底结束,准备开始无关的新任务 | 当前任务的所有上下文丢失 |
| /compact | 压缩历史为摘要 | 同一任务进行中,上下文过满但还要继续 | 细节被丢弃,关键结论保留 |
判断标准很简单:任务之间有没有连续性。要开一个和之前毫不相关的新任务,用/clear彻底清白,避免旧任务的噪音污染新任务;同一个任务还没干完只是上下文满了,用/compact压缩后继续,保住任务连续性。把/clear用在同一任务中途,等于让 Agent 失忆从头猜,必然返工;把/compact用在任务切换时,旧任务的摘要纯属占地方。
CLAUDE.md:持久上下文的正确用法
CLAUDE.md 是项目根目录下的特殊指令文件,每次对话开始都会被自动加载,相当于给 Agent 一份长期有效的"项目须知"。它的价值在于承载那些 Agent 无法从代码本身读出来的信息:团队的沟通偏好、Git 分支命名规则、不可触碰的红线操作、本机环境的特殊配置。但新手常犯的错是把 CLAUDE.md 当成事无巨细的文档库,把代码结构、API 说明全塞进去,结果文件臃肿,Agent 反而抓不住重点——官方文档明确警告,臃肿的 CLAUDE.md 会让 Agent 忽略你真正的指令。
判断一条信息该不该进 CLAUDE.md,用官方给的检验标准:"删掉这一条,Claude 会不会犯错?“会犯错才留,不会就删。Agent 能从代码读出来的(比如用了什么框架、目录长什么样)不用写;Agent 猜不到的约定(比如"提交前必须跑 lint”“禁止直接操作生产数据库”“用 ES Modules 不用 CommonJS”)才值得占位置。下面是一个精简模板片段:
# 代码风格 - 使用 ES Modules(import/export),不用 CommonJS(require) - 导入时尽量解构,如 import { foo } from 'bar' # 工作流 - 改完一系列代码后务必跑一次类型检查 - 优先跑单个测试,不要每次跑全量测试套件 # Git 规则 - 分支命名:feature/xxx、fix/xxx - 提交信息用中文,动宾结构 # 红线 - 禁止删除 migrations 目录下已执行的迁移文件 - 禁止在代码里硬编码数据库连接串这份模板每一条都是"删了会出错"的硬约束,没有任何一句废话。CLAUDE.md 要像代码一样维护:出了问题就回头审一遍,定期修剪冗余,改完后观察 Agent 的行为是否真的跟着变。它随项目演进不断增值,是团队积累协作经验的载体。
Git 即存档系统:Vibe Coding 的安全网
Vibe Coding 带来一个特性:不确定性。同一个需求,问两次 AI 可能给出两套不同实现;同一次对话里 Agent 走偏了,改回来的成本可能很高。这种不确定性不全是缺点——它也是创造力的来源——但它要求你必须有一套可靠的安全网,能在 Agent 把事情搞砸时一键回到安全状态。Git 就是这张网。在 Vibe Coding 语境下,Git 的核心用法不是团队协作,而是"存档与读档"。
黄金法则:大修改前先 commit
一条铁律:每次让 Agent 做有风险的大修改之前,先 commit 一次存档。这个 commit 不追求信息完美,它的作用是标记一个"已知良好"的检查点。改坏了,git checkout .一键回退到这个点;改好了,再 commit 一个新档。把每次大修改都框在两个 commit 之间,Agent 的任何破坏都是可逆的。这比事后手工一行行回退靠谱得多——Agent 可能改了十几个文件,手工回退既慢又容易漏,而 Git 的版本回退是原子性的、确定性的。
完整的存档-回退-再存档流程
把这套机制跑一遍。假设要在项目里加搜索功能,流程如下:
# 开始新功能前先存档,标记已知良好状态$gitadd.&&gitcommit-m"开始添加搜索功能前的存档"[main 3f4a5b6]开始添加搜索功能前的存档4files changed,12insertions(+)# 让 AI 实现搜索功能...# (Agent 改了一堆文件,跑起来发现搜索把首页布局搞乱了)# 做坏了:一键回退到存档点$gitcheckout.Updated4files from the index# 回到干净状态,重新调整方案再来一次# 这回方案对了,做出来了:存新档$gitadd.&&gitcommit-m"完成搜索功能"[main 7c8d9e0]完成搜索功能6files changed,89insertions(+)git checkout .把工作区所有改动回退到最近一次 commit 的状态,Agent 那一轮的所有破坏瞬间清零。注意这个命令只回退未提交的改动,已经 commit 的不会动——所以"大修改前先 commit"才那么重要,它确保你总有一个干净的回退点。如果 Agent 的改动已经误提交了,用git reset --hard HEAD~1回退到上一个 commit 即可。
这套存档机制和前文的工作流是配套的:Explore→Plan→Implement→Commit 里的每次 Commit,就是在制造存档点;上下文管理里的/clear,对应着开一个新存档后的干净起点。把 Git 当存档系统用,Vibe Coding 的不确定性就不再是风险,而是可以放心试错的自由——最坏情况无非是读档重来。养成"动手前先存档"的肌肉记忆,是 Vibe Coding 走向稳态的最后一道保障。
存档的粒度也有讲究。太粗——一个 commit 塞进多个功能——回退时只能整体撤销,没法只退坏的那部分;太细——每改一行就 commit——又会打断节奏、产生大量噪音。合理的粒度是"一个可验证的功能单元":完成一个能独立跑通、能单独验证的小功能就存一次档。这样每个 commit 都是一个有意义的检查点,回退时能精准定位到出问题的那一格。配合 Agent 的工作节奏,通常是每完成一个 Implement 阶段、测试通过后就 commit 一次,把"功能完成"和"存档"绑定在一起,形成自然的存档节拍。