在 Hermes Agent 这套工程中,利用 Python 的 ast(Abstract Syntax Tree,抽象语法树)模块,最根本的目的有三个:动态插件/工具注册、静态代码安全审计、以及毫秒级轻量语法自检。
在以下三种核心业务场景中,工程会调用 ast 进行处理:
1. 动态工具自动注册 ------ ast.parse(用于启动加速)
在 tools/registry.py 文件中,工程通过 ast 来静态扫描并定位各个插件模块中的工具注册(registry.register(...))调用。
- 为什么要用
ast: 如果直接用 Python 的import去加载所有 Python 工具文件(目前有约 70 多个工具文件),会因为导入大量第三方重型依赖(比如playwright、spotify、feishu等库)而导致程序启动变得非常缓慢。 - 如何使用: 系统通过
ast.parse()生成语法树,利用ast.NodeVisitor寻找特定的registry.register节点。通过这种不实际执行(Import)代码的代码分析,仅仅提取工具的 Schema 元数据。
python:45:51:/home/limx/Projects/hermes-agent/tools/registry.py
# 1. 使用 ast.parse 在不 import 运行的情况下,静态解析出所有的工具注册调用
tree = ast.parse(source, filename=str(module_path))
- 什么时候用: 系统初始化/ CLI 启动时。 这样做在启动时跳过了沉重的
import链,实现了极速启动。
2. 技能库安全深度审计(Deep Audit) ------ ast_scan_path
因为该系统支持用户通过 Skills Hub(如 agentskills.io 或第三方 URL)安装社区提交的技能,甚至智能体自己也能编写 scripts/ 辅助脚本,所以存在恶意代码注入的风险。
在 tools/skills_ast_audit.py 中,工程内置了对技能 Python 代码的静态 AST 扫描。
- 目的: 作为轻量级静态分析(SAST)工具,检测是否存在危险的动态代码执行、黑客绕过、以及未声明加载行为。
- 如何使用:
- 通过
ast检查是否有importlib.import_module(...)或非字面量的__import__节点(防止动态加载后门)。 - 检查是否有动态变量作为属性获取的
getattr(obj, <variable>),防止动态提取私有凭据。 - 检查是否有对
__dict__的非字面量下标访问,阻断混淆代码的运行。
- 通过
python:33:50:/home/limx/Projects/hermes-agent/tools/skills_ast_audit.py
class V(ast.NodeVisitor):
def visit_Call(self, node):
f = node.func
# 1. 发现 importlib.import_module(...)
if isinstance(f, ast.Attribute) and f.attr == "import_module":
findings.append((rel_path, node.lineno, "dynamic_import",
"importlib.import_module() --- loads arbitrary modules at runtime"))
# 2. 发现 __import__(非字面量字符串)
elif isinstance(f, ast.Name) and f.id == "__import__":
if node.args and not isinstance(node.args[0], ast.Constant):
findings.append((rel_path, node.lineno, "dynamic_import_computed",
"__import__ with non-literal module name"))
# 3. 发现 getattr(obj, 非字面量字符串)
elif isinstance(f, ast.Name) and f.id == "getattr":
if len(node.args) >= 2 and not isinstance(node.args[1], ast.Constant):
findings.append((rel_path, node.lineno, "dynamic_getattr",
"getattr with non-literal attribute name"))
self.generic_visit(node)
- 什么时候用: 当运行
hermes skills audit --deep手动审计,或者智能体自创技能/安装第三方 Hub 技能时。 用于向用户提示"哪些脚本使用了黑魔法,需要人工复核"。
3. 在线编写代码的微秒级语法自检 ------ ast.parse
当智能体在当前会话中写完一段 Python 代码(通过 write_file 写入或 patch 修改)时,它可能无意中留下了缺括号、冒号或者拼写等导致语法不通的问题。
为了保证代码运行安全并快速发现问题,系统在 tools/file_operations.py 中内置了轻量级、无副作用的 Linter。
- 目的: 在不产生真实子进程、不产生外部执行依赖、不运行可能有风险的脚本的情况下,超高速确认 Python 语法是否合规。
- 如何使用:
直接对要检测的代码内容运行ast.parse():
python:466:474:/home/limx/Projects/hermes-agent/tools/file_operations.py
"""In-process Python syntax check via ast.parse."""
import ast as _ast
try:
# 如果解析失败,说明有基础语法错误(例如 SyntaxError 等)
_ast.parse(content)
- 什么时候用: 智能体每次修改/写入 Python 代码之后、或者准备保存一个技能之前。
如果捕获了SyntaxError,系统就能在不运行代码、不生成 linter 进程的前提下,在一毫秒内快速向智能体返回具体的报错行号和错误提示,让智能体当场进行自我修正。
总结
在 Hermes Agent 这种高频、高可信度 AI 执行环境中,ast 是一把**"在不实际运行代码的前提下,精准看穿代码意图、检测代码漏洞与语法缺陷"**的瑞士军刀。其最核心的优势就是:极速、安全、无副作用。