Skip to content

17.4 基本技能示例

示例概述

本節將透過幾個完整的示例來展示如何開發不同型別的 Skills。這些示例涵蓋了常見的使用場景,可以作為開發自己 Skills 的參考。

示例 1:文字處理 Skill

1.1 Skill 定義

python
# src/skills/text_processor.py
from typing import Dict, Any
from claude_code_sdk import Skill, SkillContext, SkillResult

class TextProcessorSkill(Skill):
    """文本处理 Skill"""

    def __init__(self):
        super().__init__(
            name="text-processor",
            version="1.0.0",
            description="Process and transform text"
        )

    def get_parameters_schema(self) -> Dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "text": {
                    "type": "string",
                    "description": "Text to process"
                },
                "operations": {
                    "type": "array",
                    "description": "List of operations to apply",
                    "items": {
                        "type": "object",
                        "properties": {
                            "type": {
                                "type": "string",
                                "enum": ["uppercase", "lowercase", "title", "reverse", "remove_spaces", "count_words"]
                            },
                            "params": {
                                "type": "object"
                            }
                        }
                    }
                }
            },
            "required": ["text"]
        }

    def execute(self, parameters: Dict[str, Any], context: SkillContext) -> SkillResult:
        try:
            text = parameters["text"]
            operations = parameters.get("operations", [])

            # 应用操作
            result = text
            for operation in operations:
                op_type = operation.get("type")
                op_params = operation.get("params", {})

                result = self.apply_operation(result, op_type, op_params)

            return SkillResult(
                success=True,
                data={
                    "original": text,
                    "processed": result,
                    "operations_applied": len(operations)
                }
            )
        except Exception as e:
            return SkillResult(
                success=False,
                error=str(e)
            )

    def apply_operation(self, text: str, op_type: str, params: Dict[str, Any]) -> str:
        """应用单个操作"""
        if op_type == "uppercase":
            return text.upper()
        elif op_type == "lowercase":
            return text.lower()
        elif op_type == "title":
            return text.title()
        elif op_type == "reverse":
            return text[::-1]
        elif op_type == "remove_spaces":
            return text.replace(" ", "")
        elif op_type == "count_words":
            return str(len(text.split()))
        else:
            raise ValueError(f"Unknown operation: {op_type}")

1.2 使用示例

python
# examples/text_processor_example.py
from skills.text_processor import TextProcessorSkill
from claude_code_sdk import SkillContext

# 创建 Skill 实例
skill = TextProcessorSkill()
context = SkillContext()

# 示例 1:基本使用
result = skill.execute(
    {
        "text": "Hello World",
        "operations": [
            {"type": "uppercase"}
        ]
    },
    context
)

print(result.data["processed"])  # "HELLO WORLD"

# 示例 2:多个操作
result = skill.execute(
    {
        "text": "Hello World",
        "operations": [
            {"type": "lowercase"},
            {"type": "remove_spaces"}
        ]
    },
    context
)

print(result.data["processed"])  # "helloworld"

# 示例 3:反转文本
result = skill.execute(
    {
        "text": "Hello World",
        "operations": [
            {"type": "reverse"}
        ]
    },
    context
)

print(result.data["processed"])  # "dlroW olleH"

示例 2:程式碼生成 Skill

2.1 Skill 定義

python
# src/skills/code_generator.py

from typing import Dict, Any
from claude_code_sdk import Skill, SkillContext, SkillResult

class CodeGeneratorSkill(Skill):
    """代码生成 Skill"""

    def __init__(self):
        super().__init__(
            name="code-generator",
            version="1.0.0",
            description="Generate code from specifications"
        )

    def get_parameters_schema(self) -> Dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "language": {
                    "type": "string",
                    "enum": ["python", "javascript", "java", "go"],
                    "description": "Programming language"
                },
                "type": {
                    "type": "string",
                    "enum": ["function", "class", "interface", "enum"],
                    "description": "Code type to generate"
                },
                "name": {
                    "type": "string",
                    "description": "Name of the function/class"
                },
                "description": {
                    "type": "string",
                    "description": "Description of what the code should do"
                },
                "parameters": {
                    "type": "array",
                    "description": "List of parameters",
                    "items": {
                        "type": "object",
                        "properties": {
                            "name": {"type": "string"},
                            "type": {"type": "string"},
                            "default": {"type": "string"}
                        }
                    }
                },
                "return_type": {
                    "type": "string",
                    "description": "Return type"
                }
            },
            "required": ["language", "type", "name", "description"]
        }

    def execute(self, parameters: Dict[str, Any], context: SkillContext) -> SkillResult:
        try:
            language = parameters["language"]
            code_type = parameters["type"]
            name = parameters["name"]
            description = parameters["description"]
            params = parameters.get("parameters", [])
            return_type = parameters.get("return_type", "void")

            # 生成代码
            code = self.generate_code(
                language, code_type, name, description, params, return_type
            )

            return SkillResult(
                success=True,
                data={
                    "language": language,
                    "type": code_type,
                    "name": name,
                    "code": code,
                    "description": description
                }
            )
        except Exception as e:
            return SkillResult(
                success=False,
                error=str(e)
            )

    def generate_code(self, language: str, code_type: str, name: str, description: str, params: list, return_type: str) -> str:
        """生成代码"""
        generators = {
            "python": self.generate_python,
            "javascript": self.generate_javascript,
            "java": self.generate_java,
            "go": self.generate_go
        }
        generator = generators.get(language)
        if not generator:
            raise ValueError(f"Unsupported language: {language}")
        return generator(code_type, name, description, params, return_type)

    def generate_python(self, code_type: str, name: str, description: str, params: list, return_type: str) -> str:
        """生成 Python 代码"""
        param_str = ", ".join([f"{p['name']}: {p['type']}" for p in params])
        if code_type == "function":
            code = f'''def {name}({param_str}) -> {return_type}:
    """
    {description}
    """
    pass
'''
        elif code_type == "class":
            code = f'''class {name}:
    """
    {description}
    """
    def __init__(self{self._init_params(params)}):
        pass
'''
        else:
            raise ValueError(f"Unsupported code type: {code_type}")
        return code

    def generate_javascript(self, code_type: str, name: str, description: str, params: list, return_type: str) -> str:
        """生成 JavaScript 代码"""
        param_str = ", ".join([f"{p['name']}" for p in params])
        if code_type == "function":
            code = f'''/**
 * {description}
 * @param {param_str}
 * @returns {{{return_type}}}
 */
function {name}({param_str}) {{
    // TODO: implement
}}
'''
        elif code_type == "class":
            code = f'''/**
 * {description}
 */
class {name} {{
    constructor({param_str}) {{
        // TODO: implement
    }}
}}
'''
        else:
            raise ValueError(f"Unsupported code type: {code_type}")
        return code

    def generate_java(self, code_type: str, name: str, description: str, params: list, return_type: str) -> str:
        """生成 Java 代码"""
        param_str = ", ".join([f"{p['type']} {p['name']}" for p in params])
        if code_type == "function":
            code = f'''/**
 * {description}
 */
public {return_type} {name}({param_str}) {{
    // TODO: implement
    return null;
}}
'''
        elif code_type == "class":
            code = f'''/**
 * {description}
 */
public class {name} {{
    public {name}({param_str}) {{
        // TODO: implement
    }}
}}
'''
        else:
            raise ValueError(f"Unsupported code type: {code_type}")
        return code

    def generate_go(self, code_type: str, name: str, description: str, params: list, return_type: str) -> str:
        """生成 Go 代码"""
        param_str = ", ".join([f"{p['name']} {p['type']}" for p in params])
        if code_type == "function":
            code = f'''// {description}
func {name}({param_str}) {return_type} {{
    // TODO: implement
    return
}}
'''
        elif code_type == "class":
            code = f'''// {description}
type {name} struct {{
    // TODO: add fields
}}

// New{name} creates a new {name}
func New{name}({param_str}) *{name} {{
    return &{name}{{
        // TODO: initialize fields
    }}
}}
'''
        else:
            raise ValueError(f"Unsupported code type: {code_type}")
        return code

    def _init_params(self, params: list) -> str:
        """生成初始化参数"""
        if not params:
            return ""
        return ", " + ", ".join([p["name"] for p in params])

2.2 使用示例

python
# examples/code_generator_example.py
from skills.code_generator import CodeGeneratorSkill
from claude_code_sdk import SkillContext

# 创建 Skill 实例
skill = CodeGeneratorSkill()
context = SkillContext()

# 示例 1:生成 Python 函数
result = skill.execute(
    {
        "language": "python",
        "type": "function",
        "name": "calculate_sum",
        "description": "Calculate the sum of two numbers",
        "parameters": [
            {"name": "a", "type": "int"},
            {"name": "b", "type": "int"}
        ],
        "return_type": "int"
    },
    context
)

print(result.data["code"])

# 示例 2:生成 JavaScript 类
result = skill.execute(
    {
        "language": "javascript",
        "type": "class",
        "name": "User",
        "description": "User class with name and email",
        "parameters": [
            {"name": "name", "type": "string"},
            {"name": "email", "type": "string"}
        ]
    },
    context
)

print(result.data["code"])

# 示例 3:生成 Java 函数
result = skill.execute(
    {
        "language": "java",
        "type": "function",
        "name": "isValidEmail",
        "description": "Validate email address",
        "parameters": [
            {"name": "email", "type": "String"}
        ],
        "return_type": "boolean"
    },
    context
)

print(result.data["code"])

示例 3:檔案分析 Skill

3.1 Skill 定義

python
# src/skills/file_analyzer.py
from typing import Dict, Any, List
from claude_code_sdk import Skill, SkillContext, SkillResult
import os

class FileAnalyzerSkill(Skill):
    """文件分析 Skill"""

    def __init__(self):
        super().__init__(
            name="file-analyzer",
            version="1.0.0",
            description="Analyze files and directories"
        )

    def get_parameters_schema(self) -> Dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "path": {
                    "type": "string",
                    "description": "Path to file or directory"
                },
                "analysis_type": {
                    "type": "string",
                    "enum": ["structure", "size", "content", "all"],
                    "description": "Type of analysis to perform"
                },
                "recursive": {
                    "type": "boolean",
                    "description": "Analyze recursively for directories",
                    "default": False
                },
                "include_patterns": {
                    "type": "array",
                    "description": "File patterns to include",
                    "items": {"type": "string"}
                },
                "exclude_patterns": {
                    "type": "array",
                    "description": "File patterns to exclude",
                    "items": {"type": "string"}
                }
            },
            "required": ["path"]
        }

    def execute(self, parameters: Dict[str, Any], context: SkillContext) -> SkillResult:
        try:
            path = parameters["path"]
            analysis_type = parameters.get("analysis_type", "all")
            recursive = parameters.get("recursive", False)
            include_patterns = parameters.get("include_patterns", [])
            exclude_patterns = parameters.get("exclude_patterns", [])

            # 检查路径是否存在
            if not os.path.exists(path):
                return SkillResult(
                    success=False,
                    error=f"Path not found: {path}"
                )

            # 执行分析
            if os.path.isfile(path):
                result = self.analyze_file(
                    path, analysis_type, context
                )
            else:
                result = self.analyze_directory(
                    path, analysis_type, recursive,
                    include_patterns, exclude_patterns, context
                )

            return SkillResult(
                success=True,
                data=result
            )
        except Exception as e:
            return SkillResult(
                success=False,
                error=str(e)
            )

    def analyze_file(self, file_path: str, analysis_type: str,
                     context: SkillContext) -> Dict[str, Any]:
        """分析单个文件"""
        result = {
            "type": "file",
            "path": file_path,
            "name": os.path.basename(file_path),
            "extension": os.path.splitext(file_path)[1]
        }

        if analysis_type in ["size", "all"]:
            result["size"] = os.path.getsize(file_path)

        if analysis_type in ["content", "all"]:
            try:
                content = context.read_file(file_path)
                result["content"] = {
                    "lines": len(content.split('\n')),
                    "characters": len(content),
                    "words": len(content.split())
                }
            except Exception as e:
                result["content"] = {"error": str(e)}

        return result

    def analyze_directory(self, dir_path: str, analysis_type: str,
                         recursive: bool, include_patterns: List[str],
                         exclude_patterns: List[str], context: SkillContext) -> Dict[str, Any]:
        """分析目录"""
        result = {
            "type": "directory",
            "path": dir_path,
            "name": os.path.basename(dir_path)
        }

        # 收集文件
        files = []
        directories = []
        for item in os.listdir(dir_path):
            item_path = os.path.join(dir_path, item)
            if os.path.isfile(item_path):
                if self.should_include(item, include_patterns, exclude_patterns):
                    files.append(item_path)
            elif os.path.isdir(item_path) and recursive:
                directories.append(item_path)

        # 分析文件
        file_analyses = []
        for file_path in files:
            file_analysis = self.analyze_file(file_path, analysis_type, context)
            file_analyses.append(file_analysis)

        result["files"] = file_analyses
        result["file_count"] = len(files)

        # 分析子目录
        directory_analyses = []
        for dir_path in directories:
            dir_analysis = self.analyze_directory(
                dir_path, analysis_type, recursive,
                include_patterns, exclude_patterns, context
            )
            directory_analyses.append(dir_analysis)

        result["directories"] = directory_analyses
        result["directory_count"] = len(directories)

        # 计算总大小
        if analysis_type in ["size", "all"]:
            total_size = sum(f.get("size", 0) for f in file_analyses)
            for dir_analysis in directory_analyses:
                total_size += dir_analysis.get("total_size", 0)
            result["total_size"] = total_size

        return result

    def should_include(self, filename: str, include_patterns: List[str],
                      exclude_patterns: List[str]) -> bool:
        """检查文件是否应该包含"""
        # 检查排除模式
        for pattern in exclude_patterns:
            if self.match_pattern(filename, pattern):
                return False

        # 检查包含模式
        if not include_patterns:
            return True

        for pattern in include_patterns:
            if self.match_pattern(filename, pattern):
                return True

        return False

    def match_pattern(self, filename: str, pattern: str) -> bool:
        """匹配文件模式"""
        import fnmatch
        return fnmatch.fnmatch(filename, pattern)

3.2 使用示例

python
# examples/file_analyzer_example.py
from skills.file_analyzer import FileAnalyzerSkill
from claude_code_sdk import SkillContext

# 创建 Skill 实例
skill = FileAnalyzerSkill()
context = SkillContext()

# 示例 1:分析单个文件
result = skill.execute(
    {
        "path": "src/main.py",
        "analysis_type": "all"
    },
    context
)

print(result.data)

# 示例 2:分析目录
result = skill.execute(
    {
        "path": "src",
        "analysis_type": "size",
        "recursive": True
    },
    context
)

print(f"Total size: {result.data['total_size']} bytes")

# 示例 3:分析特定文件类型
result = skill.execute(
    {
        "path": "src",
        "analysis_type": "structure",
        "recursive": True,
        "include_patterns": ["*.py"],
        "exclude_patterns": ["__pycache__", "*.pyc"]
    },
    context
)

print(f"Python files found: {result.data['file_count']}")

示例 4:測試生成 Skill

4.1 Skill 定義

python
# src/skills/test_generator.py

from typing import Dict, Any
from claude_code_sdk import Skill, SkillContext, SkillResult

class TestGeneratorSkill(Skill):
    """测试生成 Skill"""

    def __init__(self):
        super().__init__(
            name="test-generator",
            version="1.0.0",
            description="Generate unit tests from code"
        )

    def get_parameters_schema(self) -> Dict[str, Any]:
        return {
            "type": "object",
            "properties": {
                "file_path": {
                    "type": "string",
                    "description": "Path to the source file"
                },
                "test_framework": {
                    "type": "string",
                    "enum": ["pytest", "unittest", "jest"],
                    "description": "Test framework to use"
                },
                "include_edge_cases": {
                    "type": "boolean",
                    "description": "Include edge case tests",
                    "default": True
                },
                "include_mocks": {
                    "type": "boolean",
                    "description": "Include mock objects",
                    "default": False
                }
            },
            "required": ["file_path"]
        }

    def execute(self, parameters: Dict[str, Any], context: SkillContext) -> SkillResult:
        try:
            file_path = parameters["file_path"]
            test_framework = parameters.get("test_framework", "pytest")
            include_edge_cases = parameters.get("include_edge_cases", True)
            include_mocks = parameters.get("include_mocks", False)

            # 读取源文件
            source_code = context.read_file(file_path)

            # 分析代码
            functions = self.analyze_functions(source_code)

            # 生成测试
            test_code = self.generate_tests(
                file_path, functions, test_framework, include_edge_cases, include_mocks
            )

            return SkillResult(
                success=True,
                data={
                    "source_file": file_path,
                    "test_framework": test_framework,
                    "functions_tested": len(functions),
                    "test_code": test_code
                }
            )
        except Exception as e:
            return SkillResult(
                success=False,
                error=str(e)
            )

    def analyze_functions(self, source_code: str) -> list:
        """分析源代码中的函数"""
        import re
        functions = []
        pattern = r'def\s+(\w+)\s*\(([^)]*)\):'
        for match in re.finditer(pattern, source_code):
            function_name = match.group(1)
            params = match.group(2).strip()
            functions.append({
                "name": function_name,
                "params": [p.strip() for p in params.split(',') if p.strip()]
            })
        return functions

    def generate_tests(self, file_path: str, functions: list, test_framework: str, include_edge_cases: bool, include_mocks: bool) -> str:
        """生成测试代码"""
        generators = {
            "pytest": self.generate_pytest,
            "unittest": self.generate_unittest,
            "jest": self.generate_jest
        }
        generator = generators.get(test_framework)
        if not generator:
            raise ValueError(f"Unsupported test framework: {test_framework}")
        return generator(file_path, functions, include_edge_cases, include_mocks)

    def generate_pytest(self, file_path: str, functions: list, include_edge_cases: bool, include_mocks: bool) -> str:
        """生成 pytest 测试"""
        import os
        module_name = os.path.splitext(os.path.basename(file_path))[0]
        test_code = f'''import pytest
from {module_name} import {', '.join([f['name'] for f in functions])}

'''
        for func in functions:
            test_code += f'''class Test{func['name'].capitalize()}:
    """Test cases for {func['name']}"""

    def test_{func['name']}_basic(self):
        """Basic test for {func['name']}"""
        # TODO: implement test
        pass

'''
            if include_edge_cases:
                test_code += f'''    def test_{func['name']}_edge_cases(self):
        """Edge case tests for {func['name']}"""
        # TODO: implement edge case tests
        pass

'''
            if include_mocks:
                test_code += f'''    def test_{func['name']}_with_mocks(self):
        """Test {func['name']} with mocks"""
        # TODO: implement tests with mocks
        pass

'''
        return test_code

    def generate_unittest(self, file_path: str, functions: list, include_edge_cases: bool, include_mocks: bool) -> str:
        """生成 unittest 测试"""
        import os
        module_name = os.path.splitext(os.path.basename(file_path))[0]
        test_code = f'''import unittest
from {module_name} import {', '.join([f['name'] for f in functions])}

class Test{module_name.capitalize()}(unittest.TestCase):
    """Test cases for {module_name}"""

'''
        for func in functions:
            test_code += f'''    def test_{func['name']}(self):
        """Test {func['name']}"""
        # TODO: implement test
        pass

'''
            if include_edge_cases:
                test_code += f'''    def test_{func['name']}_edge_cases(self):
        """Test {func['name']} edge cases"""
        # TODO: implement edge case tests
        pass

'''
        test_code += '''if __name__ == '__main__':
    unittest.main()
'''
        return test_code

    def generate_jest(self, file_path: str, functions: list, include_edge_cases: bool, include_mocks: bool) -> str:
        """生成 Jest 测试"""
        import os
        module_name = os.path.splitext(os.path.basename(file_path))[0]
        test_code = f'''const {{ {', '.join([f['name'] for f in functions])} }} = require('./{module_name}');

'''
        for func in functions:
            test_code += f'''describe('{func['name']}', () => {{
    test('basic test', () => {{
        // TODO: implement test
    }});

'''
            if include_edge_cases:
                test_code += f'''    test('edge cases', () => {{
        // TODO: implement edge case tests
    }});

'''
            if include_mocks:
                test_code += f'''    test('with mocks', () => {{
        // TODO: implement tests with mocks
    }});

'''
            test_code += '});\n'
        return test_code

4.2 使用示例

python
# examples/test_generator_example.py

from skills.test_generator import TestGeneratorSkill
from claude_code_sdk import SkillContext

# 创建 Skill 实例
skill = TestGeneratorSkill()
context = SkillContext()

# 示例 1:生成 pytest 测试
result = skill.execute(
    {
        "file_path": "src/utils.py",
        "test_framework": "pytest",
        "include_edge_cases": True,
        "include_mocks": False
    },
    context
)

print(result.data["test_code"])

# 示例 2:生成 unittest 测试
result = skill.execute(
    {
        "file_path": "src/utils.py",
        "test_framework": "unittest"
    },
    context
)

print(result.data["test_code"])

# 示例 3:生成 Jest 测试
result = skill.execute(
    {
        "file_path": "src/utils.js",
        "test_framework": "jest"
    },
    context
)

print(result.data["test_code"])

總結

透過這些示例,我們可以看到如何開發不同型別的 Skills:

  1. 文字處理 Skill:展示基本的文字轉換操作
  2. 程式碼生成 Skill:展示如何根據規範生成程式碼
  3. 檔案分析 Skill:展示如何分析檔案和目錄結構
  4. 測試生成 Skill:展示如何自動生成測試程式碼

這些示例可以作為開發自己 Skills 的起點和參考。

在下一節中,我們將探討 Skills 的測試與除錯方法。

基于 MIT 许可发布 | 永久导航