第 19 期 | 社区生态与 Skill Marketplace 贡献指南

更新于 2026/4/15

好的,这是为 Hermes Agent 教程撰写的第 19 期文章。


副标题:深入了解 Open Source 玩法:如何标准化封装并向 agentskills.io 商城发布自己开发的超酷开源 Skill。

学习目标

欢迎来到 Hermes Agent 教程的第 19 期!在本期中,我们将从 Skill 的“使用者”转变为“创造者”和“贡献者”。一个强大 Agent 的真正威力不仅在于其核心框架,更在于其繁荣的生态系统。本章将带领你深入了解 Hermes Agent 的社区生态,并手把手教你如何将自己开发的 Skill 标准化打包,最终发布到官方的 Skill Marketplace (agentskills.io),与全球的开发者共享你的智慧。

完成本期学习后,你将能够:

  1. 理解 Skill Marketplace 的核心价值:明白为什么一个标准化的 Skill 分发平台对整个生态至关重要。
  2. 掌握可发布 Skill 的标准结构:学习一个生产级 Skill 包所应包含的所有元素,特别是 skill.yaml 清单文件。
  3. 精通 skill.yaml 的配置:深入了解清单文件中每个字段的含义,包括元数据、入口点、依赖、参数和权限声明。
  4. 实战打包与发布流程:亲手将一个示例 Skill 从代码封装成可分发的 .tar.gz 包,并使用 hermes CLI 工具将其发布到 Marketplace。
  5. 了解社区贡献的最佳实践:学习如何编写清晰的文档、选择合适的许可证,让你的 Skill 更易被社区接受和使用。

核心概念讲解

在动手之前,我们需要理解几个支撑 Skill Marketplace 运作的核心概念。这不仅仅是技术细节,更是保证生态系统健康、有序发展的基石。

1. 为什么需要 Skill Marketplace?

想象一下,如果没有 App Store 或 PyPI,我们如何寻找和安装软件?我们可能需要去各种 GitHub 仓库,手动处理复杂的依赖关系,甚至面临安全风险。Skill Marketplace (我们虚构的官方商城为 agentskills.io) 解决了同样的问题:

  • 发现与分发 (Discovery & Distribution):为开发者提供一个中心化的平台来展示他们的作品,也让用户能轻松地搜索、发现和一键安装所需的 Skill。
  • 标准化与质量控制 (Standardization & Quality Control):通过定义一套标准的打包规范(例如,必须包含 skill.yaml),确保所有 Skill 的结构一致,易于 Agent 核心系统加载和管理。同时,发布前的审核流程可以保障 Skill 的质量和安全性。
  • 版本管理 (Versioning):允许开发者迭代和更新他们的 Skill,用户也可以选择安装特定版本,或者平滑升级,避免了因 Skill 更新导致的兼容性问题。
  • 依赖管理 (Dependency Management):Marketplace 可以自动处理 Skill 所需的 Python 库依赖,用户安装 Skill 时,Agent 会自动安装 requirements.txt 中指定的库,极大简化了环境配置。
  • 社区激励 (Community Incentive):开发者的贡献被看见、被使用、被点赞,这本身就是一种强大的激励。优秀的 Skill 开发者可以在社区中建立声誉,形成良性循环。

2. 可发布 Skill 的解剖学 (Anatomy of a Publishable Skill)

一个准备发布到 Marketplace 的 Skill 不再是你在本地开发时的一两个 Python 文件,而是一个结构严谨、信息完备的软件包。一个标准的 Skill 包通常包含以下文件结构:

my_awesome_skill/
├── __init__.py         # Skill 的核心逻辑与入口点
├── skill.yaml          # [核心] Skill 的清单文件,描述一切元数据
├── requirements.txt    # Python 依赖列表
├── README.md           # 详细的说明文档
├── LICENSE             # 开源许可证文件
└── icon.png            # (可选) 在 Marketplace 中显示的图标

其中,skill.yaml 是整个包的灵魂,它向 Hermes Agent 和 Marketplace 系统声明了关于这个 Skill 的一切。

3. skill.yaml 清单文件深度解析

skill.yaml 使用 YAML 格式,这是一种人类可读的数据序列化标准。它告诉系统如何加载、配置和执行你的 Skill。一个完整的 skill.yaml 文件可能包含以下字段:

# 基础元数据 (Basic Metadata)
name: "GitHubRepoInsights"
version: "1.0.0" # 遵循语义化版本 (Semantic Versioning)
author: "Your Name <[email protected]>"
description: "A skill to fetch and display key statistics (stars, forks, open issues) for a given GitHub repository."

# 执行配置 (Execution Configuration)
entry_point: "GitHubRepoInsightsSkill" # 在 __init__.py 中定义的 Skill 类名

# 依赖管理 (Dependency Management)
dependencies:
  python: ">=3.8"
  # requirements.txt 会被自动读取,这里是为更复杂的系统级依赖预留
  system: [] 

# 参数定义 (Parameters Definition)
# 定义 Skill 在执行时可以接收的参数,这对于 UI 生成和 API 调用至关重要
parameters:
  - name: "repo_url"
    type: "string"
    description: "The full URL of the public GitHub repository (e.g., https://github.com/torvalds/linux)."
    required: true
    default: ""

# 权限声明 (Permissions Declaration)
# 明确声明 Skill 需要的权限,增强安全性
permissions:
  - "network.http_request" # 声明需要访问外部网络的权限
  - "filesystem.read"      # (示例) 声明需要读取本地文件的权限
  • name: Skill 的唯一标识符,通常使用驼峰式命名法 (CamelCase)。
  • version: 必须遵循 SemVer (Semantic Versioning) 规范(MAJOR.MINOR.PATCH)。例如 1.0.0。这对于依赖管理和更新至关重要。
  • author & description: 不言而喻,作者信息和功能简介。
  • entry_point: 指定 __init__.py 文件中,继承自 BaseSkill 的主类名。Agent 会通过这个入口点来实例化你的 Skill。
  • dependencies: 声明对 Python 版本或其他系统工具的依赖。更常见的 Python 库依赖应放在 requirements.txt 中。
  • parameters: 这是让你的 Skill 变得动态和可配置的关键。这里定义的参数可以在 Agent 的 UI 中自动生成输入框,或者在通过 API 调用 Skill 时作为必需的参数。每个参数都包含 name, type, description, required 等属性。
  • permissions: 安全是第一位的。在这里明确声明你的 Skill 需要什么权限。比如,如果你的 Skill 需要访问互联网,就必须声明 network.http_request。在安装时,用户会被提示授权这些权限,这给了用户最终的控制权。

💻 实战演示

现在,让我们从零开始,创建一个名为 GitHubRepoInsights 的 Skill,它能够接收一个 GitHub 仓库 URL,然后返回该仓库的 Star 数、Fork 数和 Open Issues 数。我们将完整地走过开发、打包和发布的全部流程。

第 1 步:创建 Skill 项目结构

首先,在你的工作目录下创建 Skill 的文件夹和必要的文件。

# 创建主目录
mkdir github_repo_insights

# 进入目录
cd github_repo_insights

# 创建必要的文件
touch __init__.py skill.yaml requirements.txt README.md LICENSE

现在你的目录看起来是这样的:

github_repo_insights/
├── __init__.py
├── LICENSE
├── README.md
├── requirements.txt
└── skill.yaml

第 2 步:编写 Skill 核心逻辑 (__init__.py)

打开 __init__.py 文件,我们将在这里编写与 GitHub API 交互的 Python 代码。

# __init__.py

import requests
import json
from hermes_agent.skills import BaseSkill, SkillResult

class GitHubRepoInsightsSkill(BaseSkill):
    """
    A skill to fetch and display key statistics for a GitHub repository.
    """

    def __init__(self):
        # 调用父类的构造函数
        super().__init__()
        # 设置 GitHub API 的基础 URL
        self.api_base_url = "https://api.github.com/repos/"

    def _parse_repo_path(self, repo_url: str) -> str or None:
        """
        Helper function to parse 'owner/repo' from a full GitHub URL.
        Example: "https://github.com/torvalds/linux" -> "torvalds/linux"
        """
        try:
            parts = repo_url.strip().rstrip('/').split('/')
            if len(parts) >= 2 and parts[-2] and parts[-1]:
                return f"{parts[-2]}/{parts[-1]}"
            return None
        except Exception:
            return None

    def execute(self, parameters: dict) -> SkillResult:
        """
        The main execution method for the skill.
        """
        repo_url = parameters.get("repo_url")
        if not repo_url:
            return SkillResult(
                success=False,
                message="Error: 'repo_url' parameter is missing."
            )

        repo_path = self._parse_repo_path(repo_url)
        if not repo_path:
            return SkillResult(
                success=False,
                message=f"Error: Invalid GitHub repository URL format: {repo_url}"
            )

        # 构造完整的 API 请求 URL
        api_url = f"{self.api_base_url}{repo_path}"

        try:
            # 发起网络请求,需要 network.http_request 权限
            self.logger.info(f"Requesting data from: {api_url}")
            response = requests.get(api_url, timeout=10)
            
            # 检查请求是否成功
            response.raise_for_status() 

            data = response.json()

            # 提取所需信息
            stars = data.get('stargazers_count', 'N/A')
            forks = data.get('forks_count', 'N/A')
            open_issues = data.get('open_issues_count', 'N/A')
            
            # 格式化输出
            result_message = (
                f"📊 GitHub Repo Insights for '{repo_path}':\n"
                f"⭐ Stars: {stars}\n"
                f"🍴 Forks: {forks}\n"
                f"🐞 Open Issues: {open_issues}"
            )
            
            return SkillResult(
                success=True,
                message=result_message,
                data={
                    "stars": stars,
                    "forks": forks,
                    "open_issues": open_issues
                }
            )

        except requests.exceptions.HTTPError as e:
            error_msg = f"Error fetching data from GitHub API: {e.response.status_code} {e.response.reason}"
            if e.response.status_code == 404:
                error_msg = f"Repository '{repo_path}' not found. Please check the URL."
            self.logger.error(error_msg)
            return SkillResult(success=False, message=error_msg)
        except Exception as e:
            self.logger.error(f"An unexpected error occurred: {e}")
            return SkillResult(success=False, message=f"An unexpected error occurred: {str(e)}")

代码要点

  • 我们继承了 BaseSkill 并实现了 execute 方法。
  • execute 方法从 parameters 字典中获取 repo_url
  • 我们添加了一个辅助函数 _parse_repo_path 来从完整的 URL 中提取 owner/repo 部分。
  • 使用了 requests 库来调用 GitHub API,这正是我们需要在 requirements.txt 中声明的依赖。
  • 返回一个 SkillResult 对象,其中包含成功状态、给用户看的消息 (message) 和可供其他 Skill 使用的结构化数据 (data)。
  • 包含了详细的错误处理和日志记录,这是一个良好实践。

第 3 步:定义依赖与清单文件

  1. requirements.txt: 我们的代码用到了 requests 库,所以编辑 requirements.txt 文件,添加这一行:

    requests>=2.25.0
    
  2. skill.yaml: 现在,让我们来填写至关重要的清单文件。编辑 skill.yaml

    name: "GitHubRepoInsights"
    version: "1.0.0"
    author: "Hermes AI Labs <[email protected]>"
    description: "A skill to fetch and display key statistics (stars, forks, open issues) for a given public GitHub repository."
    
    entry_point: "GitHubRepoInsightsSkill"
    
    dependencies:
      python: ">=3.8"
    
    parameters:
      - name: "repo_url"
        type: "string"
        description: "The full URL of the public GitHub repository (e.g., https://github.com/torvalds/linux)."
        required: true
    
    permissions:
      - "network.http_request"
    

    这个文件完美地描述了我们的 Skill:它的身份、入口、参数和所需权限。

第 4 步:完善文档和许可证

  1. README.md: 一个好的 README 文件能让你的 Skill 更受欢迎。

    # GitHub Repo Insights Skill
    
    This skill provides a quick way to get essential statistics for any public GitHub repository.
    
    ## Features
    
    - Fetches Star count
    - Fetches Fork count
    - Fetches Open Issue count
    
    ## Usage
    
    To use this skill, simply provide the full URL of a public GitHub repository.
    
    **Example Input:**
    `https://github.com/facebook/react`
    
    **Example Output:**
    

    📊 GitHub Repo Insights for 'facebook/react': ⭐ Stars: 215000 🍴 Forks: 45000 🐞 Open Issues: 1200

    
    
  2. LICENSE: 选择一个开源许可证非常重要。MIT 许可证是一个流行且宽松的选择。将 MIT 许可证的文本(可以从网上轻松找到)复制到 LICENSE 文件中。

第 5 步:打包 Skill

所有文件都准备就绪了。现在我们需要将 github_repo_insights 文件夹打包成一个 .tar.gz 文件,这是 Marketplace 接受的标准格式。文件名应遵循 skill_name-version.tar.gz 的格式。

回到 github_repo_insights 的上一级目录,执行以下命令:

# 确保你在 github_repo_insights 文件夹的外面
# 将文件夹打包成 github_repo_insights-1.0.0.tar.gz
tar -czvf github_repo_insights-1.0.0.tar.gz github_repo_insights/

执行后,你会看到一个名为 github_repo_insights-1.0.0.tar.gz 的文件,这就是我们准备发布的 Skill 包。

第 6 步:发布到 Skill Marketplace

最后一步是使用 Hermes Agent 的命令行工具 hermes 来发布我们的 Skill。

  1. 登录开发者账户: 首先,你需要在 agentskills.io 网站上注册一个开发者账户,并生成一个 API Key。然后通过 CLI 登录。

    hermes login
    

    终端会提示你输入从网站获取的 API Key。

    Enter your API Key from agentskills.io: [your_api_key_here]
    Login successful. Your credentials have been saved.
    
  2. 发布 Skill: 使用 hermes skills publish 命令并指定你的包文件路径。

    hermes skills publish github_repo_insights-1.0.0.tar.gz
    

    如果一切顺利,你会看到类似下面的输出:

    Verifying package integrity... [OK]
    Parsing skill.yaml manifest... [OK]
    Uploading package to agentskills.io... [OK]
    
    🚀 Success! Your skill 'GitHubRepoInsights' (v1.0.0) has been submitted for review.
    You will receive an email notification once the review process is complete.
    Submission ID: skill-sub-xxxxxxxxxxxx
    

到此为止,你已经成功地将自己开发的 Skill 提交到了官方 Marketplace!接下来就是等待社区管理员的审核。审核通过后,全球的 Hermes Agent 用户就都能在 Marketplace 中找到并安装你的杰作了。

涉及命令

# 创建项目目录和文件
mkdir github_repo_insights
cd github_repo_insights
touch __init__.py skill.yaml requirements.txt README.md LICENSE

# 打包 Skill (在 github_repo_insights 的上级目录执行)
tar -czvf github_repo_insights-1.0.0.tar.gz github_repo_insights/

# 登录 Hermes 开发者账户
hermes login

# 发布 Skill 包
hermes skills publish github_repo_insights-1.0.0.tar.gz

要点回顾

  • 生态系统是核心:Skill Marketplace 是连接开发者和用户的桥梁,是 Hermes Agent 生态繁荣的关键。
  • skill.yaml 是灵魂:这个清单文件定义了 Skill 的一切,是 Agent 理解和运行你的 Skill 的唯一依据。务必保证其内容的准确和完整。
  • 结构标准化:遵循 __init__.py, skill.yaml, requirements.txt, README.md, LICENSE 的标准文件结构,这是一种社区通用语言。
  • 安全第一:通过 permissions 字段明确声明 Skill 所需的权限,尊重用户的隐私和安全。
  • 文档为王:清晰的 README.md 是让你的 Skill 被他人理解和使用的最有效方式。
  • hermes CLI 是你的工具:熟练使用 hermes loginhermes skills publish 命令来与 Marketplace 交互。

恭喜你完成了这重要的一步!成为开源贡献者不仅能提升你的技术能力,更能让你在社区中找到归属感和成就感。期待在 agentskills.io 上看到你开发的更多超酷 Skill!

参考资料