Files
zk-data-agent/docs/technical-architecture/04-skills.md
T
2026-05-18 19:28:02 +08:00

257 lines
4.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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
```