docs: generalize skill-template references + add TESTING.md

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-05-10 10:00:44 +08:00
parent f3f59278b4
commit f0032b2201
9 changed files with 368 additions and 122 deletions

View File

@@ -2,14 +2,14 @@
这份文档是给**技术人员**看的,目标不是解释概念,而是让你拿到 `skill-template` 后,可以**一步一步开发出一个新的 skill**。
本文默认你开发的是当前最常见的一类技能
本文默认你开发的是当前最常见的一类业务 skill
- 有明确的 `scripts/main.py` CLI 入口
- 可能需要读写本地 SQLite
- 可能需要调用兄弟技能
- 可能需要读写本地 SQLite(例如任务日志 `task_logs`
- 可能需要调用兄弟技能或外部 HTTP / RPA
- 业务逻辑主要放在 `scripts/service/`
如果你开发的是发布型 skill这个模板就是直接可用的起点
发布、对账、代发、报表分析等场景都只是业务特例;模板提供通用骨架,复制后按领域补齐实现即可
## 推荐 AI 开发工具
@@ -145,7 +145,7 @@ scripts/
- `service/`
作用:核心业务逻辑
比如发布流程、调用兄弟技能、浏览器自动化
比如任务编排、调用兄弟技能、外部 API、可选浏览器自动化
- `util/`
作用:常量、日志、路径、时间工具、通用帮助函数
@@ -160,10 +160,10 @@ scripts/
### 第一步:复制模板并改目录名
例如你要开发 `weibo-publisher`
例如你要开发 `your-skill-slug`(或 `disburse-payroll-icbc` 一类领域 skill
1. 复制 `skill-template`
2. 新目录改成 `weibo-publisher`
2. 新目录改成 `slug` 一致的名称(如 `your-skill-slug`
3. 初始化为独立 git 仓库
4. 关联它自己的远端仓库
@@ -176,7 +176,7 @@ scripts/
1. `SKILL.md`
2. `scripts/util/constants.py`
3. `references/` 下的文案
4. `scripts/service/` 下的平台占位文件名
4. `scripts/service/` 下的业务占位实现(优先改 `task_service.py`
最先要统一的是:
@@ -193,18 +193,19 @@ scripts/
复制后,至少要全局检查并替换下面这些内容:
- `your-skill-slug`
- `your-platform-key`
- `技能开发模板(复制后请修改`
- `your-platform-key`(若 skill 涉及外部平台对接,可能会用到这类占位)
- `技能开发模板(通用业务版`
- `你的平台名`
- `platform_playwright.py`
- `openclaw.skill.your_skill_slug`
如果你是做发布型 skill通常还要替换
如果你 skill 对外 CLI 需要自定义文案或别名(例如发布类对外仍叫 `publish`,通常还要替换:
- `publish` 命令中的中文提示
- `run` 命令中的中文提示与别名策略(见 `references/CLI.md`
- `references/CLI.md` 的命令示例
- `references/README.md` 的用户话术
- `references/SCHEMA.md`数据库文件名
- `references/SCHEMA.md`字段映射补充说明
如需浏览器自动化,不要在模板里保留空的 `platform_playwright.py`;请按业务新建 `xxx_playwright.py`(命名自定),并在 `task_service.py` 中按需引用。
## 6. `SKILL.md` 应该怎么写
@@ -216,7 +217,7 @@ scripts/
- 技能描述
- `slug`
作用:技能的唯一英文标识,通常用于仓库名、发布包名、运行时目录名、平台主键匹配等
示例:`weibo-publisher``douyin-publisher``xiaohongshu-publisher`
示例:`your-skill-slug``disburse-payroll-icbc``tax-invoice-verify`
- `category`
作用:技能在平台中的分类,用于市场展示与归类,不是代码内部键
示例:`通用``内容``办公协作``物流``抖音``小红书`
@@ -224,12 +225,11 @@ scripts/
作用:声明发布后默认拥有可见权限的开发者用户 ID 列表
- `dependencies`
作用:声明该技能依赖的兄弟技能或运行前置能力,便于平台或编排层识别依赖关系
示例:
示例(按业务填写;发布类可能会依赖账号 / 内容技能,其它领域可能完全不同)
```yaml
dependencies:
required:
- account-manager
- content-manager
- some-sibling-skill
```
- 何时使用本技能
- 对用户的引导话术
@@ -288,6 +288,9 @@ metadata:
- `DEVELOPMENT.md`
写给技术人员的开发教程,也就是本文档
- `TESTING.md`
写给技术人员的测试分层、隔离数据根与档位开关指南(详见 [`references/TESTING.md`](TESTING.md)
如果后面某个 skill 需要更细的说明,可以再加:
- `ERRORS.md`
@@ -319,8 +322,8 @@ metadata:
也就是说,`cli/app.py` 的职责是:
1. 打印帮助
2. 定义 `publish / logs / log-get / health / version`
3. 把参数转交给 `service.publish_service`
2. 定义 `run / logs / log-get / health / version`
3. 把参数转交给 `service.task_service`
不要在 `cli/app.py` 里直接写:
@@ -334,14 +337,14 @@ metadata:
通常可以这样拆:
- `publish_service.py`
放命令编排、参数兜底、结果分流
- `task_service.py`
放命令编排、参数兜底、结果分流(例如 `cmd_run`
- `sibling_bridge.py`
放兄弟技能调用,例如调 `account-manager`、`content-manager`
通用兄弟技能子进程工具(`call_sibling_json`**具体调用哪个 slug 由业务在 `task_service.py` 决定**,不要在本文件硬编码发布类专用 helper
- `*_playwright.py`
浏览器后台自动化
- `xxx_playwright.py`(按需新建)
浏览器后台自动化 **不在模板默认结构中**;若确有需要,按命名约定自建模块并在 `task_service.py` 引用
- `entitlement_service.py`
放鉴权逻辑
@@ -352,7 +355,7 @@ metadata:
推荐流向是:
`cli.app` -> `service.publish_service` -> `service.sibling_bridge` / `service.xxx_playwright` -> `db`
`cli.app` -> `service.task_service` -> `service.sibling_bridge` / (可选)`service.xxx_playwright` -> `db`
## 11. `db` 层怎么写
@@ -361,8 +364,8 @@ metadata:
- `db/connection.py`
只做连接和建表
- `db/publish_logs_repository.py`
只做增删查改
- `db/task_logs_repository.py`
只做增删查改(模板默认表:`task_logs`
不要在 `db` 层里:
@@ -381,10 +384,7 @@ metadata:
来做调用。
常见调用对象是:
- `account-manager`
- `content-manager`
调用哪些兄弟技能由具体业务决定;请在 `task_service.py` 中使用 `service.sibling_bridge.call_sibling_json(skill_slug, args)` 或 `get_sibling_main_path(skill_slug)`,不要在本模板仓库的 `sibling_bridge.py` 中堆积特定技能函数。
调用原则:
@@ -413,7 +413,7 @@ metadata:
- 日志或本地状态能落下来
- 错误返回值格式定好了
如果你的 skill 恰好是 publisher 类,可以把上面的“核心 `service`”具体落成 `publish_service.py`,再逐步接 `sibling_bridge.py`、`*_playwright.py`。这只是示例,不代表模板只适合发布类技能
如果你的 skill 属于外联型 / RPA 型,可以把上面的“核心 `service`”具体落成 `task_service.py`,再按需接 `sibling_bridge.py`、(可选)`*_playwright.py`。这只是示例路径组合,不代表模板绑定某一业务领域
## 14. 本地开发的最小验证顺序
@@ -442,7 +442,7 @@ python scripts/main.py <your-log-command>
python scripts/main.py <your-detail-command> <id>
```
如果你沿用了模板中的发布型骨架,那么这里可以具体对应成:
如果你沿用了模板中的通用任务日志骨架,那么这里可以具体对应成:
```bash
python scripts/main.py logs
@@ -457,8 +457,22 @@ python scripts/main.py log-get 1
python scripts/main.py <your-command>
```
## 14.5 测试驱动的开发顺序
新 skill 不应该等所有业务做完才补测试。建议在每个开发阶段都先把对应测试跑一遍:
1. **目录搭建后**:跑 `python tests/run_tests.py -v`,确认 6 个默认测试套件全部通过。
- 此时 `test_skill_metadata.py` 会校验 `SKILL.md` slug 与 `constants.SKILL_SLUG` 一致;如果你只改了一边,会立刻发现。
2. **改完 constants 后**:再跑一次必跑套件,确认未引入回归。
3. **写完 service 业务后**:从 `tests/samples/test_service_contract.py.sample` 复制一份做契约测试。
4. **接外部系统时**:写在 `tests/integration/`,并配合 `OPENCLAW_TEST_TARGET` 显式开启。
详见 `references/TESTING.md`。
## 15. 发布到正式环境验证
在执行 `release.ps1` 之前,必须先在本地确认 `python tests/run_tests.py -v` 通过。测试不通过不得发起正式发布。
当本地开发、自测和联调完成后,还需要把 skill 发布到正式环境做一次完整验证。建议技术人员严格按下面顺序执行,不要跳步。
### 第一步:在 skill 根目录执行 `release.ps1`
@@ -574,12 +588,15 @@ python scripts/main.py <your-command>
- [ ] `SKILL.md` 中 slug、名称、描述都已替换
- [ ] `scripts/util/constants.py` 已修改
- [ ] `references/CLI.md` 示例命令已改成真实命令
- [ ] `service` 下的平台文件名已改对
- [ ] `service` 下的核心业务文件(如 `task_service.py`)已按领域改名并实现
- [ ] 没有残留旧平台名
- [ ] `health` / `version` 可运行
- [ ] `.gitignore` 生效,没有把 `__pycache__` 提交进去
- [ ] `release.ps1` 存在
- [ ] `.github/workflows/release_skill.yaml` 存在
- [ ] `python tests/run_tests.py -v` 全部通过
- [ ] 没有新增默认必跑测试访问真实网络或浏览器
- [ ] 如有 integration 测试需求,已写在 `tests/integration/` 下并保持 `.sample` 后缀
## 17. 常见错误
@@ -601,11 +618,11 @@ python scripts/main.py <your-command>
表现:
- 兄弟技能筛选账号失败
- 发布命令走错平台
- `run` 命令走错平台或 task_type
要检查:
- `publish_service.py`
- `task_service.py`
- `sibling_bridge.py`
- `references/CLI.md`
@@ -644,9 +661,10 @@ python scripts/main.py <your-command>
4. 改 `references/`
5. 改 `scripts/cli/app.py`
6. 改 `scripts/service/`
7. 跑 `health` / `version`
8. 再做业务联调
9. 最后 release
7. 跑 `python tests/run_tests.py -v`
8. 跑 `health` / `version`
9. 再做业务联调
10. 最后 release
## 19. 这份模板的底线要求