173 lines
8.4 KiB
Markdown
173 lines
8.4 KiB
Markdown
# Easel SKILL 接口规范 v0.3
|
||||
|
|
|
|||
|
|
> 所有 Easel SKILL 遵循此规范。SKILL 是独立可调的原子能力单元。
|
|||
|
|
|
|||
|
|
## 目录结构
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
skills/
|
|||
|
|
├── openclaw/ 五层 SKILL(发现/策划/制作/发布/归因),由 OpenClaw 直接执行
|
|||
|
|
└── shared/ 跨 SKILL 共享工具(脚本、配置、依赖)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
每个 SKILL 是一个独立目录:
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
skill-xxx/
|
|||
|
|
├── SKILL.md 必须 — 执行流程(精简,< 200 行)
|
|||
|
|
├── references/ 可选 — 领域知识(按需加载,不常驻 prompt)
|
|||
|
|
│ └── *.md
|
|||
|
|
├── scripts/ 可选 — 可执行脚本(运行时调用,代码不进 prompt)
|
|||
|
|
│ └── *.py / *.sh
|
|||
|
|
└── tests/ 可选 — 测试用例
|
|||
|
|
├── test1.prompt 输入
|
|||
|
|
└── test1.expected 期望输出(关键字匹配)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 三层加载机制
|
|||
|
|
|
|||
|
|
| 层 | 内容 | 加载时机 | token 开销 |
|
|||
|
|
|---|---|---|---|
|
|||
|
|
| Metadata | frontmatter(name, description) | 常驻,用于 SKILL 路由 | 极小 |
|
|||
|
|
| Instructions | SKILL.md 主体 | SKILL 被触发时 | 中等 |
|
|||
|
|
| Resources | references/ + scripts/ | SKILL 执行中按需读取 | 按需 |
|
|||
|
|
|
|||
|
|
**核心原则:SKILL.md 只写"怎么做",领域知识写在 references/ 里。**
|
|||
|
|
|
|||
|
|
### 共享工具层
|
|||
|
|
|
|||
|
|
`skills/shared/` 存放多个 SKILL 共用的工具脚本和配置(如 ffmpeg 封装、API client、通用模板)。SKILL 通过相对路径引用。
|
|||
|
|
|
|||
|
|
## SKILL.md 格式
|
|||
|
|
|
|||
|
|
```markdown
|
|||
|
|
---
|
|||
|
|
name: skill-xxx
|
|||
|
|
description: >-
|
|||
|
|
用中文说明本 SKILL 做什么、用户在什么场景或用哪些说法时应触发,以及与相邻 SKILL 的边界。
|
|||
|
|
layer: discover / plan / produce / publish / attribute / general
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# SKILL 名称
|
|||
|
|
|
|||
|
|
> 一句话描述
|
|||
|
|
|
|||
|
|
## 输入
|
|||
|
|
|
|||
|
|
描述接受什么输入
|
|||
|
|
|
|||
|
|
## 输出
|
|||
|
|
|
|||
|
|
描述输出格式(字段说明,不写具体值)
|
|||
|
|
|
|||
|
|
## 执行步骤
|
|||
|
|
|
|||
|
|
1. 步骤(引用 references/ 下的文件获取领域知识)
|
|||
|
|
2. ...
|
|||
|
|
|
|||
|
|
## Profile 感知
|
|||
|
|
|
|||
|
|
有 Profile 时怎么用,没有时怎么退
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
**frontmatter 规则:**
|
|||
|
|
- 只保留 `name`、`description`、`layer` 三个常规字段,减少常驻路由上下文和无效元数据
|
|||
|
|
- `description` 是 Agent 的主要触发依据,必须用中文同时写清能力、触发场景/用户说法和相邻 SKILL 边界;可使用 YAML 块标量
|
|||
|
|
- `layer` 标明所属层:五个流水线层 `discover / plan / produce / publish / attribute`,外加 `general`(跨切面基础设施,如画像管理、产物管理、模板库——不属于任一流水线阶段)
|
|||
|
|
- 仅在 OpenClaw 需要判断操作系统、二进制、环境变量或安装方式时,允许增加 `metadata.openclaw` 运行时清单
|
|||
|
|
- 禁止 `version`、`profile_aware`、`self_developed`、普通 `metadata.trigger/impl/source`、`allowed-tools`、`tags`;来源信息放 `EASEL-META.md`,执行约束和 Profile 行为写正文
|
|||
|
|
- SKILL.md 主体控制在 200 行以内
|
|||
|
|
|
|||
|
|
全库校验:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
python scripts/validate_skills.py
|
|||
|
|
python scripts/validate_skill_commands.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
第一条检查 frontmatter、资源链接、输出和发布安全契约;第二条解析 Skill 中的 Python 命令,对照脚本的 argparse 定义检查路径与参数漂移。
|
|||
|
|
|
|||
|
|
## 调用方式
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
easel skill check-compliance -i "内容"
|
|||
|
|
easel skill check-compliance -i "内容" -p 画像名
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
所有调用统一走 OpenClaw agent,由 OpenClaw 读对应 SKILL、按 AGENTS.md 规则自己执行。
|
|||
|
|
|
|||
|
|
## SKILL 同步
|
|||
|
|
|
|||
|
|
`openclaw/sync.sh` 把 `skills/openclaw/` 与 `skills/shared/` 同步到 `~/.openclaw/workspace-easel/`。
|
|||
|
|
|
|||
|
|
## Profile 注入
|
|||
|
|
|
|||
|
|
- OpenClaw 直接读取 Profile 文件夹,按 AGENTS.md 凝练后用于产出。
|
|||
|
|
- 检测标记:`=== EASEL ACCOUNT PROFILE ===`
|
|||
|
|
|
|||
|
|
## 产物管理
|
|||
|
|
|
|||
|
|
**目录布局规约**(一个内容项目 = `outputs/<主题>/` 一个目录):
|
|||
|
|
```
|
|||
|
|
outputs/<主题>/
|
|||
|
|
├── note.md / final.mp4 / card_1.png 成品(用户要发/读的最终文件,放项目根)
|
|||
|
|
├── assets/ 中间件:frames/ clips/ 构建脚本 原始素材 草稿 重复文件
|
|||
|
|
└── .easel.json 唯一元数据:展示头 + 层间产物契约(隐藏)
|
|||
|
|
```
|
|||
|
|
- **成品放项目根、中间件进 `assets/`**:前端「内容库」据此把成品与素材分区展示。
|
|||
|
|
- 项目名用人类可读主题(中文可),禁泛名(xhs/test);测试/临时产物写 `outputs/_scratch/`。
|
|||
|
|
- 任何新脚本在创建产物前必须调用 `skills/shared/scripts/output_paths.py` 的 `validate_output_path()`;系统写入需显式传 `allow_system=True`,且只能使用已注册的 `_` 路径。
|
|||
|
|
- 系统状态一律 `_` 前缀目录(`_login/_publish/_analytics/_profile_build/_scratch`);
|
|||
|
|
**内容库只展示项目目录**,忽略根目录散文件与系统目录。
|
|||
|
|
|
|||
|
|
### 元数据契约(`.easel.json`)
|
|||
|
|
|
|||
|
|
单一元数据文件(隐藏),由 `skills/shared/scripts/manifest.py` 读写(带 selftest),含两部分:
|
|||
|
|
|
|||
|
|
**① 展示头**(供前端「内容库」富展示:标题/平台/状态/封面/标签 + 成品高亮)。收尾登记:
|
|||
|
|
```bash
|
|||
|
|
python skills/shared/scripts/manifest.py meta --topic <主题> \
|
|||
|
|
--title "<人类可读标题>" --platform 小红书 --kind cards --status draft \
|
|||
|
|
--tags "标签1,标签2" --cover cover.png --deliverables card_1.png,card_2.png
|
|||
|
|
```
|
|||
|
|
`kind` 取 `article/xhs-note/video/cards/poster/audio/other`;`status` 取 `draft/ready/published`。
|
|||
|
|
`meta` 为 upsert:只改传入字段、其余保留;缺省有兜底(title→topic、cover→首张成品媒体)。
|
|||
|
|
|
|||
|
|
**② 层间产物契约 steps[]**:纵向编排跨层时,上游产物路径与关键结论通过 manifest 结构化传递,下游无需重新推导。
|
|||
|
|
```bash
|
|||
|
|
# 上游每步产出后登记(失败也登记 --status failed,供断点续跑)
|
|||
|
|
python skills/shared/scripts/manifest.py record --topic <主题> \
|
|||
|
|
--layer plan --skill video-script --profile <画像> \
|
|||
|
|
--outputs script.md,brief.md --summary "3 幕结构,钩子在前 3s"
|
|||
|
|
|
|||
|
|
# 下游步骤前取上游最近一步作为输入
|
|||
|
|
python skills/shared/scripts/manifest.py latest --topic <主题> [--layer plan]
|
|||
|
|
python skills/shared/scripts/manifest.py read --topic <主题> # 看全链路
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
Schema:`{topic, profile, created, updated, title, summary, platform, kind, status, tags[], cover, deliverables[], steps:[{layer, skill, at, status, outputs[], upstream[], summary}]}`。
|
|||
|
|
`layer` 取 `discover/plan/produce/publish/attribute/general`;step `status` 取 `done/failed`(默认 done)。契约稳定、可被任一层消费。
|
|||
|
|
|
|||
|
|
> 存量目录用 `scripts/migrate_outputs.py`(dry-run→apply 回填展示头,`--reorganize` 归整中间件进 assets/)收敛;测试残渣用 `scripts/cleanup_outputs.sh` 清理。
|
|||
|
|
|
|||
|
|
## 出站内容安全闸门(发布/评论类 SKILL 契约)
|
|||
|
|
|
|||
|
|
任何把文本**发到公开平台**的脚本(xhs/douyin/web_publisher/xhs_comment/zhihu_answer 等),在真发(`--exec`)前**必须**过 `skills/shared/scripts/content_guard.py` 的 `guard_or_die(...)`。**分两级**(见 `BLOCK_CATEGORIES`):**BLOCK 级**=真·敏感信息(API key、内部 URL/域名、代理 IP、内部路径、env 名 + `.env` 真值)→ **fail-closed 退出码 7 阻止发布**;**WARN 级**=AI 措辞(由 AI 生成/OpenClaw/Claude/system prompt/大模型)与模型名(claude-*/gpt-image-2)→ 论文解读、AI 科普里可能是正常内容,**只提醒不拦截**。dry-run 全部只告警。放行硬拦须显式 `--allow-unsafe`。新增发布类脚本照此接入。
|
|||
|
|
|
|||
|
|
**有界编排约定**:manifest 只当**薄索引**(`summary` 一行给编排层路由 + `outputs[]` 指路径),**不复制内容**。跨层要传的东西分两类,都落 `outputs/<主题>/` 成文件,不留在对话里:
|
|||
|
|
- **产物(载荷)**:脚本/图/视频/文案 → 写文件,`--outputs` 指过去,下游按路径读全文。
|
|||
|
|
- **决策/意图**(基调、受众、钩子、do/don't 等不体现在产物里的)→ 写进 `outputs/<主题>/brief.md`(策划层的创作简报),同样列入 `--outputs`。
|
|||
|
|
|
|||
|
|
## 测试
|
|||
|
|
|
|||
|
|
SKILL 可带 `tests/` 目录,用低成本模型验证基本功能:
|
|||
|
|
- `test1.prompt` — 测试输入
|
|||
|
|
- `test1.expected` — 期望输出关键字/pattern
|
|||
|
|
|
|||
|
|
## 设计约束
|
|||
|
|
|
|||
|
|
1. **独立可调** — 不依赖其他 SKILL
|
|||
|
|
2. **无 Profile 也能用** — Profile 是加持不是前提
|
|||
|
|
3. **接口一致** — 输出格式稳定,可被下游消费
|
|||
|
|
4. **SKILL.md 精简** — 执行流程在主文件,领域知识放 references/
|
|||
|
|
5. **泛化** — 定义规则和模式,不给具体 case 示例
|