注册

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


image.png


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


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


image.png


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


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


image.png


实际体验 SKILLS


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


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

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


image.png


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


image.png


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


image.png


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


SKILLS 和 Tools


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


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


Skill.md 里的 Python 脚本

只是文本/模板

Agent 通过 Tool 执行

才真正产生结果

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


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 数据就是一个中间数据,不是最终输出。


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

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


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


Skill"写入 /tmp/intermediate.json"

LLM 理解这个意图,生成如下代码:
fs.writeFileSync('/tmp/intermediate.json', JSON.stringify(data))

LLM 调用 execute_nodejs Tool 执行这段代码

Tool 在服务器/沙箱环境里真正创建了这个文件

SKILLS 和 RAG


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


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

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


用户输入

[RAG 检索] ──→ 从知识库找相关内容 ──→ 注入 Prompt
[Skill 检索] ─→ 找对应操作规范 ────→ 注入 Prompt

[LLM] 结合两者生成计划

[Tool 执行]

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


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 报告"


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 存储,可以是本地文件,可以是数据库,反正都是文本。


/skills
/docx.md
/text-parser.md
/excel.md

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


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


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 最基础的结构了,


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 整体的工作流程如下:


用户输入

[Skill 检索] ──→ 读取 .md 文件 ──→ 注入 System Prompt

[LangChain Agent] ──→ LLM 规划步骤

[Tool 调用循环]
├── install_npm_package (环境准备)
├── generate_docx (执行代码)
└── 验证结果 / 自我修正

返回文件路径 / 下载链接

最后


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


作者:前端双越老师
来源:juejin.cn/post/7614331029458026531

0 个评论

要回复文章请先登录注册