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 后会依次提示:
- 选择技能:多选(空格键)
- 选择 AI 助手:Claude Code / Cursor / Copilot 等
- 选择安装范围:
Project(项目级)或Global(全局级) - 选择安装方式:推荐
Symlink(符号链接)
非交互式安装:使用
--agent、--global、--yes等参数自动完成。
四、技能包工作原理
AI 如何使用技能
- 启动时:AI 只读取
SKILL.md中的元数据(name和description) - 用户提问:AI 根据描述匹配到技能,动态加载完整内容
- 执行任务:AI 调用预设脚本完成精确操作
- 结果反馈:脚本执行结果返回给用户
五、完整实例: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 |
七、官方资源
- 技能目录:https://skills.sh 发现社区技能
- 常用技能集:antfu/skills(Vue、Nuxt、前端相关)
八、总结
npx skills 解决了 AI 辅助开发的核心痛点:
- 可靠性:用预设脚本替代 AI 生成代码,避免随机错误
- 效率:按需加载机制节省 token,加快响应速度
- 复用:团队可共享技能包,统一实践
通过将专业能力封装为技能包,我们可以让 AI 助手从「泛泛聊天」升级为「精准执行」,真正成为高效的工作伙伴。
