引言
上一章,我们理解了LLM是"大脑",而Skills是"手和脚"的协作关系。但一个具体的Skill到底长什么样?它由哪些"零件"构成?本章我们将化身架构师,横向对比主流生态,并亲手拆解一个标准Skill,让你对后续要"制造"的对象,有一个清晰、具象的蓝图。
核心理论
不同的平台为AI Agent赋予了使用工具的能力,我们称之为"Skill生态"。尽管命名各异(Skills, Actions, Tools, Plugins),但其核心架构思想高度一致,都旨在为LLM提供一套标准化的"工具调用说明书"。一个标准的Skill通常包含三大核心组件:
- 描述 (Description) :这是工具的"名片"和"使用场景说明书"。它用自然语言告诉LLM两件事:这个工具是干什么的? 以及 在什么情况下应该调用它? 例如,"这是一个天气查询工具,当用户询问天气、温度、是否需要带伞时使用"。
- 系统提示词 (System Prompt / Instructions):这是工具的"详细操作手册"和"思维框架"。当LLM决定调用此工具后,这部分内容会作为上下文注入,指导LLM如何理解用户输入、如何组织思维、以及如何格式化输出。它决定了工具执行的"智能"上限。
- 参数Schema (Parameter Schema):这是工具的"严格输入接口定义"。它通常以JSON Schema格式,明确规定工具需要哪些参数、参数的类型、是否必填、枚举值以及描述。这确保了LLM输出的结构化,并能被后端代码准确解析。
主流生态横向对比:
- Trae IDE Skills :强调本地化、工程化集成。Skill配置通常是一个独立的配置文件(如
skill.json或skill.yaml),清晰分离上述三大组件,便于版本管理和团队协作。适合深度定制和私有化部署场景。 - OpenAI GPTs Actions:生态封闭但用户基数大。通过自然语言配置描述和手动定义API Schema(OpenAPI规范)来创建Action。优势在于与ChatGPT生态无缝集成,但自定义和调试流程相对靠后。
- Dify等AI应用平台:提供了低代码的图形化界面来配置工具。将工具描述、提示词模板和变量参数封装在可视化工作流中,降低了使用门槛,但灵活性可能受限于平台功能。
核心共识:无论生态如何,一个设计良好的Skill,其描述、提示词和Schema必须高度自洽,共同构成一个对LLM清晰、对机器可解析的完整契约。
实战演练
理论讲完,我们直接上手,在本地查阅并剖析一个真实开源Skill的配置文件。我们以GitHub上一个模拟的"待办事项管理"Skill为例。
步骤1:创建并查看项目结构
假设我们已经克隆或初始化了一个Skill项目,其典型结构如下:
bash
项目根目录结构预览
todo-list-skill/
├── skill.yaml # Skill核心配置文件
├── main.py # 技能后端执行逻辑(Python示例)
├── requirements.txt # Python依赖
└── README.md # 项目说明文档
步骤2:深度剖析 skill.yaml 配置文件
这是整个Skill的"心脏",我们逐部分拆解:
markup
# skill.yaml
# ==================== 1. Skill 描述部分 ====================
name: ""todo_manager""
title: ""待办事项管理器""
description: |
这是一个个人待办事项管理工具。
当用户想要添加、查看、完成或删除待办事项时,你应该使用此工具。
# 关键点:用自然语言明确功能和使用时机,指导LLM的"触发判断"。
# ==================== 2. 系统提示词部分 ====================
system_prompt: |
你是一个专业的待办事项助手。请根据用户的请求,操作他们的待办列表。
操作流程:
1. **理解请求**:明确用户是想"添加"、"列出"、"标记完成"还是"删除"事项。
2. **提取参数**:从用户话语中提取关键信息。例如,对于添加任务,需要"任务内容";对于删除,需要"任务ID"。
3. **执行操作**:根据提取的参数调用对应的函数。
4. **组织回复**:以友好、清晰的方式告知用户操作结果。例如,"已为您添加'购买牛奶'到待办列表。"
当前待办列表存储在一个文件中,每次操作都会更新它。
# 关键点:这是给LLM的"思维框架"和"操作指南",决定了它如何理解、处理和回复。
# ==================== 3. 参数Schema部分 ====================
# 这里定义了工具可以调用的具体函数(actions)及其输入格式。
actions:
- name: ""add_todo""
description: ""向待办列表中添加一个新项目""
parameters:
type: ""object""
properties:
task:
type: ""string""
description: ""待办事项的具体内容,例如'编写周报'""
required:
- ""task""
# 关键点:定义了函数名、描述,并用JSON Schema严格约束输入参数。
- name: ""list_todos""
description: ""列出所有未完成的待办事项""
parameters:
type: ""object""
properties: {} # 此操作不需要参数
required: []
- name: ""complete_todo""
description: ""根据任务ID标记一个待办事项为已完成""
parameters:
type: ""object""
properties:
task_id:
type: ""integer""
description: ""要标记完成的任务ID,可以通过list_todos获取""
required:
- ""task_id""
- name: ""delete_todo""
description: ""根据任务ID删除一个待办事项""
parameters:
type: ""object""
properties:
task_id:
type: ""integer""
description: ""要删除的任务ID""
required:
- ""task_id""
# 4. 执行器配置(部分生态特有) ====================
execution:
type: ""python""
entry_point: ""main.py""
# 关键点:指明如何将LLM的结构化调用,路由到后端的实际代码(main.py中的函数)去执行。
通过这个YAML文件,一个Skill的完整轮廓就清晰了:描述 吸引LLM来用,提示词 指导LLM怎么想和说,Schema 告诉LLM应该输出什么格式的数据,而执行器则负责最终落地执行。
避坑指南/高阶技巧
- 描述陷阱:避免使用过于宽泛或模糊的描述,如"这是一个管理工具"。这会导致LLM滥用或误用该Skill。务必具体,限定场景。
- 提示词与Schema的割裂 :系统提示词中提到的参数名和逻辑,必须与Schema中的定义完全一致 。例如,提示词说"提取
task_content",Schema里属性名却是task,这会导致调用失败。 - Schema设计过紧或过松 :参数是否必填(
required)、类型约束(type)、枚举值(enum)要合理设计。过松(如全可选)会导致LLM输出不完整;过紧(如枚举值不全)则会限制LLM处理自然语言变化的能力。 - 利用描述字段进行Few-Shot学习 :在参数的
description字段中,可以加入简短的例子。例如,description: ""城市名称,例如'北京'、'New York'"",这能有效提升LLM提取参数的准确性。 - 版本控制 :将
skill.yaml这类配置文件纳入Git管理。任何对描述、提示词或Schema的修改,都应视为代码变更,进行评审和记录,这是保证Skill行为可追溯、可复现的关键。
本章小结
本章我们完成了从抽象概念到具体蓝图的跨越。首先,我们横向对比了Trae、OpenAI、Dify等主流Skill生态,理解了其异同。接着,我们深入解剖了一个标准Skill的三大核心组件:描述(为何用)、系统提示词(如何想/说)、参数Schema(输入啥),并通过一个真实的YAML配置文件进行了实战拆解。现在,你已经清楚地知道,开发一个Skill,本质上就是在精心编写这份"人机协作契约"。下一章,我们将亲手从零开始,撰写这份契约的第一个版本。