[CoPaw 教程系列] #11: Copaw Custom Skills
CoPaw 功能:自定义 Skills 开发
CoPaw 的强大之处在于你可以创建自定义 Skills,扩展其能力。本文将详细介绍如何开发和部署自定义 Skills,从简单的配置型 Skills 到复杂的编程型 Skills。
自定义 Skills 概述
为什么需要自定义 Skills?
虽然 CoPaw 提供了丰富的内置 Skills,但实际场景中你可能需要:
- 特定领域的专业知识
- 与内部系统集成
- 自定义的工作流程
- 特殊的数据处理逻辑
- 个性化的交互方式
自定义 Skills 的类型
1. 配置型 Skills
特点:
- 只需编写 Markdown 文件
- 定义能力和使用方法
- 依赖 CoPaw 的内置工具
适用场景:
- 领域知识库
- 业务规则说明
- 工作流程指导
- 回复模板
2. 编程型 Skills
特点:
- 需要编写代码
- 可以调用外部 API
- 自定义工具函数
- 复杂的逻辑处理
适用场景:
- 与第三方系统集成
- 自定义数据处理
- 特定的业务逻辑
- 高性能计算
创建配置型 Skills
配置型 Skills 是最简单的自定义 Skills,只需要编写 SKILL.md
文件。
基本结构
---
name: my_skill
description: 我的自定义能力说明
Skill 标题
功能说明
详细描述这个 Skill 的功能...
使用方法
如何使用这个 Skill...
注意事项
使用时需要注意的事项...
创建步骤
1. 创建目录
cd ~/.copaw/customized_skills/
mkdir my_skill
cd my_skill
touch SKILL.md
2. 编写 SKILL.md
---
name: weather_query
description: 天气查询 Skill
天气查询
功能说明
这个 Skill 可以查询指定城市的天气信息。
使用方法
在对话中直接输入城市名称即可,例如:
- 北京今天天气怎么样?
- 查一下上海明天的天气
- 深圳现在的气温是多少?
支持的城市
- 北京
- 上海
- 深圳
- 广州
- 杭州
- ...
注意事项
- 只支持国内主要城市
- 天气数据来源于公共 API,可能有延迟
- 数据更新频率为每小时
3. 重启 CoPaw
# 停止 CoPaw
Ctrl+C
重新启动
copaw app
实战案例
案例 1:领域知识库
场景:
为 CoPaw 添加特定领域的专业知识。
SKILL.md
---
name: blockchain_knowledge
description: 区块链技术知识库
区块链技术知识库
核心概念
区块(Block)
区块是区块链的基本单位,包含:
- 区块头:区块的元数据
- 区块体:实际交易数据
- 哈希值:区块的唯一标识
- 时间戳:区块生成时间
链(Chain)
链是区块的有序连接:
- 每个区块包含前一个区块的哈希
- 形成不可篡改的链式结构
- 任何修改都会影响后续所有区块
共识机制
- PoW(工作量证明):如比特币
- PoS(权益证明):如以太坊 2.0
- DPoS(委托权益证明):如 EOS
常见问题
Q: 什么是去中心化?
A: 去中心化是指系统不依赖单一中心节点,数据分布在多个节点上。
Q: 什么是智能合约?
A: 智能合约是运行在区块链上的自动执行程序,当满足条件时自动执行。
Q: 区块链的安全来自哪里?
A: 来自密码学保证和分布式共识机制。
回复风格
- 使用专业但易懂的语言
- 提供具体的例子
- 适当使用图示和类比
- 避免过于技术化的术语
使用示例:
你:什么是区块链?
CoPaw:(调用 blockchain_knowledge Skill)
区块链是一种分布式数据库技术,由多个区块组成,每个区块包含交易数据和前一个区块的哈希值。
想象一个共享的笔记本,每个人都有一个副本。每当有人添加新的交易,所有人都会同步更新。一旦记录下来,就无法被篡改,因为任何修改都会破坏整个链的完整性。
核心特点:
- 去中心化:没有单一的控制中心
- 不可篡改:一旦记录就无法修改
- 透明公开:所有人都可以查看交易记录
案例 2:工作流程指导
场景:
为 CoPaw 添加特定的工作流程指导。
SKILL.md
---
name: code_review_workflow
description: 代码审查工作流程
代码审查工作流程
审查前准备
1. 理解背景
- 阅读需求文档或问题描述
- 了解修改的目的和范围
- 查看相关的 issue 或 ticket
2. 准备环境
- 拉取最新代码
- 运行测试,确保代码可以正常工作
- 查看依赖的变更
审查步骤
第一步:整体概览
- 查看 commit message
- 了解修改的文件和代码量
- 快速浏览主要变更
第二步:代码审查
- 功能性
- 代码是否实现了需求?
- 是否有遗漏的功能?
- 是否有过度实现?
- 代码质量
- 代码是否易于理解?
- 是否符合团队的代码规范?
- 变量/函数命名是否清晰?
- 性能
- 是否有明显的性能问题?
- 是否有不必要的计算或 I/O?
- 是否考虑了大数据量情况?
- 安全性
- 是否有安全漏洞?
- 是否正确处理用户输入?
- 是否泄露敏感信息?
第三步:测试检查
- 单元测试是否充分?
- 集成测试是否覆盖?
- 边界情况是否考虑?
第四步:文档检查
- 是否更新了相关文档?
- 代码注释是否充分?
- API 文档是否完整?
常见问题
应该指出的问题
- 功能性缺陷
- 严重的代码质量问题
- 安全性问题
- 性能问题
不应该指出的问题
- 个人编码风格偏好(除非违反团队规范)
- 可以优化的细节(不影响功能)
- 可以重构的地方(不在本次修改范围内)
回复风格
- 建设性:指出问题并提供改进建议
- 尊重:尊重作者的工作
- 具体:提供具体的示例和代码
- 优先级:指出问题的重要性(必须修复/建议修复/可选)
使用示例:
你:帮我看一下这段代码的问题
[代码内容]
CoPaw:(调用 code_review_workflow Skill)
我来按照代码审查流程检查这段代码...
代码审查报告
整体概览
- 修改范围:2 个文件,50 行代码
- 主要变更:添加用户登录功能
代码审查结果
✅ 功能性
- 代码实现了登录需求
- 功能完整
⚠️ 代码质量
- [必须修复] 缺少错误处理
python
# 当前代码
user = db.query_user(username)
password = user.password # 如果 user 为 None 会报错
建议修改:
python
user = db.query_user(username)
if user is None:
return error("用户不存在")
password = user.password
- [建议修复] 密码应该加密存储
python
# 建议使用 bcrypt 或类似库
hashed_password = bcrypt.hash(password)
✅ 性能
- 没有明显的性能问题
⚠️ 安全性
- [必须修复] SQL 注入风险
python
# 当前代码
query = f"SELECT
FROM users WHERE username = '{username}'"
建议使用参数化查询:
python
query = "SELECT
FROM users WHERE username = %s"
cursor.execute(query, (username,))
测试检查
- ⚠️ 缺少单元测试
- 建议添加以下测试用例:
- 用户名不存在的情况
- 密码错误的情况
- 登录成功的情况
文档检查
- ✅ 已更新 API 文档
- ⚠️ 缺少代码注释
总结
必须修复:
- 添加用户不存在检查
- 密码加密存储
- 修复 SQL 注入风险
建议修复:
- 添加单元测试
- 添加代码注释
评分:7/10
创建编程型 Skills
编程型 Skills 允许你编写自定义代码,扩展 CoPaw 的能力。
基本结构
my_skill/
├── SKILL.md # Skill 说明文件
├── __init__.py # Python 包文件
├── tools.py # 自定义工具函数
└── requirements.txt # 依赖列表
创建步骤
1. 创建目录结构
cd ~/.copaw/customized_skills/
mkdir my_custom_skill
cd my_custom_skill
touch SKILL.md
touch __init__.py
touch tools.py
touch requirements.txt
2. 编写 SKILL.md
---
name: my_custom_skill
description: 我的自定义编程型 Skill
我的自定义 Skill
功能说明
这个 Skill 提供了自定义的功能。
使用方法
直接使用,CoPaw 会自动调用相应的工具函数。
可用工具
my_function - 说明功能
注意事项
使用时注意...
3. 编写 tools.py
from typing import Optional, Dict, Any
def my_function(param1: str, param2: Optional[int] = None) -> Dict[str, Any]:
"""
自定义工具函数
Args:
param1: 参数1说明
param2: 参数2说明(可选)
Returns:
返回结果
"""
# 实现你的逻辑
result = {
"status": "success",
"data": f"处理结果:{param1}"
}
return result
4. 编写 requirements.txt
requests>=2.28.0
numpy>=1.24.0
5. 重启 CoPaw
# 停止 CoPaw
Ctrl+C
重新启动
copaw app
实战案例
案例 1:调用外部 API
场景:
创建一个调用天气 API 的 Skill。
SKILL.md
---
name: weather_api
description: 天气 API 调用
天气 API
功能说明
调用外部天气 API 获取实时天气信息。
使用方法
- 查询北京的天气
- 上海今天天气怎么样
- 明天的天气预报
可用工具
get_weather - 获取天气信息
注意事项
- 需要配置 API Key
- 数据更新频率有限制
tools.py
import requests
from typing import Dict, Any, Optional
配置 API Key
API_KEY = "your-api-key-here"
API_URL = "http://api.weather.com/v1/current"
def get_weather(city: str, days: int = 1) -> Dict[str, Any]:
"""
获取天气信息
Args:
city: 城市名称
days: 查询天数(1-7)
Returns:
天气信息
"""
try:
# 构建请求参数
params = {
"city": city,
"days": min(days, 7), # 最多 7 天
"key": API_KEY
}
# 发送请求
response = requests.get(API_URL, params=params)
response.raise_for_status()
# 解析响应
data = response.json()
# 格式化结果
result = {
"status": "success",
"city": city,
"current": {
"temperature": data["current"]["temp"],
"condition": data["current"]["text"],
"humidity": data["current"]["humidity"]
},
"forecast": [
{
"date": day["date"],
"temperature_max": day["temp_max"],
"temperature_min": day["temp_min"],
"condition": day["text"]
}
for day in data.get("forecast", [])[:days]
]
}
return result
except requests.RequestException as e:
return {
"status": "error",
"message": f"请求失败:{str(e)}"
}
except Exception as e:
return {
"status": "error",
"message": f"处理失败:{str(e)}"
}
requirements.txt
requests>=2.28.0
使用示例:
你:查一下北京的天气
CoPaw:(调用 get_weather 函数)
北京天气
当前天气
- 气温:18°C
- 天气:晴
- 湿度:45%
未来 3 天预报
明天(3月16日)
- 最高气温:22°C
- 最低气温:10°C
- 天气:多云
后天(3月17日)
- 最高气温:24°C
- 最低气温:12°C
- 天气:晴
3月18日
- 最高气温:20°C
- 最低气温:11°C
- 天气:阴
案例 2:数据处理
场景:
创建一个处理 CSV 文件的 Skill。
SKILL.md
---
name: csv_processor
description: CSV 文件处理
CSV 文件处理
功能说明
处理 CSV 文件,包括读取、分析、转换等。
使用方法
- 读取 data.csv 文件
- 分析这个 CSV 文件
- 把 CSV 转换成 JSON
可用工具
read_csv - 读取 CSV 文件analyze_csv - 分析 CSV 数据convert_csv_to_json - 转换 CSV 为 JSON
注意事项
- 支持 UTF-8 编码
- 文件大小限制为 100MB
tools.py
import csv
import json
from typing import Dict, Any, List, Optional
from pathlib import Path
def read_csv(file_path: str, delimiter: str = ",") -> List[Dict[str, str]]:
"""
读取 CSV 文件
Args:
file_path: 文件路径
delimiter: 分隔符(默认为逗号)
Returns:
数据列表
"""
try:
with open(file_path, 'r', encoding='utf-8') as f:
reader = csv.DictReader(f, delimiter=delimiter)
data = [row for row in reader]
return data
except FileNotFoundError:
return []
except Exception as e:
raise Exception(f"读取文件失败:{str(e)}")
def analyze_csv(file_path: str) -> Dict[str, Any]:
"""
分析 CSV 文件
Args:
file_path: 文件路径
Returns:
分析结果
"""
data = read_csv(file_path)
if not data:
return {"error": "文件为空或读取失败"}
# 获取列名
columns = list(data[0].keys())
# 统计行数和列数
row_count = len(data)
col_count = len(columns)
# 分析每列的数据类型
column_types = {}
for col in columns:
values = [row[col] for row in data if col in row]
column_types[col] = _infer_column_type(values)
# 检查缺失值
missing_values = {}
for col in columns:
missing_count = sum(1 for row in data if col not in row or not row[col])
missing_values[col] = {
"count": missing_count,
"percentage": (missing_count / row_count * 100) if row_count > 0 else 0
}
return {
"file_path": file_path,
"row_count": row_count,
"column_count": col_count,
"columns": columns,
"column_types": column_types,
"missing_values": missing_values,
"sample_data": data[:5] # 前 5 行样本
}
def convert_csv_to_json(csv_path: str, json_path: Optional[str] = None) -> Dict[str, Any]:
"""
转换 CSV 为 JSON
Args:
csv_path: CSV 文件路径
json_path: JSON 文件路径(可选,默认为同目录同名)
Returns:
转换结果
"""
data = read_csv(csv_path)
if not data:
return {"error": "CSV 文件为空或读取失败"}
# 确定 JSON 文件路径
if json_path is None:
csv_path_obj = Path(csv_path)
json_path = str(csv_path_obj.with_suffix('.json'))
# 写入 JSON
try:
with open(json_path, 'w', encoding='utf-8') as f:
json.dump(data, f, ensure_ascii=False, indent=2)
return {
"status": "success",
"csv_path": csv_path,
"json_path": json_path,
"record_count": len(data)
}
except Exception as e:
return {
"status": "error",
"message": f"写入 JSON 失败:{str(e)}"
}
def _infer_column_type(values: List[str]) -> str:
"""
推断列的数据类型
Args:
values: 值列表
Returns:
数据类型
"""
if not values:
return "unknown"
# 检查是否为整数
try:
int_values = [int(v) for v in values if v]
if len(int_values) == len([v for v in values if v]):
return "integer"
except ValueError:
pass
# 检查是否为浮点数
try:
float_values = [float(v) for v in values if v]
if len(float_values) == len([v for v in values if v]):
return "float"
except ValueError:
pass
# 检查是否为布尔值
bool_values = [v.lower() for v in values if v]
if all(v in ['true', 'false', 'yes', 'no', '1', '0'] for v in bool_values):
return "boolean"
# 默认为字符串
return "string"
requirements.txt
# 无需额外依赖,使用标准库
使用示例:
你:分析一下 sales.csv 这个文件
CoPaw:(调用 analyze_csv 函数)
CSV 文件分析报告
文件信息
- 文件路径:sales.csv
- 行数:150
- 列数:5
列信息
| 列名 | 数据类型 | 缺失值 | 缺失率 |
|------|---------|--------|--------|
| 日期 | string | 0 | 0% |
| 产品 | string | 0 | 0% |
| 数量 | integer | 0 | 0% |
| 单价 | float | 0 | 0% |
| 销售额 | float | 0 | 0% |
数据质量
- ✅ 无缺失值
- ✅ 数据类型正确
- ✅ 数据完整性良好
样本数据(前 5 行)
| 日期 | 产品 | 数量 | 单价 | 销售额 |
|------|------|------|------|--------|
| 2024-03-01 | 产品A | 10 | 100 | 1000 |
| 2024-03-01 | 产品B | 5 | 200 | 1000 |
| 2024-03-02 | 产品A | 8 | 100 | 800 |
| 2024-03-02 | 产品C | 3 | 300 | 900 |
| 2024-03-03 | 产品B | 6 | 200 | 1200 |
建议
数据质量良好,可以直接进行分析和可视化。
Skills 最佳实践
1. 命名规范
- 使用小写字母和下划线:
my_skill而不是MySkill - 名称应该简洁且具有描述性
- 避免与内置 Skill 冲突
2. 文档完整
在 SKILL.md
中提供:
- 清晰的功能说明
- 详细的使用方法
- 可用工具列表
- 注意事项和限制
3. 错误处理
- 合理处理异常
- 提供有意义的错误信息
- 记录日志便于调试
4. 性能优化
- 避免重复计算
- 合理使用缓存
- 注意资源消耗
5. 安全考虑
- 不在代码中硬编码敏感信息
- 验证输入参数
- 限制资源使用
6. 测试覆盖
- 编写单元测试
- 测试边界情况
- 集成测试
常见问题
Q1: 自定义 Skill 加载失败?
A: 检查:
SKILL.md文件是否存在且格式正确- 目录结构是否正确
- 依赖是否安装
- CoPaw 是否重启
Q2: 如何调试自定义 Skill?
A:
- 检查 CoPaw 的日志
- 在代码中添加日志输出
- 使用
print输出调试信息 - 检查返回值格式
Q3: 自定义 Skill 可以调用其他 Skill 吗?
A: 可以。但要注意循环依赖,建议保持 Skill 的独立性。
Q4: 如何分享自定义 Skill?
A:
- 将 Skill 上传到 GitHub
- 按照规范编写文档
- 在社区分享 Skill URL
- 提交到 Skills Hub
Q5: 如何更新自定义 Skill?
A:
- 直接编辑文件
- 或删除后重新创建
- 重启 CoPaw 使更改生效
下一步
现在你已经了解了如何创建自定义 Skills。接下来建议:
- 阅读下一篇:CoPaw 功能:MCP 模型上下文协议 - 学习 MCP 的使用
- 创建你的第一个 Skill:从简单的配置型 Skill 开始
- 探索编程型 Skills:尝试编写自定义工具函数
- 分享你的 Skills:与社区分享你的创建
总结
自定义 Skills 让 CoPaw 的能力无限扩展:
✅ 配置型 Skills
- 简单易用,无需编程
✅ 编程型 Skills
- 强大灵活,支持自定义逻辑
✅ 工具函数
- 调用外部 API 和系统
✅ 文档驱动
- 清晰的说明和使用方法
✅ 社区共享
- 分享和发现更多 Skills
通过自定义 Skills,你可以让 CoPaw 适应任何场景和需求。
相关资源
:
- CoPaw 官方文档:https://copaw.agentscope.io/
- CoPaw Skills 文档:https://copaw.agentscope.io/docs/skills
- anthropics/skills:https://github.com/anthropics/skills
- Skills Hub:https://skills.sh/







