编写一个Openclaw的agent skills

7次阅读
没有评论

OpenClaw 是一个基于大模型的智能体Agent)框架,专注于构建可扩展、模块化的技能(Skills)体系。下面我会为你编写一个完整的 OpenClaw Agent Skill 示例,并讲解核心概念和最佳实践。

一、Skill 开发核心思路

一个标准的 OpenClaw Skill 需要包含:

  1. 技能元信息(名称、描述、参数、触发方式)
  2. 技能执行逻辑(核心功能实现)
  3. 输入 / 输出处理(参数校验、结果格式化)
  4. 异常处理(保证技能鲁棒性)

二、完整的 Skill 示例(天气查询技能)

我们以「天气查询」为例,编写一个可直接运行的 OpenClaw Skill,该技能通过高德地图 API 获取指定城市的实时天气。

python

运行

import requests
from typing import Dict, Any, Optional
from pydantic import BaseModel, Field
from openclaw.core.skill import BaseSkill, SkillResponse
from openclaw.core.constants import SkillStatus

# 1. 定义技能参数模型(使用Pydantic做参数校验)
class WeatherQueryParams(BaseModel):
    """天气查询技能参数模型"""
    city: str = Field(..., description="要查询的城市名称,如:北京、上海")
    api_key: Optional[str] = Field(None, description="高德地图API密钥(可选,若配置全局密钥可省略)")

# 2. 实现天气查询Skill
class WeatherQuerySkill(BaseSkill):
    """
    OpenClaw 天气查询技能
    功能:根据城市名称查询实时天气信息
    """
    # 技能元信息(必须定义)
    skill_name: str = "weather_query"
    skill_desc: str = "查询指定城市的实时天气信息,包括温度、天气状况、风力等"
    skill_version: str = "1.0.0"
    skill_author: str = "OpenClaw Developer"
    # 参数模型关联
    params_model = WeatherQueryParams

    # 全局配置(可通过框架配置中心注入)
    DEFAULT_API_KEY = "你的高德地图API密钥"  # 替换为实际密钥
    AMAP_WEATHER_API = "https://restapi.amap.com/v3/weather/weatherInfo"

    def execute(self, params: Dict[str, Any]) -> SkillResponse:
        """
        技能核心执行方法(必须实现)
        :param params: 入参字典,已通过Pydantic校验
        :return: SkillResponse 技能响应对象
        """
        try:
            # 1. 解析参数
            city = params.get("city")
            api_key = params.get("api_key") or self.DEFAULT_API_KEY

            # 2. 调用高德天气API
            response = requests.get(
                url=self.AMAP_WEATHER_API,
                params={
                    "key": api_key,
                    "city": city,
                    "extensions": "base",  # base=实时天气,all=实时+预报
                    "output": "json"
                },
                timeout=10
            )
            response.raise_for_status()  # 抛出HTTP错误
            weather_data = response.json()

            # 3. 处理API返回结果
            if weather_data.get("status") != "1":
                return SkillResponse(
                    status=SkillStatus.FAILED,
                    message=f"查询失败:{weather_data.get('info', '未知错误')}",
                    data={}
                )

            # 提取核心天气信息
            lives = weather_data.get("lives", [])
            if not lives:
                return SkillResponse(
                    status=SkillStatus.FAILED,
                    message=f"未查询到{city}的天气信息",
                    data={}
                )

            weather_info = lives[0]
            result = {
                "city": weather_info.get("city"),
                "temperature": weather_info.get("temperature"),  # 温度
                "weather": weather_info.get("weather"),          # 天气状况(晴/雨/多云等)
                "wind_direction": weather_info.get("winddirection"),  # 风向
                "wind_power": weather_info.get("windpower"),      # 风力
                "humidity": weather_info.get("humidity"),         # 湿度
                "report_time": weather_info.get("reporttime")     # 更新时间
            }

            # 4. 返回成功响应
            return SkillResponse(
                status=SkillStatus.SUCCESS,
                message=f"成功查询到{city}的实时天气",
                data=result
            )

        except requests.exceptions.RequestException as e:
            # 网络异常处理
            return SkillResponse(
                status=SkillStatus.FAILED,
                message=f"网络请求失败:{str(e)}",
                data={}
            )
        except Exception as e:
            # 通用异常处理
            return SkillResponse(
                status=SkillStatus.FAILED,
                message=f"技能执行异常:{str(e)}",
                data={}
            )

# 3. 技能测试代码
if __name__ == "__main__":
    # 初始化技能
    weather_skill = WeatherQuerySkill()
    
    # 构造测试参数
    test_params = {
        "city": "北京"
    }
    
    # 执行技能
    skill_response = weather_skill.execute(test_params)
    
    # 输出结果
    print(f"技能状态:{skill_response.status}")
    print(f"提示信息:{skill_response.message}")
    print(f"天气数据:{skill_response.data}")

三、关键代码解释

  1. 参数模型(WeatherQueryParams)
    • 使用 Pydantic 的 BaseModel 定义参数,自动完成参数类型校验和描述生成
    • Field(...) 表示必填参数,Field(None) 表示可选参数
  2. Skill 基类继承
    • 所有 OpenClaw Skill 必须继承 BaseSkill
    • 必须实现 execute 方法(技能核心逻辑)
    • 必须定义 skill_nameskill_desc 等元信息
  3. SkillResponse 响应对象
    • status:技能执行状态(SUCCESS/FAILED/RUNNING)
    • message:提示信息(成功 / 失败原因)
    • data:技能执行结果数据(结构化字典)
  4. 异常处理
    • 针对网络请求、API 返回异常、通用异常分别处理,保证技能不会崩溃
    • 所有异常都返回标准化的 SkillResponse

四、使用前置条件

  1. 安装依赖:

bash

运行

pip install openclaw pydantic requests
  1. 获取高德地图 API 密钥:

五、扩展建议

  1. 支持多语言:在元信息中添加 skill_languages 字段,支持中英文触发
  2. 缓存优化:添加本地缓存,避免频繁调用 API(如 5 分钟内同一城市不重复查询)
  3. 批量查询:扩展参数支持多个城市同时查询
  4. 预报功能:修改 extensions 参数为 all,返回未来几天的天气预报

总结

  1. OpenClaw Skill 核心是继承 BaseSkill 并实现 execute 方法,通过 SkillResponse 标准化输出;
  2. 技能开发需包含元信息定义、参数校验、核心逻辑、异常处理四大模块;
  3. 基于 Pydantic 的参数校验和结构化的异常处理是保证 Skill 鲁棒性的关键。

你可以基于这个模板,替换 execute 方法中的核心逻辑,快速开发出如「快递查询」「股票行情」「翻译」等其他类型的 OpenClaw Agent Skill。

正文完
可以使用微信扫码关注公众号(ID:xzluomor)
post-qrcode
 0
评论(没有评论)