hermes-agent/website/i18n/zh-Hans/docusaurus-plugin-content-docs/current/user-guide/features/code-execution.md
Teknium 76135b329d
docs(i18n): translate all docs into Simplified Chinese (zh-Hans) (#31942)
Translates the full English docs corpus (335 files) into Simplified
Chinese under website/i18n/zh-Hans/. Combined with PR #31895 (cross-
locale link fix), the 简体中文 locale toggle now serves a complete
Chinese site with working cross-page navigation.

Pipeline:
- Claude Sonnet 4.6 via OpenRouter, 8-way concurrent
- Preserves frontmatter keys, code blocks, MDX/JSX, link URLs, brand
  names, and technical jargon (prompt/token/hook/MCP/ACP/etc.)
- Translates only frontmatter title/description and prose
- Two largest files (configuration.md 93KB, research-paper-writing.md
  107KB) retried with 64K max_tokens after initial fence-drift
- 3 manual post-fixes for MDX edge cases the model didn't escape:
  < in optional-skills-catalog table, double-quotes in an alt= tag,
  and a bare URL adjacent to a full-width period

Cost: ~$30 total (Sonnet 4.6 input $3/M + output $15/M).

Verified `npm run build` succeeds for both en and zh-Hans locales,
no double-prefixed /docs/zh-Hans/docs/ URLs in rendered output,
all in-page navigation resolves correctly.

Translations are machine-generated and may need human review on
specific pages — but they're an enormous improvement over the
previous state (3 zh-Hans pages out of 335).
2026-05-25 01:47:38 -07:00

9.5 KiB
Raw Blame History

sidebar_position title description
8 代码执行 通过 RPC 工具访问实现程序化 Python 执行——将多步骤工作流压缩至单次对话轮次

代码执行(程序化工具调用)

execute_code 工具允许 agent 编写调用 Hermes 工具的 Python 脚本,将多步骤工作流压缩至单次 LLM 对话轮次。脚本在 agent 宿主机的子进程中运行,通过 Unix 域套接字 RPC 与 Hermes 通信。

工作原理

  1. Agent 编写使用 from hermes_tools import ... 的 Python 脚本
  2. Hermes 生成带有 RPC 函数的 hermes_tools.py 存根模块
  3. Hermes 打开 Unix 域套接字并启动 RPC 监听线程
  4. 脚本在子进程中运行——工具调用通过套接字传回 Hermes
  5. 只有脚本的 print() 输出会返回给 LLM中间工具结果不会进入上下文窗口
# The agent can write scripts like:
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"]])
    # ... filter and process ...
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

# Find all config files and extract database settings
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

# Search, extract, and summarize in one turn
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

# Find all Python files using deprecated API and fix them
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

# Run tests, parse results, and report
result = terminal("cd /project && python -m pytest --tb=short -q 2>&1", timeout=120)
output = result.get("output", "")

# Parse test 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))

执行模式

execute_code 有两种执行模式,通过 ~/.hermes/config.yaml 中的 code_execution.mode 控制:

模式 工作目录 Python 解释器
project(默认) 会话的工作目录(与 terminal() 相同) 活跃的 VIRTUAL_ENV / CONDA_PREFIX python回退至 Hermes 自身的 python
strict 与用户项目隔离的临时暂存目录 sys.executableHermes 自身的 python

何时保持 project 模式: 当你希望 import pandasfrom my_project import fooopen(".env") 等相对路径与 terminal() 中的行为一致时。这几乎是你始终想要的模式。

何时切换至 strict 模式: 当你需要最大可复现性时——希望无论用户激活哪个 venv每次会话都使用相同的解释器并且希望脚本与项目目录隔离避免通过相对路径意外读取项目文件

# ~/.hermes/config.yaml
code_execution:
  mode: project   # or "strict"

project 模式的回退行为:若 VIRTUAL_ENV / CONDA_PREFIX 未设置、已损坏或指向低于 3.8 的 Python解析器会干净地回退至 sys.executable——agent 始终有可用的解释器。

两种模式的安全关键不变量完全相同:

  • 环境变量清理API key、token、凭据默认被剥离
  • 工具白名单(脚本不能递归调用 execute_codedelegate_task 或 MCP 工具)
  • 资源限制超时、stdout 上限、工具调用上限)

切换模式只改变脚本的运行位置和使用的解释器,不改变脚本可见的凭据或可调用的工具。

资源限制

资源 限制 说明
超时 5 分钟300 秒) 脚本先收到 SIGTERM5 秒宽限期后收到 SIGKILL
Stdout 50 KB 输出截断并附加 [output truncated at 50KB] 提示
Stderr 10 KB 非零退出时包含在输出中,用于调试
工具调用 每次执行 50 次 达到上限时返回错误

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

# In ~/.hermes/config.yaml
code_execution:
  mode: project      # project (default) | strict
  timeout: 300       # Max seconds per script (default: 300)
  max_tool_calls: 50 # Max tool calls per execution (default: 50)

脚本内工具调用的工作方式

当脚本调用 web_search("query") 等函数时:

  1. 调用被序列化为 JSON通过 Unix 域套接字发送至父进程
  2. 父进程通过标准 handle_function_call 处理器进行分发
  3. 结果通过套接字发回
  4. 函数返回解析后的结果

这意味着脚本内的工具调用与普通工具调用行为完全一致——相同的速率限制、相同的错误处理、相同的能力。唯一的限制是 terminal() 仅支持前台模式(不支持 backgroundpty 参数)。

错误处理

脚本失败时agent 会收到结构化的错误信息:

  • 非零退出码stderr 包含在输出中agent 可看到完整的 traceback
  • 超时脚本被终止agent 看到 "Script timed out after 300s and was killed."
  • 中断若用户在执行期间发送新消息脚本被终止agent 看到 [execution interrupted — user sent a new message]
  • 工具调用上限:达到 50 次调用上限后,后续工具调用返回错误消息

响应始终包含 statussuccess/error/timeout/interruptedoutputtool_calls_madeduration_seconds

安全性

:::danger 安全模型 子进程在最小化环境中运行。API key、token 和凭据默认被剥离。脚本只能通过 RPC 通道访问工具——除非显式允许,否则无法从环境变量中读取密钥。 :::

名称中包含 KEYTOKENSECRETPASSWORDCREDENTIALPASSWDAUTH 的环境变量会被排除。只有安全的系统变量(PATHHOMELANGSHELLPYTHONPATHVIRTUAL_ENV 等)会被传递。

Skill 环境变量透传

当 skill 在其 frontmatter 中声明 required_environment_variables 时,这些变量会在 skill 加载后自动透传execute_codeterminal 子进程。这使 skill 可以使用其声明的 API key而不会削弱任意代码的安全态势。

对于非 skill 场景,可在 config.yaml 中显式添加变量白名单:

terminal:
  env_passthrough:
    - MY_CUSTOM_KEY
    - ANOTHER_TOKEN

详情参见安全指南

Hermes 始终将脚本和自动生成的 hermes_tools.py RPC 存根写入临时暂存目录,执行完成后清理。在 strict 模式下,脚本也在该目录中运行;在 project 模式下,脚本在会话的工作目录中运行(暂存目录保留在 PYTHONPATH 中以确保导入正常解析)。子进程在独立的进程组中运行,以便在超时或中断时干净地终止。

execute_code 与 terminal 对比

使用场景 execute_code terminal
调用之间含逻辑的多步骤工作流
简单 shell 命令
过滤/处理大量工具输出
运行构建或测试套件
对搜索结果进行循环处理
交互式/后台进程
需要环境变量中的 API key ⚠️ 仅通过透传 (大多数可透传)

经验法则: 需要在调用之间含逻辑地程序化调用 Hermes 工具时,使用 execute_code。运行 shell 命令、构建和进程时,使用 terminal

平台支持

代码执行依赖 Unix 域套接字,仅在 Linux 和 macOS 上可用。在 Windows 上会自动禁用——agent 回退至常规的顺序工具调用。