首页 › tutorials › 从零构建技术债扫描Skill全流程

本教程面向已能在 Claude Code 里完成基本对话、但从未写过自定义 Skill 的开发者。学完后你将独立交付一个可在真实仓库里运行的 tech-debt-scanner Skill:扫描 TODO/FIXME/HACK 等技术债标记、按严重度归类、产出一份可追踪的技术债登记表,并掌握 Skill 的解剖结构、热加载调试、自动触发调优与多层级分发。

前置条件


第一步:先吃透 Skill 的解剖结构

很多人写 Skill 的第一反应是"往 SKILL.md 里堆提示词"。这是错的起点。Skill 是一个目录而不是一个文件,它的真正力量来自三层渐进式披露(progressive disclosure)——上下文按需加载,而不是一次性灌满。

官方定义的目录骨架如下:

tech-debt-scanner/
├── SKILL.md            # 必需:入口指令
├── references/         # 可选:按需加载的参考资料
│   └── severity.md     # 严重度分级标准
├── scripts/            # 可选:被"执行"而非"阅读"的脚本
│   └── scan.sh
└── assets/             # 可选:模板、图标等输出素材
    └── report-template.md

关键认知:Claude 在每个会话里只常驻所有 Skill 的 name + description(约占 100 tokens/个),这是"第一层";当某个 Skill 被触发时,SKILL.md 正文进入上下文,这是"第二层"(官方建议 < 500 行);scripts/ 与 references/ 是"第三层",只有在 Claude 主动读取或执行时才消耗 token,脚本的输出可以无限长而不挤占正文预算。

flowchart TB
    subgraph L1["第一层:元数据 始终常驻 ~100 tokens"]
        A["name: tech-debt-scanner"]
        B["description: 扫描技术债标记…"]
    end
    subgraph L2["第二层:触发后加载 < 500 行"]
        C["SKILL.md 正文<br/>指令 + 动态注入"]
    end
    subgraph L3["第三层:按需访问 无上限"]
        D["scripts/scan.sh 执行"]
        E["references/severity.md 阅读"]
        F["assets/report-template.md 引用"]
    end
    A --> C
    B --> C
    C --> D
    C --> E
    C --> F
    style L1 fill:#e8f5e9
    style L2 fill:#fff8e1
    style L3 fill:#fce4ec

把这个三层模型刻进脑子里,后面所有的设计取舍(为什么 description 要短、为什么大段参考要外置、为什么确定性逻辑要写成脚本)都源于它。

第二步:决定 Skill 放在哪一层目录

Claude Code 有四类 Skill 存放位置,位置决定了谁能用:

层级 路径 生效范围
个人级 ~/.claude/skills/tech-debt-scanner/SKILL.md 你的所有项目
项目级 .claude/skills/tech-debt-scanner/SKILL.md 仅当前项目(随仓库提交给团队)
插件级 <plugin>/skills/tech-debt-scanner/SKILL.md 启用该插件的环境
企业级 通过 managed settings 下发 全组织

同名时优先级为:企业 > 个人 > 项目 > 内置。技术债扫描这类"强项目相关、需要随仓库走"的工具,我们放到项目级,这样团队成员 clone 仓库后即用。如果你只是想自己全项目复用,放个人级即可。

创建骨架(项目级):

mkdir -p .claude/skills/tech-debt-scanner/{scripts,references,assets}

第三步:写 frontmatter——决定"何时触发"的唯一钥匙

SKILL.md 顶部是 YAML frontmatter,夹在两行 --- 之间。其中 description 字段是决定 Claude 是否调用该 Skill 的主要机制,所有"何时使用"的信息都必须放在这里,而不是正文。

技术债扫描 Skill 的初版 frontmatter:

---
name: tech-debt-scanner
description: 扫描代码库中的技术债标记(TODO/FIXME/HACK/XXX/@deprecated),按严重度归类并生成可追踪的技术债登记表。当用户想了解项目欠了多少技术债、盘点 TODO、排查遗留问题、做技术债清理规划,或提到"扫一下 TODO""有哪些 FIXME"时使用。
allowed-tools: Bash(bash *) Bash(grep *) Bash(git *)
paths:
  - "**/*.py"
  - "**/*.ts"
  - "**/*.tsx"
  - "**/*.js"
  - "**/*.go"
  - "**/*.java"
---

写 description 时有三个务必遵守的原则:

  1. 关键词要覆盖用户真实说法。"扫一下 TODO""有哪些 FIXME""项目欠了多少债"这类口语化、带标点的句子都要被覆盖到,因为 Claude 是按语义匹配 description 的。
  2. 适度"推一把"(be pushy)。官方 skill-creator 明确指出当前模型有欠触发倾向——该用 Skill 时不用。所以可以在 description 末尾补一句"即使用户没有明确说'技术债',只要在讨论遗留问题、代码质量盘点、重构前评估,也应使用本 Skill"。
  3. 关键用例放最前。description + when_to_use 合并后在 Skill 列表里被截断到 1536 字符,且整个列表还要受"预算"约束(默认约为模型上下文窗口的 1%),越靠前的内容越容易被保留。

paths 字段是一个常被忽略的利器:设置后,Claude 只有在编辑或讨论匹配这些 glob 的文件时才会自动加载该 Skill。对技术债扫描来说,它只关心源码文件,所以列出常见源码后缀,能避免在改文档、改配置时被无谓触发。

第四步:写正文,并用动态注入把"实况"喂进去

SKILL.md 正文是 Skill 被触发后进入上下文的"第二层"。技术债扫描的正文不需要长,核心是用 ! 反引号语法做动态上下文注入——在 Claude 读到 Skill 之前,先由 Claude Code 跑命令、把输出原地替换进提示词:

# 技术债扫描

## 当前仓库实况

下列数据在 Skill 触发时由 Claude Code 自动采集并内联,请基于真实数据而非猜测工作:

- 当前分支:!`git rev-parse --abbrev-ref HEAD`
- 待扫描源码文件数:!`git ls-files '*.py' '*.ts' '*.tsx' '*.js' '*.go' '*.java' | wc -l`

## 任务

1. 执行扫描脚本(无需重新发明扫描逻辑):
   ```bash
   bash ${CLAUDE_SKILL_DIR}/scripts/scan.sh
   ```
2. 读取 `references/severity.md`,把脚本输出的每一类标记按 P0–P3 分级。
3. 用 `assets/report-template.md` 作为模板,生成 `TECH_DEBT.md`,写到仓库根目录。
4. 在报告开头用两三句话给出总体评估:债务规模、最该优先处理的 3 项、近期新增趋势。

这里有三个要点:

第五步:把"确定性的脏活"下沉成脚本

正文里反复出现的、可机械化的步骤,应当写成 scripts/ 下的脚本——这是 skill-creator 总结的核心规律:"如果几个测试用例都在独立地写类似的辅助脚本,那就把它固化进 scripts/,省得每次调用都重新发明轮子。"

scripts/scan.sh(扫描并按标记聚类):

#!/usr/bin/env bash
# 扫描技术债标记,输出 TSV:行号前缀\t标记类型\t内容
set -euo pipefail
ROOT="${1:-.}"
PATTERN='TODO|FIXME|HACK|XXX|@deprecated'

echo -e "file\tline\tmarker\ttext"
# 只扫 Git 跟踪的文件,避开 node_modules、构建产物
git -C "$ROOT" ls-files -z \
  | grep -zE '\.(py|ts|tsx|js|go|java|rb|rs|c|cpp|h)$' \
  | xargs -0 grep -rnIE "$PATTERN" "$ROOT" 2>/dev/null \
  | sed -E 's/^([^:]+):([0-9]+):[^:]*('"$PATTERN"')[[:space:]:]*[[:space:]]*(.*)/\1\t\2\t\3\t\4/' \
  | sort

references/severity.md(按需加载的分级标准,第三层):

# 技术债严重度分级

- **P0 阻断**:FIXME 涉及安全、数据丢失、生产崩溃;HACK 绕过鉴权或事务。
- **P1 高**:FIXME 涉及核心逻辑正确性;TODO 标注的未实现关键功能。
- **P2 中**:XXX 性能/可维护性隐患;@deprecated 仍在被新代码调用。
- **P3 低**:普通 TODO(文档、小重构、命名优化)。

判定优先看"影响面"再看"发生频率",单点高频标记可升一级。

assets/report-template.md(输出模板):

# 技术债登记表 · {{date}}

> 总体评估:{{summary}}

| 优先级 | 数量 | 代表文件 |
| --- | --- | --- |
| P0 | {{p0}} | {{p0_files}} |
| P1 | {{p1}} | {{p1_files}} |
| P2 | {{p2}} | {{p2_files}} |
| P3 | {{p3}} | {{p3_files}} |

## 建议优先处理
1. ...

为什么把分级标准外置到 references/?因为它是"长尾参考",每次只在生成报告时读一次,外置后不占 SKILL.md 正文预算,也方便团队单独维护这一份标准。

第六步:热加载,两种方式触发它

Claude Code 会监听 Skill 目录的文件变化,新增、编辑、删除都无需重启即在当前会话生效(仅限 SKILL.md 文本;若同时是插件目录,hooks/、agents/ 等变更需要 /reload-plugins)。这意味着你可以边改边测。

测试有两种路径,都要验证:

路径 A:直接斜杠调用

/tech-debt-scanner

这条最稳,能确认 Skill 本身能跑通。

路径 B:自然语言自动触发

我们这个项目欠了多少技术债?最近 TODO 多不多,列一下最该先还的

如果这条触发了你的 Skill,说明 description 写到位了。如果没触发,先问一句 当前有哪些可用的 Skill? 确认它出现在列表里;若出现却不触发,多半是 description 关键词没覆盖到你的措辞,或者问题太"轻"——Claude 只在它判断"靠自己处理不好"时才咨询 Skill,简单的一步式提问往往不触发。

预期结果:仓库根目录生成 TECH_DEBT.md,终端打印一段两三句话的总评 + P0–P3 分布表。

第七步:触发调优——这是 Skill 区别于普通提示词的关键

写完能跑,只是及格。Skill 的工程价值在于触发既不漏也不过激。三组工具按场景选用:

1. 控制谁能调用

frontmatter 你能调用 Claude 自动调用
默认 ✅ ✅
disable-model-invocation: true ✅ ❌(仅手动)
user-invocable: false ❌(隐藏菜单) ✅

技术债扫描希望 Claude 在合适时主动用,也允许你 /tech-debt-scanner 手动跑,所以保持默认即可。对比之下,/deploy、/commit 这类有副作用的,就该加 disable-model-invocation: true,免得 Claude 看"代码差不多了"就自作主张部署。

2. 收紧工具与执行范围

3. 让它跑在子代理里

如果仓库很大、扫描耗时长,加 context: fork 让 Skill 在隔离的子代理里跑,不污染主对话上下文:

context: fork
agent: Explore

agent 可选内置的 Explore(只读、上下文最小)、Plan 或自定义 agent。注意 context: fork 只适合"有明确任务"的 Skill;纯约定参考型 Skill(如"API 命名规范")在子代理里拿不到可执行任务,会空手返回。

4. 描述级优化(进阶)

官方 skill-creator 提供一条 description 自动优化链路:生成 20 条"应触发/不应触发"的真实查询(应触发的要多变措辞、含文件路径等细节;不应触发的要用"近义但不该命中"的棘手负例),再用 run_loop.py 做 60% 训练 / 40% 留出的 5 轮迭代,按测试集得分(而非训练集)选出 best_description 回填 frontmatter。如果你的 Skill 要分发给很多人,这步值得做。

第八步:分发与排错

排错速查:


实战案例:在真实仓库里跑通 tech-debt-scanner

准备一个最小复现仓库:

mkdir demo-debt && cd demo-debt && git init -q
cat > app.py <<'EOF'
def login(user, pwd):
    # FIXME 明文比对密码,上线前必须换成 bcrypt
    return user.pwd == pwd

def cache_get(key):
    # TODO 命中率统计还没接,先返回 None
    return None

# HACK 跳过鉴权方便联调,记得删
def dev_bypass(): ...
EOF
git add -A && git commit -qm "demo with debt"

把前面八步的 tech-debt-scanner/ 目录建到 .claude/skills/ 下,给 scripts/scan.sh 加可执行权限:

chmod +x .claude/skills/tech-debt-scanner/scripts/scan.sh

启动 claude,输入:

这个项目技术债情况怎么样?帮我扫一遍并出个登记表

预期 TECH_DEBT.md 里 P0 命中那条 FIXME 明文密码、P0/P1 命中 HACK 鉴权绕过、P3 命中 TODO 命中率。这个闭环跑通,你就掌握了 Skill 从"零"到"可分发"的完整链路。

flowchart LR
    M["1 明确意图<br/>扫描+归类+登记"] --> S["2 建目录骨架<br/>skills/scanner/{scripts,references,assets}"]
    S --> F["3 写 frontmatter<br/>name+description+paths"]
    F --> B["4 写正文+动态注入<br/>!`git ls-files`"]
    B --> C["5 下沉脚本/参考<br/>scan.sh / severity.md"]
    C --> T["6 热加载测试<br/>/slash 与自然语言双验"]
    T --> O{"触发准确?"}
    O -- "漏触发" --> F
    O -- "过触发" --> F
    O -- "准确" --> D["7 调优<br/>invocation/tools/fork"]
    D --> SH["8 分发<br/>personal/project/plugin"]
    style O fill:#fff8e1

常见问题与解法

Q1:! 反引号里的命令没执行,原样出现在回复里。 多半是 ! 紧跟在别的字符后面(如 KEY=!cmd)。内联形式只在!出现在行首或紧跟空白时才被识别。多行命令改用 ``! 围栏。

Q2:${CLAUDE_SKILL_DIR} 没被替换。 确认你写的是 ${CLAUDE_SKILL_DIR}(带 ${}),它指向 SKILL.md 所在目录;插件 Skill 指向插件内该 Skill 子目录而非插件根。

Q3:Skill 跑一次后后面就不"听话"了。 Skill 内容作为单条消息进入对话后会常驻,Claude Code 不会每轮重读文件。若开了自动压缩,会按"最近优先 + 每 Skill 前 5000 tokens、合计 25000 tokens 预算"重新挂载,老的可能被丢。压缩后若发现失效,重新 /tech-debt-scanner 一次即可恢复全文。

Q4:脚本在 macOS 上 grep 报错。 BSD grep 不支持 GNU 的 -z/-P。脚本里用了 POSIX 友好的写法,若仍遇问题,可 brew install grep 后用 ggrep,或在团队里统一用 Docker 跑扫描。


延伸阅读


训练营适用性评估

参考来源

  1. Extend Claude with skills — Claude Code Docs — 官方 Skill 创建、frontmatter 字段、动态注入与分发的权威说明。
  2. skill-creator SKILL.md — anthropics/skills — 官方"造 Skill 的 Skill",含三层解剖、description 调优与评测闭环。
  3. Best Claude Code Skills to Try in 2026 — Firecrawl — 渐进式披露与"每 Skill 约 100 tokens 常驻"的实践解读。
  4. Agent Skills Overview — Claude API Docs — Agent Skills 开放标准的结构与跨工具兼容性。

[!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学通信知识星球海报-扫码加入