这次我们来看的是 Agent Skills 的入门到实战。
核心答案先放在前面:Agent Skills 不是一套需要单独安装的软件,也不是某个大模型独有的黑科技,而是一套“给 Agent 加技能包”的标准做法。它的价值在于,把你业务里的操作流程、领域术语、脚本模板、注意事项打包成一个一个技能文件,让大模型在遇到对应任务时自己加载、照着执行。相比让模型直接“自由发挥”,这种方式结果稳定得多,也更容易复用、维护和共享。
这个方向最近热度很高,不少做 Agent 应用的同学都在把 Function Calling 和 MCP 之外的能力沉淀成技能库。把它学会之后,你既可以在 Claude Code 这类现成工具里直接用,也可以在自己的 Agent 框架里实现一套技能调度机制,甚至可以封装成 HTTP API 供其他系统调用。
这篇文章会按照典型的保姆级入门路线展开:先解释 Agent Skills 到底是什么、解决什么问题;然后给出一套通用的环境准备清单;接着从零创建第一个技能文件;再演示如何让 Agent 按需调用;之后加入多技能调度、批量任务和接口 API 封装;最后整理一套常见问题的排查表和工程化落地建议。全文不依赖特定显卡,也不要求你必须手动部署大模型,重心放在技能机制的工程实现上。
1. Agent Skills 核心能力速览
| 能力项 | 说明 |
|---|---|
| 技能本质 | 由 SKILL.md 主文件 + 脚本/模板/文档等资源组成的技能目录 |
| 触发方式 | 模型根据任务描述自动匹配技能,也可以显式指定 |
| 主流实现 | Claude 生态的 Agent Skills;社区大量自建实现同样适用 |
| 运行方式 | 不强制启动独立服务,由 Agent 运行时按需加载 |
| 硬件门槛 | 技能机制本身无独立 GPU 要求,取决于底层大模型服务 |
| 接口能力 | 可封装为 HTTP API,也可以通过 MCP 方式暴露给上层系统 |
| 批量能力 | 支持任务队列、批量调用、失败重试,需要自行设计调度逻辑 |
| 适合场景 | 文档解析、代码审查、数据分析、客服 SOP、内容生产、自动化运维 |
| 不适合场景 | 高频实时外部数据查询、需要严格权限隔离的高危操作 |
从表格可以看出来,Agent Skills 最大的优势是轻量。它不需要你额外启动一个微服务,也不需要维护一套复杂的工具注册协议。你只需要按照约定写好技能文件,然后让 Agent 在合适的时候加载即可。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Agent Skills 是什么:适用场景与使用边界
先给出一个直觉理解:普通对话里,大模型只能根据训练时学到的知识来回答;而 Agent Skills 相当于在模型之外挂了一个“操作手册”。这个操作手册里不仅写清楚步骤,还附带可以执行的脚本、可以直接套用的模板,以及一些只有你们团队才知道的经验约定。
以 Claude 生态中的 Agent Skills 为例,一个技能通常是一个目录,里面有一个 SKILL.md 文件,用 Markdown 编写正文,并且在文件头部用 YAML 声明技能的名称和描述。这个描述非常重要,它是整个触发机制的关键。当用户提出任务时,Agent 会先读取所有技能的描述,判断哪一个最匹配,然后把对应技能的完整内容加载到上下文里,模型就能按照技能里的步骤执行。
这里有一个容易混淆的点,需要认真区分:
第一,Agent Skills 与 Function Calling 不同。Function Calling 是把工具定义成结构化接口,模型负责生成参数,程序负责调用函数。而 Agent Skills 更像是一段“知识加流程”,模型除了执行脚本,更主要的是理解技能里的操作规范并逐步完成。
第二,Agent Skills 与 MCP 不同。MCP 的作用是让 Agent 连接外部数据源和工具服务器,比如查询数据库、读取文件、调用第三方服务。它解决的是“数据从哪里来”的问题。而 Agent Skills 解决的是“拿到数据之后怎么处理、按什么标准输出”的问题。两者可以组合使用,并不冲突。
适用场景方面,以下几类任务最适合用 Agent Skills:
- 重复性高且有固定流程的任务,例如每周生成项目周报、批量整理会议纪要。
- 需要特定领域知识的任务,例如法律合同审核、医疗报告摘录、金融指标分析。
- 结合本地脚本的任务,例如调用 PDF 解析脚本、Excel 处理脚本、图片压缩脚本。
- 团队内部需要统一输出标准的任务,例如代码审查规范、客服话术模板、内容发布检查清单。
使用边界方面,也要说清楚:
- 需要实时获取外部数据的任务,应该优先考虑 MCP 或普通 API 调用,而不是把数据硬编码进技能。
- 涉及删除文件、转账、发消息、修改生产配置等高风险操作,即便有技能兜底,也仍然需要人工审批。
- 技能文件内部不要保存密钥、Token、账号密码等敏感信息,这些应该统一放到环境变量或密钥管理服务中。
3. Agent Skills 本地环境准备与前置条件
Agent Skills 的入门路径有两条,你可以根据手头资源选择任何一条。
路径一是直接使用 Claude Code 等现成 Agent 工具。这是最省事的方式,你只需要安装好工具,登录账号,然后按约定把技能文件放入指定目录即可。路径二是自建 Agent 框架。这种方式更灵活,适合想要把技能机制接入自己业务系统的开发者,你只需要有大模型 API 或本地模型服务,然后自己写一套技能加载与调度逻辑。
无论选哪条路径,下面这些环境都是建议准备的:
| 项目 | 建议版本 | 用途 |
|---|---|---|
| 操作系统 | Windows 10/11、macOS、Ubuntu 均可 | 通用开发环境 |
| Python | 3.10 或更高 | 技能脚本编写与调度代码测试 |
| Node.js | 18 或更高 | 可选,某些技能脚本依赖 Node |
| Git | 最新稳定版 | 对技能库做版本管理 |
| 编辑器 | VSCode 或任意 Markdown 编辑器 | 编写 SKILL.md |
| 模型 API | Anthropic API 或 OpenAI 兼容接口 | 自建 Agent 时的推理底座 |
| 本地模型 | 可选,Ollama 等工具 | 完全本地运行时使用 |
如果你走 Claude Code 路径,安装完工具后,技能目录一般有两种位置:一是用户级别的全局技能目录,二是项目级别的 .claude/skills 目录。项目里的技能只对当前项目生效,全局技能对所有项目生效。这个机制的好处是,团队可以将公共技能沉淀到项目目录里,随代码一起走。
如果你走自建 Agent 路径,本质上只需要做三件事:解析技能目录、构建技能描述索引、在模型对话时按需加载技能正文。这也是后面几章要重点展开的内容。
4. 从零创建第一个 Agent Skill
先看一个最小技能目录结构。
text复制skills/
└── pdf-summary/
├── SKILL.md
├── scripts/
│ └── extract_text.py
└── templates/
└── report_template.md
一个技能就是一个文件夹,文件夹名称建议用小写短横线命名,例如 pdf-summary、weekly-report、code-reviewer。核心文件是 SKILL.md。
打开 SKILL.md,先写 YAML 头部:
yaml复制---
name: pdf-summary
description: 用于 PDF 文档解析与摘要生成。当用户要求总结 PDF、提取 PDF 重点、将 PDF 转为结构化摘要时使用。
---
这里有两个字段需要注意:
name是技能的唯一标识,建议与目录名保持一致。description是触发条件。它必须写清楚“什么时候用”和“能处理什么”。描述写得越具体,模型误匹配的概率越低。
接着写正文部分,正文就是给模型的执行指令。这里有两个原则:分成明确的步骤,并且给出输入输出格式。以 PDF 摘要技能为例:
markdown复制# PDF 摘要技能
执行步骤:
1. 使用 `scripts/extract_text.py <pdf_path>` 提取 PDF 文本。
2. 如果文本过长,按章节切分,分段处理。
3. 输出摘要,结构固定为:
- 核心结论
- 关键数据
- 待办事项
4. 输出语言跟随用户输入语言,用户用中文提问就用中文输出。
模型加载这段文字后,就会把“提取文本、切分、按固定结构输出摘要”当作操作标准。相比在每次对话里重新描述需求,技能里的规范稳定得多。
脚本示例可以这样写:
python复制#!/usr/bin/env python3
import sys
from pathlib import Path
def main(pdf_path: str):
# 替换为项目实际使用的 PDF 解析库
print(f"开始解析: {pdf_path}")
if __name__ == "__main__":
if len(sys.argv) < 2:
print("用法: python extract_text.py <pdf_path>")
sys.exit(1)
main(sys.argv[1])
写完技能文件后,建议做一次简单检查:
- YAML 头部是否正确,
name和description是否齐全。 - 正文里的脚本路径是否与真实文件一致。
- 脚本是否有可执行权限,Python 脚本是否安装了对应依赖。
在 Claude Code 里测试时,直接提出一个任务,例如“帮我总结一下项目根目录下的 report.pdf”,然后观察模型是否加载了 pdf-summary 技能。如果加载成功,对话中通常可以看到技能被启用的提示。
5. 让 Agent 按需调用 Skill:从手动到自动
Agent 自动决定是否使用技能,是整个机制里最关键的一环。
在 Claude Code 等工具里,这个过程是封装好的:你把技能放进目录,剩下交给 Agent 处理。但在自建系统里,你需要实现一套简单的调度逻辑,通常分两步。
第一步,提前解析所有技能,把它们的名称和描述构建成一个索引。第二步,在每轮对话中,根据用户输入决定加载哪个或哪些技能。
这里给出一个最直接的实现思路。解析技能文件的代码可以这样写:
python复制# skill_loader.py
import re
from pathlib import Path
import yaml
def parse_skill(skill_dir: Path):
skill_file = skill_dir / "SKILL.md"
if not skill_file.exists():
return None
content = skill_file.read_text(encoding="utf-8")
match = re.match(r"^---\n(.*?)\n---\n(.*)", content, re.DOTALL)
if not match:
raise ValueError(f"SKILL.md 格式错误: {skill_dir}")
frontmatter = yaml.safe_load(match.group(1))
body = match.group(2).strip()
return {
"name": frontmatter["name"],
"description": frontmatter["description"],
"body": body,
}
def load_all_skills(root: str):
root_path = Path(root)
return {
item.name: parse_skill(item)
for item in root_path.iterdir()
if item.is_dir() and (item / "SKILL.md").exists()
}
第二步,把技能描述注入系统提示词,让模型决定是否调用某个技能。一个比较省 token 的写法是:先把所有技能的 name 和 description 拼进系统提示,让模型输出“使用哪个技能”的 JSON,然后再把对应技能的正文完整加载进下一轮对话。
伪代码如下:
python复制system_prompt = build_system_prompt(skill_index)
first_response = call_llm(system_prompt, user_query)
selected_skill = parse_skill_choice(first_response)
skill_content = skills[selected_skill]["body"]
final_prompt = f"{skill_content}\n\n用户需求: {user_query}"
final_response = call_llm(final_prompt, user_query)
当然,这里要注意一个细节:如果用户输入比较复杂,可能同时涉及多个技能。比如“分析这份周报数据,然后按模板生成一份项目月报”,可能既要数据分析技能,也要报告模板技能。这种情况下,要么让模型输出一个技能列表,要么你预先定义好技能组合规则,在调度层做合并。
6. 进阶:多 Skill 调度与批量任务
当技能数量变多之后,会面临两个典型问题:选错技能,以及多个技能之间的优先级。选错技能通常是描述不够清晰导致的,所以技能维护的核心工作之一就是持续优化 description。优先级问题则可以通过给技能增加权重字段来解决,例如在 frontmatter 里加一个 priority 字段,当多技能匹配时优先加载高优先级的那个。
批量任务适合把技能流程固定下来之后使用。比如你有 100 份文档需要生成摘要,人工一份一份问模型显然不现实。这时候可以用一个任务调度脚本来跑。
下面是一个简易批量处理脚本的骨架,它具备读取任务列表、加载技能、调用模型、失败重试、写日志这几个环节。
python复制# batch_run.py
import time
import json
from pathlib import Path
from skill_loader import load_all_skills
skills = load_all_skills("skills")
tasks = json.loads(Path("input/tasks.json").read_text(encoding="utf-8"))
log_path = Path("output/log.txt")
for task in tasks:
skill_name = task.get("skill", "default")
skill = skills.get(skill_name)
if not skill:
log_path.write_text(f"跳过未知技能: {task}\n", encoding="utf-8")
continue
retries = 3
for attempt in range(retries):
try:
result = invoke_skill(skill, task["content"], timeout=120)
output_file = Path("output") / f"{task['id']}.json"
output_file.write_text(json.dumps(result, ensure_ascii=False, indent=2), encoding="utf-8")
break
except Exception as exc:
log_path.write_text(f"任务 {task['id']} 第 {attempt + 1} 次失败: {exc}\n", encoding="utf-8")
if attempt < retries - 1:
time.sleep(2 ** attempt)
批量处理的关键点有三个:
- 每个任务必须有独立 ID,输出文件按 ID 命名,方便追溯。
- 失败任务要重试,但不能无限重试,一般 3 次以内,并且采用退避策略。
- 日志要记录每次调用的时间、使用的技能、输入内容摘要和输出状态。不要因为某个任务失败就中断整个队列。
如果一次要处理的任务量很大,建议再加一层并发控制,例如使用线程池,但并发数不要太高,否则容易触发模型 API 的限流。
7. 接口 API 与自动化集成
技能流程稳定之后,通常会有两个需求:把技能能力暴露给自己的其他系统,或者把技能集合接入已有的自动化工作流。这两种情况都可以通过封装 HTTP API 来解决。
这里给出一套通用实现模板,用 FastAPI 写一个极简的接口服务。
python复制# api_server.py
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from skill_loader import load_all_skills
app = FastAPI()
skills = load_all_skills("skills")
class InvokeRequest(BaseModel):
skill: str
input_text: str
parameters: dict = {}
class InvokeResponse(BaseModel):
status: str
result: str
skill: str
@app.post("/api/skill/invoke", response_model=InvokeResponse)
def invoke_skill(request: InvokeRequest):
if request.skill not in skills:
raise HTTPException(status_code=404, detail=f"技能不存在: {request.skill}")
skill = skills[request.skill]
prompt = f"技能说明:\n{skill['body']}\n\n用户输入:\n{request.input_text}"
# 这里替换为你实际的模型调用逻辑
result = call_llm(prompt, **request.parameters)
return InvokeResponse(status="ok", result=result, skill=request.skill)
上面的接口路径是 POST /api/skill/invoke,这只是示例路径,实际部署时按你自己项目调整。假设服务启动在本机 8000 端口,用 curl 调用是这样:
bash复制curl -X POST http://127.0.0.1:8000/api/skill/invoke \
-H "Content-Type: application/json" \
-d '{
"skill": "pdf-summary",
"input_text": "请总结 docs/report.pdf"
}'
如果不想自己写服务,也可以把技能能力发布成 MCP 工具,让支持 MCP 的客户端直接使用。技能本身不关心你是用 REST 暴露还是用 MCP 暴露,它只是被封装的一组指令加资源。
接口层需要特别注意安全。生产环境必须加认证,最简单的做法是使用 Token 或 API Key;如果服务需要供多个团队使用,还应该做限流,防止某个调用方占满模型额度。建议在接口层做统一的输入校验和错误码定义,不要把底层模型服务的原始报错直接丢给调用方。
8. Agent Skills 常见问题与排查方法
下面是高频问题清单,几乎每个上手实践的人都会遇到其中几个。
| 问题现象 | 可能原因 | 排查方式 | 解决方案 |
|---|---|---|---|
| 模型完全没有加载技能 | description 与任务描述不匹配 | 查看 Agent 调用日志,确认技能是否被匹配 | 重写 description,加入更多触发词和业务场景 |
| 技能加载了但执行结果不对 | 正文步骤不够明确 | 检查输出是否偏离步骤要求 | 拆细步骤,加入输入输出示例 |
| SKILL.md 解析失败 | YAML frontmatter 格式错误 | 用 yaml 解析器单独校验 | 检查冒号、缩进、特殊字符 |
| 模型总是选错技能 | 多个技能描述过于相似 | 对比各个技能 description | 精简描述,突出每个技能的差异点 |
| 批量任务中途卡死 | 缺少超时和重试机制 | 查看日志中最后一条记录 | 为每次调用增加 timeout,并实现退避重试 |
| API 调用频繁限流 | 并发数过高 | 查看请求返回的状态码 | 增加线程池上限,降低并发,或加入请求队列 |
| 技能内脚本报错 | 运行环境依赖不一致 | 在本地单独执行脚本验证 | 使用独立虚拟环境,锁定依赖版本 |
| 结果不稳定,前后不一致 | 温度参数过高 | 对比多轮输出 | 降低 temperature,或固定随机种子 |
| 技能目录里出现敏感信息 | 密钥被写入技能文件 | 搜索技能内是否含明文 Token | 全部改为环境变量引用 |
| 项目迁移后技能失效 | 脚本路径或依赖丢失 | 检查技能内路径是否存在 | 统一使用相对路径,并补齐依赖清单 |
这些问题的解决思路可以归纳为一句话:技能是代码,要用工程化的方式维护。日志、版本控制、自动化测试,缺一不可。
9. Agent Skills 最佳实践与安全合规建议
到这里,Agent Skills 的完整链路已经跑通了。最后补充几个工程化落地的建议,这些也是长期维护技能库时必须注意的。
技能要保持单一职责。一个技能只解决一类问题,不要试图在一个 SKILL.md 里既写数据清洗、又写报表生成、还带发送邮件。技能粒度太粗会导致两个后果:description 难以精确匹配,模型加载后上下文浪费严重。衡量粒度是否合适的方法很简单:描述是否不超过三句话就能让一个不了解背景的开发者看懂。
description 是投入产出比最高的优化点。如果技能老是匹配不到,不要急着改正文,先改描述。描述里应该包含任务动词、处理对象、触发场景和排除条件。例如“仅当用户明确要求生成中文周报时使用,其他语言不适用”这种否定描述往往能显著降低误匹配率。
技能库要用 Git 管理。技能文件本质上与代码没有区别,升级、回滚、评审都应该走代码仓库的流程。团队的技能库可以分成基础技能、领域技能、项目专属技能三部分。基础技能全团队共享,领域技能由对应小组维护,项目专属技能随代码仓库走。
脚本依赖要隔离。凡是技能里带了 Python 或 Node 脚本,尽量使用虚拟环境或容器,并锁定依赖版本。不要让技能依赖本机全局环境,否则换一台机器就全盘失效。
安全合规方面必须单独强调。技能里不要出现密钥、Token、数据库地址等敏感信息,一律用环境变量注入。凡是需要读取用户文件、调用外部服务、修改数据的技能,都要先评估权限边界。涉及人脸、声音、个人隐私数据的处理场景,必须确认数据来源合法,并获得相应授权后再将技能投入使用。涉及版权素材、商业文档时,要确认使用范围符合约定。接口服务如果部署在公网,必须加认证、限流和审计日志,不能裸奔。
验证技能质量时,建议为每个技能准备一组固定的测试用例。这组用例覆盖典型输入、边界输入和失败输入三种情况。每次修改技能后都跑一遍用例,确保改动不破坏原有能力。这个习惯越早建立,后续技能规模扩大时维护成本反而越低。
下一步可以扩展的方向,最常见的有三个:将技能库接入团队协作平台,例如在 CI/CD 流水线中自动执行部分技能;将多个技能组合成复合工作流,例如“数据提取技能 + 报告模板技能 + 校验技能”自动生成周报;再把稳定的技能发布为 MCP 工具,让其他 Agent 客户端也能直接调用。
最后补一句实用忠告:Agent Skills 的曲线不算陡,但最先要解决的不是写法,而是构建“技能索引-自动匹配-结果验证”的闭环习惯。第一次实验时,挑一个你真正每天会重复做的任务,比如“整理会议纪要”“审核 PR 描述”“生成日报”,把它写成一个最小技能,然后连续用一周。一周之后你对技能粒度、描述写法、错误排查的体感,会远超过看十篇教程得到的收获。建议先把文中的最小技能跑通,再逐步扩展成自己的技能库。
