Skills 你不知道的参数细节分享
公众号名称:朱昆鹏AI手记
作者名称:朱昆鹏mm
发布时间:2026-05-28 23:20
前言:为什么Skills需要参数功能?
假设你写了一个 Skill 叫 /分析文件,内容是:
请帮我分析 src/index.ts 这个文件有没有问题。
能用,但有个问题——文件名是写死的。
今天想分析 index.ts,明天想分析 login.ts,你总不能每次都去改这个文件吧?
我们想要的效果是这样:
用户输入:/分析文件 src/login.ts
↓
Skill自动把"src/login.ts"填进去
↓
请帮我分析 src/login.ts 这个文件有没有问题。
让用户调用时带着「参数」进来,也就是一个符号:$ 就可以解决这个问题
下面跟着我们来看一下这个参数符号
一、$ 初步讲解
Claude Code 里跟 $ 有关的写法,其实只有两类:
第一类:参数占位符(接受用户输入的东西)
| 写法 | 含义 |
|---|---|
$ARGUMENTS | 用户传进来的全部内容 |
$0``$1``$2 | 第几个参数(从 0 开始数) |
$ARGUMENTS[0]``$ARGUMENTS[1] | 上面那种的「全名版」 |
$名字 | 给参数起个有意义的名字 |
第二类:环境变量(运行环境自动提供的信息)
| 写法 | 含义 |
|---|---|
${CLAUDE_SKILL_DIR} | 当前 Skill 自己所在的目录 |
${CLAUDE_SESSION_ID} | 当前会话的编号 |
重点划一下: 第一类是
$XXX,没有花括号。 第二类是${XXX},有花括号。 这俩是被两套不同的代码处理的,写错花括号就不会替换,这是新手最容易栽的坑之一。
下面一个一个讲。
二、最基础的 $ARGUMENTS
基本用法
在 SKILL.md 正文里直接写 $ARGUMENTS:
---
description:分析指定文件
---
请帮我分析这个文件有没有问题:$ARGUMENTS
用户这样调用:
/分析文件 src/login.ts
$ARGUMENTS 就会被替换成用户跟在命令后面写的那串字:
请帮我分析这个文件有没有问题:src/login.ts
就这么简单。 $ARGUMENTS 拿到的是用户在命令名后面写的所有内容。
一句话记忆
$ARGUMENTS= 「用户输入的所有东西」的占位符。 你把它放哪里,用户的输入就填到哪里。
容易踩的坑:大小写
$ARGUMENTS 必须全大写。写成 $arguments、 $Arguments 一律不认,不会替换。
如果记不住,就记成「它在喊」,所以全大写。
三、$ARGUMENTS 自动兜底机制
新手常问一个问题:
「如果我忘了写
$ARGUMENTS,用户传的参数是不是就丢了?」
不会丢。
举个例子,假设你的 Skill 长这样,正文里没写任何占位符:
请帮我做代码审查。
用户照样传了参数:
/审查 src/login.ts
Claude Code 会发现你正文里没有占位符,于是自动把参数贴到正文末尾,注入给模型的内容会变成:
请帮我做代码审查。
ARGUMENTS: src/login.ts
所以参数永远不会凭空消失。这只是个兜底机制,建议还是显式写 $ARGUMENTS 让效果更可控。
四、参数切片: $0 / $1 / $2
为什么需要
很多时候用户传的不是一个东西,而是几个。比如:
/建任务修复登录bug 高优先级张三
这里有三段信息:做什么、多急、给谁。我们想分别接住它们。
怎么用
用编号占位符
$0
$1
$2
:
任务内容:$0
优先级:$1
负责人:$2
用户调用 /建任务修复登录bug 高优先级张三,结果:
任务内容:修复登录bug
优先级:高优先级
负责人:张三
一句话记忆
把参数想象成一排储物柜,编号从 0 开始:
$0是第 1 个柜子、$1是第 2 个、$2是第 3 个…… (程序员数数都从 0 开始,习惯一下就好)
等价写法
$0 是简写,它的「全名」是 $ARGUMENTS[0]:
任务内容:$ARGUMENTS[0]
优先级:$ARGUMENTS[1]
两种写法效果完全一样,平时用 $0 就够了,省事。
容易踩的两个坑
坑 1:编号取多了会变成空白
如果你写了 $2(想取第 3 个),但用户只传了 2 个参数,那 $2 会被替换成空字符串——不会报错,也不会留下原样的 $2。
所以建议你在正文里写好「后路」,比如:「如果没填负责人,默认指派给我自己」。
坑 2: $1 后面紧贴字母不行
$1 你好✅ 正常替换(后面是空格)$1st❌ 不会替换(系统怕认错,看到数字后面紧跟字母就不动了)
如果非要紧贴,改用全名 $ARGUMENTS[0]st 就能正常工作。
五、给参数起名字: $文件名、 $负责人
为什么需要
$0
$1
$2
有个问题——过两天你自己都忘了 $1 到底是啥。
更糟的是别人接手你的 Skill,看到一堆 $0 $1 $2 完全猜不到含义。
我们希望写出这样的代码:
任务内容:$任务内容
优先级:$优先级
负责人:$负责人
一眼就能看懂。这就是「具名参数」。
怎么用(两步)
第一步:在 SKILL.md 最上面的 frontmatter 里,用 arguments 字段按顺序列出参数名:
---
description:创建任务
arguments:
-任务内容
-优先级
-负责人
---
第二步:正文里就能直接用名字了:
任务内容:$任务内容
优先级:$优先级
负责人:$负责人
用户调用 /建任务修复登录bug 高张三,结果:
任务内容:修复登录bug
优先级:高
负责人:张三
比 $0 $1 $2 好读太多了。
一个关键认知:名字只是「外号」,本质还是按顺序
这是这一节最重要的一点,很多人会理解错:
❌ 误解:以为可以这样写命令
/建任务负责人=张三优先级=高(像填表格那样指定) ✅ 真相:还是严格按位置对号入座
arguments 里写的第 1 个名字,永远绑定用户传的第 1 个参数。
名字只是给「1 号柜子」贴了个标签叫「任务内容」方便你读,但东西还是按顺序塞进柜子的。位置错了,名字救不了你。
容易踩的坑:名字不能用纯数字
别把参数命名成 1、 2 这种纯数字。
因为系统已经用
$1
$2
表示编号了,如果你的参数名也叫 1,两套语法就打架了。系统会直接无视这种命名,相当于没声明。
起名就起有意义的人话,比如 文件名、 模式、 负责人。
六、带空格的参数怎么传?引号大法
为什么需要
假设用户想传一句带空格的任务描述:「修复 登录页 崩溃」(中间有空格)。直接传:
/建任务修复登录页崩溃高张三
系统会按空格切,结果就乱了:
$0=修复$1=登录页$2=崩溃- 本来这三个该是一个整体!
怎么用:加引号
把要保持完整的内容用引号包起来:
/建任务"修复 登录页 崩溃"高张三
现在系统就知道这一坨是一个整体了:
$0=修复登录页崩溃✅$1=高$2=张三
双引号 "..." 和单引号 '...' 都能用,效果一样。
一句话记忆
参数里有空格,就用引号
"..."抱成一团,别让系统切散了。
一个安全方面的小知识
如果用户传了 $HOME 这种看起来像变量的东西进来,它不会被偷偷换成你电脑里 $HOME 的真实值,而是原样保留成 $HOME 这几个字。
这是故意设计的——防止有人通过参数偷读你的环境变量。
记住一句话:参数里的 $ 都是死字,不会被自动展开。
七、 ${CLAUDE_SKILL_DIR} 介绍
为什么需要
一个 Skill 经常不只有 SKILL.md 一个文件,旁边可能还放着脚本、模板、参考资料:
我的Skill/
├── SKILL.md
└── scripts/
└──检查.sh ←我想在Skill里运行这个脚本
问题来了:怎么写脚本的路径?
如果写死成 /Users/你/.claude/skills/我的Skill/scripts/检查.sh,那别人下载你的 Skill 装到自己电脑就找不到了——每个人电脑的路径都不一样。
怎么用
用魔法变量 ${CLAUDE_SKILL_DIR},它会自动变成「当前 Skill 自己所在的文件夹路径」:
运行检查脚本:
!`${CLAUDE_SKILL_DIR}/scripts/检查.sh`
不管这个 Skill 被装到谁的电脑、哪个项目, ${CLAUDE_SKILL_DIR} 都能准确指向它自己的位置。
一句话记忆
${CLAUDE_SKILL_DIR}= 「我这个 Skill 住在哪」。 想引用同目录的脚本/模板,用它就对了,别写死路径。
重点:花括号别忘了!
再强调一遍上面提过的:
- 参数家族(接用户输入的):
$ARGUMENTS、$0、$名字,没有花括号 - 环境家族(运行环境的):
${CLAUDE_SKILL_DIR}、${CLAUDE_SESSION_ID},必须带花括号
如果你把环境变量写成 $CLAUDE_SKILL_DIR(少了花括号),它不会被替换。这是新手最常踩的坑之一。
顺便认识一下 ${CLAUDE_SESSION_ID}
${CLAUDE_SESSION_ID} 会被替换成当前对话的编号,常用于给临时文件起不重名的名字,例如:
把结果保存到/tmp/result-${CLAUDE_SESSION_ID}.json
用法和 ${CLAUDE_SKILL_DIR} 一样,记得带花括号。
八、组装一个真正干活的 Skill
把前面学到的全用上,做一个真能用的例子:用户传一个模块名,Skill 自动跑测试 + 分析失败原因。
先认识两个新朋友
$ 很少单独用,它经常和另外两个符号一起出现:
| 符号 | 作用 |
|---|---|
$ | 接参数 / 用变量 |
!`命令` | 真去执行一条命令,把命令的输出填进来 |
@文件路径 | 把某个文件的内容读进来 |
完整代码
---
description:跑指定模块的测试并分析失败
arguments:
-module
allowed-tools:Bash(npm test:*)
---
我要测试的模块是:$module
先看看当前 git 状态:
!`git status --short`
跑一下测试:
!`npm test -- $module 2>&1`
请根据上面的测试输出,告诉我哪里挂了、怎么修。
用户只要敲一句
/测试模块 auth
幕后发生了什么
$module被换成auth(第五节学的具名参数)!`git status --short`真的去执行了 git 命令,把输出填进上下文!`npm test -- auth`真的跑了测试,把测试结果填进上下文- 整段打包丢给 AI,让它根据真实输出来分析
一句命令,背后自动做了一整套活。 这就是 Skill 从「静态说明书」进化成「智能助手」的样子。
九、随身速查卡
打印贴显示器旁边的那种:
| 我想做什么 | 用这个 | 例子 |
|---|---|---|
| 接住用户的全部输入 | $ARGUMENTS | 分析:$ARGUMENTS |
| 接住第 1 个 / 第 2 个参数 | $0``$1(从 0 数) | 给 $1 |
| 给参数起个名字 | frontmatter 加 arguments:,正文用 $名字 | $负责人 |
| 传带空格的参数 | 用引号包起来 | "a b c" |
| 指向 Skill 自己的目录 | ${CLAUDE_SKILL_DIR}(带花括号) | ${CLAUDE_SKILL_DIR}/x.sh |
| 跑一条命令并塞结果 | !`命令` | !`ls` |
十、新手常踩的 5 个雷
| 翻车现场 | 真正原因 | 怎么救 |
|---|---|---|
$arguments没被替换 | 写成了小写 | 必须全大写$ARGUMENTS |
$负责人没被替换 | frontmatter 里忘了声明 | 先在 arguments: 里加上 负责人 |
${CLAUDE_SKILL_DIR}没被替换 | 花括号丢了,写成了 $CLAUDE_SKILL_DIR | 环境变量必须带 {} |
| 参数被切成好几段 | 内容有空格但没加引号 | 用 "..." 把它抱成一团 |
$2变成了空白 | 用户没传够那么多参数 | 在正文里写好「没传时怎么办」 |
十一、建议你按这个顺序练手
光看不练等于白看。建议你真的敲一遍下面这 5 步,比看 10 遍都强:
- 第一步:写一个 Skill,正文就一句
你想说的是:$ARGUMENTS,调用试试 - 第二步:改成
$0``$1,故意少传一个参数,看看是不是真的变空白 - 第三步:在 frontmatter 加
arguments,把它改成具名参数 - 第四步:传一个
"带 空 格 的"参数,验证有没有被切散 - 第五步:照第八节,配合
${CLAUDE_SKILL_DIR}和!`命令`,做一个真能跑的小工作流
走完这 5 步,你就不只是「会用 Skill」,而是「会造 Skill」了。
十二、最后总结
回顾一下整篇的核心:
| 内容 | 一句话总结 |
|---|---|
两类 $ 写法 | 参数 $XXX(无花括号) vs 环境变量 ${XXX}(有花括号) |
$ARGUMENTS | 接住用户的全部输入 |
$0``$1``$2 | 接住第几个参数,从 0 数起 |
具名参数 $名字 | 在 frontmatter 用 arguments 声明,按位置对应 |
引号 "..." | 让带空格的参数保持完整 |
${CLAUDE_SKILL_DIR} | 当前 Skill 自己的目录路径 |
| 兜底机制 | 没写占位符也会自动追加,参数永远不会丢 |
理解了这些,你就掌握了 Skills 参数系统的全部要点。
今天的文章就到这里了,希望读完你能对skills的参数有更深入的理解
往期推荐





内容效果不满意?点此反馈