Thời gian chạy công cụ
Công cụ Hermes là các chức năng tự đăng ký được nhóm thành các bộ công cụ và được thực thi thông qua hệ thống đăng ký/điều phối trung tâm.
Các tập tin chính:
tools/registry.pymodel_tools.pytoolsets.pytools/terminal_tool.pycông cụ/môi trường/*
##Mô hình đăng ký công cụ
Mỗi mô-đun công cụ gọi registry.register(...) tại thời điểm nhập.
model_tools.py chịu trách nhiệm nhập/khám phá các mô-đun công cụ và xây dựng danh sách lược đồ được mô hình sử dụng.
Cách hoạt động của registry.register()
Mọi tệp công cụ trong tools/ đều gọi registry.register() ở cấp mô-đun để tự khai báo. Chữ ký hàm là:
registry.register(
name="terminal", # Unique tool name (used in API schemas)
toolset="terminal", # Toolset this tool belongs to
schema={...}, # OpenAI function-calling schema (description, parameters)
handler=handle_terminal, # The function that executes when the tool is called
check_fn=check_terminal, # Optional: returns True/False for availability
requires_env=["SOME_VAR"], # Optional: env vars needed (for UI display)
is_async=False, # Whether the handler is an async coroutine
description="Run commands", # Human-readable description
emoji="💻", # Emoji for spinner/progress display
)
Mỗi lệnh gọi tạo ra một ToolEntry được lưu trữ trong lệnh ToolRegistry._tools đơn lẻ được khóa theo tên công cụ. Nếu xung đột tên xảy ra giữa các bộ công cụ, một cảnh báo sẽ được ghi lại và việc đăng ký sau sẽ thắng.
Khám phá: _discover_tools()
Khi model_tools.py được nhập, nó gọi _discover_tools() để nhập mọi mô-đun công cụ theo thứ tự:
_modules = [
"tools.web_tools",
"tools.terminal_tool",
"tools.file_tools",
"tools.vision_tools",
"tools.mixture_of_agents_tool",
"tools.image_generation_tool",
"tools.skills_tool",
"tools.skill_manager_tool",
"tools.browser_tool",
"tools.cronjob_tools",
"tools.rl_training_tool",
"tools.tts_tool",
"tools.todo_tool",
"tools.memory_tool",
"tools.session_search_tool",
"tools.clarify_tool",
"tools.code_execution_tool",
"tools.delegate_tool",
"tools.process_registry",
"tools.send_message_tool",
# "tools.honcho_tools", # Removed — Honcho is now a memory provider plugin
"tools.homeassistant_tool",
]
Mỗi lần nhập sẽ kích hoạt lệnh gọi registry.register() của mô-đun. Lỗi trong các công cụ tùy chọn (ví dụ: thiếu fal_client để tạo hình ảnh) được phát hiện và ghi lại — chúng không ngăn các công cụ khác tải.
Sau khi khám phá công cụ cốt lõi, các công cụ MCP và công cụ plugin cũng được khám phá:
- Công cụ MCP —
tools.mcp_tool.discover_mcp_tools()đọc cấu hình máy chủ MCP và đăng ký các công cụ từ máy chủ bên ngoài. - Công cụ plugin —
hermes_cli.plugins.discover_plugins()tải các plugin người dùng/dự án/pip có thể đăng ký các công cụ bổ sung.
Kiểm tra tính khả dụng của công cụ (check_fn)
Mỗi công cụ có thể tùy ý cung cấp một check_fn — một lệnh gọi có thể trả về True khi công cụ này khả dụng và False nếu không. Kiểm tra điển hình bao gồm:
- Có khóa API — ví dụ:
lambda: bool(os.environ.get("SERP_API_KEY"))cho tìm kiếm trên web - Dịch vụ đang chạy — ví dụ: kiểm tra xem máy chủ Honcho đã được định cấu hình chưa
- Đã cài đặt nhị phân — ví dụ: xác minh
nhà viết kịchcó sẵn cho các công cụ trình duyệt
Khi registry.get_def địnhs() xây dựng danh sách lược đồ cho mô hình, nó sẽ chạy check_fn() của từng công cụ:
# Simplified from registry.py
if entry.check_fn:
try:
available = bool(entry.check_fn())
except Exception:
available = False # Exceptions = unavailable
if not available:
continue # Skip this tool entirely
Các hành vi chính:
- Kết quả kiểm tra được lưu vào bộ nhớ đệm cho mỗi cuộc gọi — nếu nhiều công cụ dùng chung
check_fnthì nó chỉ chạy một lần. - Các ngoại lệ trong
check_fn()được coi là "không khả dụng" (không an toàn). - Phương thức
is_toolset_available()kiểm tra xemcheck_fncủa bộ công cụ có vượt qua hay không, được sử dụng để hiển thị giao diện người dùng và độ phân giải của bộ công cụ.
Độ phân giải của bộ công cụ
Bộ công cụ được đặt tên là các gói công cụ. Hermes giải quyết chúng thông qua:
- danh sách bộ công cụ được bật/tắt rõ ràng
- cài đặt trước nền tảng (
hermes-cli,hermes-telegram, v.v.) - bộ công cụ MCP động
- các bộ mục đích đặc biệt được tuyển chọn như
hermes-acp
Cách lọc các công cụ get_tool_def địnhs()
Điểm vào chính là model_tools.get_tool_def định(enabled_toolsets,disabled_toolsets, Quiet_mode):
-
Nếu
enabled_toolsetsđược cung cấp — chỉ bao gồm các công cụ từ các bộ công cụ đó. Mỗi tên bộ công cụ được phân giải thông quaresolve_toolset()để mở rộng các bộ công cụ tổng hợp thành các tên công cụ riêng lẻ. -
Nếu
disabled_toolsetsđược cung cấp — bắt đầu với TẤT CẢ các bộ công cụ, sau đó trừ đi những bộ công cụ bị vô hiệu hóa. -
Nếu không — bao gồm tất cả các bộ công cụ đã biết.
-
Lọc sổ đăng ký — bộ tên công cụ đã giải quyết được chuyển đến
registry.get_def địnhs(), áp dụng tính năng lọccheck_fnvà trả về các lược đồ định dạng OpenAI. -
Vá lược đồ động — sau khi lọc, các lược đồ
execute_codevàbrowser_navigateđược điều chỉnh linh hoạt để chỉ các công cụ tham chiếu thực sự đã vượt qua quá trình lọc (ngăn ảo giác mô hình về các công cụ không khả dụng).
Tên bộ công cụ kế thừa
Tên bộ công cụ cũ có hậu tố _tools (ví dụ: web_tools, terminal_tools) được ánh xạ tới tên công cụ hiện đại của chúng thông qua _LEGACY_TOOLSET_MAP để tương thích ngược.
Gửi đi
Trong thời gian chạy, các công cụ được gửi đi thông qua sổ đăng ký trung tâm, với các ngoại lệ vòng lặp tác nhân đối với một số công cụ cấp tác nhân như xử lý bộ nhớ/việc cần làm/tìm kiếm phiên.
Luồng điều phối: model tool_call → thực thi trình xử lý
Khi mô hình trả về tool_call, quy trình sẽ là:
Model response with tool_call
↓
run_agent.py agent loop
↓
model_tools.handle_function_call(name, args, task_id, user_task)
↓
[Agent-loop tools?] → handled directly by agent loop (todo, memory, session_search, delegate_task)
↓
[Plugin pre-hook] → invoke_hook("pre_tool_call", ...)
↓
registry.dispatch(name, args, **kwargs)
↓
Look up ToolEntry by name
↓
[Async handler?] → bridge via _run_async()
[Sync handler?] → call directly
↓
Return result string (or JSON error)
↓
[Plugin post-hook] → invoke_hook("post_tool_call", ...)
Lỗi gói
Tất cả việc thực thi công cụ đều được gói gọn trong việc xử lý lỗi ở hai cấp độ:
-
registry.dispatch()— bắt bất kỳ ngoại lệ nào từ trình xử lý và trả về{"error": "Việc thực thi công cụ không thành công: ExceptionType: message"}dưới dạng JSON. -
handle_function_call()— gói toàn bộ công văn trong một lần thử/ngoại trừ trả về{"error": "Lỗi thực thi tool_name: message"}.
Điều này đảm bảo mô hình luôn nhận được chuỗi JSON đúng định dạng, không bao giờ có ngoại lệ chưa được xử lý.
Công cụ vòng lặp tác nhân
Bốn công cụ bị chặn trước khi gửi đăng ký vì chúng cần trạng thái cấp tác nhân (TodoStore, MemoryStore, v.v.):
todo— lập kế hoạch/theo dõi nhiệm vụbộ nhớ— ghi bộ nhớ liên tụcsession_search— thu hồi giữa các phiêndelegate_task— sinh ra các phiên tác nhân phụ
Lược đồ của các công cụ này vẫn được đăng ký trong sổ đăng ký (đối với get_tool_def địnhs), nhưng trình xử lý của chúng trả về lỗi sơ khai nếu việc gửi đi bằng cách nào đó đến trực tiếp với chúng.
Cầu nối không đồng bộ
Khi trình xử lý công cụ không đồng bộ, _run_async() sẽ kết nối nó với đường dẫn điều phối đồng bộ hóa:
- Đường dẫn CLI (không có vòng lặp đang chạy) — sử dụng vòng lặp sự kiện liên tục để duy trì hoạt động của các máy khách không đồng bộ được lưu trong bộ nhớ đệm
- Đường dẫn cổng (vòng lặp đang chạy) — tạo ra một luồng dùng một lần với
asyncio.run() - Luồng công nhân (công cụ song song) — sử dụng các vòng lặp liên tục trên mỗi luồng được lưu trữ trong bộ nhớ cục bộ của luồng
Luồng phê duyệt DANGEROUS_PATTERNS
Công cụ đầu cuối tích hợp hệ thống phê duyệt lệnh nguy hiểm được xác định trong tools/approval.py:
- Phát hiện mẫu —
DANGEROUS_PATTERNSlà danh sách các bộ dữ liệu(regex, description)bao gồm các hoạt động phá hoại:
- Xóa đệ quy (
rm -rf) - Định dạng hệ thống tập tin (
mkfs,dd) - Các thao tác phá hoại SQL (
DROP TABLE,DELETE FROMkhông cóWHERE) - Ghi đè cấu hình hệ thống (
> /etc/) - Thao tác dịch vụ (
systemctl stop) - Thực thi mã từ xa (
curl | sh) - Fork bom, xử lý tiêu diệt, v.v.
-
Phát hiện — trước khi thực hiện bất kỳ lệnh đầu cuối nào,
detect_dangeous_command(command)sẽ kiểm tra tất cả các mẫu. -
Lời nhắc phê duyệt — nếu tìm thấy kết quả phù hợp:
- Chế độ CLI — lời nhắc tương tác yêu cầu người dùng phê duyệt, từ chối hoặc cho phép vĩnh viễn
- Chế độ cổng — lệnh gọi lại phê duyệt không đồng bộ sẽ gửi yêu cầu đến nền tảng nhắn tin
- Phê duyệt thông minh — tùy chọn, LLM phụ trợ có thể tự động phê duyệt các lệnh có rủi ro thấp khớp với các mẫu (ví dụ:
rm -rf node_modules/là an toàn nhưng khớp với "xóa đệ quy")
-
Trạng thái phiên — phê duyệt được theo dõi mỗi phiên. Sau khi bạn phê duyệt "xóa đệ quy" cho một phiên, các lệnh
rm -rftiếp theo sẽ không được nhắc lại. -
Danh sách cho phép vĩnh viễn — tùy chọn "cho phép vĩnh viễn" ghi mẫu vào
command_allowlistcủaconfig.yaml, tồn tại qua các phiên.
Môi trường đầu cuối/thời gian chạy
Hệ thống đầu cuối hỗ trợ nhiều phụ trợ:
- địa phương
- docker
- sss
- điểm kỳ dị
- phương thức
- daytona
Nó cũng hỗ trợ:
- ghi đè cwd trên mỗi tác vụ
- quản lý quá trình nền
- Chế độ PTY
- gọi lại phê duyệt cho các lệnh nguy hiểm
Đồng thời
Lệnh gọi công cụ có thể thực hiện tuần tự hoặc đồng thời tùy thuộc vào yêu cầu tương tác và kết hợp công cụ.