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 城市列表
错误处理 超时、无效城市、无数据

相关推荐
傲笑风3 小时前
【openvino】tinybert基于openvino服务化部署(四)
人工智能·python·自然语言处理·nlp·bert·openvino
维基框架4 小时前
WIKI 知识库 v1.1.1 正式发布
人工智能·python
谢白羽8 小时前
SGLang的AWQ量化笔记
笔记·python·sglang
迷迭香yy8 小时前
基金档案数据工程实战从收入分析到持仓穿透的Python解析 IG50免费开源股票数据API接口
开发语言·python
清水白石0088 小时前
Python 类型设计深度解析:TypedDict 能否替代 dataclass?从 JSON 数据边界到 API 设计的最佳实践
java·python·json
️学习的小王9 小时前
Git项目提交忽略文件怎么做?以Python项目为例,详解.gitignore
git·python·elasticsearch
前端 贾公子9 小时前
第09章:上下文与记忆 (6)
开发语言·前端·python
evans在进步9 小时前
Java 常用设计模式入门:建造者、工厂、单例、外观与代理
java·python·设计模式
jayson.h10 小时前
PDF 合并+添加页码 相关库、类、函数
开发语言·前端·python
典典分享指南10 小时前
用飞书多维表格搭建内容管理看板
java·python·r语言·composer·symfony