Hermes子代理委托与失败 | AI生成和翻译

Home 2026.05

以下是 Hermes 中子代理的工作机制以及网络问题处理的全面说明:

子代理委派如何工作

架构(工具位于 tools/delegate_tool.py):

父代理(你的主对话)
  └─ delegate_task 工具调用
       ├─ [subagent-0] ── ThreadPoolExecutor 工作线程 ── child.run_conversation()
       ├─ [subagent-1] ── ThreadPoolExecutor 工作线程 ── child.run_conversation()
       └─ [subagent-2] ── ThreadPoolExecutor 工作线程 ── child.run_conversation()
            (最多 max_concurrent_children,默认 3 个)

每个子代理获得:

子代理在 ThreadPoolExecutor 中运行。父代理会阻塞直到所有子代理完成(最多等待 child_timeout_seconds,默认 600 秒)。父代理只看到最终摘要 —— 绝不会看到中间的工具调用。

网络故障处理 —— 两层机制

你的日志显示了来自 xiaomi 的流中断。以下是确切发生的情况:

第一层:流级别重试(位于 _interruptible_streaming_api_call 中)

agent/chat_completion_helpers.py 中,流式调用在后台线程中运行,主线程上有一个轮询循环。三个故障检测器:

  1. 过时流检测器 —— 如果在 HERMES_STREAM_STALE_TIMEOUT(默认 180 秒)内没有新块到达,则终止连接,并让重试循环重新连接。对于大上下文会延长超时(>100k token → 300 秒,>50k → 240 秒)。

  2. 工具调用中途流中断 —— 如果流在工具调用 JSON 正在流式传输时中断,并且错误是瞬态的(ReadTimeout、连接重置、SSE “网络连接丢失”),则静默重试,最多 _max_stream_retries 次。它会重置所有累加器,重建 OpenAI 客户端连接池,并重新开始。用户会看到 “⚠ xiaomi 流中断(ReadTimeout)在 122.6 秒后 —— 重新连接,重试 2/3”。

  3. 交付前流中断 —— 如果在任何 token 交付之前流中断,应用相同的重试逻辑。重试用尽后,错误会传播到外层重试循环。

第二层:对话级别重试(位于 conversation_loop.py

当流式层的重试用尽并抛出异常时,外层循环捕获错误:

“模型在工具调用后返回空 —— 提示继续” 这条消息是另一条路径:模型完成了工具调用但没有返回文本内容,因此循环注入一条合成的用户消息,提示模型进行总结/继续。

当网络变化时会发生什么

对于子代理具体来说:

  1. 每个子代理有自己的 API 调用循环。任务中途网络变化意味着所有正在进行的 HTTP 请求都会遇到 ReadTimeout 或连接重置。

  2. 每个子代理独立触发流级别重试(这就是为什么你会看到 [subagent-0]、[subagent-1]、[subagent-2] 在大约 122-123 秒同时中断)。

  3. 如果网络在重试窗口内(通常是 3 次尝试)恢复,子代理会静默重新连接并继续。它们的对话历史得以保留 —— 重试会使用相同的消息重新发送相同的 API 调用。

  4. 如果网络在全部重试中保持断开:
    • 流层抛出错误
    • 对话层使用退避重试
    • 如果仍然失败,尝试回退提供商(如果配置了)
    • 如果全部用尽,子代理返回 {"failed": True, "error": "..."}
    • 父代理在委派结果中看到 “failed” 条目并报告它
  5. child_timeout(默认 600 秒)是硬性上限。一个被网络问题卡住的子代理最终会超时。心跳线程(30 秒间隔)监控子代理进度 —— 如果迭代计数和当前工具在 15 个周期内(450 秒空闲)都没有进展,它会停止触碰父代理的活动,让网关超时触发。

  6. 每个子代理在重试时重建自己的 OpenAI 客户端(agent._replace_primary_openai_client),从连接池中清除死连接。

关键配置旋钮

简短回答:子代理执行期间的网络变化会导致所有子代理并行流中断。每个子代理在流级别(3 次尝试,连接重建)和对话级别(退避 + 凭证轮换 + 回退)独立重试。如果网络在大约 5-10 分钟内恢复,大多数子代理会透明地恢复。如果没有,它们会优雅地失败,父代理会收到错误摘要而非结果。


Back Donate