# 04. Skill 体系和能力包约定

![Skill 体系和能力包约定](assets/04-skills.png)

## 1. Skill 的定位

Skill 是经验层。它不是单纯 prompt，也不是单纯脚本。

一个 Skill 应该回答：

- 什么场景触发。
- 输入材料是什么。
- Agent 应该按什么流程做。
- 哪些地方必须让用户 review。
- 应该调用哪些工具或脚本。
- 产物应该写到哪里。
- 哪些做法是禁止的。

稳定可执行逻辑不应该长期写在 Skill 文本里，而应该进入：

```text
skills/<skill-name>/scripts/
```

或者平台级工具。

## 2. Skill loader 实现

关键文件：

```text
src/bundled_skills.py
```

项目级 Skill 目录：

```text
skills/<skill-name>/SKILL.md
```

核心数据结构：

```text
src/bundled_skills.py:28 BundledSkill
```

字段：

```text
name
description
when_to_use
aliases
allowed_tools
user_invocable
source
path
get_prompt
```

## 3. SKILL.md 解析

解析逻辑：

```text
src/bundled_skills.py:147 _parse_front_matter
src/bundled_skills.py:176 _load_directory_skill
```

`SKILL.md` 必须有 frontmatter：

```yaml
---
name: product-data
description: 从产品/标签定义、手写边界规则或示例 query 中提取标签边界...
when_to_use: 当用户提供产品定义、标签规则...
aliases: definition-data, label-data
allowed_tools: read_file, write_file, python_exec
---
```

解析后：

- frontmatter 进入 `BundledSkill` 元数据。
- body 作为真正的 Skill prompt。
- 如果调用 Skill 时带 args，会追加到 `## Invocation Arguments`。

对应实现：

```text
src/bundled_skills.py:138 _directory_skill_prompt
```

## 4. Skill 发现顺序

项目 Skill 发现入口：

```text
src/bundled_skills.py:199 load_directory_skills
src/bundled_skills.py:215 load_project_skills
```

系统提示词中可见 Skill 列表由：

```text
src/bundled_skills.py:270 format_skills_for_system_prompt
```

生成。

Web 后端会按当前账号和 session 配置计算启用 Skill：

```text
backend/api/server.py:691 enabled_skill_names
backend/api/server.py:706 set_skill_enabled
backend/api/server.py:738 set_all_skills_enabled
```

这意味着：

- Skill 可以存在于项目中，但不一定对某个 session 启用。
- 启用状态影响系统提示词里的 Skill 列表。
- 被禁用的 Skill 不应该被模型主动选择。

## 5. Skill 工具

Skill 本身也是一个工具：

```text
src/agent_tools.py:1012 AgentTool(name='Skill')
```

模型调用：

```json
{
  "skill": "product-data",
  "args": "用户原始需求或显式参数"
}
```

执行后，Skill body 会被加入对话，让模型按 Skill 中的流程继续做任务。

## 6. Skill 和 Agent Loop 的关系

Skill 不会替代 Agent loop，而是改变 Agent loop 的下一步决策依据。

典型模式：

```text
用户提出任务
  -> 模型从 Skill 列表中选择某个 Skill
  -> 调用 Skill 工具
  -> Skill.md 正文进入上下文
  -> 模型按 Skill 指令调用 read_file/python_exec/data_agent 等工具
  -> 工具结果进入上下文
  -> 模型继续按 Skill 流程推进
```

因此 Skill 的好坏直接影响：

- 模型能否召回正确能力。
- 是否会过早执行。
- 是否能在 review 门禁停下来。
- 是否能使用正确工具而不是手写不稳定逻辑。

## 7. 推荐 Skill 目录结构

```text
skills/<skill-name>/
  SKILL.md
  README.md
  knowledge/
  scripts/
  examples/
  schemas/
  tools.yaml
  requirements.txt
```

各部分职责：

```text
SKILL.md
  运行时入口，写流程、门禁、工具调用方式和禁止事项。

README.md
  给维护者看的说明，不一定进入模型上下文。

knowledge/
  业务知识、标签规则、字段说明、边界案例。

scripts/
  确定性脚本，优先通过 python_exec.script_path 执行。

examples/
  示例输入输出，用于回归和讲解。

schemas/
  JSON schema 或字段约定。

tools.yaml
  描述 portable scripts 如何注册为工具，便于迁移到其他 Agent。

requirements.txt
  Skill 脚本的 Python 依赖。
```

## 8. Skill 更新

Web 后端提供 Skill 更新能力：

```text
backend/api/server.py:765 sync_skills_from_git
```

核心行为：

```text
1. 检查当前目录是否是 git 仓库。
2. 检查 tracked 文件是否干净。
3. git fetch origin。
4. git pull --ff-only origin 当前分支。
5. 清理当前账号 agent cache。
6. 重新读取 get_bundled_skills。
```

这让新增或修改 Skill 后，不一定需要重启服务才能让 Skill 列表刷新。

## 9. Skill 设计边界

适合写在 Skill：

- 工作流。
- 何时提问。
- 何时 review。
- 哪些工具优先。
- 输出位置约定。
- 常见失败经验。

不适合长期写在 Skill：

- 大段可检索知识。
- 复杂代码。
- 格式转换。
- 查询外部系统的具体实现。
- 需要校验的稳定数据结构。

这些应该分别放到：

```text
knowledge/
scripts/
schemas/
platform tools
```
