🤖HermesBlog
Hermes 官方教程 · 第25篇2026/8/9· Easy Understand Hermes Agent

第25篇:代码执行——AI 写代码跑代码

Hermes Agent 官方教程第25篇:AI 写代码跑代码

代码执行:AI 的自动流水线

第25篇:代码执行——AI 写代码跑代码

你有没有遇到过这种情况:让 AI 帮你查资料、改文件、跑命令,它得一步一步来,来回折腾好几轮,既慢又费 token。今天要讲的 execute_code 功能,就像给 AI 配了一个“自动流水线”——它自己写脚本、自己调工具、自己处理中间结果,最后只把成品端给你。

它是怎么工作的?

简单说,就是让 AI 写一段 Python 脚本,脚本里可以调用 Hermes 的各种工具(搜索、读文件、改代码、跑命令等)。整个流程分五步:

  1. AI 写脚本:用 from hermes_tools import ... 导入工具函数
  2. Hermes 生成辅助模块:自动创建 hermes_tools.py,里面封装了工具调用接口
  3. 建立通信通道:Hermes 开一个 Unix socket,让脚本和主程序对话
  4. 子进程执行:脚本在独立进程中运行,工具调用通过 socket 传回 Hermes
  5. 只返回 print 结果:脚本里 print() 的内容才会回到对话中,中间过程全部“屏蔽”
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("搜索完成,共处理", len(results["data"]["web"]), "条结果")

什么时候 AI 会主动用这个功能?

  • 需要连续调用 3 次以上工具,且中间有逻辑判断
  • 要批量筛选数据,比如从一堆文件里提取关键信息
  • 需要循环处理结果,比如逐个检查并修复代码

最大的好处是:中间结果不进上下文窗口,只有最终的 print() 输出回来,能省下大量 token。

实战例子:批量改代码

假设要找出项目里所有用了旧 API 的文件并自动修复:

from hermes_tools import search_files, patch

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} 个文件,共找到 {len(matches.get('matches', []))} 处匹配")

两种执行模式

~/.hermes/config.yaml 里可以设置 code_execution.mode

模式 工作目录 Python 解释器
project(默认) terminal() 一致 优先用你当前虚拟环境
strict 临时隔离目录 用 Hermes 自己的 Python

建议:日常开发保持 project 模式,这样脚本里能正常 import pandas、访问项目文件。只有在需要严格隔离时才切到 strict

调用之间的状态(会话内核)

在本地终端后端上,execute_code 并不是每次调用都新开一个解释器。每个会话拥有一个常驻的 Python 内核,所以上一次调用里的变量、导入的模块、加载的数据,在下一次调用里还能直接用。AI 可以把一份数据只加载一次,然后在后续几轮里反复查询,而不用每次都重新读一遍。子代理有各自独立的内核;内核绝不会跨会话共享。子代理的内核生命周期和子代理本身一样长:子代理运行期间它不计入存活内核上限(所以一次大规模并发不会再中途把兄弟内核挤掉),子代理结束后它就被销毁。

内核会在这些情况下结束:

  • 超时或中断:某个单元超时(或被中断)会杀掉内核进程,状态会被有意丢弃,结果里会说明这一点,下一次调用会从全新内核开始。
  • reset=true:AI 可以传 reset: true 来丢弃内核状态、从头开始。这也是让环境变更生效的方式:内核在启动时环境就固定了,所以新加入白名单的透传变量在内核重置前是看不到的。
  • 空闲超时与淘汰:内核会随会话结束而消亡,或在空闲 code_execution.kernel_idle_timeout 秒(默认 1800)后被回收,或当存活的顶层会话内核超过 code_execution.max_session_kernels(默认 4)时淘汰最旧的那个(正在运行的子代理内核不计入这个上限)。
# ~/.hermes/config.yaml
code_execution:
  kernel_idle_timeout: 1800   # 内核空闲多少秒后被回收
  max_session_kernels: 4      # 同时保活的内核数,超出后淘汰最旧的

远程后端(Docker、SSH、Modal)运行的是契约相同的远程会话内核。如果内核无法在后端启动,Hermes 会退回到把每次调用当作独立脚本运行,并在结果里说明。

大输出:超过 50 KB 的 stdout 会以“首尾各取一段”的方式内联展示,完整文本保存在 ~/.hermes/cache/exec/ 下,路径会包含在结果里,这样 AI 可以用 read_file 分页查看,而不用重跑脚本。

小结

execute_code 让 AI 从“一步一步指挥”变成“写个脚本全自动跑”,特别适合数据处理、批量重构、自动化测试这类场景。记住核心思路:脚本内部随便折腾,只把最终结果 print 出来

下一篇预告:第26篇将介绍 Hermes 的「文件编辑」功能——AI 如何精准修改代码而不破坏其他内容,敬请期待!

📖 官方文档

本文根据 Hermes Agent 官方文档编写,原文见:官方文档 › user-guide/features/code-execution