顶部广告
当前位置:首页 » OpenClaw小龙虾专区 » Skill 参数设计:让用户用得爽

Skill 参数设计:让用户用得爽

   作者:mpoll.top   发布时间:2026-04-21   0 次浏览

文章广告

概述

OpenClaw 的 Skill 参数系统 是技能与用户交互的核心机制。通过精心设计的参数,技能可以接收用户输入、提供灵活配置、实现复杂交互。本文将深入解析 Skill 参数的设计原则、类型系统、最佳实践和高级用法。

---

参数基础

什么是 Skill 参数?

Skill 参数是技能接收外部输入的方式,类似于函数的参数:

// 技能定义示例
module.exports = {
  name: 'weather',
  description: '查询天气信息',
  parameters: {
    location: {
      type: 'string',
      description: '城市名称',
      required: true
    },
    days: {
      type: 'number',
      description: '预报天数',
      default: 3
    }
  },
  execute: async (params) => {
    // 使用 params.location 和 params.days
  }
};

参数的作用

  • 接收输入:从用户或调用方获取数据
  • 类型检查:确保输入符合预期格式
  • 默认值:提供合理的默认行为
  • 验证逻辑:确保输入的有效性
  • 文档生成:自动生成使用帮助

参数类型系统

基础类型

#### string - 字符串

最常用的参数类型:

{
  type: 'string',
  description: '用户姓名',
  required: true,
  minLength: 1,
  maxLength: 50,
  pattern: '^[a-zA-Z\\s]+$'  // 可选:正则验证
}

适用场景

  • 文本输入
  • 名称、标题
  • 搜索关键词
  • 文件路径

#### number - 数字

支持整数和浮点数:

{
  type: 'number',
  description: '温度阈值',
  default: 25,
  minimum: -50,
  maximum: 100,
  multipleOf: 0.5  // 可选:必须是 0.5 的倍数
}

适用场景

  • 数量、计数
  • 阈值、限制
  • 评分、权重
  • 时间间隔

#### boolean - 布尔值

真/假开关:

{
  type: 'boolean',
  description: '是否包含周末',
  default: false
}

适用场景

  • 开关选项
  • 是否包含某内容
  • 启用/禁用功能

#### array - 数组

多个值的集合:

{
  type: 'array',
  description: '要通知的用户列表',
  items: {
    type: 'string'
  },
  minItems: 1,
  maxItems: 10,
  uniqueItems: true
}

适用场景

  • 多个选项
  • 标签列表
  • 批量操作目标

#### object - 对象

结构化数据:

{
  type: 'object',
  description: '高级配置',
  properties: {
    timeout: {
      type: 'number',
      default: 30
    },
    retries: {
      type: 'number',
      default: 3
    }
  }
}

适用场景

  • 复杂配置
  • 嵌套选项
  • 结构化数据

高级类型

#### enum - 枚举

限定取值范围:

{
  type: 'string',
  description: '日志级别',
  enum: ['debug', 'info', 'warn', 'error'],
  default: 'info'
}

适用场景

  • 固定选项
  • 模式选择
  • 状态值

#### date - 日期

日期时间处理:

{
  type: 'string',
  format: 'date',  // 或 'date-time'
  description: '查询日期',
  default: 'today'  // 支持特殊值
}

适用场景

  • 日期选择
  • 时间范围
  • 定时任务

参数修饰符

required - 必填项

{
  type: 'string',
  required: true,  // 必须提供
  description: 'API 密钥'
}

注意事项

  • 必填参数必须在调用时提供
  • 缺少必填参数会导致调用失败
  • 谨慎使用,避免降低易用性

default - 默认值

{
  type: 'number',
  default: 10,  // 未提供时使用此值
  description: '结果数量'
}

最佳实践

  • 为常用参数提供合理默认值
  • 默认值应该是安全的选择
  • 文档中明确说明默认值

description - 描述

{
  type: 'string',
  description: `
    城市名称,支持中文和英文。
    示例:北京、Beijing、上海市
  `,
  examples: ['北京', 'Shanghai', 'New York']
}

写作要点

  • 清晰说明参数用途
  • 提供使用示例
  • 说明格式要求

validation - 验证规则

{
  type: 'string',
  pattern: '^\\d{4}-\\d{2}-\\d{2}$',  // YYYY-MM-DD
  description: '日期(格式:YYYY-MM-DD)',
  errorMessage: '日期格式不正确,请使用 YYYY-MM-DD 格式'
}

验证类型

  • `pattern`: 正则表达式
  • `minimum/maximum`: 数值范围
  • `minLength/maxLength`: 字符串长度
  • `enum`: 枚举值
  • 自定义验证函数

参数组设计

互斥参数组

某些参数不能同时使用:

parameters: {
  userId: {
    type: 'string',
    description: '按用户 ID 查询'
  },
  username: {
    type: 'string',
    description: '按用户名查询'
  },
  // 互斥组定义
  exclusiveGroups: [
    ['userId', 'username']  // 只能选一个
  ]
}

依赖参数组

某些参数需要一起使用:

parameters: {
  startDate: {
    type: 'string',
    format: 'date'
  },
  endDate: {
    type: 'string',
    format: 'date',
    dependsOn: ['startDate']  // 需要提供 startDate
  }
}

条件参数

基于其他参数值显示/隐藏:

parameters: {
  notifyType: {
    type: 'string',
    enum: ['email', 'sms', 'both']
  },
  email: {
    type: 'string',
    description: '邮箱地址',
    showWhen: { notifyType: ['email', 'both'] }
  },
  phone: {
    type: 'string',
    description: '手机号',
    showWhen: { notifyType: ['sms', 'both'] }
  }
}

最佳实践

1. 参数数量控制

✅ 推荐:3-5 个参数
⚠️ 注意:6-8 个参数
❌ 避免:超过 10 个参数

参数过多时

  • 考虑拆分为多个技能
  • 使用对象参数分组
  • 提供预设配置

2. 命名规范

// ✅ 好的命名
{
  location: ...,      // 清晰明确
  maxRetries: ...,    // 驼峰命名
  timeoutSeconds: ... // 带单位
}

// ❌ 差的命名
{
  loc: ...,           // 太简略
  n: ...,             // 无意义
  time: ...           // 歧义(时间?时长?)
}

3. 默认值策略

// ✅ 好的默认值
{
  limit: { type: 'number', default: 10 },      // 合理数量
  verbose: { type: 'boolean', default: false }, // 安静模式
  format: { type: 'string', default: 'json' }   // 机器友好
}

// ❌ 差的默认值
{
  limit: { type: 'number', default: 10000 },   // 太大
  delete: { type: 'boolean', default: true },  // 危险
  format: { type: 'string', default: 'xml' }   // 过时
}

4. 错误信息

// ✅ 好的错误信息
{
  pattern: '^\\d{11}$',
  errorMessage: '手机号应为 11 位数字'
}

// ❌ 差的错误信息
{
  pattern: '^\\d{11}$',
  errorMessage: '无效输入'  // 太模糊
}

5. 文档完整性

// ✅ 完整文档
{
  name: 'backup',
  description: '备份指定目录到云存储',
  parameters: {
    source: {
      type: 'string',
      description: '源目录路径',
      required: true,
      examples: ['/home/user/docs', '~/projects']
    },
    destination: {
      type: 'string',
      description: '目标存储桶',
      required: true,
      examples: ['my-backups', 'archive-2026']
    }
  },
  examples: [
    {
      description: '备份文档目录',
      params: { source: '~/docs', destination: 'docs-backup' }
    }
  ]
}

高级用法

动态参数

基于运行时条件调整参数:

async function getParameters(context) {
  const params = {
    location: {
      type: 'string',
      required: true
    }
  };
  
  // 根据用户订阅级别添加参数
  if (context.user.premium) {
    params.days = {
      type: 'number',
      default: 14,  // 高级用户 14 天
      maximum: 30
    };
  } else {
    params.days = {
      type: 'number',
      default: 3,  // 普通用户 3 天
      maximum: 7
    };
  }
  
  return params;
}

参数转换

自动转换输入格式:

parameters: {
  date: {
    type: 'string',
    transform: (value) => {
      // 支持多种输入格式
      if (value === 'today') return new Date().toISOString();
      if (value === 'tomorrow') {
        const d = new Date();
        d.setDate(d.getDate() + 1);
        return d.toISOString();
      }
      return value;
    }
  }
}

参数验证回调

复杂验证逻辑:

parameters: {
  url: {
    type: 'string',
    required: true,
    validate: async (value, context) => {
      // 异步验证 URL 是否可访问
      try {
        await fetch(value, { method: 'HEAD' });
        return true;
      } catch {
        return 'URL 无法访问';
      }
    }
  }
}

参数继承

基础参数集复用:

// 基础参数
const baseParams = {
  timeout: { type: 'number', default: 30 },
  retries: { type: 'number', default: 3 }
};

// 技能 A
module.exports = {
  name: 'api-call-a',
  parameters: {
    ...baseParams,
    endpoint: { type: 'string', required: true }
  }
};

// 技能 B
module.exports = {
  name: 'api-call-b',
  parameters: {
    ...baseParams,
    query: { type: 'string', required: true }
  }
};

调试技巧

1. 参数日志

execute: async (params, context) => {
  context.logger.debug('接收参数:', JSON.stringify(params, null, 2));
  // ...
}

2. 验证测试

// 测试参数验证
const testCases = [
  { input: { location: '北京' }, expected: 'pass' },
  { input: { location: '' }, expected: 'fail' },
  { input: {}, expected: 'fail' }  // 缺少必填
];

for (const test of testCases) {
  const result = await validateParams(test.input);
  console.assert(
    result.success === (test.expected === 'pass'),
    `测试失败:${JSON.stringify(test.input)}`
  );
}

3. 类型检查

// 开发时启用严格类型检查
if (process.env.NODE_ENV === 'development') {
  enableStrictParamValidation();
}

常见问题

Q1: 如何处理可选参数?

// 方式 1:使用 default
{
  type: 'number',
  default: null  // 明确允许 null
}

// 方式 2:不设置 required
{
  type: 'string'
  // 不提供时值为 undefined
}

Q2: 如何处理参数冲突?

// 在 execute 中检查
execute: async (params) => {
  if (params.userId && params.username) {
    throw new Error('userId 和 username 不能同时提供');
  }
  // ...
}

Q3: 如何支持多语言参数描述?

{
  description: {
    en: 'City name',
    zh: '城市名称',
    ja: '都市名'
  }
}

总结

Skill 参数系统是 OpenClaw 技能与用户交互的核心。良好的参数设计可以:

  • ✅ 提升用户体验
  • ✅ 减少错误使用
  • ✅ 便于文档生成
  • ✅ 支持自动化测试

遵循本文的最佳实践,设计清晰、灵活、易用的参数系统,让你的技能更加专业和可靠。


发布分类:OpenClaw
标签:OpenClaw, 技能开发,参数系统,最佳实践,教程
字数:约 5,500 字

本文标签: , ,

    关于作者

    作者头像
    OpenClaw技术团队
    专注AI Agent技术分享