Skip to content

npx skills 核心指南

问题先行

本文要解决什么问题?

  • 如何让 AI 助手掌握专业技能而非通用聊天?
  • 如何避免 AI 生成代码的错误,保证执行可靠性?
  • 如何团队共享和复用 AI 能力?

适合谁看:对 AI 辅助开发感兴趣,想提升 AI 执行确定性的开发者。

一、npx skills 是什么?

npx skills 是 AI 助手的「技能商店」,通过简单的命令即可让 AI 掌握专业能力。每个技能包(Skill)是一个结构化的文件夹,包含:

plain
skill-name/
├── SKILL.md          # 技能描述 + 工作流程
├── scripts/          # 可执行脚本(Python/Shell/Node.js)
├── references/       # 参考文档(按需加载)
└── assets/          # 模板、图片等资源

核心优势

优势说明
按需加载仅技能元数据常驻上下文,节省 token
可靠执行复杂任务调用预设脚本,避免 AI 生成错误代码
可复用技能可在项目、团队间共享

二、核心命令速查

命令作用
npx skills add <来源>安装技能包(GitHub 短名/URL/本地路径)
npx skills find [关键词]搜索可用技能
npx skills list列出已安装技能
npx skills update更新所有技能
npx skills remove <技能名>移除指定技能
npx skills init <名称>创建新技能模板

安装示例

sh
# 从 GitHub 安装
npx skills add vercel-labs/agent-skills

# 指定安装某个技能
npx skills add antfu/skills --skill vue

# 安装到全局
npx skills add ./.skills --global

三、安装交互流程

运行 npx skills add 后会依次提示:

  1. 选择技能:多选(空格键)
  2. 选择 AI 助手:Claude Code / Cursor / Copilot 等
  3. 选择安装范围Project(项目级)或 Global(全局级)
  4. 选择安装方式:推荐 Symlink(符号链接)

非交互式安装:使用 --agent--global--yes 等参数自动完成。

四、技能包工作原理

AI 如何使用技能

  1. 启动时:AI 只读取 SKILL.md 中的元数据(namedescription
  2. 用户提问:AI 根据描述匹配到技能,动态加载完整内容
  3. 执行任务:AI 调用预设脚本完成精确操作
  4. 结果反馈:脚本执行结果返回给用户

五、完整实例:pdf-processor

下面以一个完整的 pdf-processor 技能包为例,详细展示每个文件的内容和作用。

目录结构

plain
pdf-processor/
├── SKILL.md                      # 技能描述与工作流程
├── scripts/
│   ├── extract-text.js           # 提取 PDF 文本
│   ├── merge-pdfs.js             # 合并多个 PDF
│   └── add-watermark.js          # 添加水印
├── references/
│   └── pdf-lib-guide.md          # pdf-lib 库参考文档
└── assets/
    └── watermark.png             # 水印图片模板

SKILL.md

markdown
---
name: pdf-processor
description: 处理 PDF 文件的技能,支持提取文本、合并文档、添加水印等操作(基于 Node.js)。
---

# PDF 处理器

## 适用场景
- 用户需要从 PDF 中提取文本内容
- 需要合并多个 PDF 文件
- 需要为 PDF 添加水印

## 环境要求
- Node.js 18+
- 依赖库:`pdf-parse``pdf-lib`(可通过 `npm install pdf-parse pdf-lib` 安装)

## 工作流程
1. 判断用户需求属于哪一类操作
2. 根据需求调用 scripts/ 目录下的对应脚本:
   - 提取文本 → `node scripts/extract-text.js <输入文件> [输出文件]`
   - 合并 PDF → `node scripts/merge-pdfs.js <文件列表> <输出文件>`
   - 添加水印 → `node scripts/add-watermark.js <输入文件> <水印文件> <输出文件>`
3. 将脚本执行结果反馈给用户

## 注意事项
- 脚本执行前请确保 Node.js 环境和所需依赖已安装
- 若用户未指定输出文件,默认保存为 `output.pdf``extracted.txt`

作用SKILL.md 是技能的入口文件,AI 根据 description 判断何时调用此技能,并根据 工作流程 决定执行哪个脚本。

scripts/extract-text.js

javascript
#!/usr/bin/env node
/**
 * 提取 PDF 中的纯文本
 * 用法: node extract-text.js <input.pdf> [output.txt]
 */
const fs = require('fs');
const path = require('path');
const pdfParse = require('pdf-parse');

async function extractText(pdfPath, txtPath = null) {
  if (!fs.existsSync(pdfPath)) {
    console.error(`错误:文件不存在 - ${pdfPath}`);
    process.exit(1);
  }

  const dataBuffer = fs.readFileSync(pdfPath);
  const data = await pdfParse(dataBuffer);

  if (txtPath) {
    fs.writeFileSync(txtPath, data.text, 'utf8');
    console.log(`文本已保存至: ${txtPath}`);
  } else {
    console.log(data.text);
  }
}

if (require.main === module) {
  const args = process.argv.slice(2);
  if (args.length < 1) {
    console.error('用法: node extract-text.js <input.pdf> [output.txt]');
    process.exit(1);
  }
  const [input, output] = args;
  extractText(input, output || null).catch(err => {
    console.error('处理失败:', err.message);
    process.exit(1);
  });
}

module.exports = { extractText };

作用:提取 PDF 文件中的文本内容,支持指定输出文件路径或不指定(直接打印到控制台)。

scripts/merge-pdfs.js

javascript
#!/usr/bin/env node
/**
 * 合并多个 PDF 文件
 * 用法: node merge-pdfs.js <file1.pdf> <file2.pdf> ... <output.pdf>
 */
const fs = require('fs');
const { PDFDocument } = require('pdf-lib');

async function mergePDFs(inputPaths, outputPath) {
  const mergedPdf = await PDFDocument.create();

  for (const filePath of inputPaths) {
    if (!fs.existsSync(filePath)) {
      console.error(`错误:文件不存在 - ${filePath}`);
      process.exit(1);
    }
    const fileBytes = fs.readFileSync(filePath);
    const pdf = await PDFDocument.load(fileBytes);
    const pages = await mergedPdf.copyPages(pdf, pdf.getPageIndices());
    pages.forEach(page => mergedPdf.addPage(page));
  }

  const mergedBytes = await mergedPdf.save();
  fs.writeFileSync(outputPath, mergedBytes);
  console.log(`合并完成,共 ${inputPaths.length} 个文件,保存至: ${outputPath}`);
}

if (require.main === module) {
  const args = process.argv.slice(2);
  if (args.length < 3) {
    console.error('用法: node merge-pdfs.js <file1.pdf> <file2.pdf> ... <output.pdf>');
    process.exit(1);
  }
  const output = args.pop();
  const inputs = args;
  mergePDFs(inputs, output).catch(err => {
    console.error('合并失败:', err.message);
    process.exit(1);
  });
}

module.exports = { mergePDFs };

作用:将多个 PDF 文件合并为一个,支持 3 个以上文件输入,最后一个参数为输出文件路径。

scripts/add-watermark.js

javascript
#!/usr/bin/env node
/**
 * 为 PDF 添加水印(图片)
 * 用法: node add-watermark.js <input.pdf> <watermark.png> <output.pdf>
 */
const fs = require('fs');
const { PDFDocument } = require('pdf-lib');

async function addWatermark(inputPath, watermarkPath, outputPath) {
  if (!fs.existsSync(inputPath)) {
    console.error(`错误:输入文件不存在 - ${inputPath}`);
    process.exit(1);
  }
  if (!fs.existsSync(watermarkPath)) {
    console.error(`错误:水印文件不存在 - ${watermarkPath}`);
    process.exit(1);
  }

  const pdfBytes = fs.readFileSync(inputPath);
  const pdfDoc = await PDFDocument.load(pdfBytes);

  const watermarkBytes = fs.readFileSync(watermarkPath);
  const watermarkImage = await pdfDoc.embedPng(watermarkBytes);
  const pages = pdfDoc.getPages();

  pages.forEach(page => {
    const { width, height } = page.getSize();
    page.drawImage(watermarkImage, {
      x: width / 2 - 100,
      y: height / 2 - 100,
      width: 200,
      height: 200,
      opacity: 0.3,
    });
  });

  const modifiedPdfBytes = await pdfDoc.save();
  fs.writeFileSync(outputPath, modifiedPdfBytes);
  console.log(`水印添加完成,保存至: ${outputPath}`);
}

if (require.main === module) {
  const args = process.argv.slice(2);
  if (args.length < 3) {
    console.error('用法: node add-watermark.js <input.pdf> <watermark.png> <output.pdf>');
    process.exit(1);
  }
  const [input, watermark, output] = args;
  addWatermark(input, watermark, output).catch(err => {
    console.error('添加水印失败:', err.message);
    process.exit(1);
  });
}

module.exports = { addWatermark };

作用:为 PDF 添加图片水印,默认放置在页面中心,大小 200x200,透明度 0.3。

references/pdf-lib-guide.md

markdown
# pdf-lib 常用操作速查

## 安装

```bash
npm install pdf-lib pdf-parse
```

## 核心概念

- `PDFDocument` - 代表一个 PDF 文件
- `Page` - PDF 中的单页
- `Embedded Image` - 嵌入 PDF 的图片

## 常用操作

### 加载 PDF

```javascript
const pdfDoc = await PDFDocument.load(pdfBytes);
```

### 创建新页面

```javascript
const page = pdfDoc.addPage([width, height]);
```

### 绘制文本

```javascript
page.drawText('Hello World', {
  x: 50,
  y: 700,
  size: 12,
});
```

### 绘制图片

```javascript
page.drawImage(image, {
  x: 0,
  y: 0,
  width: 100,
  height: 100,
});
```

### 保存 PDF

```javascript
const pdfBytes = await pdfDoc.save();
fs.writeFileSync('output.pdf', pdfBytes);
```

作用:提供 pdf-lib 库的常用 API 参考,仅在 AI 需要处理复杂 PDF 操作时加载使用。

六、典型应用场景

场景说明示例技能
自动化工作流生成周报、PPT、测试报告report-generator
代码规范强制命名规则、生成符合团队风格的代码eslint-custom-rules
工具集成让 AI 学会使用 playwright、docker 等工具playwright-automation
知识沉淀将专家经验封装成技能,供团队使用api-design-checker

七、官方资源

八、总结

npx skills 解决了 AI 辅助开发的核心痛点:

  1. 可靠性:用预设脚本替代 AI 生成代码,避免随机错误
  2. 效率:按需加载机制节省 token,加快响应速度
  3. 复用:团队可共享技能包,统一实践

通过将专业能力封装为技能包,我们可以让 AI 助手从「泛泛聊天」升级为「精准执行」,真正成为高效的工作伙伴。