深度拆解 HermesAgent(三):工具注册与技能系统 —— 40+ 工具和 400+ 技能的组织之道

系列导读:本文是 HermesAgent 深度拆解系列 的第三篇。我们将深入探讨 HermesAgent 的两个核心支柱:极简而强大的工具注册系统,以及灵活可扩展的技能生态系统

上一篇闭环学习系统深度解析 | 下一篇多终端后端与 Gateway 网关


一、工具系统:从混乱到秩序

大多数 Agent 项目的工具管理都面临一个难题:工具越来越多,代码越来越乱

常见的反模式:

  • 工具散落在各个文件,难以查找
  • 添加新工具需要修改多处代码
  • 工具间缺乏统一的安全策略
  • 难以控制哪些工具对哪些用户可用

HermesAgent 的解决方案是一个中心化、声明式的工具注册系统。


二、极简注册表设计

核心理念:一个函数搞定

# tools/registry.py
from typing import Dict, Callable, List

class ToolRegistry:
    def __init__(self):
        self._tools: Dict[str, Callable] = {}
        self._schemas: Dict[str, dict] = {}
    
    def register(self, name: str, func: Callable, schema: dict = None):
        """一行代码注册一个工具"""
        self._tools[name] = func
        if schema:
            self._schemas[name] = schema
    
    def execute(self, name: str, **kwargs):
        if name not in self._tools:
            raise ValueError(f"Tool '{name}' not registered")
        return self._tools[name](**kwargs)

使用示例

# tools/web_search.py
from tools.registry import registry

def web_search(query: str, max_results: int = 5):
    """执行网络搜索"""
    # 实现搜索逻辑
    return search_results

# 注册!就这一行
registry.register("web_search", web_search, {
    "type": "function",
    "description": "搜索网络获取信息",
    "parameters": {...}
})

自动发现机制

更妙的是:不需要手动导入!系统会自动发现所有工具:

# tools/__init__.py
import os
import importlib.util

def discover_tools():
    """自动发现并加载所有工具"""
    tools_dir = os.path.dirname(__file__)
    
    for filename in os.listdir(tools_dir):
        if filename.endswith('.py') and filename != '__init__.py':
            module_path = os.path.join(tools_dir, filename)
            module_name = filename[:-3]
            
            spec = importlib.util.spec_from_file_location(module_name, module_path)
            module = importlib.util.module_from_spec(spec)
            spec.loader.exec_module(module)

启动时自动扫描 tools/ 目录下所有 .py 文件,执行其中的 registry.register() 调用。零配置,零手动导入


三、工具集(Toolset)分组

40+ 个工具如果平铺直叙,用户很难找到想要的。HermesAgent 采用语义分组

# toolsets.py
TOOLSETS = {
    "web": ["web_search", "http_request", "url_fetch"],
    "terminal": ["bash", "powershell", "zsh"],
    "file": ["read_file", "write_file", "list_directory"],
    "browser": ["browse", "click", "type", "navigate"],
    "code": ["execute_python", "execute_node", "compile_code"],
    "voice": ["speech_to_text", "text_to_speech"],
    "smart_home": ["control_light", "adjust_thermostat"],
    "mcp": ["mcp_connect", "mcp_list_tools", "mcp_call_tool"],
    # ... 共 14 个类别
}

好处

  • CLI 中可以按组启用:hermes tools --enable web,browser
  • 权限控制可以按组管理
  • 用户可以轻松理解工具的分类

四、危险命令审批系统

有些工具很安全(读文件),有些工具很危险(rm -rf)。HermesAgent 实现了三级审批

1. 风险分级

# tools/security.py
RISK_LEVELS = {
    "SAFE": 0,      # 只读操作,无副作用
    "NEEDS_CONFIRM": 1,  # 有副作用,需要确认
    "DANGEROUS": 2   # 高风险,严格限制
}

RISKY_PATTERNS = [
    (r"rm\s+-rf", "DANGEROUS"),      # 危险删除
    (r"format\s+/dev/", "DANGEROUS"), # 格式化磁盘
    (r"sudo\s+", "NEEDS_CONFIRM"),   # 提权操作
    (r"curl.*\|\s*sh", "DANGEROUS"), # 管道执行
]

2. 动态风险评估

不只是简单的正则匹配,还结合了上下文:

def assess_risk(tool_name: str, args: dict, context: dict) -> int:
    risk = RISK_LEVELS.get(tool_name, "SAFE")
    
    # 检查参数中的危险模式
    for pattern, level in RISKY_PATTERNS:
        if re.search(pattern, str(args)):
            risk = max(risk, RISK_LEVELS[level])
    
    # 考虑上下文
    if context.get("is_production_server"):
        risk = min(risk + 1, "DANGEROUS")
    
    return risk

3. 审批流程

def execute_with_approval(tool_name: str, args: dict):
    risk = assess_risk(tool_name, args, get_context())
    
    if risk == "SAFE":
        return registry.execute(tool_name, **args)
    
    elif risk == "NEEDS_CONFIRM":
        if confirm_user(f"Tool '{tool_name}' has side effects. Proceed?"):
            log_action("CONFIRMED_RISKY_TOOL", tool_name, args)
            return registry.execute(tool_name, **args)
        else:
            return {"status": "rejected", "reason": "user_declined"}
    
    else:  # DANGEROUS
        if require_admin_approval(tool_name, args):
            notify_admin(f"Dangerous tool executed: {tool_name}")
            return registry.execute(tool_name, **args)
        else:
            raise SecurityError("Dangerous tool execution denied")

五、技能系统:从工具到智慧

如果说工具是"动手能力",那技能就是"动脑经验"。

技能 vs 工具

维度 工具 技能
本质 Python 代码 Markdown 文档
作用 执行具体操作 提供解决方案
创建者 开发者 Agent 或用户
格式 可执行代码 自然语言描述
复用性 通用 高度特定

类比:工具像"螺丝刀",技能像"如何用螺丝刀组装家具的说明书"。

技能文件示例

# 技能:销售数据分析模式

## 触发条件
当用户请求分析销售数据时

## 解决思路
1. 探索数据结构,识别关键字段
2. 检查数据质量(缺失值、异常值)
3. 按时间维度分析趋势
4. 识别 top/bottom 产品和客户
5. 生成可视化图表
6. 提供 actionable insights

## 实现步骤
```python
# Step 1: 加载和探索
df = pd.read_csv(data_file)
print(df.info())
print(df.describe())

# Step 2: 数据清洗
df = df.dropna(subset=['revenue'])
df['date'] = pd.to_datetime(df['date'])

# Step 3: 趋势分析
monthly = df.groupby(df['date'].dt.to_period('M'))['revenue'].sum()

# Step 4: Top 分析
top_products = df.groupby('product')['revenue'].sum().nlargest(10)

### 技能发现与应用

```python
# skills/hub.py
class SkillsHub:
    def find_relevant_skills(self, task_description: str) -> List[Skill]:
        """基于任务描述找到相关技能"""
        # 使用嵌入向量相似度搜索
        query_embedding = embed(task_description)
        skills = self.skill_index.search(query_embedding, n_results=5)
        return skills
    
    def adapt_skill(self, skill: Skill, context: dict) -> str:
        """根据具体上下文调整技能"""
        prompt = f"""
原始技能:
{skill.content}

当前上下文:
{context}

请调整上述技能以适应具体情况,保持核心思路不变。
"""
        return llm_generate(prompt)

六、400+ 技能生态

HermesAgent 的技能生态令人印象深刻:

内置技能(288 个)

覆盖常见场景:

  • 数据处理:CSV 分析、Excel 处理、数据库查询
  • 编程辅助:代码审查、性能优化、测试生成
  • 内容创作:文章写作、邮件起草、PPT 大纲
  • 运维管理:日志分析、性能监控、故障排查
  • 业务分析:市场研究、竞品分析、用户调研

可选技能(116 个)

专业化场景:

  • 金融分析:股票分析、投资组合优化
  • 科研助手:论文写作、实验设计、数据分析
  • 教育培训:课程设计、习题生成、学习路径
  • 法律助手:合同审查、法条检索、案例分析

技能市场(Skills Hub)

类似"App Store"的技能分发平台:

  • 浏览热门技能
  • 按评分和下载量排序
  • 一键安装/卸载
  • 用户评价和反馈

七、MCP 协议扩展

为了让技能生态系统更加开放,HermesAgent 支持 MCP(Multi-Channel Protocol)

# mcp_client.py
class MCPClient:
    def connect_to_server(self, server_url: str):
        """连接到外部工具服务器"""
        self.server = MCPConnection(server_url)
        
    def list_remote_tools(self):
        """获取远程服务器的工具列表"""
        return self.server.list_tools()
    
    def call_remote_tool(self, tool_name: str, args: dict):
        """调用远程工具"""
        return self.server.call_tool(tool_name, args)

优势

  • 第三方可以提供专业工具(如 Bloomberg 数据、Figma API)
  • Agent 无需预先安装所有工具
  • 按需使用,节省资源

八、工具与技能的协同

工具和技能不是孤立的,它们形成能力放大器

任务需求
    │
    ▼
技能匹配 ←── 技能告诉我们需要什么能力
    │
    ▼
工具选择 ←── 找到具备所需能力的工具
    │
    ▼
执行计划 ←── 结合技能和工具制定方案
    │
    ▼
分步执行

实际例子

  • 技能:“制作数据可视化报告”
  • 需要:数据读取工具 + 分析工具 + 绘图工具
  • 协同:技能规划步骤,工具执行具体操作

九、设计哲学与启示

1. 约定优于配置

工具注册只需要一个装饰器,自动发现机制消除了繁琐的配置。

2. 安全第一,但不牺牲便利

三级审批既保证了安全,又避免了过度阻碍正常操作。

3. 开放生态

MCP 协议让工具生态系统可以无限扩展。

4. 人机协作

技能系统让人可以指导 Agent,Agent 也可以教人。


十、实践建议

如果你想在自己的项目中借鉴这套系统:

  1. 从小开始:先实现基本的注册表,再逐步添加高级特性
  2. 安全第一:尽早考虑权限控制和风险评估
  3. 重视文档:技能系统的价值很大程度在于良好的文档
  4. 社区建设:技能市场需要社区贡献才能繁荣

十一、总结

HermesAgent 的工具注册与技能系统展现了简约而不简单的设计哲学:

  • 技术上:极简的注册机制,强大的自动发现
  • 安全上:分级审批,兼顾安全与便利
  • 生态上:开放的 MCP 协议,无限的扩展可能
  • 体验上:技能让 Agent 更懂业务,工具让技能能落地

这套系统不仅解决了工具管理的技术难题,更重要的是建立了人机协作的新范式:人类提供经验和直觉(技能),机器提供精确和效率(工具),两者结合创造出 1+1>2 的效果。

在下一篇中,我们将探索 HermesAgent 如何实现多终端支持和消息平台集成。


本文基于 HermesAgent 源码分析,项目持续迭代中,具体实现可能随版本更新而变化。

Logo

欢迎加入 MCP 技术社区!与志同道合者携手前行,一同解锁 MCP 技术的无限可能!

更多推荐