代碼執行(程序化工具調用)
execute_code 工具允許 Agent 編寫調用 Hermes 工具的 Python 腳本,將多步驟工作流壓縮為單次 LLM 調用。腳本在 Agent 主機上的沙箱子進程中運行,通過 Unix 域套接字 RPC 進行通信。
工作原理
- Agent 編寫使用
from hermes_tools import ...的 Python 腳本 - Hermes 生成一個包含 RPC 函數的
hermes_tools.py模塊存根 - Hermes 打開一個 Unix 域套接字並啟動 RPC 監聽線程
- 腳本在子進程中運行 —— 工具調用通過套接字返回到 Hermes
- 只有腳本的
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_search、web_extract、read_file、write_file、search_files、patch、terminal(僅前臺模式)。
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") 的函數時:
- 調用被序列化為 JSON,並通過 Unix 域套接字發送到父進程
- 父進程通過標準的
handle_function_call處理器進行分發 - 結果通過套接字返回
- 函數返回解析後的結果
這意味著腳本內的工具調用行為與普通工具調用完全一致 —— 相同的速率限制、相同的錯誤處理、相同的功能。唯一限制是 terminal() 僅支持前臺模式(不支持 background、pty 或 check_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)、output、tool_calls_made 和 duration_seconds。
安全性
子進程以最小環境運行。API 密鑰、令牌和憑證默認被移除。腳本僅能通過 RPC 通道訪問工具 —— 除非顯式允許,否則無法從環境變量讀取密鑰。
名稱中包含 KEY、TOKEN、SECRET、PASSWORD、CREDENTIAL、PASSWD 或 AUTH 的環境變量將被排除。僅安全的系統變量(如 PATH、HOME、LANG、SHELL、PYTHONPATH、VIRTUAL_ENV 等)會被傳遞。
技能環境變量透傳
當某個技能在其 frontmatter 中聲明 required_environment_variables 時,這些變量在技能加載後自動透傳至 execute_code 和 terminal 沙箱。這使得技能可以使用其聲明的 API 密鑰,同時不削弱對任意代碼的安全防護。
對於非技能使用場景,你可以在 config.yaml 中顯式白名單變量:
terminal:
env_passthrough:
- MY_CUSTOM_KEY
- ANOTHER_TOKEN
完整詳情請參見 安全指南。
腳本在臨時目錄中運行,執行後自動清理。子進程運行在獨立的進程組中,可在超時或中斷時被幹淨地終止。
execute_code 與 terminal 對比
| 使用場景 | execute_code | terminal |
|---|---|---|
| 包含工具調用的多步驟工作流 | ✅ | ❌ |
| 簡單的 shell 命令 | ❌ | ✅ |
| 大量工具輸出的過濾/處理 | ✅ | ❌ |
| 運行構建或測試套件 | ❌ | ✅ |
| 循環處理搜索結果 | ✅ | ❌ |
| 交互式/後臺進程 | ❌ | ✅ |
| 需要環境變量中的 API 密鑰 | ⚠️ 僅通過 透傳 | ✅(大多數情況可透傳) |
經驗法則: 當您需要在調用 Hermes 工具時加入邏輯控制,以程序化方式執行代碼時,請使用 execute_code。當您需要運行 shell 命令、構建項目或處理進程時,請使用 terminal。
平臺支持
代碼執行需要 Unix 域套接字,僅在 Linux 和 macOS 上可用。在 Windows 上會自動禁用該功能——Agent 將回退到常規的順序工具調用。