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 Agent 跨平台排错:Windows 代理 502、Docker 后端残留和飞书表格源码显示Hermes Agent 跨平台排错:Windows 代理 502、Docker 后端残留和飞书表格源码显示

基于 Hermes GitHub Issues,总结 Windows 系统代理导致 auxiliary client 502、terminal.backend=local 仍跑 Docker、飞书 Markdown 表格显示源码等跨平台问题,帮助区分 DeepAI 模型层和 Hermes 运行环境层。

Hermes Provider 兼容性排错:reasoning_content、custom headers、上下文长度和 api_mode 继承Hermes Provider 兼容性排错:reasoning_content、custom headers、上下文长度和 api_mode 继承

OpenAI-compatible 不等于 provider 细节完全一致。本文基于 Hermes Issues 解析 reasoning_content 400、Custom Provider headers 403、上下文长度误判、delegate api_mode 继承等兼容性问题,并说明 DeepAI 接 Hermes 时该如何分层测试。

Feishu 配好了,Hermes Gateway 却一启动就崩:RedactingFormatter 没导入造成的假象Feishu 配好了,Hermes Gateway 却一启动就崩:RedactingFormatter 没导入造成的假象

Feishu/Lark 配置看起来没问题,但 Hermes Gateway 启动后反复崩溃?本文复盘 #8173:gateway/run.py 使用 RedactingFormatter 却没有导入,导致启动阶段 NameError,消息根本还没进入平台 adapter。