DeepDojo.AI发布 2026-11-12English

SKILL.md 太长?拆成按需读取的文件

Claude CodeAI 编程

一个代码审查 Skill 用了几个月,SKILL.md 越写越长:开头是审查步骤,中间塞了一份四十条的检查表,后面跟着五个正例、五个反例,最后还贴了一段收集 diff 的 Shell 脚本。每次调用,这一整份都进入上下文,Claude 真正要先看的那几步反而被埋在中间。

更麻烦的是,Skill 一旦加载,正文就会留在对话里。文件越长,后面每一轮都要多背一份成本。可要是把内容全拆出去,又可能出现另一种情况:Claude 判断严重程度时,不知道标准写在哪个文件里,干脆凭感觉来。

组织 Skill 要处理好三类内容:

  • 每次都要用的输入、关键判断、步骤和停止条件,留在 SKILL.md;
  • 某一步才用到的检查表、例子和脚本,放进辅助文件,并写明什么时候读;
  • Git 状态、当前分支这类每次都要重新查的实时信息,用动态注入放进来,只注入下一步用得上的部分。

下面按 Skill 的加载过程,把这三类内容各放到位。

01 Skill 怎样一步步进入上下文

把稳定、反复使用的方法封装为 Skill,可以在相关任务中加载。CLAUDE.md 保留每次会话都需要的项目约定,较长的任务方法则按需使用:

会话平时只看到 Skill 名称与 `description`
  → 任务匹配或用户显式调用
加载 `SKILL.md`
  → 按需读取参考、示例或脚本
  → 按 Skill 规定的方法执行并验证

正文加载后留在当前会话里,后续每轮不会重读磁盘。改文件也不会替换历史里的旧版。重复调用的内容相同,通常不再插入一整份;参数或动态输出变了,仍可能再加入全文。

Claude Code 的 Skills 文档把这一点当作写正文的首要约束:Skill 加载后内容会跨轮次留在上下文里,所以每一行都是反复发生的 token 成本,正文要保持简洁。官方给的参考线是 SKILL.md 控制在 500 行以内,详细的参考资料移到单独的文件里。

Claude Code 最佳实践拿这一点和 CLAUDE.md 做了对比:对于 Claude 能自行启动的 Skill,每个会话里它只看到名称和描述,等任务需要时才读完整文件;放在 Skill 里的一份长发布流程,不会拖累你手上无关的 bug 修复。

02 主文件留什么,辅助文件放什么

成熟 Skill 可以按职责拆分:

review-changes/
├── SKILL.md
├── checklist.md
├── examples/
│   ├── valid-finding.md
│   └── rejected-finding.md
└── scripts/
    └── collect-diff.sh

主文件保留输入、关键判断、步骤和停止条件。长检查表、例子和脚本放在辅助文件中,并写清读取时机,例如“开始审查前读 checklist.md;不确定某条发现是否成立时查 examples/”。

官方文档的说法几乎一致:辅助文件让 SKILL.md 专注于要点,Claude 只在需要时读取详细资料;大型参考文档、API 规格、示例集合用不着每次运行都进入上下文。官方还特别区分了脚本:scripts/ 里的脚本是拿来执行的,不会加载进上下文。要让 Claude 知道每个文件装着什么、什么时候该读,就在 SKILL.md 里引用它们。

小黑把重复出现的输入、步骤、工具和质量标准装进按需加载的 Skill 工具箱

03 拆完以后,按一次审查走一遍

拆完以后,可以按一次审查的过程检查:判断严重程度前能否读到标准?对某条发现拿不准时,能否找到例子?文件拆开后,还要确保需要时能找到并读取。

开头那份四十条的检查表,拆进 checklist.md 以后,SKILL.md 里要留一句“开始审查前读 checklist.md”。少了这句,拆分就等于把标准藏了起来。Skill 是否在该出场时出场,是另一个问题,见Claude Code Skill 不触发或乱触发。

04 用动态注入放进实时状态

有些状态每次都得重新查,比如 Git 差异、当前分支和依赖版本。可以让命令先执行,把结果放进 Skill:

## 当前分支
!`git branch --show-current`

## 暂存区改动统计
```!
git diff --cached --stat
```

带感叹号的 Shell 命令在模型读到正文前执行。${CLAUDE_SKILL_DIR} 可定位 Skill 自带脚本,${CLAUDE_PROJECT_DIR} 可定位项目脚本。官方文档提醒,注入的命令在会话 Shell 当前的工作目录里运行,而这个目录会随 Claude 执行 cd 改变,所以需要每次都解析到同一位置的路径,要用这两个变量。

注入内容应只读、简短且有输出上限。预处理失败时,正文可能尚未加载:官方说明任何一条注入命令失败都会中止整次调用,Claude 看不到这次的 Skill 内容;预期会返回非零退出码的检查脚本,要在后面加 || true。组织禁止预处理时,应提供进入方法后再查询状态的替代步骤。

动态命令在模型看到正文之前就运行,审查别人写的 Skill 时要把它当作会执行的代码来看,具体见Skill 设了只读,为什么还能改文件。

05 只注入下一步用得上的部分

选择注入内容时,先想这份材料下一步拿来做什么。git diff --cached --stat 给出总览,足够决定先读哪个文件;完整补丁可能有数百行,等选定范围后再按文件读。把每次必需的状态与后续材料分开,上下文才更集中。

内容放在哪里什么时候进入上下文
输入、关键判断、步骤、停止条件SKILL.md每次调用
检查表、正反例辅助文件正文里写明的那一步
收集数据的脚本scripts/被执行,输出才进入
当前分支、改动统计动态注入每次调用,先于正文
完整补丁按文件读取选定范围之后

每次都要的放主文件,某一步才要的写明何时读,实时状态只注入下一步用得上的部分。开头那份臃肿的审查 Skill 按这张表拆一遍,SKILL.md 会短到一眼能看清步骤,需要的标准和例子也都找得到。拆完后记得验收,方法见自定义 Skill 不显示或调到旧版的排查方法。