DeepAI Paper Hermes Agent 教程,Hermes Gateway 与消息平台,Hermes 终端、Docker 与安装 9000 轮配置,为什么跑着跑着又变成 90?Hermes Gateway 被旧 .env 反杀的配置优先级坑

9000 轮配置,为什么跑着跑着又变成 90?Hermes Gateway 被旧 .env 反杀的配置优先级坑

你在 config.yaml 里把 Hermes Agent 的最大轮数设成 9000,重启 Gateway,看起来一切正常。

结果长任务跑起来后,状态提示却写着:

Still working... (10 min elapsed — iteration 30/90, running: delegate_task)

这不是错觉。

NousResearch/hermes-agent issue #19158 记录的正是这个问题:Gateway 的 agent.max_turns 可能会被 ~/.hermes/.env 里一个陈旧的 HERMES_MAX_ITERATIONS=90 覆盖。

最恶心的是,它不是启动时立刻暴露,而是可能在 Gateway 后续 turn 里被 .env reload 重新污染。


现象:config 写 9000,Gateway 仍显示 90

用户的配置是:

agent:
  max_turns: 9000
  gateway_notify_interval: 600

预期很明确:Gateway 创建的 AIAgent 应该使用 9000 轮上限。

但 Slack Gateway 的长任务心跳却显示:

Still working... (10 min elapsed — iteration 30/90, running: delegate_task)

也就是说,运行中的 Agent 仍然认为上限是 90。

这类问题特别容易误导排查方向:

  • 以为 Gateway 没重启;
  • 以为 config.yaml 没加载;
  • 以为 Slack Gateway 有单独限制;
  • 以为 delegate_task 自己限制了轮数。

但 issue 给出的关键线索是:旧 .env 里还残留:

HERMES_MAX_ITERATIONS=90

根因:启动桥接修了,但 per-turn dotenv reload 又把旧值带回来

issue 的调查非常清楚。

Hermes Gateway 启动时,会把:

agent.max_turns: 9000

桥接到环境变量:

HERMES_MAX_ITERATIONS=9000

这一步本来是为了让旧的 env-based 读取路径也能拿到新配置。

但后续 Gateway turn 里,为了刷新 credentials,又会调用类似:

load_dotenv(_env_path, override=True, encoding="utf-8")

如果 ~/.hermes/.env 里还留着:

HERMES_MAX_ITERATIONS=90

那么 override=True 就会把启动时桥接出来的 9000 覆盖回 90。

下一次创建 agent 时,又会走:

max_iterations = int(os.getenv("HERMES_MAX_ITERATIONS", "90"))

于是问题发生:

config.yaml 写了 9000
启动时也桥接成了 9000
但 per-turn reload .env 后又被旧 90 覆盖
最终 Agent 读到 90

这就是标题里的“旧 .env 反杀新配置”。


为什么这个问题不像普通优先级冲突?

普通配置冲突通常是启动时一次性决定:

.env 优先,或 config.yaml 优先

#19158 更危险,因为它发生在运行过程中。

启动时看起来可能是对的,后续某个 turn 重新加载 .env,环境变量才被污染。

这会导致:

  • 第一次看日志不一定能发现;
  • 重启后短时间内可能看起来正常;
  • 长任务或多轮 Gateway 才暴露;
  • 用户很难判断到底哪个来源生效。

对消息平台 Agent 来说,这类 bug 很典型:Gateway 不是一次性 CLI,而是长期进程。长期进程里的 dotenv reload 如果没有边界,很容易把“旧配置”重新带回 runtime。


官方评论:可能是 #18764 的同类问题或回归路径

评论里维护者指出,这很可能是 #18764 的重复问题:同样属于 .env-overrides-config 类 bug。

还提到相关问题:

  • #18764:已合并修复的同类问题;
  • #17534 / #17672:setup wizard dual-write 相关;
  • 本 issue 可能捕获了 post-#18764 的 dotenv-reload 剩余路径。

用户进一步说明:

  • #18764 修了启动桥接;
  • 但当前 origin/main 里,Gateway 创建 agent 仍直接读 os.getenv("HERMES_MAX_ITERATIONS", "90")
  • 后续 run_sync 又以 override=True reload .env
  • 因此 stale .env value 仍可能在下一轮污染环境。

这就是为什么这篇不是简单写“删掉 env 就好”,而是强调运行时 reload 路径的配置优先级问题。


临时 workaround:注释掉旧 HERMES_MAX_ITERATIONS

issue 中给出的本地规避方式很直接:

# HERMES_MAX_ITERATIONS=90

保留 config.yaml

agent:
  max_turns: 9000

然后重启 Gateway。

这样 .env reload 时就不会再把 90 写回 os.environ

但这只是 workaround,不是理想修复。


更合理的修复方向

issue 提了两个方向。

1. 明确让 config.yaml 优先

特别是在 Gateway 已经有 agent.max_turns 的情况下,runtime dotenv reload 不应该覆盖它。

可以理解为:

agent.max_turns 是 Gateway 配置,不应被后续 credentials reload 反向覆盖。

2. 如果 env 是 intentional override,就要显式告警

如果 Hermes 设计上允许:

HERMES_MAX_ITERATIONS=90

覆盖:

agent.max_turns: 9000

那也应该在启动或 agent creation 时打印清楚:

Resolved max_iterations=90 from ~/.hermes/.env, overriding config agent.max_turns=9000

否则用户只能从 iteration 30/90 反推,体验很差。

3. 最应该补的是 resolved source diagnostics

配置类问题最怕“值变了,但不知道谁改的”。

一个好的日志应该包含:

  • resolved value;
  • source;
  • conflicting value;
  • whether override occurred;
  • whether reload changed previous runtime value。

比如:

Gateway max_iterations resolved: 9000 from config.yaml agent.max_turns
Ignoring stale .env HERMES_MAX_ITERATIONS=90

或:

Gateway max_iterations resolved: 90 from .env HERMES_MAX_ITERATIONS
Warning: overrides config.yaml agent.max_turns=9000

怎么判断你是否遇到这个坑?

如果你遇到以下现象,就很像 #19158

  • config.yaml 里设置了很大的 agent.max_turns
  • Gateway 重启过;
  • 长任务状态仍显示 iteration X/90
  • ~/.hermes/.env 里有旧的 HERMES_MAX_ITERATIONS
  • 注释掉 .env 里的旧值后恢复正常。

排查顺序建议:

1. 查 config.yaml

agent:
  max_turns: 9000

2. 查 .env

grep HERMES_MAX_ITERATIONS ~/.hermes/.env

如果看到:

HERMES_MAX_ITERATIONS=90

先注释掉。

3. 重启 Gateway

例如 issue 中的进程形式:

python -m hermes_cli.main gateway run --replace

4. 观察下一次长任务心跳

重点看:

iteration X/90

是否变成你设置的目标上限。


和 DeepAI API 中转站的关系

这不是 DeepAI API 中转站问题,也不是模型 API 质量问题。

DeepAI API 中转站适合解决模型接入、OpenAI-compatible API、统一 Key / base URL / 模型路由等问题。

但 Gateway 的 max_turns.env 旧值覆盖,属于 Hermes 配置优先级和运行时 dotenv reload 问题。

准确边界是:

DeepAI 管模型接口,Hermes 管 Agent 运行时配置。

如果你在 Cherry Studio、Cline、Dify、Open WebUI 这类支持 OpenAI-compatible API 的工具中接入 DeepAI,需要关注的是 base URL、API key、模型名和调用协议。

如果你在 Hermes Gateway 里看到 iteration X/90,则应该查 agent.max_turnsHERMES_MAX_ITERATIONS.env reload,而不是换模型 provider。


FAQ

为什么我写了 agent.max_turns: 9000,Gateway 还是 90?

可能是 ~/.hermes/.env 里残留了 HERMES_MAX_ITERATIONS=90,并且 Gateway later turn 使用 load_dotenv(..., override=True) 重新覆盖了环境变量。

重启 Gateway 为什么不一定解决?

因为重启后启动桥接可能短暂写入 9000,但后续 turn reload .env 时又把旧 90 覆盖回来。

最快 workaround 是什么?

注释或删除 ~/.hermes/.env 中的旧 HERMES_MAX_ITERATIONS=90,保留 config.yaml 里的 agent.max_turns,然后重启 Gateway。

这是 Slack Gateway 特有问题吗?

issue 的复现平台是 Slack Gateway,但根因是 Gateway 配置与 dotenv reload 的优先级,因此类似长期 Gateway 入口都值得检查。

DeepAI 能解决这个问题吗?

不能。这是 Hermes Gateway runtime 配置问题,不是模型 API 问题。


总结

#19158 的核心教训是:

配置优先级不是只在启动时决定一次,长期 Gateway 进程里的 reload 也会改写现实。

agent.max_turns: 9000 本身没错,启动桥接也可能没错。真正的问题是旧 .env 在后续 turn 中以 override=True 重新进入环境,把 HERMES_MAX_ITERATIONS 拉回 90。

对 Agent 框架来说,配置系统最需要的不是“多给用户一个字段”,而是让每个运行时值都能回答:

我是谁设置的?什么时候设置的?为什么我赢了?

Related Post

一个工具会失败,两个工具反而可能成功:Hermes Memory 调度路径的反直觉 bug一个工具会失败,两个工具反而可能成功:Hermes Memory 调度路径的反直觉 bug

Hermes Honcho memory tools 在单工具调用时返回 Unknown tool,但多工具并发路径有时正常。本文复盘 #15118:schema 已注入不代表执行层会路由成功,sequential dispatch 漏掉 MemoryManager.has_tool() 才是真正根因。

Hermes terminal 误拦截 setsid:安全过滤为什么不能只靠全文正则Hermes terminal 误拦截 setsid:安全过滤为什么不能只靠全文正则

Hermes terminal tool 为了拦截 nohup、disown、setsid 这类 shell-level background wrapper 使用了全文关键词正则,结果连引号、commit message、PR body、echo 和 Python 字符串里的 setsid 也被误拦。本文客观复盘 #20064:安全过滤应识别 shell 命令位置,而不是只匹配任意文本。

Gemini 报 missing thought_signature?Hermes Agent 工具调用历史丢签名的排错指南Gemini 报 missing thought_signature?Hermes Agent 工具调用历史丢签名的排错指南

Hermes Agent 使用 Gemini 3 / preview 模型时报 Function call is missing a thought_signature?这通常不是 API Key 或网络问题,而是 tool call 历史消息丢失 extra_content / thought_signature。本文整理升级、复现和源码排查清单。