Files

173 lines
8.4 KiB
Markdown
Raw Normal View History

# 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 示例