Hermes Agent 源码解析 · 第 16 讲
Hermes Agent 源码解析 第 16 讲:Tool Executor 深度解析与安全护栏 基于 Hermes Agent v0.16.0 源码 · 2026-06-28 一、工具执行:Agent 的"手脚" 上一讲我们深入了 System Prompt 构建引擎。这一讲我们进入 Hermes 的 工具执行层 ——当 LLM 返回一个 tool_call 后,Hermes 如何调度、执行、收集结果,并通过多层安全护栏确保执行安全。这是 Hermes 最核心的运行时路径之一,几乎每一轮对话都会经过它。 📦 本讲核心文件 agent/tool_executor.py (1428 行)— 串行/并发调度 agent/tool_guardrails.py (475 行)— 工具调用安全护栏 agent/tool_dispatch_helpers.py (417 行)— 并行决策引擎 agent/file_safety.py (640 行)— 文件读写安全 tools/tool_result_storage.py (232 行)— 结果持久化 二、工具执行流水线全景 tool_executor.py 实现了完整的工具调用生命周期。从 LLM 返回 tool_calls 开始,到结果回注 messages 结束,中间经过 8 个关键阶段 : ① Parse & Unwrap ⬇️ JSON 解析 + Tool Search 解包 ② Middleware 预处理 ⬇️ 参数改写/增强 ③ Block 评估(三重拦截) ⬇️ 作用域 → 插件 → 护栏 ④ Checkpoint 快照 ⬇️ 文件/命令前快照 ⑤ 执行(串行/并发) ⬇️ _invoke_tool → 结果收集 ⑥ 结果后处理 ⬇️ 持久化 + 预算控制 ⑦ Guardrail 观测 ⬇️ 循环检测 + 警告注入 ⑧ 结果回注 Messages 三、串行 vs 并发执行 Hermes 提供两种执行模式,由 _should_parallelize_tool_batch() 自动决策: 特性 串行执行 并发执行 入口函数 execute_tool_calls_sequential() execute_tool_calls_concurrent() 适用场景 单工具调用、交互式工具 多工具独立调用 线程模型 主线程顺序执行 ThreadPoolExecutor(最多 8 线程) 中断支持 每工具前检查 5s 轮询 + 线程级中断 心跳机制 — 每 30s 发送心跳 四、并发决策引擎 _should_parallelize_tool_batch() 是并发调度的核心决策函数。它通过三层规则判断一个工具批次是否可以安全并行: 第一层:绝对禁止并行 如果批次中包含 _NEVER_PARALLEL_TOOLS (当前为 clarify 交互式工具),直接降级为串行执行。 第二层:路径范围检查 文件工具( read_file 、 write_file 、 patch )通过 _paths_overlap() 检查目标路径是否冲突。只有当所有文件工具指向 不同目录树 时才允许并发。 📄 tool_dispatch_helpers.py (第 166-174 行) def _paths_overlap(left: Path, right: Path) -> bool: """Return True when two paths may refer to the same subtree.""" left_parts = left.parts right_parts = right.parts common_len = min(len(left_parts), len(right_parts)) return left_parts[:common_len] == right_parts[:common_len] 第三层:安全工具白名单 不在路径范围列表中的工具,必须存在于 _PARALLEL_SAFE_TOOLS 白名单中(如 web_search 、 vision_analyze 等),或者来自支持并行的 MCP 服务器。 五、三重拦截:Block 评估机制 在工具真正执行之前,Hermes 施加…