Thêm công cụ
Trước khi viết một công cụ, hãy tự hỏi: thay vào đó, đây có phải là một skill không?
Biến nó thành Kỹ năng khi khả năng có thể được thể hiện dưới dạng hướng dẫn + lệnh shell + công cụ hiện có (tìm kiếm arXiv, quy trình công việc git, quản lý Docker, xử lý PDF).
Biến nó thành Công cụ khi nó yêu cầu tích hợp từ đầu đến cuối với khóa API, logic xử lý tùy chỉnh, xử lý dữ liệu nhị phân hoặc phát trực tuyến (tự động hóa trình duyệt, TTS, phân tích tầm nhìn).
Tổng quan
Thêm một công cụ chạm vào 3 tệp:
tools/your_tool.py— trình xử lý, lược đồ, hàm kiểm tra, lệnh gọiregistry.register()toolsets.py— thêm tên công cụ vào_HERMES_CORE_TOOLS(hoặc một bộ công cụ cụ thể)model_tools.py— thêm"tools.your_tool"vào danh sách_discover_tools()
Bước 1: Tạo File công cụ
Mọi tệp công cụ đều tuân theo cùng một cấu trúc:
# 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"],
)
Quy tắc chính
:::nguy hiểm Quan trọng
- Trình xử lý PHẢI trả về chuỗi JSON (thông qua
json.dumps()), không bao giờ trả về các ký tự thô - Các lỗi PHẢI được trả về dưới dạng
{"error": "message"}, không bao giờ được đưa ra dưới dạng ngoại lệ check_fnđược gọi khi xây dựng định nghĩa công cụ — nếu nó trả vềFalse, công cụ này sẽ bị loại trừ một cách âm thầmhandlernhận(args: dict, **kwargs)trong đóargslà đối số lệnh gọi công cụ của LLM :::
Bước 2: Thêm vào bộ công cụ
Trong toolsets.py, thêm tên công cụ:
# 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": []
},
Bước 3: Thêm Discovery Import
Trong model_tools.py, thêm mô-đun vào danh sách _discover_tools():
def _discover_tools():
_modules = [
...
"tools.weather_tool", # <-- add here
]
Quá trình nhập này kích hoạt lệnh gọi registry.register() ở cuối tệp công cụ của bạn.
Trình xử lý không đồng bộ
Nếu trình xử lý của bạn cần mã không đồng bộ, hãy đánh dấu mã đó bằng 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
)
Sổ đăng ký xử lý việc kết nối không đồng bộ một cách minh bạch — bạn không bao giờ tự gọi asyncio.run().
Trình xử lý cần task_id
Các công cụ quản lý trạng thái mỗi phiên nhận task_id qua **kwargs:
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,
)
Công cụ chặn vòng lặp tác nhân
Một số công cụ (todo, memory, session_search, delegate_task) cần quyền truy cập vào trạng thái tác nhân mỗi phiên. Chúng bị chặn bởi run_agent.py trước khi tiếp cận cơ quan đăng ký. Cơ quan đăng ký vẫn giữ các lược đồ của chúng, nhưng dispatch() trả về lỗi dự phòng nếu việc chặn bị bỏ qua.
Tùy chọn: Tích hợp trình hướng dẫn cài đặt
Nếu công cụ của bạn yêu cầu khóa API, hãy thêm khóa đó vào 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,
},
}
Danh sách kiểm tra
- Tệp công cụ được tạo bằng trình xử lý, lược đồ, chức năng kiểm tra và đăng ký
- Đã thêm vào bộ công cụ thích hợp trong
toolsets.py - Đã thêm tính năng nhập khám phá vào
model_tools.py - Trình xử lý trả về chuỗi JSON, lỗi trả về dưới dạng
{"error": "..."} - Tùy chọn: Đã thêm khóa API vào
OPTIONAL_ENV_VARStronghermes_cli/config.py - Tùy chọn: Đã thêm vào
toolset_distributions.pyđể xử lý hàng loạt - Đã thử nghiệm với
hermes chat -q "Use the weather tool for London"