Прежде чем писать инструмент, спросите себя: не лучше ли это сделать навыком?:::предупреждение Только основные встроенные инструменты
Эта страница предназначена для добавления встроенного инструмента Hermes непосредственно в репозиторий.
Если вам нужен личный, локальный для проекта или другой пользовательский инструмент без
изменения ядра Гермеса, викор вместо этого пути плагинов:
По умолчанию для создания большинства инструментов используются плагины. Следуйте этой странице только тогда, когда
Вы заявили, что хотите добавить новый встроенный инструмент в tools/ и toolsets.py.
Делайте это Навыком, когда возможность может быть выражена как инструкция + команда + добавление инструментов (поиск arXiv, рабочие процессы git, управление Docker, обработка PDF).
Делайте это Инструментом, когда требуется сквозная интеграция с API-ключами, пользовательская логика обработки, работа с бинарными данными или потоковая передача (автоматизация браузера, TTS, анализ изображений).
toolsets.py — добавление имени инструмента в _HERMES_CORE_TOOLS (или в конкретный набор инструментов)
Любой файл tools/*.py с вызовом registry.register() на верхнем уровне автоматически обнаруживается при запуске — ручной импорт списка не требуется.
Шаг 1: Создание файла встроенного инструмента
Каждый файл инструмента следует один и той же:
# tools/weather_tool.py"""Weather Tool -- look up current weather for a location."""importjsonimportosimportlogginglogger=logging.getLogger(__name__)# --- Проверка доступности ---defcheck_weather_requirements()->bool:"""Return True if the tool's dependencies are available."""returnbool(os.getenv("WEATHER_API_KEY"))# --- Обработчик ---defweather_tool(location:str,units:str="metric")->str:"""Fetch weather for a location. Returns JSON string."""api_key=os.getenv("WEATHER_API_KEY")ifnotapi_key:returnjson.dumps({"error":"WEATHER_API_KEY not configured"})try:#... call weather API...returnjson.dumps({"location":location,"temp":22,"units":units})exceptExceptionase:returnjson.dumps({"error":str(e)})# --- Схема ---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"]}}# --- Регистрация ---fromtools.registryimportregistryregistry.register(name="weather",toolset="weather",schema=WEATHER_SCHEMA,handler=lambdaargs,**kw:weather_tool(location=args.get("location",""),units=args.get("units","metric")),check_fn=check_weather_requirements,requires_env=["WEATHER_API_KEY"],)
Ключевые правила:::опасность Важно
Обработчики ОБЯЗАНЫ возвращают JSON-строку (через json.dumps()), никогда не сырые словари
Ошибки ОБЯЗАНЫ появляются как {"error": "message"}, никогда не сохраняются как исключения
check_fn возникает при построении определений инструментов — если возвращается False, инструмент молчат
handler получает (args: dict, **kwargs), где args — аргументы вызова инструмента от LLM
Шаг 2: Добавление встроенного инструмента в набор инструментов
В toolsets.py имя инструмента:
# Если он должен быть доступен на всех платформах (CLI + обмен сообщениями):_HERMES_CORE_TOOLS=[..."weather",# <-- добавить сюда]# Или создайте новый отдельный набор инструментов:"weather":{"description":"Инструменты для получения погоды","tools":["weather"],"includes":[]},
~~Шаг 3: Добавление импорта для обнаружения~~ (больше не требуется)
Модули инструментов с вызовом registry.register() на верхнем уровне автоматически находят изменения discover_builtin_tools() в tools/registry.py. Никакого ручного списка импорта поддержки не требуется — просто создайте файл в tools/, и он будет захвачен при запуске.
Асинхронные обработчики
Если вашему обработчику нужен асинхронный код, используйте его с помощью is_async=True:
asyncdefweather_tool_async(location:str)->str:asyncwithaiohttp.ClientSession()assession:...returnjson.dumps(result)registry.register(name="weather",toolset="weather",schema=WEATHER_SCHEMA,handler=lambdaargs,**kw:weather_tool_async(args.get("location","")),check_fn=check_weather_requirements,is_async=True,# registry вызывает _run_async() автоматически)
Реестр прозрачности обрабатывает асинхронное мостовое соединение — вам никогда не понадобится включать asyncio.run() самостоятельно.
Обработчики, которым нужен Task_id
Инструменты, управляющие состоянием сессии, получают Task_id через **kwargs:
Некоторые инструменты («todo», «memory», «session_search», «delegate_task») требуют доступа к состоянию агента сессии. Они перехватываются run_agent.py до того, как требования реестра. Реестр всё ещё хранит их схемы, но dispatch() возвращает резервную ошибку, если перехват обойдён.
Опционально: Интеграция с мастером настроек
Если для вашего инструмента требуется ключ API, впишите его в hermes_cli/config.py:
OPTIONAL_ENV_VARS={..."WEATHER_API_KEY":{"description":"API-ключ погоды для получения данных о погоде","prompt":"API-ключ погоды","url":"https://weatherapi.com/","tools":["weather"],"password":True,},}
Контрольный список
[ ] Создан файловый инструмент с обработчиком, схемой, временной проверкой и регистрацией.
[ ] Добавлен соответствующий набор инструментов в toolsets.py
[ ] Подтверждено, что это действительно должен быть встроенный/основной инструмент, а не подключаемый.
[ ] Обработчик получает JSON-строки, ошибки возвращаются как {"error": "..."}
[ ] Опционально: API-ключ добавлен в OPTIONAL_ENV_VARS в hermes_cli/config.py
[ ] Опционально: добавлено в toolset_distributions.py для пакетной обработки.
[ ] Протестировано с помощью hermeschat -q "Использовать инструмент погоды для Лондона"