docs: standardize skill-template and add development guide
All checks were successful
技能自动化发布 / release (push) Successful in 22s
All checks were successful
技能自动化发布 / release (push) Successful in 22s
This commit is contained in:
440
references/DEVELOPMENT.md
Normal file
440
references/DEVELOPMENT.md
Normal file
@@ -0,0 +1,440 @@
|
||||
# 技能开发教程
|
||||
|
||||
这份文档是给**技术人员**看的,目标不是解释概念,而是让你拿到 `skill-template` 后,可以**一步一步开发出一个新的 skill**。
|
||||
|
||||
本文默认你开发的是当前最常见的一类技能:
|
||||
|
||||
- 有明确的 `scripts/main.py` CLI 入口
|
||||
- 可能需要读写本地 SQLite
|
||||
- 可能需要调用兄弟技能
|
||||
- 业务逻辑主要放在 `scripts/service/`
|
||||
|
||||
如果你开发的是发布型 skill,这个模板就是直接可用的起点。
|
||||
|
||||
## 1. 先理解模板的定位
|
||||
|
||||
`skill-template` 不是业务 skill,它只是一个**新 skill 仓库模板**。
|
||||
|
||||
你不应该直接在这个仓库里开发业务,而应该:
|
||||
|
||||
1. 复制这个目录
|
||||
2. 改成新 skill 的目录名
|
||||
3. 把占位内容替换掉
|
||||
4. 再开始写业务逻辑
|
||||
|
||||
## 2. 新 skill 的标准目录结构
|
||||
|
||||
复制模板后,你应该保留下面这套结构:
|
||||
|
||||
```text
|
||||
your-skill/
|
||||
├─ .github/
|
||||
├─ assets/
|
||||
├─ evals/
|
||||
├─ references/
|
||||
├─ scripts/
|
||||
│ ├─ cli/
|
||||
│ ├─ db/
|
||||
│ ├─ jiangchang_skill_core/
|
||||
│ ├─ service/
|
||||
│ └─ util/
|
||||
├─ tests/
|
||||
├─ .gitignore
|
||||
├─ README.md
|
||||
├─ release.ps1
|
||||
└─ SKILL.md
|
||||
```
|
||||
|
||||
各目录职责如下:
|
||||
|
||||
- `assets/`:放示例输出、schema、静态说明资源
|
||||
- `references/`:放研发和编排需要长期维护的文档
|
||||
- `scripts/`:放真正的代码
|
||||
- `tests/`:放自动化测试
|
||||
- `evals/`:放人工验收材料、评估清单、示例场景
|
||||
|
||||
## 3. `scripts/` 内部如何分层
|
||||
|
||||
`scripts/` 不是乱放 Python 文件,而是按职责分层:
|
||||
|
||||
```text
|
||||
scripts/
|
||||
├─ main.py
|
||||
├─ cli/
|
||||
├─ db/
|
||||
├─ jiangchang_skill_core/
|
||||
├─ service/
|
||||
└─ util/
|
||||
```
|
||||
|
||||
每层的职责要明确:
|
||||
|
||||
- `main.py`
|
||||
作用:唯一 CLI 入口
|
||||
只做启动、编码兼容、引入 `cli.app`
|
||||
|
||||
- `cli/`
|
||||
作用:参数解析、命令分发、用法说明
|
||||
不写具体业务逻辑
|
||||
|
||||
- `db/`
|
||||
作用:SQLite 连接、建表、repository
|
||||
不写页面操作和业务编排
|
||||
|
||||
- `service/`
|
||||
作用:核心业务逻辑
|
||||
比如发布流程、调用兄弟技能、浏览器自动化
|
||||
|
||||
- `util/`
|
||||
作用:常量、日志、路径、时间工具、通用帮助函数
|
||||
|
||||
- `jiangchang_skill_core/`
|
||||
作用:运行时环境与统一日志副本
|
||||
一般按现有规范技能复制,不要自己乱改结构
|
||||
|
||||
## 4. 开发一个新 skill 的标准步骤
|
||||
|
||||
下面这套顺序建议严格按步骤做,不要一上来就直接写 `service`。
|
||||
|
||||
### 第一步:复制模板并改目录名
|
||||
|
||||
例如你要开发 `weibo-publisher`:
|
||||
|
||||
1. 复制 `skill-template`
|
||||
2. 新目录改成 `weibo-publisher`
|
||||
3. 初始化为独立 git 仓库
|
||||
4. 关联它自己的远端仓库
|
||||
|
||||
目录名要和 skill slug 对齐,后面很多地方都依赖这个命名。
|
||||
|
||||
### 第二步:先改 4 个最关键的标识
|
||||
|
||||
复制后优先改下面这些地方:
|
||||
|
||||
1. `SKILL.md`
|
||||
2. `scripts/util/constants.py`
|
||||
3. `references/` 下的文案
|
||||
4. `scripts/service/` 下的平台占位文件名
|
||||
|
||||
最先要统一的是:
|
||||
|
||||
- 技能中文名
|
||||
- `slug`
|
||||
- 平台中文名
|
||||
- 平台内部键
|
||||
- 日志 logger 名
|
||||
|
||||
## 5. 哪些占位内容必须替换
|
||||
|
||||
复制后,至少要全局检查并替换下面这些内容:
|
||||
|
||||
- `your-skill-slug`
|
||||
- `your-platform-key`
|
||||
- `技能开发模板(复制后请修改)`
|
||||
- `你的平台名`
|
||||
- `platform_playwright.py`
|
||||
- `openclaw.skill.your_skill_slug`
|
||||
|
||||
如果你是做发布型 skill,通常还要替换:
|
||||
|
||||
- `publish` 命令中的中文提示
|
||||
- `references/CLI.md` 的命令示例
|
||||
- `references/README.md` 的用户话术
|
||||
- `references/SCHEMA.md` 的数据库文件名
|
||||
|
||||
## 6. `SKILL.md` 应该怎么写
|
||||
|
||||
`SKILL.md` 是技能清单,不是设计文档。
|
||||
|
||||
应该重点写:
|
||||
|
||||
- 技能名称
|
||||
- 技能描述
|
||||
- slug
|
||||
- category
|
||||
- dependencies
|
||||
- 何时使用本技能
|
||||
- 对用户的引导话术
|
||||
- CLI 使用原则
|
||||
|
||||
不要在 `SKILL.md` 里写大量实现细节。
|
||||
实现细节放在:
|
||||
|
||||
- `references/`
|
||||
- 代码注释
|
||||
- `service/` 实现里
|
||||
|
||||
## 7. `references/` 应该放什么
|
||||
|
||||
`references/` 是当前规范 skill 的文档中心,建议至少有这些:
|
||||
|
||||
- `README.md`
|
||||
面向内部说明和技能作用介绍
|
||||
|
||||
- `CLI.md`
|
||||
写清楚命令、参数、默认值、兄弟技能调用方式
|
||||
|
||||
- `RUNTIME.md`
|
||||
写清楚运行时目录、环境变量、入口约定
|
||||
|
||||
- `SCHEMA.md`
|
||||
写清楚数据库路径、核心表结构、日志表结构
|
||||
|
||||
- `DEVELOPMENT.md`
|
||||
写给技术人员的开发教程,也就是本文档
|
||||
|
||||
如果后面某个 skill 需要更细的说明,可以再加:
|
||||
|
||||
- `ERRORS.md`
|
||||
- `INTEGRATION.md`
|
||||
- `PLATFORMS.md`
|
||||
|
||||
## 8. `assets/` 应该放什么
|
||||
|
||||
`assets/` 不放业务代码,只放辅助材料。
|
||||
|
||||
建议放:
|
||||
|
||||
- `examples/`
|
||||
比如 `version` 输出示例、`log-get` 输出示例
|
||||
|
||||
- `schemas/`
|
||||
比如日志记录、机读 JSON 的 schema
|
||||
|
||||
不要把正式研发文档放到 `assets/`。
|
||||
文档应该进 `references/`。
|
||||
|
||||
## 9. `cli` 层怎么写
|
||||
|
||||
建议保持一个原则:
|
||||
|
||||
- `cli` 只负责解析参数和路由
|
||||
- `service` 才负责干活
|
||||
|
||||
也就是说,`cli/app.py` 的职责是:
|
||||
|
||||
1. 打印帮助
|
||||
2. 定义 `publish / logs / log-get / health / version`
|
||||
3. 把参数转交给 `service.publish_service`
|
||||
|
||||
不要在 `cli/app.py` 里直接写:
|
||||
|
||||
- 浏览器自动化
|
||||
- 子进程调用兄弟技能
|
||||
- SQLite 逻辑
|
||||
|
||||
## 10. `service` 层怎么写
|
||||
|
||||
`service` 是核心层。
|
||||
|
||||
通常可以这样拆:
|
||||
|
||||
- `publish_service.py`
|
||||
放命令编排、参数兜底、结果分流
|
||||
|
||||
- `sibling_bridge.py`
|
||||
放兄弟技能调用,例如调 `account-manager`、`content-manager`
|
||||
|
||||
- `*_playwright.py`
|
||||
放浏览器后台自动化
|
||||
|
||||
- `entitlement_service.py`
|
||||
放鉴权逻辑
|
||||
|
||||
### 一个很重要的原则
|
||||
|
||||
不要把所有逻辑都堆进一个文件。
|
||||
|
||||
推荐流向是:
|
||||
|
||||
`cli.app` -> `service.publish_service` -> `service.sibling_bridge` / `service.xxx_playwright` -> `db`
|
||||
|
||||
## 11. `db` 层怎么写
|
||||
|
||||
如果你的 skill 需要记录日志或本地状态,建议:
|
||||
|
||||
- `db/connection.py`
|
||||
只做连接和建表
|
||||
|
||||
- `db/publish_logs_repository.py`
|
||||
只做增删查改
|
||||
|
||||
不要在 `db` 层里:
|
||||
|
||||
- 调浏览器
|
||||
- 打印用户提示
|
||||
- 拼接业务流程
|
||||
|
||||
## 12. 如何接兄弟技能
|
||||
|
||||
如果 skill 要依赖兄弟 skill,不要在业务代码里写死绝对路径。
|
||||
|
||||
统一通过:
|
||||
|
||||
- `scripts/util/runtime_paths.py`
|
||||
- `scripts/service/sibling_bridge.py`
|
||||
|
||||
来做调用。
|
||||
|
||||
常见调用对象是:
|
||||
|
||||
- `account-manager`
|
||||
- `content-manager`
|
||||
|
||||
调用原则:
|
||||
|
||||
1. 通过 `get_skills_root()` 找到兄弟技能根目录
|
||||
2. 再拼出对应 `scripts/main.py`
|
||||
3. 用子进程调用
|
||||
4. 机器可读输出优先 JSON
|
||||
|
||||
## 13. 如何开发发布型 skill
|
||||
|
||||
如果你开发的是 publisher 类 skill,建议按这个顺序做:
|
||||
|
||||
1. 先把目录结构搭完整
|
||||
2. 先让 `health` / `version` 跑通
|
||||
3. 再让 `publish_service.py` 的骨架跑通
|
||||
4. 再接 `sibling_bridge.py`
|
||||
5. 最后再写 `*_playwright.py`
|
||||
|
||||
不要一开始就直接写页面选择器。
|
||||
|
||||
推荐先确保这些基础能力正常:
|
||||
|
||||
- 能取到账号
|
||||
- 能取到文章
|
||||
- 能写日志
|
||||
- CLI 子命令通了
|
||||
- 错误返回值格式定好了
|
||||
|
||||
然后再进浏览器自动化。
|
||||
|
||||
## 14. 本地开发的最小验证顺序
|
||||
|
||||
建议每次新 skill 开发时按下面顺序验证:
|
||||
|
||||
### 1. 验证入口
|
||||
|
||||
```bash
|
||||
python scripts/main.py health
|
||||
python scripts/main.py version
|
||||
```
|
||||
|
||||
### 2. 验证 CLI 路由
|
||||
|
||||
```bash
|
||||
python scripts/main.py -h
|
||||
python scripts/main.py publish -h
|
||||
```
|
||||
|
||||
### 3. 验证本地日志与数据库
|
||||
|
||||
如果是发布型 skill,再继续:
|
||||
|
||||
```bash
|
||||
python scripts/main.py logs
|
||||
python scripts/main.py log-get 1
|
||||
```
|
||||
|
||||
### 4. 最后再验证真实业务
|
||||
|
||||
比如:
|
||||
|
||||
```bash
|
||||
python scripts/main.py publish
|
||||
```
|
||||
|
||||
## 15. 发布前检查清单
|
||||
|
||||
每个新 skill 发布前,建议技术人员逐条确认:
|
||||
|
||||
- [ ] 目录结构符合当前模板
|
||||
- [ ] `SKILL.md` 中 slug、名称、描述都已替换
|
||||
- [ ] `scripts/util/constants.py` 已修改
|
||||
- [ ] `references/CLI.md` 示例命令已改成真实命令
|
||||
- [ ] `service` 下的平台文件名已改对
|
||||
- [ ] 没有残留旧平台名
|
||||
- [ ] `health` / `version` 可运行
|
||||
- [ ] `.gitignore` 生效,没有把 `__pycache__` 提交进去
|
||||
- [ ] `release.ps1` 存在
|
||||
- [ ] `.github/workflows/release_skill.yaml` 存在
|
||||
|
||||
## 16. 常见错误
|
||||
|
||||
### 错误 1:只改了目录名,没改 slug
|
||||
|
||||
表现:
|
||||
|
||||
- 数据目录不对
|
||||
- 版本输出不对
|
||||
- 日志名不对
|
||||
|
||||
要检查:
|
||||
|
||||
- `SKILL.md`
|
||||
- `scripts/util/constants.py`
|
||||
|
||||
### 错误 2:平台中文名改了,内部键没改
|
||||
|
||||
表现:
|
||||
|
||||
- 兄弟技能筛选账号失败
|
||||
- 发布命令走错平台
|
||||
|
||||
要检查:
|
||||
|
||||
- `publish_service.py`
|
||||
- `sibling_bridge.py`
|
||||
- `references/CLI.md`
|
||||
|
||||
### 错误 3:把业务逻辑写进 CLI
|
||||
|
||||
表现:
|
||||
|
||||
- 文件越来越乱
|
||||
- 不方便测
|
||||
- 参数和业务耦合太重
|
||||
|
||||
要改回:
|
||||
|
||||
- `cli` 只做参数解析
|
||||
- `service` 才做业务
|
||||
|
||||
### 错误 4:保留了旧模板结构
|
||||
|
||||
表现:
|
||||
|
||||
- 仓库同时存在 `docs/`、`optional/`、`skill_main.py`
|
||||
- 技术人员不知道看哪一套
|
||||
|
||||
现在的新模板原则是:
|
||||
|
||||
- 不做旧结构兼容
|
||||
- 统一走 `references/` + `scripts/main.py`
|
||||
|
||||
## 17. 推荐开发顺序总结
|
||||
|
||||
如果让一个新人照着做,我建议他按这个顺序:
|
||||
|
||||
1. 复制模板并改目录名
|
||||
2. 改 `SKILL.md`
|
||||
3. 改 `scripts/util/constants.py`
|
||||
4. 改 `references/`
|
||||
5. 改 `scripts/cli/app.py`
|
||||
6. 改 `scripts/service/`
|
||||
7. 跑 `health` / `version`
|
||||
8. 再做业务联调
|
||||
9. 最后 release
|
||||
|
||||
## 18. 这份模板的底线要求
|
||||
|
||||
以后新建 skill,至少要满足这几点:
|
||||
|
||||
- 目录结构统一
|
||||
- 入口统一为 `scripts/main.py`
|
||||
- 文档统一放 `references/`
|
||||
- 业务核心逻辑统一放 `scripts/service/`
|
||||
- 不再使用旧模板历史结构
|
||||
|
||||
如果做不到这些,后面 skill 一多,就会越来越乱。
|
||||
Reference in New Issue
Block a user