引言

Claude Code 作者 Boris Cherny 说过一句话:“我已经不写 Prompt 了,我写 Loop。”

这句话被很多人转发,但少有人真正解释清楚它到底意味着什么。Prompt 和 Loop 的差别,不是写一句话还是写一段话的差别——而是两种完全不同的工程思维。

这篇文章就顺着这条线,把三个核心问题讲清楚:Loop 到底是什么、四层扩展能力(CLAUDE.md / Hooks / Skills / Subagents)怎么分工、以及 Skills 到底怎么写才不是废纸。

一、为什么只写 Prompt 不够了?

Prompt 当然有用。你问一个概念、贴一段代码让它改写、让它生成一个 SQL——这些场景里,Prompt 就够了。因为任务短、边界清楚、结果也容易人工判断。

但真实项目不是这样。你让 Claude Code 修一个登录 Bug,往往不是一句话能完成的:先读代码,定位调用链,判断哪个文件该改哪个不能动,修改实现,跑测试——测试失败了还要回头看日志,日志里可能暴露了另一个问题。

这时候你会发现:Prompt 只是任务的起点,不是任务的完成机制。 你只给了它目标,但没告诉它去哪里找入口、哪些文件不能动、怎么判断修好了、测试失败怎么办、什么时候必须停下来。如果这些都靠模型自己猜,它就会浪费大量上下文摸索,或者看起来很努力,最后朝错方向越走越远。

二、Loop 到底是什么

一个最小的 Agent Loop 大概长这样:

目标 → 计划 → 执行 → 观察 → 验证 → 反馈 → 下一步

验证通过就停止。验证失败就把失败信息带回去,重新计划。触碰边界就暂停,让人决策。

这和普通 Prompt 的差别很大。Prompt 是"我说一句,你答一句"。Loop 是"我给你目标、工具、规则和验收标准,你自己推进,但每一步都要留下证据"。

但坏 Loop 比坏 Prompt 更危险。一个坏 Prompt,最多回答不理想。一个坏 Loop,会一直跑、一直改、一直消耗 token,还可能把项目改乱。

好的 Loop 至少要有四个东西:

  1. 明确目标——不是"优化一下性能",是"让接口 P95 从 800ms 降到 300ms 以内,不改变返回结构"
  2. 可执行工具——能读代码、跑测试、看日志、查文档、调用脚本
  3. 验证反馈——测试结果、lint 结果、构建结果、接口返回、日志差异,全要回到上下文
  4. 停止条件——什么时候算完成?什么时候算失败?什么时候必须停下来问人?

Prompt 工程和 Loop 工程不是一回事

Prompt 工程关心的是"模型怎么回答"——角色、背景、输出格式、示例、约束。

Loop 工程关心的是"任务怎么被可靠完成"——任务怎么拆、信息怎么进上下文、工具怎么调用、失败怎么反馈、规则怎么长期保存、验收怎么自动化、权限怎么限制。

举个例子。只写 Prompt 的人会说:“帮我修一下支付回调偶尔失败的问题,注意代码质量。”

会写 Loop 的人会这样给任务:“先从支付回调入口开始读,不要修改数据库迁移文件。定位失败原因后,给出改动计划。修改完成后跑支付模块单测,如果测试失败,优先根据错误日志修复;如果涉及幂等逻辑或金额计算,先停下来说明风险,不要直接改核心规则。”

差别不是提示词更华丽,而是把 Loop 的关键部件放进去了:搜索入口、禁止范围、计划阶段、测试反馈、错误恢复、高风险暂停点。

普通开发者怎么开始写 Loop

  1. 别只写目标,要写验收——“修完后跑登录模块测试,并说明失败用例是否恢复”
  2. 别只让它改,要让它先定位——“先找登录入口、认证中间件和错误日志位置,列出可能原因”
  3. 给它边界——“不要修改数据库 schema"“不要改公开 API 返回结构”
  4. 把反复说的话写进项目规则——如果你每次都提醒同一件事,别再靠聊天提醒了,写进 CLAUDE.md
  5. 优先补反馈信号——没有测试的项目,Agent 会很累;补了测试、lint、构建脚本,Agent 才有东西可以观察

三、四层能力的分工与演进

很多人学完 CLAUDE.md、Hooks、Skills、Subagents 之后会问同一个问题:这些东西不都是给 Claude 加规则吗,为什么要分四套?

因为它们控制的根本不是一回事。这条演进线是:

让 Claude 记住规则 → 让关键动作确定发生 → 让专项能力按需加载 → 让复杂任务交给独立角色

第一层:CLAUDE.md —— 常驻的项目说明书

每次让 Claude Code 干活都要重复交代的事,写进 CLAUDE.md。包管理器、金额单位、数据库禁区、测试命令——这些跨任务都稳定的规则,放在常驻上下文里。

但它有两个边界:第一,“看到了"不代表"一定做到”——“修改后运行测试"仍然只是一条自然语言指令,最终靠模型记住并执行。第二,常驻上下文不是免费仓库——把所有文档全塞进去,每一轮都要背着暂时用不到的信息。

第二层:Hooks —— 把"应该做"升级成"触发就做”

写在 CLAUDE.md 里是"Claude,记得做”。写成 Hook 是"只要编辑完成,这个检查点就会被触发"。

Hooks 插在 Claude Code 生命周期的事件节点上:PreToolUsePostToolUsePostToolUseFailureStopSubagentStartSubagentStop。它不是循环外的一份说明,而是卡在"准备行动、行动完成、准备结束"这些节点上的闸门。

Hooks 适合"每次命中这个事件都要做"的动作——格式化、危险命令拦截、审计记录。它不适合承载需要理解业务、根据现场调整步骤的发布手册。确定性动作交给 Hook,需要推理的流程交给 Skill。

第三层:Skills —— 按需加载的专项能力

发布时才需要的检查清单、排查线上问题时才需要的 Runbook、评审支付代码时才需要的安全规则——这些很重要,但不是每个任务都要看。

塞进 CLAUDE.md,上下文会越来越胖;做成 Hook,又没办法表达"先根据现象判断,再选择不同排查路径"。这时候该用 Skill。

Skill 是一套按需加载的知识和工作流,启动时只加载名称和描述,判断任务相关时才展开完整内容。CLAUDE.md 是"每次都带上",Skill 是"这次用到才展开"。

第四层:Subagents —— 独立上下文里的角色分工

有了 Skills,Claude 已经能按需获得专项能力。但复杂任务还有一个问题:所有工作挤在同一个上下文里。

主 Agent 先读几十个文件定位问题,又改代码、跑测试,最后还让它审查自己的实现——上下文越来越脏,早期约束被压缩;让同一个 Agent 给自己的答案挑错,天然容易自我认可。

Subagents 解决的不是"再加一份提示词",而是再开一个独立的执行上下文。探索过程噪音留在子 Agent 的上下文里,只把带证据的结论带回主 Agent。执行者和审查者也被结构性地分开。

怎么选:四个判断问题

一条新要求来了,写到哪?

判断问题放哪里典型例子
Claude 是否每次都应该知道?CLAUDE.md技术栈、目录、构建命令、禁区
是否命中事件就必须执行?Hooks格式化、阻止危险命令、审计
是否只在某类任务中需要一套方法?Skills发布、评审、排障
是否需要独立上下文或独立角色?Subagents大范围探索、安全复核、并行测试

四层不是互相竞争,而是分别控制 Agent 的四个位置:上下文里放什么,生命周期中卡什么,任务需要时加载什么,复杂工作交给谁。

别一上来就抄别人的全家桶——几百行 CLAUDE.md、几十个 Hooks、十几个 Skills 再加一队 Subagents。同一条规则说了两次,写进 CLAUDE.md;某个动作必须发生,做成 Hook;某套流程反复复制,养成 Skill;某项工作需要独立探索,交给 Subagent。看问题卡在哪一层,就补哪一层。

四、Skills 实战:Anthropic 的九类分类与写作原则

Anthropic 内部用了好几百个 Skill,总结出了一些硬经验。

Skill 不是"一个 markdown 文件",是一个文件夹

很多人以为 Skill 就是写个 .md 文件告诉 Claude 怎么做。这是错的。Skill 是"指令、脚本和资源的文件夹":SKILL.md 放主指令和触发描述,references/ 放按需读的参考文档,scripts/ 放可执行脚本,assets/ 放模板和示例。

九类 Skill

Anthropic 把内部几百个 Skill 归成了九类,核心原则是一个 Skill 只干一类事

  1. 库/API 参考——内部计费库的坑、内部平台 CLI 的子命令示例
  2. 产品验证——写完代码怎么验证它真的跑通了(这一类对产出质量的提升最可量化)
  3. 数据获取与分析——漏斗查询、留存对比、监控字段映射
  4. 业务流程与团队自动化——聚合日报、按固定 schema 建工单
  5. 代码脚手架/模板——按框架生成样板代码
  6. 代码质量与评审——强制代码规范、对抗式评审(另起一个子 Agent 来挑刺)
  7. CI/CD 与部署——盯着 PR、灰度放量、出问题自动回滚
  8. Runbook 排障手册——从一个报警出发,多个工具一步步查
  9. 基础设施运维——带护栏的运维操作

怎么写好一个 Skill

别说废话,只写能把 Claude 推出惯性的东西。 Claude 本来就懂很多编程知识。别写它本来就会的东西,把笔墨花在那些能把它推出默认思路的信息上——比如"我们团队的设计偏好"、“这个内部平台的特殊规则”。

Gotchas(坑)是 Skill 里信息密度最高的部分。 比如:同一个字段在 A 系统叫 user_id,在 B 系统叫 uid;某张表是 append-only 的,你以为能 update,其实只能插入。这种知识在文档里通常找不到,全靠人踩出来。

渐进式披露:SKILL.md 当索引,用到才读。 不要把所有参考文档全塞进上下文。SKILL.md 只放轻量概要和指针,Claude 真用到某个参考资料时,才去读那个文件。

描述是写给模型看的,不是写给人看的。 SKILL.md 里的 description,决定了 Claude 什么时候触发这个 Skill。把用户会用来唤起这个能力的词直接塞进去,别写文绉绉的简介。

别想着一上来就写个完美 Skill。 Anthropic 内部最好用的 Skill,几乎都不是设计出来的,是养出来的。起步:几行字 + 一个你已知的坑。撞坑:Claude 在真实使用里出错,补进 Gotchas。反复,它就慢慢长成了一个靠谱的 Skill。

总结

这篇文章串了三条线:

  1. 从 Prompt 到 Loop——AI 编程正在从对话技巧进入工程闭环。Prompt 是入口,Loop 是系统。差距不在会不会喊 AI 干活,而在能不能把模糊任务拆成可执行、可验证、可停止的闭环。

  2. 四层能力的工程演进——CLAUDE.md 管常驻规则,Hooks 管确定性触发,Skills 管按需方法,Subagents 管独立执行。不是四选一,是按问题卡在哪一层补哪一层。

  3. Skills 的正确写法——不是写一个长 md 文件,而是建一个带脚本、带资源、带记忆的文件夹。最值钱的部分是坑,最好的姿势是先小再长大。

参考链接

  • Claude Code 官方文档:Memory、Hooks、Skills、Subagents
  • Anthropic Blog: How we use skills
  • Boris Cherny 采访