乐于分享
好东西不私藏

OpenClaw Skill 标准模板+10个新手实用源码+调试避坑指南

OpenClaw Skill 标准模板+10个新手实用源码+调试避坑指南

一、OpenClaw Skill 标准结构模板

整合必选字段、可选扩展字段、通用前置检查、跨系统兼容逻辑,所有自定义Skill均可基于此模板修改,注释清晰,直接替换业务逻辑即可。

// 按需引入Node.js内置模块,无需额外安装第三方包const fs = require("fs");const path = require("path");const os = require("os");// 导出Skill核心配置(OpenClaw固定识别格式,不可修改外层结构)module.exports = {// 【必选】技能唯一ID:英文+下划线,全局唯一,避免重复id"skill_unique_id",// 【必选】技能名称:中文简洁命名,一眼看懂功能name"技能名称",// 【必选】触发词:数组格式,用户输入包含任意一个即触发,贴合日常说话习惯triggers: ["触发词1""触发词2""触发词3"],// 【必选】技能描述:说明功能、使用场景,方便后期管理description"详细说明技能功能,比如:在指定目录批量创建文本文件,支持自定义前缀和数量",// 【必选】参数定义:大模型提取用户输入参数的依据,必填/可选/默认值清晰parameters: [        {name"paramName"// 参数名:英文小写,无特殊字符type"string"// 参数类型:string/number/boolean/arrayrequiredtrue// 是否必填:true/falsedefault""// 可选参数默认值,required为false时必设description"参数说明,比如:文件所在目录的相对/绝对路径",example"./Desktop/测试目录"// 示例值,帮助大模型精准提取        },    ],// 【可选】执行超时时间:避免技能卡死,单位毫秒,默认30000(30秒)timeout30000,// 【可选】技能分类:方便管理,比如文件操作/开发工具/办公自动化category"文件操作",// 【必选】核心执行逻辑:async支持异步操作,params为解析后的用户参数asyncexecute(params) {try {// 通用前置:解构参数(和parameters字段一一对应)const { paramName1, paramName2 } = params;// 【通用封装】获取跨系统桌面路径(Windows/Mac/Linux兼容)constgetDesktopPath = () => {return os.platform() === "win32"                    ? path.join(process.env.USERPROFILE"Desktop")                    : path.join(process.env.HOME"Desktop");            };// 【通用封装】检查目录是否存在,不存在则递归创建constcheckAndCreateDir = dirPath => {if (!fs.existsSync(dirPath)) {                    fs.mkdirSync(dirPath, { recursivetrue });                }            };// -------------------------- 核心业务逻辑 --------------------------// 此处替换为自己的技能功能代码,示例:空逻辑const resultMsg = "技能执行成功";// -------------------------------------------------------------------// 【必选】成功返回格式:success为true,message为提示语,data可选返回额外数据return {successtrue,message: resultMsg,data: {/* 可选:返回执行结果的详细数据,如文件数量、路径等 */                },            };        } catch (error) {// 【必选】失败返回格式:success为false,message为具体错误原因(方便调试)return {successfalse,message`技能执行失败:${error.message},错误码:${error.code || "无"}`,            };        }    },};

二、10个新手实用Skill源码(直接运行版)

覆盖文件操作、办公自动化、开发辅助三大高频场景,均基于标准模板开发,无第三方依赖,附调用指令,复制到src/skills即可使用。

【文件操作类6个】(OpenClaw基础核心场景)

Skill1:单文件重命名(基础款)

const fs = require("fs");const path = require("path");module.exports = {id"file_rename_single",name"单文件重命名",triggers: ["重命名单个文件""修改文件名""文件改名"],description"修改单个文件的名称,支持相对/绝对路径,跨系统兼容",parameters: [        {name"oldPath",type"string",requiredtrue,description"原文件完整路径",example"./Desktop/旧文件.txt",        },        {name"newName",type"string",requiredtrue,description"新文件名(含后缀)",example"新文件_2026.txt",        },    ],category"文件操作",asyncexecute(params) {try {const { oldPath, newName } = params;if (!fs.existsSync(oldPath)) thrownewError(`原文件不存在:${oldPath}`);const newPath = path.join(path.dirname(oldPath), newName);if (fs.existsSync(newPath)) thrownewError(`新路径已存在同名文件:${newPath}`);            fs.renameSync(oldPath, newPath);return {successtrue,message`文件重命名成功!\n原路径:${oldPath}\n新路径:${newPath}`,            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:重命名单个文件 oldPath=./Desktop/测试.txt newName=工作笔记_2026.txt

Skill2:桌面新建文本文件(极简款)

const fs = require("fs");const path = require("path");const os = require("os");module.exports = {id"file_create_desktop_txt",name"桌面新建文本文件",triggers: ["新建文本文件""桌面创作文档""生成txt文件"],description"在电脑桌面新建指定名称的文本文件,支持自定义内容,跨系统兼容",parameters: [        {name"fileName",type"string",requiredtrue,description"新建文件名(必须含.txt后缀)",example"OpenClaw笔记.txt",        },        {name"content",type"string",requiredfalse,default"OpenClaw Skill 自动生成的文本文件",description"文件自定义内容",        },    ],category"文件操作",asyncexecute(params) {try {const { fileName, content } = params;if (!fileName.endsWith(".txt")) thrownewError("文件名必须以.txt为后缀");const desktopPath =                os.platform() === "win32"                    ? path.join(process.env.USERPROFILE"Desktop")                    : path.join(process.env.HOME"Desktop");const filePath = path.join(desktopPath, fileName);if (fs.existsSync(filePath)) thrownewError(`桌面已存在同名文件:${fileName}`);            fs.writeFileSync(filePath, content, "utf8");return {successtrue,message`文本文件创建成功!\n路径:${filePath}\n内容:${content}`,            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:新建文本文件 fileName=Skill开发笔记.txt content=OpenClaw Skill开发核心:固定模板+业务逻辑

Skill3:批量删除桌面空文件

const fs = require("fs");const path = require("path");const os = require("os");module.exports = {id"file_delete_desktop_empty",name"批量删除桌面空文件",triggers: ["删除桌面空文件""清理空文本文件""删除空文档"],description"扫描电脑桌面,批量删除大小为0的空文本文件(.txt),避免误删其他文件",parameters: [],category"文件操作",asyncexecute() {try {const desktopPath =                os.platform() === "win32"                    ? path.join(process.env.USERPROFILE"Desktop")                    : path.join(process.env.HOME"Desktop");const files = fs                .readdirSync(desktopPath)                .filter(file =>                        file.endsWith(".txt") &&                        fs.statSync(path.join(desktopPath, file)).size === 0                );            files.forEach(file => fs.unlinkSync(path.join(desktopPath, file)));return {successtrue,message`空文件清理完成!桌面共扫描到${files.length}个空文本文件,已全部删除`,            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:删除桌面空文件

Skill4:批量重命名指定目录文件

const fs = require("fs");const path = require("path");module.exports = {id"file_rename_batch",name"批量重命名指定目录文件",triggers: ["批量重命名文件""统一修改文件名""文件批量改名"],description"按前缀+序号重命名指定目录下的所有文件,保留原后缀,支持自定义前缀",parameters: [        {name"fileDir",type"string",requiredtrue,description"文件所在目录路径",example"./Desktop/图片",        },        {name"prefix",type"string",requiredfalse,default"file_",description"文件名自定义前缀",        },    ],category"文件操作",asyncexecute(params) {try {const { fileDir, prefix } = params;if (!fs.existsSync(fileDir)) thrownewError(`目标目录不存在:${fileDir}`);const files = fs                .readdirSync(fileDir)                .filter(file => fs.statSync(path.join(fileDir, file)).isFile());if (files.length === 0thrownewError(`目标目录下无文件可重命名`);            files.forEach((file, index) => {const oldPath = path.join(fileDir, file);const ext = path.extname(file);const newName = `${prefix}${index + 1}${ext}`;const newPath = path.join(fileDir, newName);                fs.renameSync(oldPath, newPath);            });return {successtrue,message`批量重命名成功!\n目标目录:${fileDir}\n处理文件数量:${files.length}\n文件前缀:${prefix}`,            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:批量重命名文件 fileDir=./Desktop/旅游照片 prefix=旅游2026

Skill5:复制文件到指定目录

const fs = require("fs");const path = require("path");module.exports = {id"file_copy_to_dir",name"复制文件到指定目录",triggers: ["复制文件""文件拷贝""把文件移到指定文件夹"],description"将指定文件复制到目标目录,目标目录不存在则自动创建,保留原文件名",parameters: [        {name"sourcePath",type"string",requiredtrue,description"源文件完整路径",example"./Desktop/源文件.pdf",        },        {name"targetDir",type"string",requiredtrue,description"目标目录路径",example"./Desktop/备份文件夹",        },    ],category"文件操作",asyncexecute(params) {try {const { sourcePath, targetDir } = params;if (!fs.existsSync(sourcePath)) thrownewError(`源文件不存在:${sourcePath}`);if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursivetrue });const fileName = path.basename(sourcePath);const targetPath = path.join(targetDir, fileName);if (fs.existsSync(targetPath)) thrownewError(`目标目录已存在同名文件:${fileName}`);            fs.copyFileSync(sourcePath, targetPath);return {successtrue,message`文件复制成功!\n源文件:${sourcePath}\n目标路径:${targetPath}`,            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:复制文件 sourcePath=./Desktop/工作计划.xlsx targetDir=./Desktop/工作/2026年3月

Skill6:读取文本文件内容

const fs = require("fs");const path = require("path");module.exports = {id"file_read_txt_content",name"读取文本文件内容",triggers: ["读取文件内容""查看txt内容""读取文本文件"],description"读取指定文本文件(.txt)的内容,返回完整文本,支持utf8编码",parameters: [        {name"filePath",type"string",requiredtrue,description"文本文件完整路径",example"./Desktop/笔记.txt",        },    ],category"文件操作",asyncexecute(params) {try {const { filePath } = params;if (!fs.existsSync(filePath)) thrownewError(`文件不存在:${filePath}`);if (!filePath.endsWith(".txt")) thrownewError("仅支持读取.txt格式的文本文件");const content = fs.readFileSync(filePath, "utf8");return {successtrue,message`文件读取成功!\n文件路径:${filePath}\n文件内容:\n${content}`,data: { content, filePath },            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:读取文件内容 filePath=./Desktop/Skill开发笔记.txt

【办公自动化类2个】(打工人高频需求)

Skill7:生成今日工作日报模板

const fs = require("fs");const path = require("path");const os = require("os");module.exports = {id"doc_create_work_report",name"生成今日工作日报模板",triggers: ["生成工作日报""创建日报模板""今日工作汇报"],description"在桌面生成今日日期的工作日报模板(txt),包含工作完成、待办、问题三大模块",parameters: [],category"办公自动化",asyncexecute() {try {// 获取今日日期const today = newDate();const dateStr = `${today.getFullYear()}${today.getMonth() + 1}${today.getDate()}日`;// 桌面路径const desktopPath =                os.platform() === "win32"                    ? path.join(process.env.USERPROFILE"Desktop")                    : path.join(process.env.HOME"Desktop");const filePath = path.join(desktopPath, `工作日报_${dateStr}.txt`);// 日报模板内容const reportContent = `# 工作日报日期:${dateStr}汇报人:## 一、今日工作完成1. 2. 3. ## 二、明日工作待办1. 2. 3. ## 三、遇到的问题与解决方案1. 问题:   解决方案:## 四、其他说明`;if (fs.existsSync(filePath))thrownewError(`桌面已存在今日日报文件:${path.basename(filePath)}`);            fs.writeFileSync(filePath, reportContent, "utf8");return {successtrue,message`今日工作日报模板生成成功!\n路径:${filePath}\n模板包含:工作完成、待办、问题三大核心模块`,            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:生成工作日报

Skill8:批量创建文件夹

const fs = require("fs");const path = require("path");module.exports = {id"dir_create_batch",name"批量创建文件夹",triggers: ["批量创建文件夹""新建多个目录""创建文件夹组"],description"在指定父目录下,按输入的名称列表批量创建文件夹,父目录不存在则自动创建",parameters: [        {name"parentDir",type"string",requiredtrue,description"父目录路径",example"./Desktop/项目资料",        },        {name"dirNames",type"array",requiredtrue,description"文件夹名称列表,用英文逗号分隔",example"需求文档,设计图,开发代码,测试报告",        },    ],category"办公自动化",asyncexecute(params) {try {const { parentDir, dirNames } = params;// 解析数组参数(用户输入逗号分隔,转成真正的数组)const dirNameList = Array.isArray(dirNames)                ? dirNames                : dirNames.split(",").map(name => name.trim());if (dirNameList.length === 0thrownewError("文件夹名称列表不能为空");// 检查并创建父目录if (!fs.existsSync(parentDir)) fs.mkdirSync(parentDir, { recursivetrue });// 批量创建子文件夹            dirNameList.forEach(name => {const dirPath = path.join(parentDir, name);if (!fs.existsSync(dirPath)) fs.mkdirSync(dirPath);            });return {successtrue,message`批量创建文件夹成功!\n父目录:${parentDir}\n创建数量:${dirNameList.length}\n文件夹名称:${dirNameList.join("、")}`,            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:批量创建文件夹 parentDir=./Desktop/2026新项目 dirNames=需求分析,UI设计,前端开发,后端开发,测试上线

【开发辅助类2个】(开发者刚需)

Skill9:创建Node.js基础文件

const fs = require("fs");const path = require("path");module.exports = {id"dev_create_node_file",name"创建Node.js基础文件",triggers: ["创建node文件""生成js基础模板""新建Node.js文件"],description"在指定目录创建Node.js基础文件(.js),包含模块化导出、基础注释模板",parameters: [        {name"targetDir",type"string",requiredtrue,description"目标目录路径",example"./Desktop/Node项目",        },        {name"fileName",type"string",requiredtrue,description"新建js文件名(含.js后缀)",example"index.js",        },    ],category"开发辅助",asyncexecute(params) {try {const { targetDir, fileName } = params;if (!fileName.endsWith(".js")) thrownewError("文件名必须以.js为后缀");if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursivetrue });const filePath = path.join(targetDir, fileName);if (fs.existsSync(filePath)) thrownewError(`目标目录已存在同名文件:${fileName}`);// Node.js基础模板const nodeContent = `/** * 文件名称:${fileName} * 创建时间:${newDate().toLocaleString()} * 开发说明:OpenClaw Skill 自动生成的Node.js基础文件 */// 模块化导出module.exports = {  // 示例方法  testFn() {    console.log("Hello Node.js!");  }};// 测试执行// require('./${fileName}').testFn();`;            fs.writeFileSync(filePath, nodeContent, "utf8");return {successtrue,message`Node.js基础文件创建成功!\n路径:${filePath}\n包含:模块化导出、基础注释、示例方法`,            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:创建node文件 targetDir=./Desktop/MyNodeProject fileName=main.js

Skill10:生成.gitignore基础文件

const fs = require("fs");const path = require("path");module.exports = {id"dev_create_gitignore",name"生成.gitignore基础文件",triggers: ["创建gitignore文件""生成忽略文件""git忽略配置"],description"在指定目录生成Git忽略配置文件(.gitignore),包含Node.js/前端/通用忽略规则",parameters: [        {name"targetDir",type"string",requiredtrue,description"目标目录路径",example"./Desktop/我的项目",        },    ],category"开发辅助",asyncexecute(params) {try {const { targetDir } = params;if (!fs.existsSync(targetDir)) thrownewError(`目标目录不存在:${targetDir}`);const filePath = path.join(targetDir, ".gitignore");if (fs.existsSync(filePath)) thrownewError(`目标目录已存在.gitignore文件,避免覆盖`);// 通用.gitignore规则(Node.js+前端+编辑器)const gitignoreContent = `# 依赖包node_modules/npm-debug.log*yarn-debug.log*yarn-error.log*pnpm-debug.log*package-lock.jsonyarn.lockpnpm-lock.yaml# 编译产物dist/build/out/coverage/# 编辑器/IDE.idea/.vscode/*.swp*.swo.DS_StoreThumbs.db# 环境变量.env.env.local.env.development.local.env.test.local.env.production.local# 日志logs/*.log# 临时文件tmp/temp/*.tmp`;            fs.writeFileSync(filePath, gitignoreContent, "utf8");return {successtrue,message`.gitignore文件创建成功!\n路径:${filePath}\n包含:Node.js依赖、编译产物、编辑器、环境变量等通用忽略规则`,            };        } catch (error) {return { successfalsemessage`技能执行失败:${error.message}` };        }    },};

调用指令:创建gitignore文件 targetDir=./Desktop/MyFrontProject

三、OpenClaw Skill 开发&使用调试避坑指南(新手版)

解决90%新手遇到的开发报错、技能不触发、执行失败、参数解析错误等问题,按“问题现象-原因分析-解决方案”整理,快速定位解决。

一、开发阶段避坑(编写Skill时的常见问题)

问题1:编写的Skill代码报错,提示“require is not defined”

  • • 原因:OpenClaw基于Node.js运行,部分环境误写浏览器端代码,Node.js中require是内置方法,浏览器端无此方法;
  • • 解决方案:仅使用Node.js内置模块(fs/path/os等),不使用浏览器端API(如window/document)。

问题2:路径报错“ENOENT: no such file or directory”

  • • 原因:① 文件/目录路径写错;② 相对路径基于OpenClaw根目录,而非Skill文件目录;③ 跨系统路径分隔符错误(Windows\ / Mac/Linux/);
  • • 解决方案:
    1. 1. 优先使用绝对路径或通过path.join()拼接路径;
    2. 2. 所有路径均使用path.join(),避免手动写/\
    3. 3. 增加前置检查,判断文件/目录是否存在,不存在则提示或自动创建。

问题3:执行文件操作时提示“EPERM: operation not permitted”

  • • 原因:① OpenClaw运行权限不足(如修改系统目录、只读文件);② 文件被其他程序占用(如记事本打开的txt文件);
  • • 解决方案:
    1. 1. 以管理员身份启动OpenClaw(Windows右键终端→以管理员身份运行;Mac/Linux加sudo);
    2. 2. 执行操作前关闭占用文件的程序;
    3. 3. 避免操作系统级目录(如C:\Windows、/usr),优先操作个人目录(桌面、文档)。

问题4:参数解析错误,提示“xxx is not defined”

  • • 原因:① parameters字段中定义的参数名和execute中解构的参数名不一致;② 用户输入的参数格式错误;③ 必选参数未传;
  • • 解决方案:
    1. 1. 保证parameters中的nameexecute中解构的参数名完全一致(大小写敏感);
    2. 2. 为可选参数设置default默认值,避免未传参时报错;
    3. 3. 调用时按“参数名=参数值”格式输入,数组参数用英文逗号分隔。

二、使用阶段避坑(Skill加载/触发/执行的常见问题)

问题1:新建Skill后,输入触发词无反应,不执行

  • • 原因:① Skill文件未放在src/skills目录下;② 未重启OpenClaw(OpenClaw仅启动时加载Skill);③ 触发词拼写错误或未包含在triggers数组中;④ Skill文件后缀不是.js;
  • • 解决方案【必做三步】:
    1. 1. 确认Skill文件在src/skills目录下,后缀为.js
    2. 2. 重启OpenClaw(先Ctrl+C终止,再执行pnpm start/yarn start);
    3. 3. 检查输入的指令包含任意一个triggers中的触发词,无拼写错误。

问题2:Skill触发后,执行结果提示“success: false”,无具体错误原因

  • • 原因:编写Skill时,catch块中未返回具体的error.message,仅提示“执行失败”;
  • • 解决方案:严格按标准模板编写,catch块返回${error.message},并加上错误码${error.code || '无'},方便定位。

问题3:跨系统运行Skill时报错(如Windows写的Skill在Mac上执行失败)

  • • 原因:① 手动写了路径分隔符(\或/);② 桌面路径、用户目录路径写死;
  • • 解决方案:
    1. 1. 所有路径使用path.join()拼接,不手动写分隔符;
    2. 2. 使用os.platform()判断系统,动态获取桌面/用户目录(标准模板中已封装通用方法,直接复用);
    3. 3. 避免写死绝对路径(如C:\Users\XXX\Desktop),优先使用相对路径或动态路径。

问题4:批量操作时,部分文件执行成功,部分失败

  • • 原因:① 部分文件被占用;② 部分文件名称包含特殊字符;③ 无循环异常处理,一个文件失败导致整个批量操作终止;
  • • 解决方案:
    1. 1. 批量操作时,为每个文件的执行逻辑单独加try/catch,避免一个失败全终止;
    2. 2. 过滤掉名称包含特殊字符的文件,或对特殊字符做转义处理;
    3. 3. 执行前检查所有文件是否被占用。

三、通用调试技巧(新手必学,快速定位问题)

技巧1:打印日志调试

在execute函数中加入console.log(),打印参数、路径、执行步骤,重启OpenClaw后,在终端查看日志,定位问题所在:

asyncexecute(params) {try {console.log("用户传入的参数:", params); // 打印参数const { fileDir } = params;console.log("目标目录路径:", fileDir); // 打印路径// 后续逻辑...  } catch (error) {console.error("技能执行错误:", error); // 打印完整错误信息return { successfalsemessage`技能执行失败:${error.message}` };  }}

技巧2:简化逻辑调试

新建Skill后,先写极简的核心逻辑(如仅打印一句话、创建一个简单文件),测试能正常触发执行后,再逐步增加复杂逻辑,避免一次性写太多代码导致报错难以定位。

技巧3:按“最小可用”原则测试

测试Skill时,先使用简单的测试用例(如桌面的单个txt文件、空目录),测试通过后,再用复杂用例(如大量文件、嵌套目录),避免复杂场景下的多重错误叠加。

技巧4:查看OpenClaw官方日志

OpenClaw启动后,终端会打印详细日志,包括:Skill加载日志、触发日志、参数解析日志、执行日志。若Skill未触发/执行失败,先查看终端日志,红色字体为错误信息,直接定位问题。

四、新手开发Skill的5个核心原则(避免90%的坑)

  1. 1. 遵循固定模板:所有Skill均基于标准模板开发,不修改外层导出结构,OpenClaw仅识别标准格式的Skill;
  2. 2. 仅用内置模块:新手阶段不使用第三方包(如axios、pdf-parse),避免依赖安装失败导致Skill无法执行,仅用Node.js内置模块(fs/path/os等);
  3. 3. 增加前置检查:执行任何操作前,先检查文件/目录是否存在、参数是否合法、权限是否足够,避免报错;
  4. 4. 跨系统兼容:不写死路径、不手动写路径分隔符,复用标准模板中的跨系统路径方法,适配Windows/Mac/Linux;
  5. 5. 错误信息具体:报错时不返回模糊的“执行失败”,返回具体的错误原因(如文件不存在、路径错误),方便调试。

最后:Skill开发进阶方向

新手掌握以上10个基础Skill和调试方法后,可逐步开发复杂功能:

  1. 1. 调用第三方API(如天气、快递查询):安装axios包,在Skill中引入即可;
  2. 2. 处理PDF/Excel文件:安装pdf-parse、xlsx包,实现文件内容提取/编辑;
  3. 3. 联动本地软件:通过Node.js的child_process模块,调用系统命令打开软件、执行脚本;
  4. 4. 对接OpenClaw大模型:在Skill中调用本地Ollama模型,实现智能文本处理(如总结、翻译)。

所有进阶开发均基于标准模板,仅需在核心逻辑中增加对应代码,保持结构不变即可。