第十章:技能系统与自定义技能

技能系统概述

技能(Skill)是 Hermes Agent 的能力扩展单元。如果说工具(Tool)是 Agent 的"双手",那么技能就是 Agent 的"专业技能包"——它是一组预定义的指令、工具和知识库的集合,使 Agent 能够高效完成特定领域的任务。

技能的核心特性

  • 领域专精:每个技能聚焦于特定领域(如代码审查、数据库管理、DevOps)
  • 可复用性:技能可以在不同项目间共享和复用
  • 版本管理:技能支持版本控制,可以安全地升级和回退
  • 依赖管理:技能可以声明对其他技能或工具的依赖关系
  • 隔离执行:技能在独立的上下文中运行,互不干扰

技能生命周期

发现 → 安装 → 配置 → 激活 → 执行 → 更新 → 停用 → 卸载
阶段说明操作方式
发现浏览技能商店或社区仓库hermes skill search <keyword>
安装下载技能到本地环境hermes skill install <name>
配置设置技能参数和凭据编辑技能配置文件
激活在当前会话中启用技能hermes skill activate <name>
执行使用技能完成任务自动触发或手动调用
更新升级到新版本hermes skill update <name>
停用临时禁用但不删除hermes skill deactivate <name>
卸载完全移除技能hermes skill uninstall <name>

技能商店浏览与安装

技能商店(Skill Store)是 Hermes Agent 的技能市场,开发者可以在这里发布和分享技能。

# 浏览技能商店
hermes skill search code-review
hermes skill search "database migration"

# 查看技能详情
hermes skill info code-review
# 输出示例:
#   名称: code-review
#   版本: 2.1.0
#   作者: hermes-team
#   描述: 自动代码审查,支持多种语言和规则
#   下载量: 12,345
#   评分: 4.8/5.0

# 安装技能
hermes skill install code-review

# 查看已安装的技能
hermes skill list
# 输出示例:
#   已安装技能:
#   ├── code-review (v2.1.0) [已激活]
#   ├── database-ops (v1.3.0) [已激活]
#   └── deploy-helper (v0.9.0) [未激活]

# 激活/停用技能
hermes skill activate code-review
hermes skill deactivate database-ops

技能开发环境搭建

开发自定义技能需要准备好以下环境:

# .hermes/skill-dev.yaml - 技能开发配置
skill_development:
  # 技能项目目录
  workspace: "./my-skills"

  # 脚手架模板
  template:
    default: "basic"        # 基础模板
    advanced: "full"        # 完整模板(含测试和文档)

  # 测试配置
  testing:
    sandbox:
      enabled: true
      timeout: 30
    mock_tools:
      - read_file
      - write_file
      - execute_shell

创建技能项目

# 使用脚手架创建技能项目
hermes skill create my-code-review --template full

# 项目结构
my-code-review/
├── manifest.json          # 技能清单文件
├── skill.yaml             # 技能配置
├── main.py                # 技能代码主文件
├── tools/                 # 自定义工具
│   ├── __init__.py
│   └── analyzers.py
├── prompts/               # 提示词模板
│   ├── review.md
│   └── summary.md
├── tests/                 # 测试文件
│   ├── test_manifest.json
│   └── test_analyzer.py
└── README.md              # 技能文档

创建自定义技能:manifest.json 与代码结构

manifest.json — 技能清单

技能清单是技能的"身份证",包含了技能的元数据和配置信息。

{
  "name": "code-review",
  "version": "1.0.0",
  "description": "自动代码审查技能,支持多种编程语言和自定义规则",
  "author": "your-username",
  "license": "MIT",

  "entry_point": "main.py",
  "entry_function": "CodeReviewSkill",

  "dependencies": {
    "skills": [],
    "tools": ["read_file", "search_file", "git_diff"],
    "python_packages": ["pylint", "flake8", "mypy"]
  },

  "permissions": {
    "filesystem": {
      "read": ["/workspace"],
      "write": ["/workspace/.reports"]
    },
    "network": {
      "enabled": false
    },
    "shell": {
      "commands": ["python", "npm", "git"]
    }
  },

  "config": {
    "max_files_per_review": 20,
    "default_language": "python",
    "severity_levels": ["error", "warning", "suggestion"]
  },

  "hooks": {
    "on_install": "scripts/post_install.py",
    "on_uninstall": "scripts/cleanup.py"
  }
}

技能主代码结构

# main.py - 技能核心实现
from hermes.skill import BaseSkill, SkillContext, SkillResult
from typing import List, Dict, Any

class CodeReviewSkill(BaseSkill):
    """代码审查技能"""

    name = "code-review"
    version = "1.0.0"

    async def initialize(self, context: SkillContext):
        """技能初始化:加载配置和依赖"""
        self.config = context.config
        self.max_files = self.config.get("max_files_per_review", 20)
        self.review_history = []
        print(f"[技能] 代码审查技能已初始化,最大审查文件数: {self.max_files}")

    async def execute(self, params: Dict[str, Any]) -> SkillResult:
        """技能主执行逻辑"""
        files = params.get("files", [])
        language = params.get("language", "python")

        if not files:
            return SkillResult(success=False, error="未指定待审查文件")

        results = []
        for file_path in files[:self.max_files]:
            # 读取文件内容
            content = await self.tools.read_file(path=file_path)

            # 执行代码分析
            analysis = await self._analyze_code(
                content=content,
                language=language,
                file_path=file_path
            )

            results.append(analysis)

        # 生成审查报告
        report = self._generate_report(results)

        return SkillResult(success=True, data={
            "report": report,
            "issues_found": sum(r["issue_count"] for r in results),
            "files_reviewed": len(results)
        })

    async def _analyze_code(self, content: str, language: str, file_path: str) -> Dict:
        """执行具体的代码分析"""
        issues = []

        # 安全检查
        if "eval(" in content or "exec(" in content:
            issues.append({
                "type": "security",
                "severity": "error",
                "message": f"检测到动态执行函数: {file_path}"
            })

        # 风格检查(通过 Shell 工具调用外部 linter)
        if language == "python":
            lint_result = await self.tools.execute_shell(
                command=f"flake8 --max-line-length=100 {file_path}"
            )
            issues.extend(self._parse_lint_output(lint_result))

        return {
            "file": file_path,
            "issue_count": len(issues),
            "issues": issues
        }

    def _generate_report(self, results: List[Dict]) -> str:
        """生成格式化审查报告"""
        total_issues = sum(r["issue_count"] for r in results)
        report = f"# 代码审查报告

"
        report += f"## 概览
"
        report += f"- 审查文件数: {len(results)}
"
        report += f"- 发现问题数: {total_issues}

"

        for result in results:
            if result["issues"]:
                report += f"## {result['file']}
"
                for issue in result["issues"]:
                    report += f"- [{issue['severity'].upper()}] {issue['message']}
"
                report += "
"

        return report

技能测试与调试

# tests/test_code_review.py
import pytest
from your_skill.main import CodeReviewSkill

@pytest.fixture
async def skill():
    s = CodeReviewSkill()
    await s.initialize(mock_context())
    return s

@pytest.mark.asyncio
async def test_security_check(skill):
    """测试安全检查功能"""
    code = """
def dangerous():
    result = eval("print('hello')")
    return result
"""
    analysis = await skill._analyze_code(
        content=code,
        language="python",
        file_path="test.py"
    )
    assert analysis["issue_count"] > 0
    assert any(i["type"] == "security" for i in analysis["issues"])

@pytest.mark.asyncio
async def test_clean_code(skill):
    """测试无问题的代码"""
    code = """
def add(a: int, b: int) -> int:
    return a + b
"""
    analysis = await skill._analyze_code(
        content=code,
        language="python",
        file_path="test.py"
    )
    assert analysis["issue_count"] == 0
# 运行技能测试
hermes skill test my-code-review

# 调试模式运行技能
hermes skill run my-code-review --debug

# 查看技能运行日志
hermes skill logs my-code-review

实战:创建一个"代码审查"技能

下面我们将上述代码整合为一个完整的代码审查技能。

步骤 1:完成技能配置

# skill.yaml
name: code-review
version: 1.0.0
description: 智能代码审查技能,支持安全扫描、风格检查和最佳实践建议

settings:
  # 自定义审查规则
  rules:
    python:
      max_line_length: 100
      check_security: true
      check_style: true
      check_performance: true
    javascript:
      max_line_length: 120
      check_security: true
      check_async: true

  # 报告输出配置
  report:
    format: "markdown"         # markdown / json / html
    output_dir: ".reviews"
    auto_save: true

步骤 2:注册并激活技能

# 在本地注册技能
hermes skill register ./my-code-review

# 激活技能
hermes skill activate code-review

# 验证技能是否正常运行
hermes skill invoke code-review --params '{"files": ["src/main.py"], "language": "python"}'

步骤 3:在日常工作中使用技能

# 在 Agent 会话中自动触发代码审查
hermes-agent "审查当前分支的代码变更"

# Agent 自动调用 code-review 技能
# 输出审查结果

# 或者直接调用技能
hermes skill run code-review --params '{
  "files": ["api/handler.py", "models/user.py"],
  "language": "python"
}'

通过技能系统,Hermes Agent 的能力可以得到无限扩展。无论是代码审查、数据库管理、自动化部署还是文档生成,都可以通过创建对应的技能来实现。技能的模块化设计使得团队可以共享和积累最佳实践,逐步构建起属于自己团队的 AI 辅助开发能力体系。

这是 Hermes Agent 进阶技巧系列的最后一章。通过这五章的学习,你已经掌握了工具链、沙箱安全、消息网关、语音多模态和技能系统等核心进阶功能。希望这些知识能帮助你在实际项目中充分发挥 Hermes Agent 的潜力。