Skill 工坊
所有 Skill、MCP、工作流仅供个人学习测试,功能、计费、权限以 workbuddy.cn 官方为准。
开篇|为什么要讲 Skill 健壮性
WorkBuddy 上一个能跑的 Skill 和一个不会翻车的 Skill,差距不在功能多寡,而在三件事:入参是否先校验、触发是否可控、写文件/调外部是否先预览。本栏目把这三件事拆成 8 篇,每篇都给可直接复制的 SKILL.md 模板。
阅读约定:frontmatter 字段(name / description / allowed-tools / disable)以官方文档为准;防御式编程思路、调试方法论属于通用工程实践,可直接照搬。文中涉及具体版本号、界面入口与计费口径处,一律标注「待核验(以 workbuddy.cn 官方为准)」。
| 篇号 | 主题 | 读完你能拿到什么 |
|---|---|---|
| 1 | SKILL.md 规范与 frontmatter | 一份字段齐全、注释清楚的 Skill 说明书骨架 |
| 2 | 入参校验与前置判断 | 不容易翻车的参数防御写法 |
| 3 | 技能触发控制 | 解决误触发、不触发两大高频问题 |
| 4 | 文件操作类 Skill 安全规范 | 预览确认 + 目录隔离 + 默认不越界 |
| 5 | Skill 调试三板斧 | 最小用例、隔离环境、日志定位 |
| 6 | 项目级技能与团队版本管理 | 多成员共用同一套 Skill 的目录与版本方案 |
| 7 | 交付自检 Skill(核心模板) | 给任何任务加一层自动校验 |
| 8 | 技能审计清单 | 上线前安全自查标准 + 完整模板包 |
第 1 篇|Skill 底层原理:SKILL.md 规范与 frontmatter 配置
正文
一个 Skill 在 WorkBuddy 里本质上是一份带说明的脚本:SKILL.md 告诉 AI「我是谁、什么时候用、要什么参数」,脚本本体负责真正干活。SKILL.md 写得清楚,AI 才不会乱触发、不会传错参。
SKILL.md 的三个职责:
自我介绍(name + description):决定 AI 什么时候想起你。description 写得越具体,误触发越少。
交代输入怎么给:哪些信息必须有、缺了怎么办。缺参数时要让 AI 停下来追问,而不是自己猜一个值往下跑。
写清执行步骤与边界:AI 拿到输入后按什么顺序做、哪些事不许做。
frontmatter 字段(官方口径):
name(必填):Skill 唯一标识,小写连字符,例如batch-renamer。description(必填):一句话讲清「做什么 + 适用场景 + 不适用场景」。这一句直接决定 AI 什么时候会想起你。allowed-tools(可选):允许该 Skill 使用的工具白名单,逗号分隔。disable(可选):设为true时禁用该 Skill。
⚠️ 一个常见误区:
params、version、author这类字段不是 WorkBuddy 支持的 frontmatter 字段,写进去平台既不解析也不校验。Skill 的参数约定要写在正文里(用一段「参数说明」讲清必填项和默认值),AI 读的是正文,不是自定义 YAML 键。本站早期模板曾把params当作 frontmatter 字段,现已按官方口径更正。
示例
下面是一个「文本文件批量去空行」Skill 的完整 SKILL.md 骨架:
---
name: batch-trim-blank
description: |
批量清洗指定目录下 .txt / .md 文件,删除纯空行与行尾空格。
适用:用户明确说"清洗/去空行/整理笔记"且给出目录。
不适用:二进制文件、图片、代码工程(会破坏缩进)。
---
## 参数说明(写在正文,AI 读的是这里)
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| target_dir | string | 是 | — | 待处理目录绝对路径;不接受相对路径,避免歧义。 |
| dry_run | boolean | 否 | true | 默认只打印将改动的文件清单,不真正写盘。 |
| include_ext | list[string] | 否 | \["txt", "md"\] | 仅处理这些扩展名。 |
## 执行步骤
1. 校验 target_dir 是否存在、是否为目录;不存在则报错停止。
2. 列出 include_ext 内所有文件,先输出 dry-run 清单。
3. dry_run=true 时只打印数量与样例,不写盘。
4. dry_run=false 时逐文件处理:去掉行尾空格、合并连续空行为一个空行。
5. 输出处理结果统计:扫描 N 个 / 修改 M 个 / 跳过 K 个。调用示例(示意,具体触发方式待核验):
用户:帮我清洗一下 /home/user/notes 目录下的 markdown 文件,先别真改。
→ AI 识别到 description 命中,调用 batch-trim-blank,target_dir=/home/user/notes, dry_run=true, include_ext=[md]截图脚本(待补:需在真实客户端按此清单截图)
| 序号 | 页面 / 位置 | 要展示的动作或元素 | 标注说明 |
|---|---|---|---|
| 1-1 | Skill 列表页 | 展开 batch-trim-blank 的详情抽屉 | 红框圈出 name / description 两段 |
| 1-2 | SKILL.md 编辑器 | frontmatter 高亮显示 | 标注「这里是 AI 读取的说明书」 |
| 1-3 | 对话窗口 | 用户说「清洗笔记目录」后 AI 自动匹配到该 Skill | 标注 description 命中示意 |
配套模板:frontmatter 通用骨架
# 适配版本:待核验(以 workbuddy.cn 官方为准)
---
name: your-skill-name # 小写连字符,全库唯一
description: |
一句话做什么。
适用:在什么场景下使用。
不适用:明确排除的场景(这一段极重要,防误触发)。
allowed-tools: Read, Write, Bash # 可选:工具白名单
disable: false # 可选:设 true 即禁用
---
## 参数说明(正文,非 frontmatter)
| 参数 | 类型 | 必填 | 默认值 | 缺省行为 |
|---|---|---|---|---|
| required_param | string | 是 | — | 缺了就停下来问,不要瞎猜。 |
| optional_param | boolean | 否 | false | 有默认值的可选参数。 |
## 执行步骤
1. 校验输入是否合法。
2. 列出将要做的事,让用户确认(高危操作必做)。
3. 执行。
4. 输出结构化结果:成功 N / 失败 M / 跳过 K。给 AI 写一份不会翻车的技能说明书,比写十个花架子技能有用得多。——牛班长
第 2 篇|入参校验、前置判断:怎么写不容易翻车的 Skill
正文
Skill 翻车 90% 不是逻辑错,是参数没校验就跑。常见翻车现场:目录传了相对路径找不到、扩展名没过滤把图片也改了、dry_run 默认是真写盘。防御式编程的核心就一句话:凡是外部进来的东西,先当它是恶意的。
必做的五层校验:
存在性校验:文件 / 目录 / 接口先确认存在再用。
类型校验:string / number / boolean / list 不混用;list 还要逐项校验。
范围校验:路径必须在白名单根目录下、数字不越界、枚举值在允许列表内。
权限校验:当前用户是否有读 / 写权限,提前 stat,不要等到写一半报错。
副作用校验:会改文件 / 发请求 / 删数据的操作,默认 dry_run,等用户确认。
前置判断的顺序原则:便宜的检查放前面(类型、空值),贵的检查放后面(网络、磁盘 IO);任何一步失败都要清晰报错 + 告诉用户怎么补,而不是默默吞掉。
示例
下面是「批量重命名」Skill 的入参校验片段(脚本侧伪代码,具体运行时待核验):
def validate(params):
# 1. 必填存在
if not params.get("target_dir"):
return error("缺少 target_dir,请告诉我要重命名哪个目录")
# 2. 类型
if not isinstance(params["target_dir"], str):
return error("target_dir 必须是字符串路径")
# 3. 范围:必须是绝对路径,且落在工作区根目录下
root = "/home/user/workspace"
p = os.path.abspath(params["target_dir"])
if not p.startswith(root):
return error(f"拒绝越出工作目录:{p} 不在 {root} 下")
# 4. 存在性 + 权限
if not os.path.isdir(p):
return error(f"目录不存在:{p}")
if not os.access(p, os.R_OK | os.W_OK):
return error(f"无读写权限:{p}")
# 5. 副作用:dry_run 默认 True
dry = params.get("dry_run", True)
return ok(target_dir=p, dry_run=dry, pattern=params.get("pattern"))截图脚本(待补:需在真实客户端按此清单截图)
| 序号 | 页面 / 位置 | 要展示的动作或元素 | 标注说明 |
|---|---|---|---|
| 2-1 | 对话窗口 | 用户漏传目录,AI 反问「请告诉我要处理哪个目录」 | 标注「缺失必填参数时主动澄清」 |
| 2-2 | 对话窗口 | 用户传了 /etc,AI 拒绝并提示越界 | 标注「范围校验拦住越界路径」 |
| 2-3 | 对话窗口 | dry_run 模式下输出「将修改 12 个文件」预览 | 标注「副作用前先预览」 |
配套模板:入参校验模板
# 适配版本:待核验(以 workbuddy.cn 官方为准)
# 在 SKILL.md 执行步骤里写死以下检查,或在脚本里实现
## 入参校验清单(每个 Skill 都过一遍)
- [ ] 必填参数是否齐全?缺了就停下问,不要猜默认值。
- [ ] 类型是否正确?string 不接 number,list 逐项校验。
- [ ] 路径是否为绝对路径?是否落在白名单根目录下?
- [ ] 数字是否在合理范围?日期格式是否可解析?
- [ ] 枚举值是否在允许列表内?
- [ ] 目标是否存在?是否有读写权限?
- [ ] 本操作是否有副作用(写/删/发网络请求)?是 → 默认 dry_run。
- [ ] 报错信息是否告诉用户「怎么补」,而不是只说「参数错」?Skill 翻车现场复盘 100 次,99 次都在同一句话上:参数没校验就跑。——牛班长
第 3 篇|技能触发控制:解决误触发、不触发两大高频问题
正文
Skill 上线后最常见的两个抱怨:「我只是随便聊聊,它又冒出来了」(误触发)和「我明明就是要干这个,它怎么不出来」(不触发)。这两个问题的根都在 description 写法上。
误触发的根因:description 写得太宽。例如把一个「PDF 转 Word」Skill 的 description 写成「处理文档」,那用户问「怎么写文档」也会触发。
不触发的根因:description 写得太死。例如只写「处理 .docx 文件」,用户说「帮我把这个 Word 转成 PDF」就匹配不上。
正确的 description 三段式:
做什么:一句话动词 + 对象,例如「把指定目录下的 .docx 批量转为 PDF」。
适用场景:列 2-3 个典型用户说法,例如「用户说『批量转 PDF』『Word 导出 PDF』」。
不适用场景:明确排除,例如「不适用:在线编辑单个文档、不适用:扫描件 OCR」。
触发控制决策树:下面这张图就是一个 Skill 在被调用前应该走完的判断路径。WorkBuddy 实际加载与触发机制待核验(以 workbuddy.cn 官方为准),但这个判断顺序本身是工程通用的。
其他控制手段:
命名空间隔离:项目级 Skill 放项目目录,全局 Skill 放用户目录,避免跨项目误命中。
参数门槛:description 里写清楚「必须给出目标目录 / 文件路径才触发」,没给就先澄清。
冲突仲裁:两个 Skill 都命中时,description 里写明优先级,或在脚本开头打印「我是 XX,我认为该由我来处理」便于调试。
示例
# 反面:太宽,误触发
description: 处理文档
# 反面:太死,不触发
description: 处理 .docx 文件
# 正面:三段式
description: |
把指定目录下的 .docx 文件批量转为 PDF,保留原文件名。
适用:用户说"批量转 PDF"、"Word 导出 PDF"、"docx 批量转换"且给出目录。
不适用:单文件在线编辑、扫描件 OCR、PDF 反向转 Word。截图脚本(待补:需在真实客户端按此清单截图)
| 序号 | 页面 / 位置 | 要展示的动作或元素 | 标注说明 |
|---|---|---|---|
| 3-1 | 对话窗口 | 用户闲聊时 Skill 不出现 | 标注「不适用场景排除了误触发」 |
| 3-2 | 对话窗口 | 用户说「批量转 PDF」后 Skill 自动唤起 | 标注「适用场景命中」 |
| 3-3 | Skill 管理页 | 展示同名/相似 Skill 列表 | 标注「冲突仲裁需人工确认优先级」 |
配套模板:触发控制模板
# 适配版本:待核验(以 workbuddy.cn 官方为准)
description: |
<动词 + 对象,一句话说清做什么>
适用:<列 2-3 个典型用户说法,必须包含关键名词>。
不适用:<明确排除的相邻场景,这一段防误触发最有效>。
前置条件:<必须给出什么参数才触发,否则先问用户>。description 写得好,AI 就不会在你闲聊时硬插一脚。——牛班长
第 4 篇|文件操作类 Skill 安全规范(预览确认、目录隔离)
正文
凡是会写盘、删文件、移动文件的 Skill,都是高危 Skill。这类 Skill 翻车一次就可能丢一周的工作。安全规范三条铁律:
预览确认:默认 dry_run,先列出「将要改哪些文件、改成什么样」,用户点头才真写。
目录隔离:所有写操作必须落在预先声明的工作目录下,越出即拒。不接受
../../跳出去的路径。默认不越界:不读系统目录、不写用户主目录外的位置、不碰 .git / node_modules 这类工程敏感目录。
额外建议:
写前备份:第一次改某文件前,复制一份到
.backup/<timestamp>/,出问题能回滚。输出归档:所有产物统一写到
./output/<skill-name>/,不要散落用户目录。敏感目录黑名单:
.git、node_modules、.env、~/.ssh、/etc一律跳过。
示例
ROOT = "/home/user/workspace"
BLACKLIST_DIRS = {".git", "node_modules", ".venv", ".env"}
def safe_resolve(path):
p = os.path.abspath(path)
if not p.startswith(ROOT):
raise PermissionError(f"越界:{p} 不在 {ROOT} 下")
return p
def plan_rename(target_dir, pattern, dry_run=True):
target_dir = safe_resolve(target_dir)
plan = []
for root, dirs, files in os.walk(target_dir):
dirs[:] = [d for d in dirs if d not in BLACKLIST_DIRS]
for f in files:
old = os.path.join(root, f)
new = os.path.join(root, pattern(f))
if old != new:
plan.append((old, new))
return plan
# dry_run=True 只打印;False 才真正 os.rename截图脚本(待补:需在真实客户端按此清单截图)
| 序号 | 页面 / 位置 | 要展示的动作或元素 | 标注说明 |
|---|---|---|---|
| 4-1 | 对话窗口 | dry_run 输出「将重命名 12 个文件:xxx → xxx」清单 | 标注「预览确认:先看清单再执行」 |
| 4-2 | 对话窗口 | 用户传 /etc,Skill 拒绝并提示「越出工作目录」 | 标注「目录隔离拦截」 |
| 4-3 | 文件管理器 | 展示 .backup/ 下的回滚副本 | 标注「写前备份可回滚」 |
配套模板:文件操作安全模板
# 适配版本:待核验(以 workbuddy.cn 官方为准)
# 在 SKILL.md 执行步骤开头强制写入:
## 文件操作安全约束(硬编码,不可被参数覆盖)
1. 工作根目录:/home/user/workspace(示例,按项目改)。
2. 任何传入路径先 abspath,再校验是否以根目录开头;越界即报错停止。
3. 默认 dry_run=true;必须用户显式说「真改 / 执行 / 开始」才写盘。
4. 黑名单目录一律跳过:.git / node_modules / .venv / .env / ~/.ssh。
5. 写盘前把原文件复制到 .backup/<timestamp>/,保留 7 天。
6. 产物统一输出到 ./output/<skill-name>/,不散落。
7. 不读取密钥文件(.env / id_rsa / *.pem);如必须读,内容禁止打印到日志。文件操作类 Skill,没经过 dry_run 的写盘都是耍流氓。——牛班长
第 5 篇|Skill 调试三板斧:最小用例、隔离环境、日志定位
正文
Skill 不工作时,最忌讳「上来就改代码」。正确顺序是:先做最小用例复现,再隔离环境跑,最后看日志定位。这三步能解决 80% 的「它在我电脑上是好的」类问题。
第一板斧:最小用例。把问题压到最短——只传一个参数、只处理一个文件、只触发一次。如果最小用例不复现,说明是数据组合问题,逐步加参数二分定位。
第二板斧:隔离环境。新建一个空目录、清空参数、用一个临时 SKILL.md 副本跑。排除「全局配置污染」「其他 Skill 抢触发」「历史缓存」三类干扰。
第三板斧:日志定位。在脚本关键节点打日志:入参、每一步的中间状态、异常栈。日志级别分 debug / info / error,调试开 debug,生产只留 error + info。
import logging
logging.basicConfig(level=logging.INFO, format="%(asctime)s [%(levelname)s] %(message)s")
log = logging.getLogger("batch-rename")
log.info("=== run start ===")
log.debug("params=%s", params)
try:
plan = plan_rename(target_dir, pattern)
log.info("plan size=%d", len(plan))
except Exception as e:
log.exception("plan failed: %s", e) # 自动带堆栈
raise示例
典型调试路径:
用户反馈「批量重命名把图片也改了」。
最小用例:只放 1 张 png + 1 个 txt 到临时目录,跑 Skill → 复现。
隔离环境:确认 include_ext 默认值是不是漏配了图片扩展名 → 定位。
日志:在 walk 循环里打
log.debug("skip ext=%s", ext),看是不是没走到跳过分支。
截图脚本(待补:需在真实客户端按此清单截图)
| 序号 | 页面 / 位置 | 要展示的动作或元素 | 标注说明 |
|---|---|---|---|
| 5-1 | 临时目录 | 最小用例:1 个 txt + 1 个 png | 标注「最小复现」 |
| 5-2 | 终端 / 日志面板 | 展示 debug 级日志输出 | 标注「关键节点打日志」 |
| 5-3 | 对话窗口 | AI 反馈「已在隔离目录复现并修复」 | 标注「隔离环境排除污染」 |
配套模板:调试检查清单
# 适配版本:待核验(以 workbuddy.cn 官方为准)
## Skill 不工作时按顺序做
1. 最小用例:只传 1 个必填参数,只放 1 个测试文件,能复现吗?
2. 二分定位:逐步加参数,找到第一次失败的那一步。
3. 隔离环境:新建空目录 + 临时 SKILL.md 副本,还失败吗?
4. 日志:在入参 / 每步中间状态 / 异常处打 debug 日志。
5. 对比:和上次能跑的版本 diff SKILL.md 与脚本。
6. 记录:把复现步骤写回 SKILL.md 的「Known Issues」段。调试不是猜,是把问题压到最小再看它在哪一步死的。——牛班长
第 6 篇|项目级技能:团队统一技能版本管理方案
正文
个人用 Skill 随手写就行;一旦两个人以上共用,就会遇到三个问题:谁改了什么、线上跑的是哪一版、怎么让所有人拿到最新版。项目级技能就是把 Skill 当代码管。
推荐目录结构:
your-project/
├── skills/
│ ├── batch-rename/
│ │ ├── SKILL.md
│ │ ├── run.py
│ │ └── README.md
│ ├── pdf-to-png/
│ │ └── ...
│ └── _shared/
│ ├── safe_fs.py # 目录隔离 / 备份 / dry_run 公共函数
│ └── log_util.py
└── .skills-version.yaml # 记录每个 Skill 的版本与 git commit版本管理三原则:
语义化版本:MAJOR.MINOR.PATCH。改参数或破坏行为升 MAJOR;加功能升 MINOR;修 bug 升 PATCH。
Git 跟踪:skills/ 目录进 git,每次改动走 MR / PR,不在生产目录直接改。
锁文件:
.skills-version.yaml记录每个 Skill 的 commit hash,团队成员拉到同一版再跑。
与本站已有「最小可用配套资产包」的关系:项目级 Skill 是在那 3 个基础模板上加上目录结构 + 版本锁 + shared 公共库;具体使用可参考资产包文档,本篇不重复模板内容。
示例
skills:
batch-rename:
version: 1.2.0
commit: a1b2c3d
owner: zhangsan
pdf-to-png:
version: 0.3.1
commit: e4f5g6h
owner: lisi
shared:
safe_fs:
version: 0.5.0
commit: x9y8z7w截图脚本(待补:需在真实客户端按此清单截图)
| 序号 | 页面 / 位置 | 要展示的动作或元素 | 标注说明 |
|---|---|---|---|
| 6-1 | 文件树 | 展示 skills/ 目录与 _shared/ 结构 | 标注「每个 Skill 一个文件夹」 |
| 6-2 | .skills-version.yaml | 展示版本与 commit 锁 | 标注「团队统一版本」 |
| 6-3 | Git MR 页面 | 一次 Skill 修改走 Code Review | 标注「不直接改生产目录」 |
配套模板:项目级 Skill 骨架
# 适配版本:待核验(以 workbuddy.cn 官方为准)
# 新建项目级 Skill 的标准步骤
mkdir -p skills/your-skill-name
cd skills/your-skill-name
cat > SKILL.md <<'EOF'
---
name: your-skill-name
description: |
<三段式 description:做什么 / 适用 / 不适用>
---
EOF
touch run.py README.md
git add .
git commit -m "feat(skills): scaffold your-skill-name"Skill 写着写着就成项目了,早点把它当代码管,少踩两年坑。——牛班长
第 7 篇|交付自检 Skill:给任务增加自动校验层(核心模板)
正文
「我以为它做完了」是最常见的翻车姿势。交付自检 Skill 的思路是:任何 Skill 在输出最终结果前,必须先跑一遍校验清单,把校验报告和结果一起交出来。
自检层做什么:
数量核对:声称处理了 N 个文件,磁盘上是不是真的有 N 个产物?
格式核对:声称输出 PDF,文件头是不是真的 %PDF?
内容核对:抽 1-2 个产物打开看看,字段是否齐全、有没有乱码。
副作用核对:有没有意外修改了黑名单目录?日志里有没有 ERROR?
自检输出格式:固定三段——「通过项 / 警告项 / 失败项」,失败项必须附原因和建议动作。
示例
def self_check(output_dir, expected_count):
report = {"pass": [], "warn": [], "fail": []}
files = list(Path(output_dir).glob("*"))
if len(files) != expected_count:
report["fail"].append(f"产物数量不符:期望 {expected_count},实际 {len(files)}")
for f in files:
if f.stat().st_size == 0:
report["warn"].append(f"空文件:{f.name}")
# 示例:PDF 校验
if f.suffix == ".pdf":
head = f.open("rb").read(5)
if head != b"%PDF-":
report["fail"].append(f"非 PDF 头:{f.name}")
if not report["fail"]:
report["pass"].append(f"产物 {len(files)} 个全部通过格式校验")
return report截图脚本(待补:需在真实客户端按此清单截图)
| 序号 | 页面 / 位置 | 要展示的动作或元素 | 标注说明 |
|---|---|---|---|
| 7-1 | 对话窗口 | Skill 输出末尾附带自检报告 | 标注「通过/警告/失败三段」 |
| 7-2 | 对话窗口 | 失败项被标红,附原因 | 标注「失败即阻断交付」 |
配套模板:交付自检 Skill 完整模板(教学版)
# 适配版本:待核验(以 workbuddy.cn 官方为准)
---
name: self-check-deliverable
description: |
在任何 Skill 交付产物前跑一遍自检,输出通过/警告/失败报告。
适用:其他 Skill 调用结束前,或用户说"检查一下结果"。
不适用:网络请求类、纯对话类无产物任务。
---
## 参数说明
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| output_dir | string | 是 | — | 产物目录绝对路径。 |
| expected_count | integer | 否 | — | 期望产物数量;不传则只做格式检查。 |
| allowed_ext | list[string] | 否 | \["pdf","png","jpg","md","txt","csv"\] | 参与检查的扩展名。 |
## 执行步骤
1. 校验 output_dir 存在且可读(参考第 2 篇入参校验)。
2. 列出 output_dir 内所有文件,过滤 allowed_ext 外的扩展名。
3. 数量核对:若传了 expected_count,比对实际数量。
4. 格式核对:按扩展名读文件头(PDF=%PDF-,PNG=\x89PNG)。
5. 大小核对:0 字节文件记为 warn。
6. 输出结构化报告:
- PASS:通过项列表
- WARN:警告项列表(不阻断)
- FAIL:失败项列表(阻断交付,附建议动作)
7. 若存在 FAIL,最终回复必须显式提示「交付未通过自检,请检查后重试」。Skill 跑完不算完,自检报告过了才算完。——牛班长
第 8 篇|技能审计清单:上线前安全自查标准
正文
把一个 Skill 从「自己测试能跑」变成「敢发给别人用」,中间差一份上线前审计清单。下面这张矩阵覆盖 6 个维度 × 3 个风险等级,任一高风险项未通过即阻断发布。
审计执行方式:新建 Skill 或修改 SKILL.md / 脚本后,逐项打勾;高风险项必须有对应代码或配置证据,不能口头说「我加了」。审计结果写进 Skill 仓库的 AUDIT.md,随版本一起提交。
示例
典型审计结论片段:
入参校验:通过——所有必填项在脚本开头校验,缺失即报错。
文件操作:通过——abspath + 根目录白名单 + 默认 dry_run。
密钥:不通过——SKILL.md 里硬编码了
API_KEY=xxx,必须改为环境变量占位符。
截图脚本(待补:需在真实客户端按此清单截图)
| 序号 | 页面 / 位置 | 要展示的动作或元素 | 标注说明 |
|---|---|---|---|
| 8-1 | AUDIT.md | 打勾清单全文 | 标注「高风险项阻断发布」 |
| 8-2 | Git MR | 审计人留下不通过评论 | 标注「审计结果随版本入库」 |
配套模板:审计清单 Markdown 版
# Skill 上线前审计清单
# 适配版本:待核验(以 workbuddy.cn 官方为准)
## Skill: <name> 版本: <x.y.z> 审计人: <who> 日期: YYYY-MM-DD
### 高风险(任一未通过即阻断)
- [ ] 所有入参都有类型 / 范围 / 存在性校验
- [ ] description 包含「不适用场景」,不会误触发
- [ ] 写操作全部走目录隔离 + 默认 dry_run
- [ ] SKILL.md 与脚本中无明文密钥 / Token / 密码(占位符除外)
- [ ] 外部 API 调用有超时 + 错误处理
- [ ] 交付前跑自检 Skill,无 FAIL 项
### 中风险(需在 README 说明)
- [ ] 必填参数缺失时会主动澄清,不使用隐式默认
- [ ] 高危写操作前有预览确认
- [ ] 外部依赖声明了版本范围
- [ ] 日志不打印完整敏感参数
### 低风险(建议项)
- [ ] 参数命名风格统一
- [ ] 输出产物统一归档到 ./output/
- [ ] 已知问题写进 README 的 Known Issues
## 审计结论
- [ ] 通过,可发布
- [ ] 不通过,阻断原因:<填写>附录:扩展模板包(教学完整版)
下面三个模板在「最小可用配套资产包」基础上升级为教学版,可直接复制使用。与资产包差异:补了入参校验、dry_run、自检报告三段、密钥占位符要求。
附录 A:批量重命名 Skill(教学版)
# 适配版本:待核验(以 workbuddy.cn 官方为准)
---
name: batch-rename
description: |
按给定正则 / 前缀规则批量重命名指定目录下文件。
适用:用户说"批量重命名"、"统一前缀"且给出目录与规则。
不适用:跨目录移动、覆盖已有同名文件、修改 .git 内部文件。
---
## 参数说明
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| target_dir | string | 是 | — | 待重命名目录。 |
| pattern | string | 是 | — | 重命名规则,例如 `IMG_{i:04d}.jpg`。 |
| dry_run | boolean | 否 | true | 只打印对照表,不写盘。 |
| root_whitelist | string | 否 | /home/user/workspace | 允许操作的根目录。 |
## 执行步骤
1. abspath(target_dir),校验是否以 root_whitelist 开头。
2. 列出文件,按 pattern 生成 new_name 列表。
3. 检测冲突:new_name 是否已存在于目录?存在即报错。
4. dry_run=true:打印 old → new 对照,不写盘。
5. dry_run=false:先备份到 .backup/<ts>/,再逐个 rename。
6. 调用 self-check-deliverable 输出自检报告。附录 B:风险关键词识别 Skill(教学版)
# 适配版本:待核验(以 workbuddy.cn 官方为准)
---
name: risk-keyword-scan
description: |
扫描指定文本文件中是否命中敏感 / 违规关键词清单。
适用:用户说"扫一下敏感词"、"风险词检查"。
不适用:实时舆情监控、自动删稿(本 Skill 只报告不修改)。
---
## 参数说明
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---|---|
| file_path | string | 是 | — | 待扫描文本文件。 |
| keyword_list | string | 否 | ./keywords.txt | 关键词词典路径,一行一个词。 |
## 执行步骤
1. 校验 file_path 可读;不读取 .env / id_rsa 等密钥文件。
2. 读词典,逐词在文本中查找,记录命中行号。
3. 输出报告:命中词 / 行号 / 上下文片段。
4. 不自动改写文件;只输出建议人工处理。
# 注意:命中结果可能含敏感内容,日志中只打词频,不打原文。附录 C:结果自检 Skill(教学版)
即第 7 篇正文给出的 self-check-deliverable 完整模板,此处不再重复,直接跳转第 7 篇「配套模板」段复制。
Skill 上线前多花 10 分钟审计,省得线上花 10 小时救火。——牛班长
文末|配套资源与引用
版本兼容对照表:见知识营地已交付文档(WorkBuddy 版本字段均待核验)。
资产验收测试标准:见知识营地已交付文档。
最小可用配套资产包:见知识营地已交付文档,本栏目附录在其基础上升级为教学版。
FAQ / 全站固定文案:见知识营地已交付文档。
使用提示:WorkBuddy 专有字段、加载规则、触发机制、计费与权限以 workbuddy.cn 官方为准。密钥 / Token 一律使用环境变量占位符,禁止明文存储与提交。
(注:部分内容由豆包工作 AI 生成)