首页 › tutorials › 造依赖体检Skill秒出漏洞升级榜

造依赖体检Skill:从零搭一个会扫漏洞的私有能力

概述

本教程带你从零开发一个名为 dep-checker 的 Claude Code 自定义 Skill。它会扫描项目里的依赖清单(package.json / requirements.txt / go.mod),一键产出"过期依赖 + 已知漏洞 + 推荐升级版本"的报告。学完你能掌握 Skill 的完整解剖结构、frontmatter 16 个字段的核心用法、渐进式披露(progressive disclosure)设计、捆绑脚本技巧以及三种安装作用域。适合已经能跑通 Claude Code、想把重复工作固化成可复用能力的开发者,预计动手时长 90 分钟。

前置条件

正文

步骤一:先搞懂一个 Skill 到底由什么组成

Skill 不是一段魔法,它就是一个约定好结构的目录。Claude Code 启动时会扫描特定路径下的目录,只要里面有 SKILL.md,就把它注册成一个能力。最小化结构如下:

dep-checker/
├── SKILL.md            # 必须 — 机器可读的指令,是 Skill 的"大脑"
├── scripts/
│   └── audit.sh        # 可选 — 捆绑的可执行脚本,干脏活累活
└── references/
    └── severity.md     # 可选 — 参考数据,按需加载,省 token

三个层级的职责要分清:

一句话记忆:frontmatter 决定"何时上桌",正文决定"怎么做菜",scripts 负责"切菜",references 是"菜谱附录"。

步骤二:规划 dep-checker 的能力边界

动手前先把范围圈死,否则 Skill 会越写越臃肿。我们定三条边界:

  1. 输入:项目根目录,自动识别依赖清单类型(npm / pip / go 三选一)。
  2. 处理:调用对应审计工具拉取漏洞数据,再比对最新版本算出"过期清单"。
  3. 输出:一份 Markdown 表格报告,按"严重 > 高 > 中 > 低"排序,每条给出当前版本、修复版本、升级命令。

不做的事也要写进文档:不自动改 lock 文件、不提交 PR、不联网下载补丁包。这些约束会写进 SKILL.md 的"禁止行为"段,防止模型自作主张。

步骤三:搭目录骨架

在个人技能目录下建结构。个人目录路径是 ~/.claude/skills/:

mkdir -p ~/.claude/skills/dep-checker/scripts
mkdir -p ~/.claude/skills/dep-checker/references
touch ~/.claude/skills/dep-checker/SKILL.md

命名规范要遵守:目录名和 frontmatter 的 name 字段一律 kebab-case(连字符小写),脚本用 snake_case,参考文件也用 kebab-case 加 .md。这套约定保证 Claude 能稳定地按名引用。

步骤四:写 frontmatter——这是触发器的总开关

SKILL.md 顶部是一段 YAML frontmatter,用 --- 包起来。官方支持的字段比网上老教程多得多,下面这张表是 dep-checker 会用到的核心字段:

字段 必填 dep-checker 的取值与理由
name 否(默认取目录名) dep-checker,显式写更稳
description 推荐 触发判定的唯一依据,必须写清"做什么 + 何时用"
argument-hint 否 [项目路径],自动补全时提示用户可传参
allowed-tools 否 Read Bash Grep,限定本 Skill 只能用这三个工具
disallowed-tools 否 Write Edit,明确禁止改文件,做安全围栏
disable-model-invocation 否 false,我们希望它能被自动触发
paths 否 **/package.json, **/requirements.txt, **/go.mod,只在有依赖清单时才激活

完整的官方字段还有 arguments(命名位置参数)、user-invocable(是否能用 / 触发)、model(临时切模型)、effort(思考强度)、context、agent(委托子代理)、hooks(绑定生命周期钩子)、shell、metadata 等,日常用上面七个足够。

写法如下:

---
name: dep-checker
description: 扫描项目的依赖清单(package.json / requirements.txt / go.mod),跑依赖审计并产出按严重度排序的漏洞与过期依赖升级报告。当用户提到"依赖体检""查漏洞""依赖是不是过期""supply chain""npm audit""pip-audit""govulncheck""升级依赖"时使用。
argument-hint: "[可选:项目路径,默认当前目录]"
allowed-tools: Read Bash Grep
disallowed-tools: Write Edit
paths: "**/package.json, **/requirements.txt, **/go.mod"
---

description 是整个 Skill 最值钱的一行,三条写法原则:

  1. 先写能力,再写触发词:模型先理解"这玩意能干嘛",再匹配关键词。
  2. 塞具体动词和名词:写"扫描依赖清单跑审计出报告",别写"帮助处理依赖问题"。
  3. 列举同义触发词:把用户可能说的中英文说法都列上,命中率明显提升。

步骤五:写正文指令——给模型一份可执行的菜谱

frontmatter 之下就是正文。最佳实践是"角色 → 输入 → 步骤 → 输出 → 错误处理"五段式。下面是 dep-checker 的正文骨架:

你是一名依赖供应链安全专家,擅长审计 Node / Python / Go 项目的第三方依赖。

## 输入
- 用户可传入项目路径,省略时默认为当前工作目录。
- 调用 `Glob` 探测存在哪些依赖清单。

## 处理流程
1. 探测清单类型:有 package.json 走 npm 分支;有 requirements.txt 走 pip 分支;有 go.mod 走 go 分支。可多选。
2. 对每个分支,调用捆绑脚本 `scripts/audit.sh <type>` 拿到结构化结果。不要自己逐行推理漏洞。
3. 若想判断严重度分级标准,按需读取 `references/severity.md`(不要一开始就加载)。
4. 把脚本输出的 JSON 汇总成人类可读的表格。

## 输出格式
输出一段 Markdown,包含三张表:
- 漏洞清单(按 Critical/High/Medium/Low 排序,列:包名、当前版本、修复版本、CVE、升级命令)
- 过期依赖清单(列:包名、当前版本、最新版本、落后主版本数)
- 一句行动建议(先升哪个、有哪些破坏性升级风险)

## 禁止行为
- 绝不修改 package.json / lock 文件 / requirements.txt / go.mod。
- 绝不运行 `npm install` / `pip install` 之外会改变环境的命令。
- 发现高危漏洞时只报告,不自动打补丁。

注意第 2 步那句"不要自己逐行推理漏洞"——这是刻意写的反模式刹车。模型很喜欢自己脑补 CVE,但漏洞数据每天都在变,必须让脚本去拉实时数据。

步骤六:捆绑 audit 脚本——这是 Skill 真正的肌肉

scripts/audit.sh 负责所有不确定性高、容易出错的工作。它接收一个类型参数,调对应工具,吐 JSON:

#!/usr/bin/env bash
# scripts/audit.sh — 依赖审计统一入口
set -euo pipefail
TYPE="${1:-}"
ROOT="${2:-.}"

case "$TYPE" in
  npm)
    cd "$ROOT"
    # 过期依赖:outdated 转 JSON;漏洞:audit 转 JSON
    npm outdated --json 2>/dev/null > /tmp/dc_outdated.json || true
    npm audit --json 2>/dev/null > /tmp/dc_audit.json || true
    echo "{\"type\":\"npm\",\"outdated\":$(cat /tmp/dc_outdated.json),\"audit\":$(cat /tmp/dc_audit.json)}"
    ;;
  pip)
    # 优先用 pip-audit,没有则提示
    if ! command -v pip-audit >/dev/null 2>&1; then
      echo "{\"type\":\"pip\",\"error\":\"pip-audit 未安装,请运行 pip install pip-audit\"}"
      exit 0
    fi
    pip-audit -r "$ROOT/requirements.txt" -f json 2>/dev/null || echo "{\"type\":\"pip\",\"error\":\"审计失败\"}"
    ;;
  go)
    if ! command -v govulncheck >/dev/null 2>&1; then
      echo "{\"type\":\"go\",\"error\":\"govulncheck 未安装,请运行 go install golang.org/x/vuln/cmd/govulncheck@latest\"}"
      exit 0
    fi
    (cd "$ROOT" && govulncheck -json ./... 2>/dev/null) || echo "{\"type\":\"go\",\"error\":\"审计失败\"}"
    ;;
  *)
    echo "{\"error\":\"未知类型 $TYPE,支持 npm/pip/go\"}"
    exit 1
    ;;
esac

为什么一定要把逻辑放进脚本而不是写在正文里让模型执行?四个理由:

  1. 可复现:脚本每次行为一致,模型推理每次都可能飘。
  2. 省 token:一行 bash scripts/audit.sh npm 顶替几十行工具调用。
  3. 好测试:脚本能脱离 Claude 单独跑、单独写单测。
  4. 好升级:换底层工具(比如 npm audit 改用 osv-scanner)只改脚本,SKILL.md 一字不动。

记得给脚本加可执行权限:chmod +x ~/.claude/skills/dep-checker/scripts/audit.sh。

步骤七:参考数据按需加载

references/severity.md 放严重度分级标准,SKILL.md 正文只在需要判级时才引用它:

# 漏洞严重度分级速查

- **Critical**:远程代码执行、认证绕过、可直接拿 shell。当天必须修。
- **High**:敏感信息泄露、权限提升、可导致数据被改。本周内修。
- **Medium**:需要特定条件触发的漏洞、DoS。排进迭代。
- **Low**:信息泄露有限、影响面小。可批量处理。

这正是渐进式披露的体现:Claude 默认只加载 SKILL.md(几十行),遇到判级需求才把这份附录拉进上下文。一个 Skill 越复杂,省下的 token 越可观。

步骤八:安装与三种作用域

Skill 有三种摆放位置,决定了它的可见范围:

作用域 路径 谁能用
个人 ~/.claude/skills/dep-checker/ 只有你这台机器上的所有项目
项目 <repo>/.claude/skills/dep-checker/ 任何 clone 这个仓库的人(提交进 Git 即团队共享)
插件 通过 plugin marketplace 分发 所有装了该插件的用户

个人级适合放你自己的私有习惯;项目级适合团队对齐(比如"全组都用这套依赖体检流程"),记得把目录提交进仓库;插件级适合做成产品分发。dep-checker 这种和项目强相关的,推荐放项目级,跟着仓库走。

放好后无需重启——Claude Code 会在下个会话自动发现。用 /help 或在对话里说"列出我的 skills"可以确认是否注册成功。

步骤九:测试与调试三连

新 Skill 最容易翻车的不是写错代码,而是触发不了或乱触发。三步排查:

  1. 显式触发:直接打 /dep-checker(因为 user-invocable 默认开),看流程能否跑通。
  2. 隐式触发:换个说法,比如"帮我看看这个项目的依赖有没有过期",看模型会不会自动调用。不中就回去打磨 description 的触发词。
  3. 对比测试:同一个项目,分别在"有 Skill"和"禁用 Skill"(加 disable-model-invocation: true 临时关自动触发)下跑一遍,对比报告质量。

常见问题速查:

实战案例:在一个老 React 项目上跑通

准备一个真实的 package.json,故意留两个过期包和一个已知漏洞依赖,例如:

{
  "name": "demo-app",
  "dependencies": {
    "lodash": "4.17.4",
    "axios": "0.18.0",
    "react": "17.0.0"
  }
}

在项目根目录启动 Claude Code,输入:

帮我体检这个项目的依赖,看看有没有过期和漏洞。

预期行为:Claude 探测到 package.json → 触发 dep-checker → 调 scripts/audit.sh npm → 把 JSON 汇总成报告。输出大致长这样:

## 依赖体检报告

### 漏洞清单(按严重度)
| 包名 | 当前版本 | 修复版本 | 严重度 | 建议 |
|------|----------|----------|--------|------|
| lodash | 4.17.4 | 4.17.21 | High | `npm i [email protected]` |
| axios | 0.18.0 | 1.7.x | Critical | 主版本升级,注意 API 变更 |

### 过期依赖清单
| 包名 | 当前版本 | 最新版本 | 落后主版本 |
|------|----------|----------|------------|
| react | 17.0.0 | 19.x | 2 |

### 行动建议
先升 lodash(同版本内修复,零风险),再评估 axios 主版本升级的破坏性,react 跨两个大版本需配合迁移指南。

整个过程你只说了一句话——这就是把重复劳动固化成 Skill 的回报。

工作流程图

flowchart TD
    A[用户:体检依赖] --> B{Claude 扫描 skills}
    B -->|description 命中| C[加载 dep-checker 的 SKILL.md]
    C --> D[Glob 探测清单类型]
    D --> E{哪种清单?}
    E -->|package.json| F1[调 audit.sh npm]
    E -->|requirements.txt| F2[调 audit.sh pip]
    E -->|go.mod| F3[调 audit.sh go]
    F1 --> G[拿回 JSON]
    F2 --> G
    F3 --> G
    G --> H{需要判级?}
    H -->|是| I[懒加载 references/severity.md]
    H -->|否| J[汇总成 Markdown 报告]
    I --> J
    J --> K[输出表格 + 行动建议]

Skill 自身的目录结构与加载层级:

graph LR
    L1[~/.claude/skills/dep-checker/] --> L2[SKILL.md 默认全量加载]
    L1 --> L3[scripts/audit.sh 按需调用]
    L1 --> L4[references/severity.md 按需懒加载]
    L2 -.frontmatter.-> L5[name / description / allowed-tools / paths]
    L2 -.正文.-> L6[角色 / 流程 / 输出 / 禁止行为]

常见问题与排坑

延伸阅读

参考来源

  1. Extend Claude with skills — Claude Code Docs — 官方权威,涵盖 frontmatter 全字段、三种作用域与渐进式披露机制
  2. Skill Anatomy — claude-code-skills — 社区整理的目录结构与命名规范速查,含字段对照表
  3. Claude Code Skill Frontmatter: Every YAML Option Explained — 逐字段拆解 name/description/allowed-tools/disable-model-invocation 的实战含义
  4. Claude Code Skills: The Complete Guide (2026) — 含"有/无 Skill 对比测试"与 skill-creator 评测流程
  5. How to Install Skills in Claude Code: 3 Methods — 个人级 / 项目级 / 插件级三种安装路径与取舍

训练营适用性评估

[!tip] 51学通信知识星球 星主:爱卫生(微信:gprshome201101)——公众号「51学通信」创办者,19 年通信行业运维与讲师经验,著有《GPRS网络信令实例详解》《EPC原理与实践》《5G核心网原理与实践》三本纸质书(各大电商平台有售)。 星球定位:深耕 5G 核心网、IMS、NFV/AI、云原生等 ICT 领域,主打运维岗位与信令分析。 当前规模:5200 篇主题 / 990 个回答,198 元/年。 加入福利:加入星球后请加爱卫生微信,拉您进知识星球年度陪伴与答疑群——不限量回复您的各种问题,另有群内分享。 AI 加持:51学通信知识星球已作为 skill 接入 WorkBuddy,使用 deepseek-4-flash 在海量星球帖子中精准找贴、找视频、找 FAQ 和案例,做总结、找文档和 PPT 等场景全覆盖。

51学通信知识星球海报-扫码加入