OpenClaw Skill 实战:用 SKILL.md 把 wttr.in 天气查询封装成可复用技能
1. 从零跑通 OpenClaw Skill天气查询为什么是最好的第一个练手项目如果你刚接触 OpenClaw看到 skills 目录里一堆现成的技能心里大概会冒出一个念头我能不能自己写一个答案是可以而且门槛比你想的低。OpenClaw 的 Skill 机制本质上就是「一份 Markdown 说明书 一段可执行的命令」模型读到这份说明书后就知道在什么场景下该调用什么命令、参数怎么填、结果怎么解读。它不是什么需要编译打包的插件也不需要你写复杂的注册代码一个文件夹加一个 SKILL.md 就能跑起来。天气查询之所以适合当第一个自定义 Skill原因有三个。第一它不需要 API Keywttr.in 这个服务直接 curl 就能拿到结果省去了申请密钥、配置环境变量的麻烦让你能把注意力集中在 Skill 本身的结构上。第二它的输入输出足够简单输入是城市名输出是一行天气文本调试的时候一眼就能看出对错。第三它足够实用跑通之后你真的可以每天用它查天气而不是做完就扔的玩具。这篇文章会带你走完完整链路先理解 SKILL.md 的字段结构再写出一份可以直接复制的配置然后配置 wttr.in 的请求参数最后在本地触发验证。整个过程你只需要一个能跑 Node 的环境和 curl不需要额外的账号。我试过把这套流程走了一遍从建目录到看到天气输出大概十分钟。下面按步骤拆开讲。2. OpenClaw Skill 机制与 SKILL.md 字段结构详解在动手写之前得先搞清楚 OpenClaw 是怎么发现和加载 Skill 的。OpenClaw 启动时会扫描 skills 目录每个子目录代表一个技能目录里的 SKILL.md 就是这个技能的「身份证 使用手册」。模型在规划任务时会读取所有 SKILL.md 的元信息判断当前用户请求是否匹配某个技能。匹配上了它就会按照 SKILL.md 里写的命令去执行再把执行结果组织成自然语言回复给你。SKILL.md 的结构分两部分头部是 YAML front matter用---包起来描述技能的元信息下面是 Markdown 正文写给模型看的操作说明。头部字段里name是技能标识description是一句话说明这个技能干什么模型主要靠它来判断要不要用这个技能。homepage指向文档地址方便你后续查参数。metadata里可以放一些扩展信息比如 emoji 图标、依赖的可执行文件。这里有个容易踩的坑description写得太模糊模型就不知道什么时候该调用它。比如你写「查询信息」模型根本判断不出是查天气还是查快递。所以要写清楚「Get current weather and forecasts」把能力边界说明白。另一个坑是requires.bins如果你声明了依赖 curl但系统里没装 curl技能就会加载失败。所以写之前先确认which curl有输出。正文部分才是真正给模型看的「操作手册」。它需要包含这个技能能做什么、用哪个命令、参数怎么传、输出长什么样、有什么注意事项。模型读完这些就能自己拼出正确的命令。你可以把它理解成写给一个聪明但没背景知识的实习生的文档越具体越好。下面这张表帮你快速对照各字段的作用。字段作用是否必填name技能唯一标识目录名通常与之一致是description一句话能力说明模型据此判断是否调用是homepage文档或服务地址否metadata.openclaw.emoji技能图标否metadata.openclaw.requires.bins依赖的命令行工具否理解了这些你就知道 SKILL.md 不是随便写写的说明文档而是模型决策的依据。写得好模型调用得准写得含糊模型要么不调用要么调用错。接下来我们就按这个结构把天气技能写出来。3. 可复制配置weather/SKILL.md 完整写法与 wttr.in 参数先建目录。OpenClaw 的 skills 路径取决于你的安装方式用 nvm 装的 Node全局包一般在~/.nvm/versions/node/版本/lib/node_modules/openclaw/skills/下面。你可以先找到这个路径npm root -g输出类似/Users/you/.nvm/versions/node/v22.22.0/lib/node_modules那么 skills 目录就是它下面的openclaw/skills。进去建一个 weather 文件夹cd $(npm root -g)/openclaw/skills mkdir weather cd weather然后创建 SKILL.md把下面这份配置完整复制进去。注意 front matter 的缩进和冒号后的空格YAML 对格式敏感少一个空格都可能解析失败。--- name: weather description: Get current weather and forecasts for a city (no API key required). homepage: https://wttr.in/:help metadata: openclaw: emoji: requires: bins: - curl --- # Weather Two free services, no API keys needed. wttr.in is the primary one. ## Quick one-liner bash curl -s wttr.in/London?format3 # Output: London: ⛅ 8°CCompact formatcurl -s wttr.in/London?format%l:%c%t%h%w # Output: London: ⛅ 8°C 71% ↙5km/hFull forecastcurl -s wttr.in/London?TFormat codes%c condition · %t temp · %h humidity · %w wind · %l location · %m moonTipsURL-encode spaces: wttr.in/NewYorkAirport codes: wttr.in/JFKUnits: ?m (metric) ?u (USCS)Today only: ?1 · Current only: ?0PNG: curl -s wttr.in/Berlin.png -o /tmp/weather.pngOpen-Meteo (fallback, JSON)Free, no key, good for programmatic use:curl -s https://api.open-meteo.com/v1/forecast?latitude51.5longitude-0.12current_weathertrueFind coordinates for a city, then query. Returns JSON with temp, windspeed, weathercode. Docs: https://open-meteo.com/en/docs这份配置里format3 是最简输出适合快速看一眼format%l:%c%t%h%w 是自定义格式把位置、天气状况、温度、湿度、风速拼在一起信息密度高。?T 会输出带颜色的完整预报适合终端里看。?0 只看当前?1 只看今天。这些参数你可以在 SKILL.md 里都写上模型会根据用户问法自己选。 如果你想让模型在 wttr.in 不可用时自动降级到 Open-Meteo就把 fallback 那段也写进去。Open-Meteo 返回的是 JSON字段是 temperature、windspeed、weathercode模型能直接解析。注意 Open-Meteo 需要经纬度所以你得先知道城市坐标或者让模型先查坐标再查天气。这一步稍微复杂点但作为 fallback 足够用。 写完保存目录结构应该是 skills/weather/SKILL.md。你可以用 cat 确认一下内容没写乱 bash cat SKILL.md | head -20看到 front matter 正常显示就说明文件没问题。接下来就是触发验证。4. 本地触发验证从 curl 到 OpenClaw 调用链路验证分两步走。先单独测 curl 命令能不能通再让 OpenClaw 去调用。这样出问题的时候你能快速定位是网络问题还是 Skill 配置问题。第一步直接跑命令curl -s wttr.in/Beijing?format3正常输出类似Beijing: ☀ 12°C。如果卡住不动可能是网络到 wttr.in 不通加个超时curl -s --max-time 10 wttr.in/Beijing?format3。如果返回乱码检查终端编码或者加?T看彩色输出是否正常。这一步通了说明命令本身没问题。第二步启动 OpenClaw问它天气。具体启动方式取决于你的安装通常是openclaw或npx openclaw。启动后输入类似「北京今天天气怎么样」或者「查一下 London 的天气」。模型应该会识别到 weather 技能拼出 curl 命令并执行然后把结果返回给你。这里有个关键点模型怎么知道该用哪个技能它读的是所有 SKILL.md 的description。你的 description 写的是「Get current weather and forecasts for a city」用户问天气时语义匹配模型就会选中它。如果没选中先检查 description 是不是太泛或者有拼写错误。调用链路是这样的用户输入 → 模型读技能列表 → 匹配 weather → 读 SKILL.md 正文 → 拼命令 → 执行 curl → 拿到输出 → 组织成回复。你可以在 OpenClaw 的日志里看到这个过程如果它没调用技能日志里会有「no matching skill」之类的提示。验证成功后你可以试试更复杂的问法比如「北京和上海哪个更热」模型可能会调用两次 curl 然后对比。或者「伦敦未来三天天气」它会用?T或者?1参数。这些都能跑通说明你的 Skill 已经真正可用了。5. 常见报错排查401、local proxy failed、reading choices 与 OAuth跑 Skill 的过程中报错基本集中在几类。下面按真实遇到的错误对照排查。401 Unauthorized这个通常不是 wttr.in 报的wttr.in 不需要认证。如果你在 OpenClaw 里配了某个需要 Key 的模型服务401 说明 Key 无效或过期。检查你的模型配置确认 Base URL、Key、Model ID 三件套填对了。如果你用的是 TaoToken 这类服务去 console 里重新生成一个 Key然后更新配置。注意 Key 不要有多余空格。local proxy failed这个报错说明 OpenClaw 尝试走本地代理但失败了。常见原因是环境变量里配了HTTP_PROXY或HTTPS_PROXY但代理服务没启动。检查env | grep -i proxy如果有输出但代理不可用先 unset 掉再试。另一个可能是端口被占用换个端口或者关掉冲突进程。reading choices 报错这个一般出现在模型返回格式不符合预期的时候。比如你用的模型服务返回的 JSON 里没有choices字段OpenClaw 解析就失败了。检查你的模型服务是否兼容 OpenAI 格式Base URL 是不是指向了正确的 endpoint。如果是自建服务确认返回结构里有choices[0].message.content。OAuth 相关报错如果你用的是需要 OAuth 的模型服务报错可能是 token 过期或 scope 不对。重新走一遍授权流程确认回调地址和配置里的一致。有些服务需要你在 console 里手动开启对应权限。排查顺序建议先确认 curl 命令本身能通再确认模型服务配置正确最后看 OpenClaw 日志里的具体错误行。大部分问题出在配置层而不是 Skill 本身。Skill 写错了顶多是模型不调用或者调用参数不对不会导致 401 这种认证错误。另外提醒一句SKILL.md 里的requires.bins如果写了 curl 但系统没有技能加载会直接失败日志里会有「missing binary」提示。用which curl确认一下没有就装一个。6. 把天气 Skill 用起来从验证到日常调用的实用建议跑通之后你可以把这个 Skill 真正用起来。最直接的用法是每天早上问一句「今天天气」模型调用 wttr.in 返回当前状况。如果你想要更结构化的输出可以在 SKILL.md 里加一段说明让模型把结果整理成「温度、湿度、风速、建议」的格式。比如加一句「Present the result as a short bullet list with temperature, humidity, wind, and a one-line suggestion.」模型就会按这个格式回复。如果你经常查固定城市可以在 SKILL.md 里写一个默认城市比如「If no city is specified, default to Beijing.」这样你只说「查天气」它就知道查哪。但要注意默认值写死了灵活性会降低看你的使用习惯。对于需要程序化处理的场景Open-Meteo 的 JSON 输出更合适。你可以在 SKILL.md 里写清楚字段含义让模型解析后返回结构化数据。比如问「北京现在温度多少」模型可以只提取temperature字段返回一个数字方便你后续做判断。最后说一个实用技巧把常用的几个城市做成快捷方式。在 SKILL.md 里加一段「Common cities: Beijing, Shanghai, London, New York」模型看到用户说「查上海」时能更快匹配。这不是必须的但能减少模型拼错城市名的概率。整个流程走下来你会发现 OpenClaw 的 Skill 机制核心就是「用 Markdown 描述能力用命令实现能力」。天气查询是最小可跑案例你可以照着这个结构封装更多技能比如查汇率、查快递、查服务器状态。只要有一个能返回结果的命令就能包装成一个 Skill。