WangYu::Space

cat /dev/mind

AI Agent 原理与实现(三):Skill 的工作原理

分类:人工智能标签: LLMAgent创建时间:2026-07-21 20:23:00

前言

Agent Skill(智能体技能)由 Anthropic 于 2025 年 10 月推出,并在同年 12 月发展为开放标准。Skill 出现后,Agent 的能力被大幅增强,用户可以通过 Skill 给 Agent 注入特定的操作流程和规则,让它在特定场景下按要求执行任务。本文将详细介绍 Skill 的工作原理以及 LLM 如何使用 Skill。

什么是 skill?

AI Agent 像是一位全能的助理,能帮你写周报、整理会议纪要、做表格、生成工作总结。但 Agent 背后只是个 LLM(大语言模型),它不会真的像人一样学会某件事,只是靠训练数据和当前对话的上下文来生成回答。它的能力是通用的,但不具备特定场景下的专业知识和操作流程。比如让它帮忙写周报,不加任何限制的话,它会写出一些看似合理的内容,但不一定符合公司要求。如果公司对周报的格式、内容有特定要求,Agent 就得先了解这些要求,再照着写。

Skill 就像一本工作手册,告诉 Agent 在特定情况下该怎么操作。每个 skill 都写明了完成某项任务所需的步骤和规则,还配了名称和描述,说明它的用途和适用场景。当用户提出请求时,Agent 会拿请求内容和各 skill 的描述做对比,决定要不要用、用哪个。你可以想象自己雇了一位全能助理,手边放着一摞工作手册。他执行任务不全凭个人经验,而是先搞清楚有哪些手册、每本管什么,任务来了再找出对应的那本,按上面的步骤执行。

回到 Agent 的语境中,skill 就是一份说明文档,写清了某类任务的详细操作步骤,带名称和描述,LLM 可以根据当前任务的上下文决定要不要加载 skill 以及加载哪个 skill。

一个 skill 的例子

下面是一个 skill 的例子,用来帮用户整理本周的工作内容、生成周报。这个 skill 的名称是 weekly-report,可以帮助完成“写周报、生成工作总结或整理本周成果”这类任务。

在个人电脑上,一个 skill 就是一个文件夹。

.agents/skills/weekly-report/
├── SKILL.md          # 必需的入口文件
└── scripts/
    └── download-tasks.sh  # 可选的脚本文件

其中 SKILL.md 就是那本工作手册,Agent 按它的指引完成任务。文件名固定叫 SKILL.md,是整个 skill 的入口。文件开头有一段 frontmatter,放着名称和描述。

---
name: weekly-report
description: 基于用户本周的工作内容,完成周报的整理与生成。
---

# 周报助手

1. 运行 `./scripts/download-tasks.sh` 下载本周的工作内容。
2. 按"做了什么 / 结果如何 / 下周计划"三段式整理成周报。

# 注意事项

执行 `./scripts/download-tasks.sh` 时需要获取用户的员工 ID,请在运行前提示用户输入。执行命令如下:

```bash
./scripts/download-tasks.sh --id <员工 ID>
```

执行完成后,脚本会在当前目录生成一个 `tasks.json` 文件,里面包含本周的工作内容。

Agent 启动时会扫描 .agents/skills 目录下的所有 skill 文件夹,把每个 skill 的 namedescription 读出来,注入 LLM 的系统提示词。这样 LLM 一开始就知道有哪些 skill、每个管什么。用户提出请求后,LLM 再对照描述,决定要不要用、用哪个。

skill 文件夹里只有 SKILL.md 是必需的,其他文件都可选。通常的做法是,确定性的工作交给脚本,SKILL.md 只写操作流程,流程里会提到某些场景下要运行某个脚本。至于什么时候运行、用什么参数,由 LLM 根据描述自行判断。

为什么需要 skill?

知道了 skill 是什么,你可能想问,这些要求反正最后都要喂给 LLM,为什么不直接写进提示词,非要单独抽出来做成 skill?原因有这么几条。

先说最直接的麻烦,同样的要求,每次都得重新说一遍。比如公司要求周报按“做了什么 / 结果如何 / 下周计划”三段式来写,第一次你写在提示词里,Agent 照做了。下次想完成同样的任务时,你只能把同样的话再粘一遍。规则越多,重复劳动越明显。更麻烦的是,提示词写在对话框里,写完就丢,既没有版本,也没法复用,更别提在团队里共享了。

另一个问题是上下文空间有限。LLM 的上下文窗口就那么大,把公司规定、代码规范、写作风格这些说明一股脑塞进每次对话,既费 token,又挤占了真正处理任务内容的空间。任务越复杂、说明越长,问题就越严重。

还有个问题是知识零散、难以维护。Agent 的「经验」要么靠训练数据,要么靠临时的提示词。训练数据覆盖不了你们公司内部的规矩,临时提示词又散落在各个对话里,改一处得翻遍所有地方,越用越乱。

Skill 把这几个问题一起解决。它把完成某类任务所需的知识、步骤、规则固化成一个独立的说明文档,带上名称和描述,像插件一样给 Agent 装上,具体有这几个好处:

所以 skill 干的事,就是把“经验”从提示词里抽出来,变成 Agent 可以自己发现、按需加载的能力模块。下面用一个真实例子看看它是如何注入 Agent 的。

skill 如何注入 Agent?

上一节讲了扫描注入的机制,这里放一个真实例子。opencode 是一个开源的 AI Agent 框架,启动时扫描 .opencode/skills 目录下的所有 skill 文件夹,把每个 skill 的 namedescription 读出来,注入系统提示词。下面是它实际发给 LLM 的系统提示词:

You are opencode, an interactive CLI tool that helps users with software engineering tasks. Use the instructions below and the tools available to you to assist the user.

忽略...

Skills provide specialized instructions and workflows for specific tasks.
Use the skill tool to load a skill when a task matches its description.
<available_skills>
  <skill>
    <name>weekly-report</name>
    <description>周报/日报生成与润色技能。当用户需要写周报、日报、工作总结、工作汇报,或提到"周报""日报""工作总结""汇报一下""这周干了啥""本周工作""写个周报""润色周报""改下周报"等场景时触发该技能。支持从零散口语描述生成结构化报告,也支持对已有周报润色优化。覆盖6种行业模板(标准/简明/销售/产品/OKR/体制内),自动匹配场景,零外部依赖,开箱即用。</description>
    <location>/home/wangyu/code/w4096/.opencode/skills/weekly-report/SKILL.md</location>
  </skill>
  <skill>
    <name>meeting-summary</name>
    <description>会议纪要生成技能。当用户需要整理会议内容、生成会议纪要,或提到"会议纪要"、"整理会议"、"开会总结"、"会议总结"等场景时触发该技能。</description>
    <location>/home/wangyu/code/w4096/.opencode/skills/meeting-summary/SKILL.md</location>
  </skill>
</available_skills>

Agent 发送给 LLM 的提示词很长,skill 只是其中的一小段,这里可以查看完整版的提示词

系统提示词里用 <available_skills> 这个 XML 标签列出所有可用的 skill,每个 skill 用 <skill> 标签包起来,里面都带 <name><description>。description 描述了该 skill 的作用,收到用户请求后,LLM 拿它和请求对照,命中就加载,没命中就跳过。

LLM 如何使用 skill?

前面讲了 skill 的定义,也讲了 Agent 怎么判断该加载哪个 skill,那 LLM 到底是怎么用它的?其实 LLM 不会直接读 skill 的内容,而是发起一次工具调用,让 Agent 去加载。下面是 LLM 生成的内容:

<tool_call>
{
  "name": "skill",
  "arguments": { "name": "weekly-report" }
}
</tool_call>

这段回复的意思是,LLM 决定调用 skill 工具,参数 nameweekly-report。Agent 收到 LLM 的响应后,会执行 skill 工具。这个工具会按名字找到对应的 skill,读取 SKILL.md 的内容,把它注入上下文。然后 LLM 就能读到 skill 的内容了。

加载过程没什么魔法,skill 的内容会作为工具执行的结果返回,出现在上下文里。下面是一次实际加载中发给 LLM 的消息序列。

<system>
系统提示词,这里面有所有可用的 skill 的名称和描述
</system>

<user>
帮我写一份周报
</user>

<tool_call>
{
  "name": "skill",
  "arguments": { "name": "weekly-report" }
}
</tool_call>

<tool_response>
{
  "content": "<skill content here>"
}
</tool_response>

注意:以上内容只是为了说明 LLM 和 Agent 之间的交互过程,实际的消息格式会有所不同。

工具执行的结果就是 skill 的内容,LLM 收到后就能读到 SKILL.md 里写的操作流程和规则了。然后 LLM 就可以按 skill 的指引去完成任务。

skill 内部的资源如何按需加载

前面讲的按需加载,是指只有被选中的 skill 的 SKILL.md 才会被读进上下文。这一节要讲的是另一层按需加载:SKILL.md 里提到的脚本、文件等资源,也要等执行步骤真正需要时才去取用。

SKILL.md 里可以提到其他文件或外部资源,比如某个操作需要查阅某个文件或网页。如果某步操作需要执行一个脚本,SKILL.md 里就会写明要执行哪个脚本、用什么参数。LLM 读完 SKILL.md 后,如果觉得当前任务需要这些资源,就会发起一次工具调用,比如使用 read_file 工具去读某个文件,或者使用 shell 工具去执行某个脚本。Agent 收到调用后,按要求去加载资源或执行脚本,把结果返回给 LLM。这样,LLM 就能按 skill 的指引完成任务。

这里也能看出 skill 和工具的区别:read_fileshell 这类工具是确定性的代码,由 Agent 直接执行;而 skill 本身不是工具,它是一段说明文字,作用是告诉 LLM 在特定场景下该怎么操作。LLM 读完 skill 后,按 skill 的指引去调用工具完成具体动作。

总结

skill 就是一份说明文档,写清某类任务的详细操作步骤,带名称和描述。你可以把 skill 的内容插入到 LLM 的上下文里,它也能工作,但 skill 的真正价值在于它可以按需加载。Agent 会扫描 skill 目录,把每个 skill 的名称和描述注入系统提示词,让 LLM 知道有哪些 skill、每个管什么。用户提出请求后,LLM 对照描述,决定要不要用 skill、用哪个 skill。如果决定使用某个 skill,Agent 就发起一次工具调用,把对应 SKILL.md 的内容读进上下文。

用户可以在工作过程中,将一些经常使用的操作流程和规则写成 skill,并不断完善。此前,当你需要做某件事时,你需要详细地告诉 Agent 怎么做,甚至每次都要重复一遍。现在,你只需要把操作流程和规则写成 skill,此后 Agent 就可以在遇到类似任务时,按 skill 的指引去执行。

评论 评论内容仅博主可见,不会公开显示)