OpenClaw Skill 编写规范 与示例

OpenClaw Skill 编写规范 与示例

完整的 Skill 开发指南,从基础结构到高级实践


📁 一、目录结构

标准结构

复制代码
~/.openclaw/workspace/skills/<skill-name>/
├── SKILL.md              # 必需:技能定义文件
├── scripts/              # 可选:执行脚本
│   ├── main.py
│   └── helper.sh
├── references/           # 可选:参考文档
│   └── api_examples.md
├── assets/               # 可选:静态资源
│   └── config_template.json
└── README.md             # 可选:使用说明

最小结构

复制代码
~/.openclaw/workspace/skills/<skill-name>/
└── SKILL.md              # 唯一必需文件

📝 二、SKILL.md 标准格式

完整模板

markdown 复制代码
---
name: <skill-name>
description: <一句话描述,说明触发场景和功能>
homepage: <https://...>  # 可选:项目主页
metadata:
  {
    "openclaw": {
      "emoji": "<emoji>",
      "os": ["darwin", "linux"],  # 可选:支持的系统
      "requires": {
        "bins": ["curl", "python3"],           # 必需的二进制
        "anyBins": ["node", "bun"],            # 任一存在即可
        "env": ["API_KEY"],                    # 必需的环境变量
        "config": ["feature.enabled"]          # 必需的配置项
      },
      "primaryEnv": "API_KEY",                 # 主环境变量(用于 apiKey 配置)
      "skillKey": "<custom-key>",              # 可选:自定义配置键
      "install": [                             # 可选:安装说明
        {
          "id": "brew",
          "kind": "brew",
          "formula": "package-name",
          "bins": ["binary-name"],
          "label": "Install Package (brew)"
        },
        {
          "id": "node",
          "kind": "node",
          "package": "@scope/package",
          "bins": ["binary-name"],
          "label": "Install Package (npm)"
        }
      ]
    }
  }
---

# <Skill Name> - 技能标题

简短介绍(1-2 句话)。

## 使用场景

✅ **USE when:**
- 用户询问/请求 X
- 需要执行 Y 操作
- 场景 Z

❌ **DON'T use when:**
- 情况 A(用其他技能)
- 情况 B(超出范围)

## 快速开始

```bash
# 基本用法
<command> <args>

# 进阶用法
<command> <args> --flag

详细用法

功能 1

说明 + 示例命令。

功能 2

说明 + 示例命令。

配置选项

json 复制代码
{
  "option1": "value",
  "option2": 123
}
参数 说明 默认值
option1 说明 default

错误处理

错误 处理方式
API 失败 重试 3 次,使用缓存
认证失败 提示用户配置 API Key

安全注意

⚠️ 风险提示、限制条件、合规说明等。

相关文件

  • scripts/xxx.py - 说明
  • references/yyy.md - 说明

依赖安装

bash 复制代码
# 安装依赖
pip install ...
# 或
npm install ...
复制代码
---

## 🏷️ 三、Frontmatter 字段详解

### 必需字段

| 字段 | 类型 | 说明 | 示例 |
|------|------|------|------|
| `name` | string | 技能唯一标识(小写,下划线分隔) | `stock_analyzer` |
| `description` | string | 触发场景 + 功能描述 | "股票分析。Use when user asks for stock..." |

### metadata.openclaw 字段

| 字段 | 类型 | 必需 | 说明 |
|------|------|------|------|
| `emoji` | string | 推荐 | Skills UI 显示的 emoji |
| `os` | string[] | 可选 | 支持的系统:`darwin`/`linux`/`win32` |
| `requires.bins` | string[] | 可选 | 所有必需的二进制文件 |
| `requires.anyBins` | string[] | 可选 | 任一存在即可的二进制 |
| `requires.env` | string[] | 可选 | 必需的环境变量 |
| `requires.config` | string[] | 可选 | 必需的 openclaw.json 配置路径 |
| `primaryEnv` | string | 可选 | 主环境变量(用于 apiKey 配置) |
| `skillKey` | string | 可选 | 自定义配置键(默认用 name) |
| `install` | object[] | 可选 | 安装程序定义 |

### 安装器格式

```json
{
  "id": "brew",                    // 安装器 ID
  "kind": "brew",                  // brew | node | go | uv | download
  "formula": "package-name",       // kind=brew 时必需
  "package": "@scope/pkg",         // kind=node 时必需
  "bins": ["binary-name"],         // 安装后提供的二进制
  "label": "Install (brew)",       // UI 显示文本
  "os": ["darwin"]                 // 可选:仅限某些系统
}

🎯 四、技能类型判断

判断流程图

复制代码
读 SKILL.md
   ↓
有 metadata.requires 吗?
   ├─ 有 → 需要外部工具
   │      ├─ bins: ["curl"] → 系统工具技能
   │      ├─ bins: ["oracle"] → 外部 CLI 技能
   │      └─ 调用 mcporter → MCP 工具技能
   │
   └─ 没有 → 纯文本技能
          └─ 用 exec/web_fetch 等基础工具实现

类型对比表

类型 特征 例子 调用方式
系统工具 requires.bins: ["curl"] weather exec 运行系统命令
外部 CLI requires.bins: ["oracle"] + install oracle, himalaya exec 运行 CLI
MCP 工具 调用 mcporter call mcporter MCP 协议调用
纯文本 无 metadata.requires 自定义业务逻辑 exec/web_fetch 组合

📦 五、混合技能编写

场景:静态文本 + HTTP + MCP

markdown 复制代码
---
name: hybrid_skill
description: 混合数据源技能
metadata:
  {
    "openclaw": {
      "requires": {
        "bins": ["curl", "python3", "mcporter"],
        "env": ["API_KEY"],
        "config": ["mcp.enabled"]
      }
    }
  }
---

# Hybrid Skill

## 数据源总览

| 类型 | 来源 | 调用方式 |
|------|------|---------|
| 静态文本 | 本技能文档 | 直接阅读 |
| HTTP API | 公开 API | `curl` / `python` |
| MCP 服务 | MCP 服务器 | `mcporter call` |

## 调用流程

1. **静态文本**:读取配置规则
2. **HTTP 请求**:抓取数据
   ```bash
   curl "https://api.example.com/data"
  1. MCP 服务 :获取实时数据

    bash 复制代码
    mcporter call server.tool arg:value

降级方案

错误 降级方式
MCP 不可用 降级到 HTTP API
HTTP 失败 使用缓存数据
复制代码
---

## 🔐 六、安全规范

### 环境变量

```json
// ~/.openclaw/openclaw.json
{
  "skills": {
    "entries": {
      "my-skill": {
        "enabled": true,
        "apiKey": {
          "source": "env",
          "provider": "default",
          "id": "MY_API_KEY"
        },
        "env": {
          "MY_API_KEY": "sk-xxx"  // 或用 SecretRef
        }
      }
    }
  }
}

安全清单

  • ✅ 不在 SKILL.md 中硬编码密钥
  • ✅ 敏感操作前要求用户确认
  • ✅ 外部输入需要验证/转义
  • ✅ 使用 trash 而非 rm(可恢复)
  • ✅ 沙箱环境运行不受信代码

🧪 七、测试流程

1. 创建技能

bash 复制代码
mkdir -p ~/.openclaw/workspace/skills/my-skill
# 创建 SKILL.md

2. 刷新技能

bash 复制代码
# 方式 1:重启 Gateway
openclaw gateway restart

# 方式 2:等待自动刷新(watcher 默认启用)

3. 测试技能

bash 复制代码
# 测试触发
openclaw agent --message "使用 my-skill 做 XXX"

# 或直接在聊天中测试

4. 调试

bash 复制代码
# 查看技能加载状态
openclaw skills list

# 查看技能详情
openclaw skills show my-skill

📋 八、最佳实践

命名规范

  • snake_casestock_analyzer
  • ✅ 小写字母 + 下划线
  • ❌ 不要大写字母
  • ❌ 不要用空格或特殊字符

描述写法

markdown 复制代码
# ✅ 好:包含触发场景
description: "股票分析。Use when user asks for stock recommendations, financial news..."

# ❌ 差:太模糊
description: "分析股票"

指令清晰

markdown 复制代码
# ✅ 好:具体明确
"使用 curl 调用 wttr.in API,格式:curl 'wttr.in/{city}?format=3'"

# ❌ 差:模糊
"获取天气数据"

错误处理

markdown 复制代码
## 错误处理

| 错误 | 处理方式 |
|------|---------|
| HTTP 429 | 等待 60 秒后重试 |
| HTTP 401 | 提示用户检查 API Key |
| 超时 | 使用缓存数据(如果有) |

文档结构

  1. 使用场景(USE/DON'T USE)
  2. 快速开始(最常用命令)
  3. 详细用法(分功能)
  4. 配置选项
  5. 错误处理
  6. 安全注意
  7. 相关文件

🔧 九、配置参考

openclaw.json 完整示例

json5 复制代码
{
  "skills": {
    // 仅允许列表中的 bundled skills
    "allowBundled": ["gemini", "peekaboo"],
    
    // 加载配置
    "load": {
      "extraDirs": ["~/Projects/my-skills"],  // 额外技能目录
      "watch": true,                          // 自动刷新
      "watchDebounceMs": 250
    },
    
    // 安装配置
    "install": {
      "preferBrew": true,    // 优先 brew
      "nodeManager": "npm"   // npm | pnpm | yarn | bun
    },
    
    // 单个技能配置
    "entries": {
      "my-skill": {
        "enabled": true,
        "apiKey": "sk-xxx",  // 或 SecretRef 对象
        "env": {
          "MY_API_KEY": "xxx"
        },
        "config": {
          "custom_option": "value"
        }
      },
      "another-skill": {
        "enabled": false  // 禁用
      }
    }
  }
}

📚 十、参考资源

官方文档

示例技能

bash 复制代码
# 系统自带技能
ls /opt/homebrew/lib/node_modules/openclaw/skills/

# 用户技能
ls ~/.openclaw/skills/

# 工作区技能
ls ~/.openclaw/workspace/skills/

优先级

复制代码
工作区技能 (最高) → ~/.openclaw/skills → bundled skills (最低)

🚀 十一、快速模板

最简技能

markdown 复制代码
---
name: hello
description: 打招呼技能。Use when user says hello or asks for a greeting.
---

# Hello Skill

当用户打招呼时,回复友好的问候语。

```bash
echo "Hello! How can I help you today?"
复制代码
### 完整技能

复制上面的 [完整模板](#完整模板) 开始编写。

---

---

## 📘 十二、完整案例:天气活动规划师

这是一个**综合型技能**,根据天气情况推荐去哪里玩、适合做什么活动。

### 技能特点

- ✅ 使用 HTTP API 获取天气数据
- ✅ 静态文本定义活动规则(什么天气适合什么活动)
- ✅ 决策逻辑(天气 → 活动推荐)
- ✅ 多城市支持
- ✅ 降级方案(API 失败时的处理)

---

### 目录结构

~/.openclaw/workspace/skills/weather-activity-planner/

├── SKILL.md

├── scripts/

│ └── fetch_weather.py

├── references/

│ └── activity_rules.md

└── assets/

└── cities.json

复制代码
---

### SKILL.md 完整示例

```markdown
---
name: weather_activity_planner
description: 根据天气推荐活动。Use when user asks where to go or what to do based on weather. 输入城市,输出活动建议。
homepage: https://wttr.in/:help
metadata:
  {
    "openclaw": {
      "emoji": "🎯",
      "requires": { "bins": ["curl", "python3"] },
      "install": [
        { "id": "pip", "kind": "pip", "package": "requests", "label": "Install Python deps" }
      ]
    }
  }
---

# Weather Activity Planner - 天气活动规划师

根据实时天气情况,推荐适合的活动和去处。

## 使用场景

✅ **USE when:**
- "今天天气适合干什么?"
- "推荐个地方去玩"
- "周末去哪里玩比较好"
- "这个天气适合户外活动吗"

❌ **DON'T use when:**
- 需要精确到小时的预报(用专业天气 App)
- 极端天气警报(查看官方预警)

## 数据源

| 类型 | 来源 | 调用方式 |
|------|------|---------|
| **天气数据** | wttr.in API | `curl wttr.in/{city}?format=j1` |
| **活动规则** | 本技能文档(静态文本) | 直接阅读 |
| **城市列表** | `assets/cities.json` | 读取文件 |

## 天气 → 活动映射规则

### 🌞 晴天 (Sunny/Clear)

| 温度范围 | 推荐活动 | 推荐地点 |
|----------|---------|---------|
| >25°C | 游泳、海滩、水上乐园 | 海边、水上公园 |
| 15-25°C | 徒步、骑行、野餐、露营 | 公园、山区、郊外 |
| 5-15°C | 城市漫步、摄影、放风筝 | 市中心、广场、公园 |
| <5°C | 晒太阳、温泉 | 温泉度假村、露天咖啡厅 |

### ☁️ 多云 (Cloudy)

| 温度范围 | 推荐活动 | 推荐地点 |
|----------|---------|---------|
| >20°C | 徒步、骑行、观光 | 山区、景点 |
| 10-20°C | 城市探索、骑行 | 市区、古镇 |
| <10°C | 室内景点、咖啡厅 | 博物馆、书店 |

### 🌧️ 雨天 (Rainy)

| 雨量 | 推荐活动 | 推荐地点 |
|------|---------|---------|
| 小雨 | 室内活动、雨中漫步(带伞) | 商场、室内景点 |
| 中雨 | 纯室内活动 | 博物馆、电影院、室内游乐场 |
| 大雨 | 宅家、线上活动 | 家、酒店 |

### ❄️ 雪天 (Snowy)

| 雪量 | 推荐活动 | 推荐地点 |
|------|---------|---------|
| 小雪 | 赏雪、拍照、堆雪人 | 公园、山区 |
| 中雪 | 滑雪、温泉 | 滑雪场、温泉度假村 |
| 大雪 | 避免外出 | 室内 |

### 🌡️ 极端温度

| 情况 | 建议 |
|------|------|
| >35°C | 避免户外活动,选择室内空调场所 |
| <0°C | 保暖为主,选择室内或温泉 |

## 快速开始

### 基本用法

```bash
# 获取天气(JSON 格式)
curl -s "wttr.in/Beijing?format=j1"

# 使用 Python 脚本(推荐,自动解析)
python {baseDir}/scripts/fetch_weather.py --city Beijing

完整流程

用户问:"北京今天适合干什么?"

bash 复制代码
# 1. 获取天气数据
curl -s "wttr.in/Beijing?format=j1" > /tmp/weather.json

# 2. 解析天气(使用 Python 脚本)
python {baseDir}/scripts/fetch_weather.py --city Beijing --output /tmp/result.json

# 3. 根据天气匹配活动规则(参考本文档的映射表)
# 输出推荐结果

脚本用法

fetch_weather.py

bash 复制代码
# 基本用法
python {baseDir}/scripts/fetch_weather.py --city Beijing

# 指定日期(0=今天,1=明天,2=后天)
python {baseDir}/scripts/fetch_weather.py --city Beijing --day 1

# 输出详细结果
python {baseDir}/scripts/fetch_weather.py --city Beijing --verbose

# 保存结果
python {baseDir}/scripts/fetch_weather.py --city Beijing --output result.json

参数说明

参数 说明 默认值
--city 城市名(英文或拼音) 必需
--day 日期(0-2) 0(今天)
--output 输出文件 stdout
--verbose 详细输出 false

输出示例

输入

复制代码
用户:上海今天适合干什么?

输出

复制代码
📍 上海天气概览
━━━━━━━━━━━━━━━━━━━━
🌤️ 天气:多云
🌡️ 温度:18°C (体感 17°C)
💨 风力:3 级 东北风
💧 湿度:65%
🌧️ 降水概率:10%

━━━━━━━━━━━━━━━━━━━━
🎯 推荐活动
━━━━━━━━━━━━━━━━━━━━

✅ 最佳推荐:城市探索、骑行

📍 推荐地点:
   • 外滩(城市漫步)
   • 法租界(骑行)
   • 田子坊(拍照)

📋 活动建议:
   • 温度适宜,适合户外活动
   • 多云天气,拍照光线柔和
   • 建议带薄外套,早晚较凉

⚠️ 注意事项:
   • 降水概率低,无需带伞
   • 风力适中,不影响活动

配置选项

assets/cities.json 中配置热门城市:

json 复制代码
{
  "cities": [
    { "name": "北京", "en": "Beijing", "region": "华北" },
    { "name": "上海", "en": "Shanghai", "region": "华东" },
    { "name": "广州", "en": "Guangzhou", "region": "华南" }
  ]
}

错误处理

错误 处理方式
API 返回失败 重试 3 次,提示用户稍后再试
城市名无效 提示用户检查城市名,建议用拼音
无天气数据 使用备用 API 或提示无法获取

降级方案

复制代码
wttr.in API 失败
   ↓
尝试备用 API (Open-Meteo)
   ↓
提示用户查看当地天气预报

安全注意

⚠️ 仅供参考 - 实际出行前请查看最新天气预报

⚠️ 极端天气 - 暴雨、台风等请遵循官方指引

⚠️ 个人差异 - 老人、儿童、孕妇需额外注意

相关文件

  • scripts/fetch_weather.py - 天气获取脚本
  • references/activity_rules.md - 详细活动规则
  • assets/cities.json - 城市列表

依赖安装

bash 复制代码
# Python 依赖
pip install requests

# 验证安装
python -c "import requests; print('OK')"

扩展建议

添加 MCP 服务(可选)

如果有 MCP 本地生活服务,可以整合:

bash 复制代码
# 调用 MCP 获取附近景点
mcporter call local.get_attractions city:"Beijing" type:"outdoor"

# 调用 MCP 预订门票
mcporter call local.book_ticket attraction:"Great Wall" date:"2026-03-15"

添加用户偏好

在配置中记录用户偏好:

json 复制代码
{
  "user_preferences": {
    "prefer_outdoor": true,
    "max_walking_distance": "5km",
    "budget": "medium"
  }
}
复制代码
---

### scripts/fetch_weather.py 示例

```python
#!/usr/bin/env python3
"""
Weather Activity Planner - 天气获取脚本
根据天气数据推荐适合的活动
"""

import requests
import json
import argparse
from datetime import datetime

# 天气 → 活动映射
ACTIVITY_MAP = {
    "sunny": {
        "hot": {"temp_min": 25, "activities": ["游泳", "海滩", "水上乐园"], "places": ["海边", "水上公园"]},
        "warm": {"temp_min": 15, "activities": ["徒步", "骑行", "野餐", "露营"], "places": ["公园", "山区", "郊外"]},
        "cool": {"temp_min": 5, "activities": ["城市漫步", "摄影", "放风筝"], "places": ["市中心", "广场", "公园"]},
        "cold": {"temp_min": -999, "activities": ["晒太阳", "温泉"], "places": ["温泉度假村", "露天咖啡厅"]},
    },
    "cloudy": {
        "warm": {"temp_min": 20, "activities": ["徒步", "骑行", "观光"], "places": ["山区", "景点"]},
        "cool": {"temp_min": 10, "activities": ["城市探索", "骑行"], "places": ["市区", "古镇"]},
        "cold": {"temp_min": -999, "activities": ["室内景点", "咖啡厅"], "places": ["博物馆", "书店"]},
    },
    "rainy": {
        "light": {"activities": ["室内活动", "雨中漫步"], "places": ["商场", "室内景点"]},
        "medium": {"activities": ["纯室内活动"], "places": ["博物馆", "电影院", "室内游乐场"]},
        "heavy": {"activities": ["宅家", "线上活动"], "places": ["家", "酒店"]},
    },
}

def get_weather(city, day=0):
    """获取天气数据"""
    url = f"https://wttr.in/{city}?format=j1"
    try:
        response = requests.get(url, timeout=10)
        response.raise_for_status()
        return response.json()
    except Exception as e:
        print(f"❌ 获取天气失败:{e}")
        return None

def parse_weather(data, day=0):
    """解析天气数据"""
    if not data or "current_condition" not in data:
        return None
    
    current = data["current_condition"][0]
    forecast = data["weather"][day] if "weather" in data else None
    
    return {
        "city": data.get("nearest_area", [{}])[0].get("areaName", [{}])[0].get("value", "Unknown"),
        "condition": current.get("weatherDesc", [{}])[0].get("value", "Unknown"),
        "condition_code": current.get("weatherCode", "0"),
        "temp_c": int(current.get("temp_C", 0)),
        "feels_like": int(current.get("FeelsLikeC", 0)),
        "humidity": current.get("humidity", 0),
        "wind_speed": current.get("windspeedKmph", 0),
        "wind_dir": current.get("winddir16Point", ""),
        "precip_prob": forecast.get("avgdailyChanceOfRain", 0) if forecast else 0,
    }

def recommend_activity(weather):
    """根据天气推荐活动"""
    condition = weather["condition"].lower()
    temp = weather["temp_c"]
    precip = weather["precip_prob"]
    
    # 判断天气类型
    if "rain" in condition or precip > 50:
        weather_type = "rainy"
        if precip > 70:
            rain_level = "heavy"
        elif precip > 30:
            rain_level = "medium"
        else:
            rain_level = "light"
        activities = ACTIVITY_MAP.get("rainy", {}).get(rain_level, {}).get("activities", ["室内活动"])
        places = ACTIVITY_MAP.get("rainy", {}).get(rain_level, {}).get("places", ["室内场所"])
    elif "cloud" in condition or "overcast" in condition:
        weather_type = "cloudy"
        if temp >= 20:
            level = "warm"
        elif temp >= 10:
            level = "cool"
        else:
            level = "cold"
        activities = ACTIVITY_MAP.get("cloudy", {}).get(level, {}).get("activities", ["室内活动"])
        places = ACTIVITY_MAP.get("cloudy", {}).get(level, {}).get("places", ["室内场所"])
    elif "sun" in condition or "clear" in condition:
        weather_type = "sunny"
        if temp >= 25:
            level = "hot"
        elif temp >= 15:
            level = "warm"
        elif temp >= 5:
            level = "cool"
        else:
            level = "cold"
        activities = ACTIVITY_MAP.get("sunny", {}).get(level, {}).get("activities", ["室内活动"])
        places = ACTIVITY_MAP.get("sunny", {}).get(level, {}).get("places", ["室内场所"])
    else:
        activities = ["室内活动"]
        places = ["室内场所"]
    
    return {
        "activities": activities,
        "places": places,
        "weather_type": weather_type,
    }

def format_output(weather, recommendation):
    """格式化输出"""
    output = []
    output.append(f"📍 {weather['city']}天气概览")
    output.append("━" * 40)
    output.append(f"🌤️ 天气:{weather['condition']}")
    output.append(f"🌡️ 温度:{weather['temp_c']}°C (体感 {weather['feels_like']}°C)")
    output.append(f"💨 风力:{weather['wind_speed']}km/h {weather['wind_dir']}")
    output.append(f"💧 湿度:{weather['humidity']}%")
    output.append(f"🌧️ 降水概率:{weather['precip_prob']}%")
    output.append("")
    output.append("━" * 40)
    output.append("🎯 推荐活动")
    output.append("━" * 40)
    output.append("")
    output.append(f"✅ 最佳推荐:{'、'.join(recommendation['activities'])}")
    output.append("")
    output.append("📍 推荐地点:")
    for place in recommendation['places']:
        output.append(f"   • {place}")
    output.append("")
    output.append("📋 活动建议:")
    if weather['temp_c'] >= 25:
        output.append("   • 温度较高,注意防晒补水")
    elif weather['temp_c'] <= 10:
        output.append("   • 温度较低,注意保暖")
    else:
        output.append("   • 温度适宜,适合户外活动")
    
    if weather['precip_prob'] > 50:
        output.append("   • 降水概率高,建议带伞")
    else:
        output.append("   • 降水概率低,无需带伞")
    
    output.append("")
    output.append("⚠️ 注意事项:")
    output.append("   • 仅供参考,出行前请查看最新预报")
    output.append("   • 极端天气请遵循官方指引")
    
    return "\n".join(output)

def main():
    parser = argparse.ArgumentParser(description="Weather Activity Planner")
    parser.add_argument("--city", required=True, help="城市名(英文或拼音)")
    parser.add_argument("--day", type=int, default=0, help="日期(0=今天,1=明天,2=后天)")
    parser.add_argument("--output", help="输出文件路径")
    parser.add_argument("--verbose", action="store_true", help="详细输出")
    args = parser.parse_args()
    
    # 获取天气
    if args.verbose:
        print(f"🔄 正在获取 {args.city} 的天气数据...")
    
    weather_data = get_weather(args.city, args.day)
    if not weather_data:
        print("❌ 无法获取天气数据,请稍后再试")
        return
    
    # 解析天气
    weather = parse_weather(weather_data, args.day)
    if not weather:
        print("❌ 无法解析天气数据")
        return
    
    if args.verbose:
        print(f"✅ 天气数据获取成功")
    
    # 推荐活动
    recommendation = recommend_activity(weather)
    
    # 格式化输出
    output = format_output(weather, recommendation)
    
    # 输出结果
    if args.output:
        with open(args.output, 'w', encoding='utf-8') as f:
            f.write(output)
        print(f"✅ 结果已保存到 {args.output}")
    else:
        print(output)

if __name__ == "__main__":
    main()

使用示例

bash 复制代码
# 基本用法
python {baseDir}/scripts/fetch_weather.py --city Beijing

# 明天天气
python {baseDir}/scripts/fetch_weather.py --city Shanghai --day 1

# 保存结果
python {baseDir}/scripts/fetch_weather.py --city Guangzhou --output result.json

# 详细模式
python {baseDir}/scripts/fetch_weather.py --city Shenzhen --verbose

这个案例展示了

技能要素 实现方式
静态文本 天气→活动映射规则表
HTTP 请求 curl wttr.in/{city}?format=j1
本地脚本 fetch_weather.py 处理逻辑
决策逻辑 根据天气条件匹配活动
降级方案 API 失败→备用 API→提示用户
配置选项 cities.json 城市列表
错误处理 超时、无效城市、无数据

相关推荐
nananaij2 小时前
【LeetCode-02 最小偶倍数 python解法】
python·算法·leetcode
英英_2 小时前
Selenium 常用浏览器操作全解析
python·selenium·测试工具
咕泡科技2 小时前
从0到1系统学习大模型:一份接地气的入门指南
人工智能·python·学习
KerwinChou_CN2 小时前
大模型 RAG 中 RRF(Reciprocal Rank Fusion倒数排序融合)是什么
人工智能·后端·python
无巧不成书02182 小时前
Java数值字面量速查表
java·开发语言·python·开发者·字面量
小鸡吃米…2 小时前
测试线程应用程序
开发语言·python
python开发笔记2 小时前
python(79) 底层代码追踪工具
开发语言·python
Bert.Cai2 小时前
Python函数的定义与调用
开发语言·python