1. 为什么自定义 skill 传参总踩坑
OpenClaw 的自定义 skill 一旦涉及外部服务,就绕不开一个现实问题:token、IP、端口、API 地址这些参数往哪放。直接写死在脚本里,改一次要动代码;写进 SKILL.md 的正文里,模型读的时候会当成指令内容,既浪费 token 又容易泄露。我试过把参数塞进 description,结果模型在触发时把 token 当成了对话上下文的一部分,行为变得很不稳定。
真正干净的方案是把参数抽到环境变量里,让 SKILL.md 只声明「我需要哪些变量」,脚本运行时从os.environ读取。这样 skill 的触发逻辑和敏感配置彻底解耦,换设备、换账号只需要改环境变量,不用碰 skill 本体。
这篇聚焦 OpenClaw 自定义 skill 通过环境变量传参的完整落地:skill 目录骨架怎么摆、SKILL.md 的 metadata 怎么声明 requires.env、primaryEnv 起什么作用、脚本怎么读变量、以及 blocked/eligible 状态怎么验证。适合已经在本地跑通 OpenClaw、想给自己的 skill 加一层配置隔离的开发者。下面所有配置都可以直接复制,改掉变量名就能用。
2. TaoToken 前置:把模型侧配置先理顺
在折腾 skill 传参之前,建议先把 OpenClaw 背后的模型接入配置固定下来,否则 skill 调试到一半发现模型请求失败,排查方向会被带偏。TaoToken 提供 OpenAI 兼容的接口,OpenClaw 里配置 base_url 指向https://taotoken.net/api,再填上在控制台生成的 API Key 即可。
具体动作:打开 TaoToken 控制台 创建密钥,然后在 API Keys 管理页 复制出来。如果你只是想先确认模型能不能正常对话,可以直接用 模型对话 页面发一条消息验证链路。长期跑编码类 skill 或 Agent 任务的话,Coding Plan 的额度模型更适合高频调用。
这一步的意义在于:skill 的环境变量传参是「业务参数」,模型接入是「基础设施参数」,两者分开管理。基础设施参数走 OpenClaw 的模型配置,业务参数走 skill 的 metadata 声明,互不干扰。接入细节可以参考 接入文档,配置项和 OpenAI SDK 基本一致。
3. skill 目录骨架与加载优先级
OpenClaw 的 skill 有三个存放位置,优先级从高到低是:workspace 下的skill目录、主目录下的~/.openclaw/skills、以及 npm 安装的捆绑 skill。同名 skill 冲突时按这个顺序覆盖。workspace 下的 skill 只对当前 agent 生效,属于私有;~/.openclaw/skills是共享的,所有 agent 都能用。另外还能通过~/.openclaw/openclaw.json里的skills.load.extraDirs关联外部目录,这个优先级最低。
一个标准的 skill 目录长这样:
my-skill/ ├── SKILL.md # 必需:指令 + metadata ├── scripts/ # 可选:可执行代码 ├── references/ # 可选:文档,按需读取 └── assets/ # 可选:模板、资源SKILL.md 是唯一必需的文件。如果内容太长,正确做法是拆到references/目录,在 SKILL.md 里引用路径,模型按需读取,这样能显著降低 token 消耗。下面用一个智能插座控制 skill 做例子,完整走一遍环境变量传参。
4. SKILL.md 与 metadata 配置骨架
SKILL.md 用 YAML front matter 加 Markdown 正文组成。front matter 以---开始和结束,字段里name和description必填,metadata用来声明环境变量依赖。关键字段含义如下:
| 字段 | 必需 | 说明 |
|---|---|---|
| name | 是 | skill 名称,64 字符内,小写字母和-组合,字母开头 |
| description | 是 | 功能与触发条件,直接影响模型是否调用 |
| license | 否 | 许可证描述 |
| metadata | 否 | 元数据,声明环境变量、依赖程序等 |
metadata 里和传参最相关的是requires.env和primaryEnv。requires.env列出必须存在的环境变量,缺任何一个 skill 就会被禁用;primaryEnv把某个变量关联到 UI 上的「Save key」入口,方便在界面里填值。
可复制的 SKILL.md 骨架:
--- name: smart-plug-control description: Smart plug control skill for turning plug on/off. Triggers on phrases like "turn off plug", "turn on plug", "打开插座", "关闭插座", or similar plug control commands. metadata: { "openclaw": { "requires": { "env": ["SMART_PLUG_TOKEN", "SMART_PLUG_IP"] }, "primaryEnv": "SMART_PLUG_TOKEN" } } --- # Smart Plug Control 通过环境变量读取插座 IP 和 token,调用本地 HTTP 接口控制开关。 ## 使用方式 当用户要求打开或关闭插座时,执行 `scripts/plug.py`,参数从环境变量注入。注意name必须是小写字母加连字符,别用下划线或大写,否则加载会报错。description里把中英文触发词都写上,模型识别率会高不少。
5. 脚本读取环境变量与注入片段
SKILL.md 声明完之后,脚本侧要真正去读这些变量。Python 示例:
import os import requests def get_smart_plug_ip(): return os.environ.get("SMART_PLUG_IP") def get_smart_plug_token(): return os.environ.get("SMART_PLUG_TOKEN") PLUG_IP = get_smart_plug_ip() PLUG_TOKEN = get_smart_plug_token() def set_plug(state: str): url = f"http://{PLUG_IP}/api/switch" headers = {"Authorization": f"Bearer {PLUG_TOKEN}"} resp = requests.post(url, json={"state": state}, headers=headers, timeout=5) resp.raise_for_status() return resp.json() if __name__ == "__main__": import sys print(set_plug(sys.argv[1]))环境变量的注入方式取决于你启动 OpenClaw 的方式。Linux/macOS 下可以在 shell 里 export,或者写进~/.openclaw/openclaw.json的 env 配置段。Windows 对应C:\Users\[用户名]\.openclaw目录,逻辑一致。
export SMART_PLUG_IP="192.168.1.50" export SMART_PLUG_TOKEN="your-token-here" openclaw gateway restart改完 SKILL.md 或环境变量后,必须重启 gateway 才会重新加载 skill 状态。
6. 验证请求与状态排查
重启后切换到 skill 目录,如果环境变量没配全,skill 状态会变成blocked,这正是我们要的效果——参数缺失时直接禁用,避免运行到一半才报错。
验证步骤:
openclaw gateway restart openclaw skill list预期看到smart-plug-control的状态。变量齐全时是eligible,缺变量时是blocked。然后实际触发一次:
openclaw run "打开插座"脚本会从环境变量拿到 IP 和 token,请求本地接口,返回开关结果。如果用了primaryEnv,UI 上会出现「Save key」按钮,填进去的值会以明文写进openclaw.json,关联到SMART_PLUG_TOKEN。不需要这个入口就把 metadata 里的primaryEnv删掉。
常见错误对照:
| 现象 | 原因 | 处理 |
|---|---|---|
| skill 一直 blocked | requires.env 里的变量没配 | 检查 export 或 openclaw.json |
| name 加载报错 | 含大写或下划线 | 改成小写加连字符 |
| 脚本读不到变量 | 没重启 gateway | 重启后重新加载 |
| 触发不生效 | description 触发词太窄 | 补充中英文关键词 |
7. 继续往下走
环境变量传参跑通之后,skill 的配置就和代码彻底分开了。下一步可以把 token 换成加密存储,或者把多个 skill 共享的变量抽到统一的 env 文件里管理。模型侧如果还没配好,先去 API Keys 拿密钥,接入细节看 接入文档;想先验证模型对话是否正常,用 模型对话 发一条消息最快。长期跑编码和 Agent 任务的话,Coding Plan 的额度更划算。