Chuyển tới nội dung chính

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.py
  • model_tools.py
  • toolsets.py
  • tools/terminal_tool.py
  • tools/environments/*

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 registry.register() hoạt động

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 cuộc gọi tạo một ToolEntry được lưu trữ trong lệnh đơn ToolRegistry._tools đượ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á:

  1. Công cụ MCPtools.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.
  2. Công cụ pluginhermes_cli.plugins.discover_plugins() tải 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 check_fn — một lệnh gọi có thể trả về True khi công cụ đó 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 playwright có sẵn cho các công cụ trình duyệt

Khi registry.get_definitions() 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_fn thì công cụ này 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 xem check_fn củ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 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 get_tool_definitions() lọc các công cụ

Điểm vào chính là model_tools.get_tool_definitions(enabled_toolsets, disabled_toolsets, quiet_mode) :

  1. 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 qua resolve_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ẻ.

  2. Nếu cung cấp disabled_toolsets — hãy 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.

  3. Nếu không — bao gồm tất cả các bộ công cụ đã biết.4. Lọc sổ đăng ký — bộ tên công cụ đã giải quyết được chuyển đến registry.get_definitions(), áp dụng tính năng lọc check_fn và trả về các lược đồ định dạng OpenAI.

  4. Vá lược đồ động — sau khi lọc, các lược đồ execute_codebrowser_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.

Công văn

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 , luồng 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 độ:

  1. ** registry.dispatch() ** — bắt bất kỳ ngoại lệ nào từ trình xử lý và trả về {"error": "Tool execution failed: ExceptionType: message"} dưới dạng JSON.

  2. ** handle_function_call() ** — gói toàn bộ công văn trong lần thử/ngoại trừ việc trả về {"error": "Error executing 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ụ
  • memory — ghi bộ nhớ liên tục
  • session_search — thu hồi giữa các phiên
  • delegate_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_definitions ), 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 :

  1. Phát hiện mẫuDANGEROUS_PATTERNS là danh sách các bộ (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 )
    • Hoạt động phá hoại SQL ( DROP TABLE , DELETE FROM khô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.
  2. Phát hiện — trước khi thực hiện bất kỳ lệnh đầu cuối nào, detect_dangerous_command(command) sẽ kiểm tra tất cả các mẫu.3. 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/ an toàn nhưng khớp với "xóa đệ quy")
  3. 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 -rf tiếp theo sẽ không được nhắc lại.

  4. 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 config.yaml của command_allowlist , 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ụ.

Tài liệu liên quan