hermes-agent/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/developer-guide/adding-tools.md
Teknium 76135b329d
docs(i18n): translate all docs into Simplified Chinese (zh-Hans) (#31942)
Translates the full English docs corpus (335 files) into Simplified
Chinese under website/i18n/zh-Hans/. Combined with PR #31895 (cross-
locale link fix), the 简体中文 locale toggle now serves a complete
Chinese site with working cross-page navigation.

Pipeline:
- Claude Sonnet 4.6 via OpenRouter, 8-way concurrent
- Preserves frontmatter keys, code blocks, MDX/JSX, link URLs, brand
  names, and technical jargon (prompt/token/hook/MCP/ACP/etc.)
- Translates only frontmatter title/description and prose
- Two largest files (configuration.md 93KB, research-paper-writing.md
  107KB) retried with 64K max_tokens after initial fence-drift
- 3 manual post-fixes for MDX edge cases the model didn't escape:
  < in optional-skills-catalog table, double-quotes in an alt= tag,
  and a bare URL adjacent to a full-width period

Cost: ~$30 total (Sonnet 4.6 input $3/M + output $15/M).

Verified `npm run build` succeeds for both en and zh-Hans locales,
no double-prefixed /docs/zh-Hans/docs/ URLs in rendered output,
all in-page navigation resolves correctly.

Translations are machine-generated and may need human review on
specific pages — but they're an enormous improvement over the
previous state (3 zh-Hans pages out of 335).
2026-05-25 01:47:38 -07:00

6.5 KiB
Raw Blame History

sidebar_position title description
2 添加工具 如何向 Hermes Agent 添加新工具——schema、handler、注册与 toolset

添加工具

在编写工具之前,先问自己:这是否应该是一个 skill

:::warning 仅限内置核心工具 本页面用于向仓库本身添加 Hermes 内置工具。 如果你想要个人专用、项目本地或其他自定义工具,而不修改 Hermes 核心,请使用插件方式:

大多数自定义工具创建场景默认使用插件。只有当你明确希望在 tools/toolsets.py 中发布新的内置工具时,才遵循本页面。 :::

以下情况应创建 Skill:该能力可以通过指令 + shell 命令 + 现有工具来实现(如 arXiv 搜索、git 工作流、Docker 管理、PDF 处理)。

以下情况应创建 Tool:需要与 API 密钥进行端到端集成、自定义处理逻辑、二进制数据处理或流式传输如浏览器自动化、TTS、视觉分析

概述

添加一个工具涉及 2 个文件

  1. tools/your_tool.py — handler、schema、check 函数、registry.register() 调用
  2. toolsets.py — 将工具名称添加到 _HERMES_CORE_TOOLS(或特定 toolset

任何包含顶层 registry.register() 调用的 tools/*.py 文件都会在启动时被自动发现——无需手动维护导入列表。

第一步:创建内置工具文件

每个工具文件遵循相同的结构:

# tools/weather_tool.py
"""Weather Tool -- look up current weather for a location."""

import json
import os
import logging

logger = logging.getLogger(__name__)


# --- Availability check ---

def check_weather_requirements() -> bool:
    """Return True if the tool's dependencies are available."""
    return bool(os.getenv("WEATHER_API_KEY"))


# --- Handler ---

def weather_tool(location: str, units: str = "metric") -> str:
    """Fetch weather for a location. Returns JSON string."""
    api_key = os.getenv("WEATHER_API_KEY")
    if not api_key:
        return json.dumps({"error": "WEATHER_API_KEY not configured"})
    try:
        # ... call weather API ...
        return json.dumps({"location": location, "temp": 22, "units": units})
    except Exception as e:
        return json.dumps({"error": str(e)})


# --- Schema ---

WEATHER_SCHEMA = {
    "name": "weather",
    "description": "Get current weather for a location.",
    "parameters": {
        "type": "object",
        "properties": {
            "location": {
                "type": "string",
                "description": "City name or coordinates (e.g. 'London' or '51.5,-0.1')"
            },
            "units": {
                "type": "string",
                "enum": ["metric", "imperial"],
                "description": "Temperature units (default: metric)",
                "default": "metric"
            }
        },
        "required": ["location"]
    }
}


# --- Registration ---

from tools.registry import registry

registry.register(
    name="weather",
    toolset="weather",
    schema=WEATHER_SCHEMA,
    handler=lambda args, **kw: weather_tool(
        location=args.get("location", ""),
        units=args.get("units", "metric")),
    check_fn=check_weather_requirements,
    requires_env=["WEATHER_API_KEY"],
)

关键规则

:::danger 重要

  • Handler 必须返回 JSON 字符串(通过 json.dumps()),不得返回原始 dict
  • 错误必须{"error": "message"} 形式返回,不得抛出异常
  • check_fn 在构建工具定义时被调用——若返回 False,该工具将被静默排除
  • handler 接收 (args: dict, **kwargs),其中 args 是 LLM 的工具调用参数 :::

第二步:将内置工具添加到 Toolset

toolsets.py 中添加工具名称:

# If it should be available on all platforms (CLI + messaging):
_HERMES_CORE_TOOLS = [
    ...
    "weather",  # <-- add here
]

# Or create a new standalone toolset:
"weather": {
    "description": "Weather lookup tools",
    "tools": ["weather"],
    "includes": []
},

第三步:添加发现导入(不再需要)

包含顶层 registry.register() 调用的工具模块会由 tools/registry.py 中的 discover_builtin_tools() 自动发现。无需手动维护导入列表——只需在 tools/ 中创建文件,启动时即可自动加载。

异步 Handler

如果你的 handler 需要异步代码,使用 is_async=True 标记:

async def weather_tool_async(location: str) -> str:
    async with aiohttp.ClientSession() as session:
        ...
    return json.dumps(result)

registry.register(
    name="weather",
    toolset="weather",
    schema=WEATHER_SCHEMA,
    handler=lambda args, **kw: weather_tool_async(args.get("location", "")),
    check_fn=check_weather_requirements,
    is_async=True,  # registry calls _run_async() automatically
)

registry 会透明地处理异步桥接——你无需自己调用 asyncio.run()

需要 task_id 的 Handler

管理每个会话状态的工具通过 **kwargs 接收 task_id

def _handle_weather(args, **kw):
    task_id = kw.get("task_id")
    return weather_tool(args.get("location", ""), task_id=task_id)

registry.register(
    name="weather",
    ...
    handler=_handle_weather,
)

Agent 循环拦截工具

某些工具(todomemorysession_searchdelegate_task)需要访问每个会话的 agent 状态。这些工具在到达 registry 之前会被 run_agent.py 拦截。registry 仍然保存它们的 schema但如果绕过拦截dispatch() 会返回一个回退错误。

可选Setup Wizard 集成

如果你的工具需要 API 密钥,将其添加到 hermes_cli/config.py

OPTIONAL_ENV_VARS = {
    ...
    "WEATHER_API_KEY": {
        "description": "Weather API key for weather lookup",
        "prompt": "Weather API key",
        "url": "https://weatherapi.com/",
        "tools": ["weather"],
        "password": True,
    },
}

检查清单

  • 已创建包含 handler、schema、check 函数和注册调用的工具文件
  • 已在 toolsets.py 中添加到适当的 toolset
  • 已确认该工具确实应为内置/核心工具而非插件
  • Handler 返回 JSON 字符串,错误以 {"error": "..."} 形式返回
  • 可选:已将 API 密钥添加到 hermes_cli/config.pyOPTIONAL_ENV_VARS
  • 可选:已添加到 toolset_distributions.py 以支持批量处理
  • 已通过 hermes chat -q "Use the weather tool for London" 测试