Skills 是什么?如何用于 Agent 开发?

大家好,我是双越。wangEditor 作者,前百度 滴滴 资深前端工程师,慕课网金牌讲师,PMP,前端面试派 作者。

我正致力于两个项目的开发和升级,感兴趣的可以私信我,加入项目小组。

  • 划水AI Node 全栈 AIGC 知识库,包括 AI 写作、多人协同编辑。复杂业务,真实上线。
  • 智语 AI Agent 智能体项目。一个智能面试官,可以优化简历、模拟面试、解答题目等。

本文总结了我最近调研和学习 SKILLS 的一些记录,帮助大家对 SKILLS 全面的学习和理解。

SKILLS 是什么

SKILLS 本质上就是组织 prompt 提示词。

不仅 SKILLS,很多包装得很复杂的 Agent 框架,剥开来看确实都在做"往 Prompt 里塞什么、怎么塞"这件事。

SKILLS 比传统 prompt 多了一个:按需注入。这样就能极大减少 token 使用量,关键是能省钱

基于什么发展而来?

Skills 的概念来源于以下几个演进脉络:

1. Prompt Engineering 的沉淀

早期开发者发现,同样的任务,提示词写法不同,结果差异巨大。经过大量试错后,好的提示策略需要被复用和共享,Skills 就是这种沉淀的容器。

2. RAG(检索增强生成)的思路迁移

RAG 是在运行时动态注入外部知识,Skills 借鉴了这个思路------在任务执行前动态注入过程性知识(How-to),而不仅仅是事实性知识。

3. Tool Use / Function Calling 的延伸

LLM 有了调用工具的能力后,下一步自然是让 Agent 知道**"什么场景用什么工具、怎么用得好"**,这正是 Skill 要解决的事。

4. ReAct / Chain-of-Thought 框架的落地需求

ReAct 等框架让 Agent 有了规划-行动-观察的循环能力,但每个领域的规划策略不同,Skills 为不同领域提供了领域专属的推理引导

Agent Skill = 将人类专家经验编码为 Agent 可读的操作手册,在运行时动态注入,让 Agent 像专家一样执行特定领域任务。

单一任务 Agent 使用 SKILLS 的价值

对于单一任务类型的 Agent,Skill 的核心价值------"按需选择合适的知识"------确实没有用武之地。

但 Skill 还有另一个价值维度值得考虑:知识的组织与维护,而不仅仅是"选择"。

即使是单任务 Agent,你仍然面临这些问题:

  • 这个任务的最佳实践怎么沉淀?
  • Prompt 写在哪、谁来维护、怎么迭代?
  • 新同事怎么快速理解这个 Agent 的设计意图?

这时候 Skill 文档的形式本身是有价值的------它是对 System Prompt 的结构化管理方式,而不只是动态检索的载体。

所以

  • 多任务 Agent:Skill 的动态检索能力是核心价值
  • 单任务 Agent :Skill 作为动态检索机制价值有限,但作为Prompt 知识库的组织形式仍有一定工程价值

如果单任务 Agent 的 Prompt 本身也很简单:那 Skill 机制确实基本没必要引入,直接写死在 System Prompt 里最省事

看几个 SKILLS 的例子

SKILLS 怎么写,可以看看几个官方的例子。

第一,在 Claude desktop 中内置了很多 SKILLS examples ,例如这个 MCP-builder

第二,看 SKILLS 官方给出的例子 github.com/anthropics/...

例如这个是 python 处理 PDF 文档的 SKILL

第三,Vercel 推出的 react best practice skills github.com/vercel-labs...

规定了 AI 编程工具如何正确的编写 React 代码。同理,现在 vue nextjs svelte 也都有了自己的 skills

实际体验 SKILLS

在 Claude desktop 中试一试,既然它有 MCP-builder SKill 那就让它开发一个 MCP server

arduino 复制代码
使用 nodejs 技术栈帮我开发一个 MCP server ,
用于在 cursor 中连接 notion ,
可以查看和搜索我在 notion 中的文档和内容。

它会主动搜索 skills ,并识别合适的 skill ,然后按照 skill 里的步骤来操作

然后就卡在了这里,我一度以为这是卡死了。结果等待了大概 10-15 分钟,终于做完了

它说明了制作的步骤,使用方法,其中带有哪些 tools ,最后可以下载代码。

如果没有 skills ,纯靠笨拙的、混在一起的 system prompt ,很难想象 AI 能如此精细的开发一个任务。

SKILLS 和 Tools

Skills 中会定义很多脚本和命令,python 脚本,js 脚本,或者 shell 命令行等。

这些代码和 skill 其他文字一样,也会作为 prompt 被传递给 LLM ,而 LLM 无法直接执行这些代码。它们需要调用 agent 相关的 tools 来执行。

markdown 复制代码
Skill.md 里的 Python 脚本
        ↓
   只是文本/模板
        ↓
Agent 通过 Tool 执行
        ↓
   才真正产生结果

如果要自己开发一个 agent ,你需要自己定义执行 python 代码的 tool ,skill 中的 python 脚本才能被执行。

js 复制代码
const executePythonTool = tool(
  async ({ code }) => {
    const tmpFile = `/tmp/script_${Date.now()}.py`;
    fs.writeFileSync(tmpFile, code);
    
    return new Promise((resolve) => {
      exec(`python3 ${tmpFile}`, (error, stdout, stderr) => {
        fs.unlinkSync(tmpFile);
        resolve(error ? `执行失败: ${stderr}` : stdout);
      });
    });
  },
  {
    name: 'execute_python',
    description: '执行 Python 脚本',
    schema: z.object({
      code: z.string().describe('要执行的 Python 代码'),
    }),
  }
);

SKILL 中的"中间数据"

例如 SKILL 中有如下描述,这里的 JSON 数据就是一个中间数据,不是最终输出。

javascript 复制代码
1. 先把文档转换为一个 JSON 格式;2. 再把 JSON 格式生成 表格 。

skill 的"中间数据"一般不需要管理,会把这个描述作为 prompt 一起传递个 LLM 统一由 LLM 处理。

但如果中间数据过大,需要提供一个 write_file tool ,让 LLM 调用,写入本地/服务器的临时文件。

javascript 复制代码
Skill 说"写入 /tmp/intermediate.json"
        ↓
LLM 理解这个意图,生成如下代码:
  fs.writeFileSync('/tmp/intermediate.json', JSON.stringify(data))
        ↓
LLM 调用 execute_nodejs Tool 执行这段代码
        ↓
Tool 在服务器/沙箱环境里真正创建了这个文件

SKILLS 和 RAG

RAG 本质上也是一种信息注入机制,和 Skill 类似,但目的不同:

arduino 复制代码
Skill   → 注入"怎么做"(操作规范、流程)
RAG     → 注入"知识内容"(业务数据、文档库)

所以 RAG 在架构里的位置是:

csharp 复制代码
用户输入
    ↓
[RAG 检索] ──→ 从知识库找相关内容 ──→ 注入 Prompt
[Skill 检索] ─→ 找对应操作规范 ────→ 注入 Prompt
    ↓
[LLM] 结合两者生成计划
    ↓
[Tool 执行]

RAG 和 Skill 是同一层次的东西,都在 LLM 推理前注入 Prompt。Skill 给方法,RAG 给数据,Tool 负责执行。

js 复制代码
async function runAgent(userInput) {

  // Step 1: 并行检索(RAG + Skill)
  const [ragContext, skill] = await Promise.all([
    retrieveFromRAG(userInput),      // 检索业务知识
    retrieveSkill(userInput),        // 检索操作规范
  ]);

  // Step 2: 组装 Prompt
  const systemPrompt = `
你是一个智能助手。

<knowledge>
${ragContext}
</knowledge>

<skill>
${skill}
</skill>
  `;

  // Step 3: LLM 推理 + Tool 执行
  const agent = createReactAgent({ llm, tools, prompt: systemPrompt });
  return agent.invoke({ input: userInput });
}

说一个真实的例子,用户问"把我们公司 Q3 销售数据生成 Word 报告"

arduino 复制代码
RAG 检索
  → 从公司文档库找到 Q3 销售数据.csv 的内容
  → 注入 Prompt:"以下是相关数据:销售额 300万,同比+15%..."

Skill 检索
  → 匹配到 docx Skill
  → 注入 Prompt:"生成 Word 文档请遵循以下规范:..."

LLM 结合两者
  → 知道数据内容(来自 RAG)
  → 知道怎么生成文档(来自 Skill)
  → 生成代码调用 Tool 执行

没有 RAG,LLM 不知道 Q3 数据是什么。 没有 Skill,LLM 不知道怎么规范地生成 Word。 两者缺一不可。

如何在 Agent 中实现 SKILLS 功能

SKILLS 说白了就是一堆文本,而且除了 name description 之外没有其他约定。如果你自己开发 Agent 是需要自己实现 SKILLS 功能的。

以 langChain 框架为例子,要开发 agent 实现 SKILLS 主要有如下步骤。

第一,skills 存储,可以是本地文件,可以是数据库,反正都是文本。

bash 复制代码
/skills
  /docx.md
  /text-parser.md
  /excel.md

第二,按需获取 Skill(按需动态检索),推荐使用向量检索,这样更适合配置多种 skill

js 复制代码
const { MemoryVectorStore } = require('langchain/vectorstores/memory');
const { OpenAIEmbeddings } = require('@langchain/openai');

// 启动时把所有 Skill 索引进向量库
async function indexSkills() {
  const skills = [
    { name: 'docx', content: loadSkill('docx'), desc: '生成Word文档' },
    { name: 'excel', content: loadSkill('excel'), desc: '生成Excel表格' },
  ];
  
  const vectorStore = await MemoryVectorStore.fromTexts(
    skills.map(s => s.desc),
    skills.map(s => ({ name: s.name })),
    new OpenAIEmbeddings()
  );
  
  return vectorStore;
}

// 按需检索最相关的 Skill
async function retrieveSkill(userInput, vectorStore) {
  const results = await vectorStore.similaritySearch(userInput, 1);
  return loadSkill(results[0].metadata.name);
}

第三,把检索出来的 Skill 注入到 prompt

js 复制代码
const { ChatPromptTemplate } = require('@langchain/core/prompts');

async function buildPromptWithSkill(userInput, skill) {
  const prompt = ChatPromptTemplate.fromMessages([
    ['system', `你是一个文档生成助手。
    
以下是你完成任务需要遵循的操作规范:
<skill>
{skill}
</skill>

请严格按照规范中的步骤和要求完成任务。`],
    ['human', '{input}']
  ]);
  
  return prompt.formatMessages({
    skill: skill,
    input: userInput
  });
}

第四,定义必要的 tools 。上文有介绍。

第五,完成 agent 串联,包括 LLM toos prompt ,这就是 agent 最基础的结构了,

javascript 复制代码
const { createReactAgent } = require('langchain/agents');
const { ChatOpenAI } = require('@langchain/openai');

async function runDocumentAgent(userInput) {
  const llm = new ChatOpenAI({ model: 'gpt-4o' });
  
  // 1. 按需加载 Skill
  const skill = await retrieveSkill(userInput, vectorStore);
  
  // 2. 构建带 Skill 的 System Prompt
  const systemPrompt = `你是文档生成助手,严格遵循以下规范:
<skill>${skill}</skill>`;

  // 3. 创建带 Tool 的 Agent
  const agent = createReactAgent({
    llm,
    tools: [generateDocxTool, installDepTool],
    prompt: systemPrompt,
  });

  // 4. 执行
  const result = await agent.invoke({ input: userInput });
  return result;
}

// 调用
runDocumentAgent('把这段文字转成 Word 文档:...');

这个 agent 整体的工作流程如下:

csharp 复制代码
用户输入
   ↓
[Skill 检索] ──→ 读取 .md 文件 ──→ 注入 System Prompt
   ↓
[LangChain Agent] ──→ LLM 规划步骤
   ↓
[Tool 调用循环]
   ├── install_npm_package  (环境准备)
   ├── generate_docx        (执行代码)
   └── 验证结果 / 自我修正
   ↓
返回文件路径 / 下载链接

最后

以上就是我对于 SKILLS 及其周边功能的理解,如果你有新的见解欢迎留言补充。

相关推荐
yiyu071615 小时前
3分钟搞懂深度学习AI:环境安装与工具使用
人工智能·深度学习
GitLqr17 小时前
AI - Antigravity 不认全局 skills 怎么办?
agent·ai编程·gemini
冬奇Lab17 小时前
一天一个开源项目(第44篇):GitNexus - 零服务器的代码智能引擎,为 AI Agent 构建代码库知识图谱
人工智能·开源·资讯
冬奇Lab17 小时前
OpenClaw 深度解析(七):安全模型与沙盒
人工智能·开源
哈里谢顿18 小时前
agent中的Function Calling详细解释
agent
周末程序猿18 小时前
Veri-ReActAgent:让 AI 写代码前先学会写测试
aigc·agent·ai编程
IT_陈寒19 小时前
别再死记硬背Python语法了!这5个思维模式让你代码量减半
前端·人工智能·后端
Ray Liang19 小时前
彻底治愈AI“失忆”和胡说八道的真正办法
人工智能·rag·智能体·ai助手·mindx
阿星AI工作室20 小时前
飞书OpenClaw插件太香了!自动写文+整理表格+按评论修改保姆级教程
人工智能