158 lines
8.1 KiB
Markdown
Raw Normal View History

2026-05-20 21:39:12 +08:00
---
title: 技能系统
created: 2026-04-13
updated: 2026-05-15
type: entity
tags: [skill, agent]
sources: [packages/backend/src/modules/netaclaw/service/skill_loader.ts, packages/backend/src/modules/netaclaw/service/skill_installer.ts, packages/backend/src/modules/netaclaw/service/skill_registry.ts, packages/backend/src/modules/netaclaw/service/skill_config.ts, packages/backend/src/modules/netaclaw/service/skill_secret.ts, packages/backend/src/modules/netaclaw/service/skill_executor.ts, packages/backend/src/modules/netaclaw/tools/builtin/read_skill.ts, packages/backend/src/modules/netaclaw/tools/builtin/execute_skill.ts, packages/backend/src/modules/netaclaw/controller/admin/skill.ts]
---
# 技能系统
Skill 是 Agent 的可插拔能力扩展,以 `SKILL.md` 为主入口支持本地、GitHub、ZIP 三种安装方式。2026-04-27 后系统从单纯 prompt skill 扩展为 prompt / compute-entry / compute-toolkit 三分类:加载器负责扫描解析,安装器管理生命周期,注册表追踪指纹和来源,配置/密钥/执行器负责运行时能力ToolResolver 负责把 `read_skill``read_skill_file``skill_manage``execute_skill` 注入 Agent。
## 关键文件
| 文件 | 职责 |
|------|------|
| `service/skill_loader.ts` | 扫描 skills/ 目录,解析 SKILL.md条件过滤构建 prompt |
| `service/skill_installer.ts` | GitHub 克隆、ZIP 解压、依赖安装Node/UV、卸载、更新检查 |
| `service/skill_registry.ts` | .skillhub/ 锁文件、SHA256 指纹、来源元数据管理 |
| `service/skill_config.ts` | 解析 `skill.config.yaml`,推导 prompt / compute-entry / compute-toolkit 分类 |
| `service/skill_secret.ts` | AES-256-GCM 加密保存 skill scoped secrets并解析 env |
| `service/skill_executor.ts` | 执行 compute-entry skill使用 stdin/stdout JSON 协议 |
| `service/tool_resolver.ts` | 构建 `<available_skills>` prompt并按 Agent 配置注入 Skill 工具 |
| `tools/builtin/read_skill.ts` | Agent 工具:读取 SKILL.md 完整内容 + 附属文件索引 |
| `tools/builtin/read_skill_file.ts` | Agent 工具:读取 Skill 附属文件references/ 等) |
| `tools/builtin/skill_manage.ts` | Agent 工具:创建/编辑/删除 Skill |
| `tools/builtin/execute_skill.ts` | Agent 工具:执行 compute-entry skill |
| `controller/admin/skill.ts` | REST APICRUD + 安装/卸载/更新/上传/检查更新 |
## SKILL.md 格式
```yaml
---
name: skill-name # 必填,唯一标识
description: 描述 # 必填
version: 1.0.0 # 可选
metadata:
skillType: llm|compute|multimodal
emoji: "🔧"
tags: [标签]
conditions:
requires_tools: ["bash"] # 需要这些工具才激活
fallback_for_tools: ["selenium"] # 作为这些工具的替代
install:
- kind: node
package: "@package/name"
- kind: uv
package: "package>=1.0.0"
---
# Markdown 内容Agent 读取后遵循的指令)
```
## Skill Runtime 分类
详见 [[skill-runtime]]。当前分类不是旧 `skillType` 的替代,而是运行方式维度:
| 分类 | 判定 | 运行方式 |
| --- | --- | --- |
| `prompt` | 无 `skill.config.yaml` | Agent 用 `read_skill` 读取指令并遵循 |
| `compute-entry` | config 有 `entrypoint` | Agent 用 `execute_skill` 输入 JSON执行器返回 JSON |
| `compute-toolkit` | config 有 `runtime` 但无 `entrypoint` | Agent 读取指令和 references 后,用 `bash` 执行脚本 |
`minimax-pdf``minimax-docx``minimax-xlsx` 属于文档处理 skill详见 [[document-skills]]。2026-05-07 后又新增了 [[vehicle-damage-skill]]、`netabrowser-cli``patchwright-cli`分别覆盖车辆视频旧伤检测、国内反风控浏览器自动化和国外反爬场景。2026-05-15 新增 `data-analyst-mysql` prompt skill用于在 `mysql_list_sources``mysql_schema``mysql_query` 可用时引导 Agent 做只读 MySQL 智能问数完整的数据源、SQL guard 和审计边界见 [[mysql-data-source]]。
## 安装方式
| 方式 | 接口 | 说明 |
|------|------|------|
| GitHub | `POST /admin/netaclaw/skill/install` | git clone → 验证 SKILL.md → 计算指纹 → 写入 origin |
| ZIP 上传 | `POST /admin/netaclaw/skill/uploadInstall` | 解压 → 路径穿越防护 → 同上 |
| 本地 | 直接放入 `skills/` 目录 | 启动时自动扫描 |
| Agent 创建 | `POST /admin/netaclaw/skill/create` | Agent 运行时通过 skill_manage 工具自主创建 |
## 文件结构
```
skills/
├── {skillName}/
│ ├── SKILL.md # Skill 定义(必须)
│ ├── skill.config.yaml # 运行时、依赖、env、references可选
│ └── references/ # 附属文件可选Agent 通过 read_skill_file 按需读取)
│ ├── guide.md
│ └── examples/
└── .skillhub/
├── lock.json # 全局锁文件version + fingerprint + installedAt
└── origins/
└── {skillName}.json # 来源元数据source/url/branch/commitHash
```
## Skill 加载流程
```
启动 → scanSkills() 扫描 skills/ 目录(上限 200 个)
→ 读取每个子目录的 SKILL.md上限 256KB
→ parseSkillMd() 解析 YAML frontmatter + Markdown 内容
→ validateSkillName() 记录命名规范和目录名不一致诊断
→ skill_config.loadConfig() 解析 skill.config.yaml
→ collectFiles() 递归收集附属文件列表
→ 过滤 skill.config.yaml / requirements.txt / package.json 等基础设施文件
→ 存入内存 Map<name, SkillMeta>
→ 同步到 netaclaw_skill 数据库表
```
扫描期间还会收集 `NAME_INVALID``NAME_MISMATCH``NAME_COLLISION``DESC_MISSING``CONFIG_PARSE_ERROR``VENV_MISSING``ENV_NOT_CONFIGURED` 等诊断,供 `/admin/netaclaw/skill/diagnostics` 和前端技能页展示。
## 条件激活
`filterByConditions(builtinToolNames)` 根据当前可用工具过滤 Skill
- `requires_tools: ["bash"]` — 只有当 bash 工具可用时才激活
- `fallback_for_tools: ["selenium"]` — 当 selenium 不可用时作为替代激活
## 上下文构建
当前主路径由 `tool_resolver.ts` 收敛:
1. 根据 Agent 配置的 `skills` 列表过滤。
2. 调用 `buildSkillsPrompt()` 生成 `<available_skills>` XML 索引(上限 30,000 字符),并带上 skill 分类。
3. 注入 `read_skill``read_skill_file``skill_manage`
4. 当 Agent 选择了 compute-entry skill 时,额外注入 `execute_skill`
`skill_context.ts` 仍保留兼容,但不再是理解当前 Skill 工具注入的主入口。
## 密钥与配置 API
`netaclaw_skill` 现在新增运行时配置字段:
- `secrets`: AES-256-GCM 加密的 JSON。
- `envSchema`: 环境变量声明。
管理端接口:
- `GET /admin/netaclaw/skill/envSchema?name=...`
- `POST /admin/netaclaw/skill/secrets`
- `GET /admin/netaclaw/skill/diagnostics`
前端 `skill-detail.vue` 的详情抽屉已分为“基本信息 / 配置 / 诊断”三块,`skills.vue` 顶部会显示诊断横幅。
## 安全限制
- `MAX_SKILLS = 200``MAX_SKILL_FILE_BYTES = 256KB``MAX_SKILLS_PROMPT_CHARS = 30,000`
- ZIP 安装:`MAX_ZIP_SIZE = 50MB``MAX_SINGLE_FILE = 1MB`
- GitHub URL 正则校验、路径穿越防护realpath + startsWith
- skill 名称要求小写字母、数字和连字符,且需要与目录名一致;不合规项会记录诊断。
- compute-entry 子进程只继承白名单环境变量,再叠加 skill scoped env避免主系统敏感变量泄漏。
## 相关页面
- [[netaclaw-module]] — 所属模块
- [[agent-runtime]] — 运行时加载 Skill 上下文
- [[tool-system]] — read_skill / read_skill_file / skill_manage 工具
- [[mysql-data-source]] — data-analyst-mysql 使用的 MySQL 问数工具和数据源配置
- [[skill-runtime]] — Skill 运行时、密钥、分类和执行器
- [[document-skills]] — PDF / DOCX / XLSX 文档处理 skill
- [[vehicle-damage-skill]] — 汽车环车视频旧伤检测 skill
- [[netabrowser-runtime]] — netabrowser-cli / patchwright-cli 浏览器自动化 skill 的运行后端
- [[crew-orchestration]] — Crew 主/子 Agent 均可加载 Skill