ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Claude Code Skill 工程化:从提示词到可复用工作流的完整设计指南

Claude Code Skill 工程化:从提示词到可复用工作流的完整设计指南 我前前后后写了 50 多个 Claude Code Skill结果回头整理的时候算了一笔账前 30 个基本都属于看着能用、真到用的时候想不起来、偶尔触发一次又完全没按预期走的尴尬状态。这篇文章不是劝你少写 Skill而是想把我交过的学费摊开讲清楚——Claude Code Skill 到底是套一层提示词就行还是一个需要设计输入、输出、边界和验证的工程产物。如果你正准备开始搭自己的 Skill 库或者手里已经攒了几个食之无味弃之可惜的技能文件这篇应该能帮你少走好几个来回。Claude Code Skill 的核心价值是让 Claude Code 在合适的场景里自动加载一段高质量工作流帮你完成那些有套路、有标准、但反复出现的任务。它适合所有想在命令行里提升效率的开发者和内容工作者尤其是那种每次都要临时想一遍怎么做的重复劳动。技能不在于多而在于每一次被调用时都能准确理解需求、拿到正确输入、输出可被下一步直接使用的结果。1. 前 30 个 Skill 为什么白写了三个核心原因1.1 把提示词错当成了Skill前 30 个技能里有一大半其实只是换了个文件名的提示词。它们的典型长相是打开一个 markdown 文件里面写着你是一个经验丰富的架构师请对代码进行评审并给出建议然后又补了几句注意性能、注意安全、注意可维护性。这种内容放在对话里没什么问题但作为 Skill 就彻底不合格。Claude Code 的 Skill 强调的是按需加载也就是说模型要先根据任务判断该不该加载这个技能。如果描述只有你是一个经验丰富的架构师那么模型在用户说帮我看看这段代码时很容易把它当作一个通用的角色设定而不是一个特定任务的工具箱。更糟的是它会被很多不相关的对话触发——只要涉及代码两个字它就可能跳出来结果反而污染了当前上下文。真正能用的 Skill本质是一个可以被条件触发的函数它有明确的调用条件、有参数、有处理流程、有输出格式。没有这些边界那它就不是 Skill只是一份静态的 prompt 模板而且是一份交到模型手里却不知道怎么用的模板。1.2 过度设计把流程写成玄学另一个极端是过度设计。我早期写过一个会议纪要根据不同角色整理出待办事项的技能里面写了十几步先识别参与者、再提取讨论主题、然后按时间线整理、最后生成待办清单每一步还要求输出中间结果。听起来逻辑严密实际上运行起来非常脆弱参与者要是没有明确身份标识模型的角色提取就开始瞎猜讨论主题一多按时间线整理就变成流水账有时候用户只是想让 Claude 快速列三点最重要的结论结果模型硬是走完了一大套流程把简单问题复杂化了。问题出在把自己的理想流程当成了用户的真实任务流程。实战中的任务往往带着模糊性模型需要根据上下文自主判断路径。Skill 的核心职责是提供约束和质量标准而不是把所有步骤都焊死。一个好的 Skill 应该像给新同事一份工作手册告诉他交付标准是什么、常见的坑在哪里、遇到异常情况怎么处理而不是事无巨细地规定每一个动作。我后来的做法是把 Skill 里的流程压到三段以内收集输入、执行核心分析、输出结构化结果。超过三段的流程一定是我的设计出了问题而不是任务本身太复杂。1.3 忽视了输入输出接口技能变成一次性产品前 30 个技能还有一个通病没有认真定义输入和输出。Claude Code 的 Skill 不是活在真空里的它需要接受用户的命令、路径、文件内容然后产出能被用户直接使用的结果。我早期写的技能输入经常是用户说什么就是什么输出更是随心所欲有时候是一段话有时候是一份清单有时候干脆只给一个已完成。这就导致一个局面同一个技能每次跑出来的格式都不一样。我不得不在每次使用后手动整理结果那写技能的意义就大打折扣了。我踩过的最典型的坑是一个代码提交信息生成技能。它一开始的输入要求是用户描述这次的改动输出是一段提交信息。听起来没问题但实际调用时用户往往只说帮我提交一下根本没提供描述。技能里没有写如果用户没有提供描述先用 git diff 分析改动再生成结果模型就卡住了反复问用户要描述最后技能变成了一个累赘。把输入输出接口想清楚是技能从能用走向好用的分水岭。输入边界、缺省行为、输出格式这三件事必须在 SKILL.md 里写明否则每次调用都是一次新的赌博。2. 好 Skill 的设计逻辑我只留下这 20 个的原因2.1 描述要像一把尺子怎么写 descriptionSkill 的 frontmatter 里description是最重要的一个字段它决定了 Claude Code 什么时候加载这个技能。很多人的 description 写得又宽又虚比如用于代码审查可用于各种场景帮助用户提升效率——这种描述等于没写模型根本不知道什么时候该用它。我现在的标准是描述必须写清楚什么条件下用、输入大致长什么样、任务目标是什么。拿我用得最多的代码评审技能来说--- name: code-review description: Use when 用户要求评审代码、粘贴一段代码、查看未提交的改动、检查 PR 风险或想找出隐患。输入可以是文件路径、git diff、代码片段。 ---这段描述的信息量比进行代码审查大得多。它给了模型三个判断维度触发词评审、检查、隐患、输入类型文件路径、git diff、代码片段、任务目标找风险。模型在面对用户需求时能迅速匹配到这个技能。反过来也一样重要当用户只是闲聊关闭状态时描述里的Use when限定词会帮助技能保持安静不会随便混进上下文。我前 30 个技能里有一半是死于描述写得太泛、什么都能触发解决这一个问题就能救回一大半技能。2.2 参数、输入和边界划定设计技能时少用对话里的自由发挥多用结构化输入。在 Claude Code 里当用户通过自定义命令或斜杠命令调用技能时参数会被放进$ARGUMENTS变量里。这意味着技能脚本可以通过读取这个变量来获得用户输入的原始内容而不需要在对话历史里翻找。我在 SKILL.md 里会给模型明确的参数处理指引先检查$ARGUMENTS是否为空如果是空的就输出使用说明并停止执行不要硬着头皮瞎做。这一步非常关键它避免了模型不知道用户要什么但为了完成任务开始自作主张的尴尬场景。边界划定同样重要。技能里要明确告诉模型什么可以做、什么不可以做。比如代码评审技能我会写只审查用户指定的范围不要扫描整个仓库不要主动修改代码文件只输出评审意见。边界写清楚了模型就不会在你不希望它动的方向上过度发挥。就我观察Claude Code 的技能失灵极少是能力不够绝大多数是边界不明导致的胡乱行为。2.3 把验证环节写进流程可用性测试Skill 写完之后一定要做验证而且验证不能是跑一遍看着差不多就行。我在后 20 个技能里总结出了一套简单的验收检查单是否能被定向触发当用户用常规语言提出相关请求时模型是否稳定加载这个技能。是否能在无关场景下保持沉默聊一些不相关的话题时技能不应该出现。输出结果是否可以被下一步直接使用格式是否统一是否包含必要的信息。失败时是否有清晰反馈没有输入、路径不存在、命令失败时模型是否知道该怎么处理。这套检查单看起来简单但能过滤掉大多数手感欠佳的技能。我见过太多人写完技能就扔进仓库第一次部署感觉很新鲜第二次使用发现不触发然后就再也不管了。这种技能还不如不写它除了占用目录空间和给你的技能数量凑数之外没有任何价值。3. 从零搭一个能长期复用的 Skill完整实操过程3.1 目录结构和命名规范Claude Code 的技能默认放在项目的.claude/skills/目录下每个技能一个子目录子目录里至少要有一个SKILL.md文件。以一个代码评审技能为例我的目录结构长这样.claude/skills/code-review/ ├── SKILL.md ├── scripts/ │ └── collect_diff.sh └── assets/ └── review_prompt.md命名规范用 kebab-case小写字母加短横线文件夹名和 SKILL.md 里的name字段保持一致。这是我自己踩过的坑之前有一个技能文件夹叫CodeReviewToolSKILL.md 里名字叫code-review结果在实际使用中模型对技能库里的名字产生了不一致的理解Claude Code 在内部索引时也可能因为这个不一致而出现识别问题整个过程非常头大。所有名字统一能减少不必要的错配。scripts/目录用来放可独立运行的脚本assets/目录用来放模型需要按需读取的补充模板。之所以要拆目录是为了让SKILL.md保持短小精悍正文只放最核心的策略和校验规则不把一大堆参考文案塞进初始上下文。3.2 写 SKILL.md 时真正需要的内容一份合格的 SKILL.md结构应该是触发判断 输入处理 执行策略 输出契约四段式。它的核心不是长篇大论地教模型做事而是给模型一个高效做事的框架。以下是我一个代码评审技能 SKILL.md 的精简版--- name: code-review description: Use when 用户要求评审代码、粘贴一段代码、查看未提交的改动、检查 PR 风险或想找出隐患。输入可以是文件路径、git diff、代码片段。 --- # 代码评审技能 ## 收集输入 1. 如果 $ARGUMENTS 中包含文件路径优先读取这些路径的内容。 2. 如果用户没有指定范围运行 bash scripts/collect_diff.sh 获取最近的改动。 3. 如果用户直接粘贴了代码直接使用粘贴内容不要画蛇添足再取其他文件。 ## 执行评审 按以下维度逐项检查不要混在一起写评论 - 正确性边界条件、异常处理、逻辑漏洞。 - 安全性敏感信息、输入校验、危险命令。 - 可维护性命名、结构、重复代码。 ## 输出格式 严格以下格式输出 - 结论总体评价和是否建议合并/继续开发。 - 改动点按文件维度列出关键问题。 - 风险按高、中、低列出可能出问题的点。 - 建议给出可执行的下一个动作。 ## 边界 - 只审查用户指定范围绝不扫描整个仓库。 - 不要修改任何代码文件只输出审查意见。 - 如果信息不足先反问你缺少的上下文不要替用户做假设。这份 SKILL.md 最核心的设计是输出格式部分。它给了模型一个强契约不管什么代码、什么项目最终的输出结构都是统一可预期的。我早期写的技能输出形式飘忽不定根源就是没在 SKILL.md 里固化输出格式。加上这一段之后技能产物的可用性直接提升了一个台阶。3.3 增加一个本地脚本把脏活从模型手里摘出来SKILL.md 里描述的是策略真正涉及操作系统底层的细节尽量放在脚本里。比如获取 git 改动没必要让模型去苦思冥想 git diff 的各种参数直接封装一个脚本模型调用它就是几秒钟的事。我用来获取近期改动的脚本长这样#!/usr/bin/env bash set -euo pipefail cd ${CLAUDE_PROJECT_DIR:-$PWD} if git rev-parse --is-inside-work-tree /dev/null 21; then echo ## Staged changes git diff --cached --stat echo echo ## Unstaged changes git diff --stat else echo 当前目录不是 git 仓库$PWD exit 1 fi这里有两个细节值得说。第一set -euo pipefail是 shell 脚本的保命符任何一个中间命令出错就会立刻退出避免模型拿到半截错误结果后还在傻乎乎地往下分析。第二CLAUDE_PROJECT_DIR是项目根目录脚本先切过去再执行 git 命令这样不管用户的当前工作目录在哪都能拿到同一个仓库的改动如果没有这个环境变量就退回到当前目录。把逻辑从 SKILL.md 里摘到脚本里还有一个对我的好处模型不再需要理解 git 的所有细节。它只需要知道调用了这个脚本、拿到输出、按 SKILL.md 的策略去分析。这既降低了模型推理的负担也让实现细节可以在本地单独调试跑通了再交还给技能使用。另外脚本写完后记得执行chmod x scripts/collect_diff.sh否则权限不够的话Claude Code 在执行时可能会遇到拒绝访问的报错。Windows 环境下如果使用 Git Bash脚本同样能运行但要注意换行符和路径分隔符的差异。3.4 完整的调用链路一个新技能从写到用把技能文件放好之后完整的调用链路是这样的用户在 Claude Code 里输入帮我 review 一下今天改动的代码。Claude 根据 code-review 的description判断这个需求匹配当前技能于是加载SKILL.md。模型看到收集输入部分提到$ARGUMENTS为空时跑脚本于是调用bash scripts/collect_diff.sh。脚本输出最近 staged 和 unstaged 的改动统计模型拿到这些上下文按 SKILL.md 里定义的维度进行分析。最终模型按结论、改动点、风险、建议四个部分输出审查结果。这里最微妙的地方在于模型不是被强制调用技能而是判断后主动调用。所以 description 的质量会先于技能正文影响这次调用的成败。如果 description 写不清楚后续的流程再完美也起不了作用因为模型压根没有进入这个技能的流程。3.5 权限和安全设置别让技能变成脱缰野马技能会驱动模型执行命令这就涉及权限管理。我在每个技能的正交或配置文件里尽量明确最小权限原则模型只被允许执行这个任务真正需要的命令剩下的操作一律先明确征求用户同意。具体来说我会在 SKILL.md 的边界部分写清楚不要执行rm之类的危险命令不要向任何外部网络地址发送仓库内容不要在未授权的情况下修改系统文件。对于技能引用的脚本我也会检查一遍里面有没有不可控的命令拼接。这个习惯是从一次事故中养成的——我之前写的一个日志分析技能脚本里拼接了用户输入的文件名后直接传给cat遇到带空格的路径就报错后来改成使用引号包裹变量这才从根上解决问题。技能是给模型开的一扇窗但它不应该变成一扇任意门。每次运行前只要有不可逆的影响就让模型停下来跟用户确认一遍。4. 常见问题与排查技巧实录4.1 技能完全不触发用户提了明确需求也没反应这是我在前 30 个技能里遇到最多的状况。排查思路顺序如下先看目录是否在.claude/skills/下且文件名是否是SKILL.md大小写不能错再看 frontmatter 是否完整有没有name和description两个字段最后看 description 是否过于抽象。我调过一个把项目文档生成结构化索引的技能description 写的是帮助用户整理文档。结果它几乎从来没有被触发。后来我把描述改成Use when 用户想要为 README 或 docs 目录生成索引目录、梳理文档结构、检查缺失文档链接当天就被成功调用了好几次。核心原则是你要在描述里给出具体的触发信号而不是只描述任务类型。4.2 技能被加载了但输出完全不符合预期这种情况多半是 SKILL.md 里的执行策略不够具体。我见过最典型的是代码修复技能它只说请修复用户报告的问题至于怎么定位问题、改完之后要不要跑测试、测试不过怎么处理全都没写。模型加载这个技能后跟没加载几乎没区别。我的处理方式是给技能增加反馈闭环在步骤中写明修改完成之后必须运行相关测试如果测试失败立即把失败信息贴回上下文并分析原因而不是直接声称修复完成。这个闭环看起来是增加复杂度实际上是把模型的思考方向锁死在可验证的路径上输出质量会明显提升。4.3 调用时参数丢了技能不知道要处理什么Claude Code 里通过命令调用技能时用户输入的内容通常会被放入$ARGUMENTS。但模型有时会在调用脚本时忘记传递这个变量导致脚本拿不到参数。我的解决方法是在 SKILL.md 的输入处理部分显式写一句——先把$ARGUMENTS赋值给一个本地变量如果它为空立即输出使用说明并停止。不要小看这一句它把空参数这一异常状态变得可预期。没有这一句时模型可能会自行推导一个假设的参数值然后沿着错误的假设走完整个流程最后给你一个看似合理实则毫无意义的结果。4.4 技能文件太长每次触发都在消耗大量上下文这是我在选型时特别在意的点。Claude Code 加载技能时SKILL.md的内容会成为模型上下文的一部分。如果一个技能文件写了两千字那么即便只被调用一次这两千字也会占掉模型的注意力预算。要是每次会话里技能还反复触发上下文膨胀带来的问题会越来越明显——模型开始忽略早先的指令前后行为不一致输出质量断崖式下跌。我的经验是SKILL.md控制在 600 字以内只保留最核心的触发条件、输出格式和边界约束。那些需要补充的案例、参考模板一律放到assets/目录里并明确告诉模型如果有需要再打开对应文件阅读。这样技能在未触发前只消耗一个轻量级的注册信息不会拖累整个会话。4.5 多个技能互相抢活行为混乱当技能多了以后最容易出现的是描述之间的重叠。我有两个技能一个是生成技术方案一个是评估技术方案description 里都包含用户问技术选型这个触发词。结果就是用户问选型时两个技能同时被加载模型一会按生成的思路走一会按评估的思路走整个会话的氛围极其分裂。处理办法是给技能划出独立边界触发词尽量不要重叠如果一个任务会自然导致另一个任务就在前一个技能里写明本技能只生成方案评估请交给单独对话。技能不是越多越好如果每次写新技能时发现它和旧技能共用了一半触发条件那就该考虑是合并而不是继续加新文件。4.6 技能里的脚本跑不通报错信息看不懂脚本跑不通首先要确认执行环境。单独在终端里跑一遍bash scripts/xxx.sh看它还报不报错不报错的话问题大概率出在模型拼接命令时少了变量、路径没加引号或者工作目录不对。我曾经写过一个日志聚合脚本在终端里跑得好好的但 Claude Code 调用时始终说找不到文件。排查了半天发现脚本用的是相对路径而 Claude Code 执行命令时的工作目录是某个子目录。修正方法是让脚本在开头用cd ${CLAUDE_PROJECT_DIR:-$PWD}固定工作目录或者对外部传入的文件路径做一次绝对路径解析问题立刻消失。这里我补充一个容易被忽略的点在 SKILL.md 里要求模型在运行脚本前先把脚本路径转换成绝对路径再用绝对路径去执行。这可以避免余下当前目录不对和路径有空格两类问题实测下来非常管用。5. 我现在留下这 20 个技能靠的是一张排查速查表把踩过的坑整理成速查表之后我现在维护技能时的检查动作变得很固定检查项检查方法修复思路description 是否能触发用 3 个典型请求在对话中试一下加入具体触发词和输入类型删掉宽泛描述SKILL.md 是否超过 600 字统计文件字数把长内容移到 assets正文只留策略空参数是否有兜底不带参数调用一次在输入处理部分写明空参数时输出使用说明并停止输出格式是否统一连续调用 3 次对比结果在 SKILL.md 里固化结论-改动点-风险-建议这类输出契约脚本是否可独立运行在项目根目录手动执行一遍修正工作目录、路径引号、错误处理脚本是否包含危险命令通读一遍脚本源码删除或限制危险操作仅保留最小权限这张表既是自查清单也是我删技能的依据。一个技能只要在表格里有任何一项不合格我就不会把它纳入正式技能库而是扔回草稿区继续打磨。前 30 个技能之所以白写是因为我连这张表都没有写完一个就觉得自己完成了一个技能根本没想清楚它该在什么场景下发生作用、怎么保证每次产出都可靠。现在每写一个新技能我都会花和写代码一样的时间来调试它。换个说法技能不是一个 prompt 文件它是一段需要维护的产品代码。用这个心态去写你会不得不承认合格的技能确实没有那么多但每一个留下来的都能在关键时刻替你省下大把时间。回看这段经历我真正的体会是Claude Code 的技能系统并不复杂复杂的是人很容易高估一个想法的完成度。写 50 个技能不难难的是把 50 个都维持到可被稳定使用的标准。如果你现在正准备动手我的建议是先把每个技能的目的压成一句话什么情况下、谁来用、用了之后产出什么。如果这句话你写不清楚那么这个技能还不到开始写文件的时候。宁可手写一两句话的任务描述也不要让一个半成品技能留在你的仓库里消耗你的注意力。
返回列表