跳到主要內容

代碼執行(程序化工具調用)

execute_code 工具允許 Agent 編寫調用 Hermes 工具的 Python 腳本,將多步驟工作流壓縮為單次 LLM 調用。腳本在 Agent 主機上的沙箱子進程中運行,通過 Unix 域套接字 RPC 進行通信。

工作原理

  1. Agent 編寫使用 from hermes_tools import ... 的 Python 腳本
  2. Hermes 生成一個包含 RPC 函數的 hermes_tools.py 模塊存根
  3. Hermes 打開一個 Unix 域套接字並啟動 RPC 監聽線程
  4. 腳本在子進程中運行 —— 工具調用通過套接字返回到 Hermes
  5. 只有腳本的 print() 輸出會被返回給 LLM;中間工具結果永遠不會進入上下文窗口
# agent 可以編寫如下腳本:
from hermes_tools import web_search, web_extract

results = web_search("Python 3.13 features", limit=5)
for r in results["data"]["web"]:
content = web_extract([r["url"]])
# ... 過濾和處理 ...
print(summary)

沙箱中可用的工具: web_searchweb_extractread_filewrite_filesearch_filespatchterminal(僅前臺模式)。

Agent 使用此功能的場景

當存在以下情況時,Agent 會使用 execute_code

  • 3 次及以上工具調用,且調用之間有處理邏輯
  • 大批量數據過濾或條件分支
  • 對結果進行循環處理

主要優勢:中間工具結果不會進入上下文窗口 —— 只有最終的 print() 輸出返回,顯著降低 token 使用量。

實用示例

數據處理流水線

from hermes_tools import search_files, read_file
import json

# 查找所有配置文件並提取數據庫設置
matches = search_files("database", path=".", file_glob="*.yaml", limit=20)
configs = []
for match in matches.get("matches", []):
content = read_file(match["path"])
configs.append({"file": match["path"], "preview": content["content"][:200]})

print(json.dumps(configs, indent=2))

多步驟網絡研究

from hermes_tools import web_search, web_extract
import json

# 搜索、提取、總結一次完成
results = web_search("Rust async runtime comparison 2025", limit=5)
summaries = []
for r in results["data"]["web"]:
page = web_extract([r["url"]])
for p in page.get("results", []):
if p.get("content"):
summaries.append({
"title": r["title"],
"url": r["url"],
"excerpt": p["content"][:500]
})

print(json.dumps(summaries, indent=2))

批量文件重構

from hermes_tools import search_files, read_file, patch

# 使用已棄用的 API 查找所有 Python 文件並修復它們
matches = search_files("old_api_call", path="src/", file_glob="*.py")
fixed = 0
for match in matches.get("matches", []):
result = patch(
path=match["path"],
old_string="old_api_call(",
new_string="new_api_call(",
replace_all=True
)
if "error" not in str(result):
fixed += 1

print(f"Fixed {fixed} files out of {len(matches.get('matches', []))} matches")

構建與測試流水線

from hermes_tools import terminal, read_file
import json

# 運行測試、解析結果並報告
result = terminal("cd /project && python -m pytest --tb=short -q 2>&1", timeout=120)
output = result.get("output", "")

# 解析測試輸出
passed = output.count(" passed")
failed = output.count(" failed")
errors = output.count(" error")

report = {
"passed": passed,
"failed": failed,
"errors": errors,
"exit_code": result.get("exit_code", -1),
"summary": output[-500:] if len(output) > 500 else output
}

print(json.dumps(report, indent=2))

資源限制

資源限制說明
超時時間5 分鐘(300 秒)腳本被髮送 SIGTERM,5 秒寬限期後發送 SIGKILL
標準輸出50 KB輸出截斷並附帶 [output truncated at 50KB] 提示
標準錯誤10 KB非零退出時包含在輸出中,用於調試
工具調用次數每次執行最多 50 次達到限制時返回錯誤

所有限制均可通過 config.yaml 配置:

# 在“0”中
code_execution:
timeout: 300 # 每個腳本的最大秒數(默認值:300)
max_tool_calls: 50 # 每次執行的最大 tool 調用次數(默認值:50)

腳本內工具調用的工作機制

當你的腳本調用如 web_search("query") 的函數時:

  1. 調用被序列化為 JSON,並通過 Unix 域套接字發送到父進程
  2. 父進程通過標準的 handle_function_call 處理器進行分發
  3. 結果通過套接字返回
  4. 函數返回解析後的結果

這意味著腳本內的工具調用行為與普通工具調用完全一致 —— 相同的速率限制、相同的錯誤處理、相同的功能。唯一限制是 terminal() 僅支持前臺模式(不支持 backgroundptycheck_interval 參數)。

錯誤處理

當腳本失敗時,Agent 會收到結構化的錯誤信息:

  • 非零退出碼:stderr 包含在輸出中,Agent 可查看完整堆棧跟蹤
  • 超時:腳本被終止,Agent 看到 "Script timed out after 300s and was killed."
  • 中斷:若用戶在執行期間發送新消息,腳本被終止,Agent 看到 [execution interrupted — user sent a new message]
  • 工具調用次數上限:達到 50 次調用限制後,後續工具調用返回錯誤消息

響應始終包含 status(success/error/timeout/interrupted)、outputtool_calls_madeduration_seconds

安全性

安全模型

子進程以最小環境運行。API 密鑰、令牌和憑證默認被移除。腳本僅能通過 RPC 通道訪問工具 —— 除非顯式允許,否則無法從環境變量讀取密鑰。

名稱中包含 KEYTOKENSECRETPASSWORDCREDENTIALPASSWDAUTH 的環境變量將被排除。僅安全的系統變量(如 PATHHOMELANGSHELLPYTHONPATHVIRTUAL_ENV 等)會被傳遞。

技能環境變量透傳

當某個技能在其 frontmatter 中聲明 required_environment_variables 時,這些變量在技能加載後自動透傳execute_codeterminal 沙箱。這使得技能可以使用其聲明的 API 密鑰,同時不削弱對任意代碼的安全防護。

對於非技能使用場景,你可以在 config.yaml 中顯式白名單變量:

terminal:
env_passthrough:
- MY_CUSTOM_KEY
- ANOTHER_TOKEN

完整詳情請參見 安全指南

腳本在臨時目錄中運行,執行後自動清理。子進程運行在獨立的進程組中,可在超時或中斷時被幹淨地終止。

execute_code 與 terminal 對比

使用場景execute_codeterminal
包含工具調用的多步驟工作流
簡單的 shell 命令
大量工具輸出的過濾/處理
運行構建或測試套件
循環處理搜索結果
交互式/後臺進程
需要環境變量中的 API 密鑰⚠️ 僅通過 透傳✅(大多數情況可透傳)

經驗法則: 當您需要在調用 Hermes 工具時加入邏輯控制,以程序化方式執行代碼時,請使用 execute_code。當您需要運行 shell 命令、構建項目或處理進程時,請使用 terminal

平臺支持

代碼執行需要 Unix 域套接字,僅在 Linux 和 macOS 上可用。在 Windows 上會自動禁用該功能——Agent 將回退到常規的順序工具調用。