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/array
            required: true, // 是否必填:true/false
            default: "", // 可选参数默认值,required为false时必设
            description: "参数说明,比如:文件所在目录的相对/绝对路径",
            example: "./Desktop/测试目录", // 示例值,帮助大模型精准提取
        },
    ],
    // 【可选】执行超时时间:避免技能卡死,单位毫秒,默认30000(30秒)
    timeout: 30000,
    // 【可选】技能分类:方便管理,比如文件操作/开发工具/办公自动化
    category: "文件操作",
    // 【必选】核心执行逻辑:async支持异步操作,params为解析后的用户参数
    async execute(params) {
        try {
            // 通用前置:解构参数(和parameters字段一一对应)
            const { paramName1, paramName2 } = params;

            // 【通用封装】获取跨系统桌面路径(Windows/Mac/Linux兼容)
            const getDesktopPath = () => {
                return os.platform() === "win32"
                    ? path.join(process.env.USERPROFILE, "Desktop")
                    : path.join(process.env.HOME, "Desktop");
            };

            // 【通用封装】检查目录是否存在,不存在则递归创建
            const checkAndCreateDir = dirPath => {
                if (!fs.existsSync(dirPath)) {
                    fs.mkdirSync(dirPath, { recursive: true });
                }
            };

            // -------------------------- 核心业务逻辑 --------------------------
            // 此处替换为自己的技能功能代码,示例:空逻辑
            const resultMsg = "技能执行成功";
            // -------------------------------------------------------------------

            // 【必选】成功返回格式:success为true,message为提示语,data可选返回额外数据
            return {
                success: true,
                message: resultMsg,
                data: {
                    /* 可选:返回执行结果的详细数据,如文件数量、路径等 */
                },
            };
        } catch (error) {
            // 【必选】失败返回格式:success为false,message为具体错误原因(方便调试)
            return {
                success: false,
                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",
            required: true,
            description: "原文件完整路径",
            example: "./Desktop/旧文件.txt",
        },
        {
            name: "newName",
            type: "string",
            required: true,
            description: "新文件名(含后缀)",
            example: "新文件_2026.txt",
        },
    ],
    category: "文件操作",
    async execute(params) {
        try {
            const { oldPath, newName } = params;
            if (!fs.existsSync(oldPath)) throw new Error(`原文件不存在:${oldPath}`);
            const newPath = path.join(path.dirname(oldPath), newName);
            if (fs.existsSync(newPath)) throw new Error(`新路径已存在同名文件:${newPath}`);
            fs.renameSync(oldPath, newPath);
            return {
                success: true,
                message: `文件重命名成功!\n原路径:${oldPath}\n新路径:${newPath}`,
            };
        } catch (error) {
            return {
                success: false,
                message: `技能执行失败:${error.message},错误码:${error.code || "无"}`,
            };
        }
    },
};

调用指令:重命名单个文件 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",
            required: true,
            description: "新建文件名(必须含.txt后缀)",
            example: "OpenClaw笔记.txt",
        },
        {
            name: "content",
            type: "string",
            required: false,
            default: "OpenClaw Skill 自动生成的文本文件",
            description: "文件自定义内容",
        },
    ],
    category: "文件操作",
    async execute(params) {
        try {
            const { fileName, content } = params;
            if (!fileName.endsWith(".txt")) throw new Error("文件名必须以.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)) throw new Error(`桌面已存在同名文件:${fileName}`);
            fs.writeFileSync(filePath, content, "utf8");
            return {
                success: true,
                message: `文本文件创建成功!\n路径:${filePath}\n内容:${content}`,
            };
        } catch (error) {
            return {
                success: false,
                message: `技能执行失败:${error.message},错误码:${error.code || "无"}`,
            };
        }
    },
};

调用指令:新建文本文件 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: "文件操作",
    async execute() {
        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 {
                success: true,
                message: `空文件清理完成!桌面共扫描到${files.length}个空文本文件,已全部删除`,
            };
        } catch (error) {
            return {
                success: false,
                message: `技能执行失败:${error.message},错误码:${error.code || "无"}`,
            };
        }
    },
};

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

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

const fs = require("fs");
const path = require("path");
module.exports = {
    id: "file_rename_batch",
    name: "批量重命名指定目录文件",
    triggers: ["批量重命名文件", "统一修改文件名", "文件批量改名"],
    description: "按前缀+序号重命名指定目录下的所有文件,保留原后缀,支持自定义前缀",
    parameters: [
        {
            name: "fileDir",
            type: "string",
            required: true,
            default: "", // 明确设置默认值
            description: "文件所在目录路径",
            example: "./Desktop/图片",
        },
        {
            name: "prefix",
            type: "string",
            required: false,
            default: "file_",
            description: "文件名自定义前缀",
        },
    ],
    category: "文件操作",
    async execute(params) {
        try {
            const { fileDir, prefix } = params;
            if (!fs.existsSync(fileDir)) throw new Error(`目标目录不存在:${fileDir}`);
            const files = fs
                .readdirSync(fileDir)
                .filter(file => fs.statSync(path.join(fileDir, file)).isFile());
            if (files.length === 0) throw new Error(`目标目录下无文件可重命名`);
            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 {
                success: true,
                message: `批量重命名成功!\n目标目录:${fileDir}\n处理文件数量:${files.length}\n文件前缀:${prefix}`,
            };
        } catch (error) {
            return {
                success: false,
                message: `技能执行失败:${error.message},错误码:${error.code || "无"}`,
            };
        }
    },
};

调用指令:批量重命名文件 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",
            required: true,
            description: "源文件完整路径",
            example: "./Desktop/源文件.pdf",
        },
        {
            name: "targetDir",
            type: "string",
            required: true,
            description: "目标目录路径",
            example: "./Desktop/备份文件夹",
        },
    ],
    category: "文件操作",
    async execute(params) {
        try {
            const { sourcePath, targetDir } = params;
            if (!fs.existsSync(sourcePath)) throw new Error(`源文件不存在:${sourcePath}`);
            if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true });
            const fileName = path.basename(sourcePath);
            const targetPath = path.join(targetDir, fileName);
            if (fs.existsSync(targetPath)) throw new Error(`目标目录已存在同名文件:${fileName}`);
            fs.copyFileSync(sourcePath, targetPath);
            return {
                success: true,
                message: `文件复制成功!\n源文件:${sourcePath}\n目标路径:${targetPath}`,
            };
        } catch (error) {
            return {
                success: false,
                message: `技能执行失败:${error.message},错误码:${error.code || "无"}`,
            };
        }
    },
};

调用指令:复制文件 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",
            required: true,
            description: "文本文件完整路径",
            example: "./Desktop/笔记.txt",
        },
    ],
    category: "文件操作",
    async execute(params) {
        try {
            const { filePath } = params;
            if (!fs.existsSync(filePath)) throw new Error(`文件不存在:${filePath}`);
            if (!filePath.endsWith(".txt")) throw new Error("仅支持读取.txt格式的文本文件");
            const content = fs.readFileSync(filePath, "utf8");
            return {
                success: true,
                message: `文件读取成功!\n文件路径:${filePath}\n文件内容:\n${content}`,
                data: { content, filePath },
            };
        } catch (error) {
            return {
                success: false,
                message: `技能执行失败:${error.message},错误码:${error.code || "无"}`,
            };
        }
    },
};

调用指令:读取文件内容 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: "办公自动化",
    async execute() {
        try {
            // 获取今日日期
            const today = new Date();
            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))
                throw new Error(`桌面已存在今日日报文件:${path.basename(filePath)}`);
            fs.writeFileSync(filePath, reportContent, "utf8");
            return {
                success: true,
                message: `今日工作日报模板生成成功!\n路径:${filePath}\n模板包含:工作完成、待办、问题三大核心模块`,
            };
        } catch (error) {
            return {
                success: false,
                message: `技能执行失败:${error.message},错误码:${error.code || "无"}`,
            };
        }
    },
};

调用指令:生成工作日报

Skill8:批量创建文件夹

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

调用指令:批量创建文件夹 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",
            required: true,
            description: "目标目录路径",
            example: "./Desktop/Node项目",
        },
        {
            name: "fileName",
            type: "string",
            required: true,
            description: "新建js文件名(含.js后缀)",
            example: "index.js",
        },
    ],
    category: "开发辅助",
    async execute(params) {
        try {
            const { targetDir, fileName } = params;
            if (!fileName.endsWith(".js")) throw new Error("文件名必须以.js为后缀");
            if (!fs.existsSync(targetDir)) fs.mkdirSync(targetDir, { recursive: true });
            const filePath = path.join(targetDir, fileName);
            if (fs.existsSync(filePath)) throw new Error(`目标目录已存在同名文件:${fileName}`);
            // Node.js基础模板
            const nodeContent = `/**
 * 文件名称:${fileName}
 * 创建时间:${new Date().toLocaleString()}
 * 开发说明:OpenClaw Skill 自动生成的Node.js基础文件
 */

// 模块化导出
module.exports = {
  // 示例方法
  testFn() {
    console.log("Hello Node.js!");
  }
};

// 测试执行
// require('./${fileName}').testFn();
`;
            fs.writeFileSync(filePath, nodeContent, "utf8");
            return {
                success: true,
                message: `Node.js基础文件创建成功!\n路径:${filePath}\n包含:模块化导出、基础注释、示例方法`,
            };
        } catch (error) {
            return {
                success: false,
                message: `技能执行失败:${error.message},错误码:${error.code || "无"}`,
            };
        }
    },
};

调用指令:创建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",
            required: true,
            description: "目标目录路径",
            example: "./Desktop/我的项目",
        },
    ],
    category: "开发辅助",
    async execute(params) {
        try {
            const { targetDir } = params;
            if (!fs.existsSync(targetDir)) throw new Error(`目标目录不存在:${targetDir}`);
            const filePath = path.join(targetDir, ".gitignore");
            if (fs.existsSync(filePath)) throw new Error(`目标目录已存在.gitignore文件,避免覆盖`);
            // 通用.gitignore规则(Node.js+前端+编辑器)
            const gitignoreContent = `# 依赖包
node_modules/
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
package-lock.json
yarn.lock
pnpm-lock.yaml

# 编译产物
dist/
build/
out/
coverage/

# 编辑器/IDE
.idea/
.vscode/
*.swp
*.swo
.DS_Store
Thumbs.db

# 环境变量
.env
.env.local
.env.development.local
.env.test.local
.env.production.local

# 日志
logs/
*.log

# 临时文件
tmp/
temp/
*.tmp
`;
            fs.writeFileSync(filePath, gitignoreContent, "utf8");
            return {
                success: true,
                message: `.gitignore文件创建成功!\n路径:${filePath}\n包含:Node.js依赖、编译产物、编辑器、环境变量等通用忽略规则`,
            };
        } catch (error) {
            return {
                success: false,
                message: `技能执行失败:${error.message},错误码:${error.code || "无"}`,
            };
        }
    },
};

调用指令:创建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. 优先使用 绝对路径 或通过path.join()拼接路径;
    2. 所有路径均使用path.join(),避免手动写/\
    3. 增加 前置检查,判断文件/目录是否存在,不存在则提示或自动创建。

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

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

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

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

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

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

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

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

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

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

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

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

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

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

技巧1:打印日志调试

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

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

技巧2:简化逻辑调试

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

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

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

技巧4:查看OpenClaw官方日志

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

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

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

最后:Skill开发进阶方向

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

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

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


文章作者: 弈心
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 弈心 !
评论
  目录