158 lines
8.1 KiB
Markdown
158 lines
8.1 KiB
Markdown
|
|
---
|
|||
|
|
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 API:CRUD + 安装/卸载/更新/上传/检查更新 |
|
|||
|
|
|
|||
|
|
## 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
|