从30亿Token到全自治AGI:飞书回复被"腰斩"的真相(附3行代码修复方案)

0 阅读6分钟

因为刚从csdn迁移到本平台,会先搬运一些以前的文章,还请读者见谅~。~

烧了30亿+token,超10万+api调用次数养龙虾之后,我彻底转向以hermes为执行者的harness工程agi全自治架构

你以为配置了 max_tokens=16384,LLM 就能输出长文本?天真。

在 Hermes Gateway 里,这个参数根本就没传递给 AIAgent。同一套配置,CLI 模式正常,Gateway 模式被静默截断——这不是 bug,是两条代码路径对同一配置字段的不同处理。我花了 3 小时找到它。

一、现象:迁移后飞书回复"腰斩"

从 OpenClaw 迁移到 Hermes 后,我遇到了一个诡异的 bug:

发送"请详细解释量子计算原理" → 收到3行简要总结
发送"写一段10000字的代码教程" → 收到500字概览

同样的模型、同样的 prompt、同样的配置,在 Hermes CLI 里输出完整长文本,但飞书里只有寥寥数行。

我开始怀疑一切:

  1. 飞书 API 限制了消息长度?—— 检查后发现 Hermes 设的是 8000,比 Telegram 的 4096 还宽松
  2. 模型变了?—— 确认是同一个 MiniMax-M2.7-highspeed
  3. prompt 被截断了?—— 检查后发现用户输入完整传递
  4. 流式输出的安全边界?—— 计算后发现 7898 字符上限,但我收到的远不到这个数

真正的问题,远比这些猜测更隐蔽。


二、排查过程:从表面现象到代码真相

第一步:排除输出端限制

检查 gateway/platforms/feishu.py

MAX_MESSAGE_LENGTH = 8000  # 飞书的限制是 8000,比 Telegram(4096)、Discord(2000) 都宽松

消息分块机制 truncate_message 会在超过 8000 时自动分割,不会丢失内容。问题不在输出端。

第二步:检查流式输出

流式消费者有一个安全边界计算:

_safe_limit = max(500, raw_limit - len(cursor) - 100)  # 8000 - 2 - 100 = 7898

但这只是提前分块,不会减少总输出量。我实际收到的回复连 2000 字都不到,问题不在分块。

第三步:对比 CLI 和 Gateway 的行为差异

关键发现:同样的模型配置,CLI 正常,Gateway 异常。

这说明问题在输入端——AIAgent 接收到的参数不同。

检查 cli.py

# CLI 模式
_model_max_tokens = None
if isinstance(_model_config, dict):
    _raw = _model_config.get("max_tokens")
    if _raw is not None:
        _model_max_tokens = int(_raw)  # 16384
self.max_tokens = _model_max_tokens

# 传递给 AIAgent
agent = AIAgent(
    ...
    max_tokens=self.max_tokens,  # ← 16384
)

检查 gateway/run.py

# Gateway 模式
def run_sync():
    agent = AIAgent(
        model=turn_route["model"],
        **turn_route["runtime"],     # ← 只含 api_key/base_url/provider/api_mode
        max_iterations=max_iterations,
        # ❌ max_tokens 根本没有传递!
        quiet_mode=True,
        ...
    )

真相大白turn_route["runtime"] 来自 _resolve_runtime_agent_kwargs() → resolve_runtime_provider(),整个链条完全不读取 model.max_tokens

第四步:验证

$ python3 -c "from hermesCLI.runtime_provider import resolve_runtime_provider; 
runtime = resolve_runtime_provider(); 
print('max_tokens in runtime:', 'max_tokens' in runtime)"
max_tokens in runtime: False

确认:resolve_runtime_provider() 返回的字典里根本没有 max_tokens 字段。


三、根因分析:为什么 CLI 和 Gateway 对同一配置处理不同?

路径max_tokens 处理结果
CLI (cli.py)从 config.yaml 读取并传递给 AIAgent✅ 正常输出 16384 tokens
Gateway (gateway/run.py)完全不读取,不传递❌ 使用 provider 默认值(可能 4096 或更低)

这不是用户配错了,而是代码路径不完整——Hermes 的两个入口(CLI 和 Gateway)对同一配置字段做了不同的处理。

更深层的问题:

  1. _resolve_runtime_agent_kwargs() 设计时只考虑了"连接 provider 需要什么"(api_key, base_url, provider, api_mode)
  2. 没考虑"模型行为配置需要什么"(max_tokens, context_length, temperature 等)
  3. 导致 Gateway 路径的 AIAgent 实际上是一个"半配置"状态——能连上 API,但输出行为不受用户控制

四、修复方案:3 行代码 + 2 处修改

# 在 gateway/run.py 两处 AIAgent 创建前添加:
_max_tokens = None
try:
    _model_cfg = _load_gateway_config().get("model", {})
    if isinstance(_model_cfg, dict):
        _raw = _model_cfg.get("max_tokens")
        if _raw is not None:
            _max_tokens = int(_raw)
except Exception:
    pass

# 然后在 AIAgent(...) 中添加:
max_tokens=_max_tokens,

修复后验证

  • 飞书发送"详细解释" → 得到完整长文本
  • 代码块不再被强制截断
  • 输出质量与 CLI 模式一致

验证命令

# 确认 resolve_runtime_provider 返回值中包含 max_tokens
python3 -c "from hermesCLI.runtime_provider import resolve_runtime_provider; \
runtime = resolve_runtime_provider(); \
print('max_tokens in runtime:', 'max_tokens' in runtime)"

# 验证飞书回复长度是否恢复正常
# 发送测试消息:"请详细解释HTTP/2的多路复用机制,至少500字"
# 对比修复前后的实际输出长度

五、更深层的启示:为什么不要让 Hermes 自己改自己的配置

这次排查让我确认了一个原则:复杂配置的修改应该交给具备 LLM 能力的 IDE(KimiCode、Lingma),而不是让 Hermes 自己改自己。

原因

  1. 跨文件追踪能力:IDE 里的 LLM 能同时查看 config.yaml 和 gateway/run.py,发现 "config 里配置了 max_tokens,但 gateway 没用到" 这类跨模块不一致。而 Hermes 自己运行时只能看到当前文件上下文。
  2. Schema 校验:IDE 的 YAML Language Server 会在保存前检查语法,红色波浪线即时标出错误。Hermes 的"先写入后验证"模式会导致滞后错误。
  3. 事务保护:IDE 的编辑器有撤销/重做机制,改错了可以回退。Hermes 的自修改是单向的,没有自动回滚。
  4. update 安全:每次 hermes update 前,用 IDE 的 Git 功能查看即将变更的文件,让 LLM 评估对现有本地修改的影响,再决定是否合并。

关键区别:不是"不用 LLM",而是"让 LLM 在正确的地方工作"——LLM 负责理解和建议,IDE 负责校验和执行。


六、与 OpenClaw 的对比

维度OpenClawHermes(修复前)Hermes(修复后)
飞书消息长度正常长文本被静默截断正常长文本
max_tokens 传递统一处理CLI 传递,Gateway 遗漏CLI 和 Gateway 都传递
配置一致性单一路径多路径不一致多路径一致
排查难度高(需代码级分析)

OpenClaw 的飞书实现是串行队列处理,没有后来添加的流式输出系统,因此不存在 Gateway/CLI 路径分叉的问题。Hermes 的流式输出是后来通用化到所有平台的,但通用化过程中遗漏了 max_tokens 的传递。


七、迁移检查清单(针对 OpenClaw → Hermes 用户)

  • 发送一条要求详细回答的测试消息,确认回复长度正常
  • 检查 config.yaml 中的 model.max_tokens 是否在 Gateway 路径生效
  • 验证 CLI 和 Gateway 对关键配置字段的处理一致
  • 执行 hermes doctor 识别现有配置错误
  • 使用 IDE(KimiCode/Lingma)管理配置修改,而非自然语言指令

引用来源列表

  1. Hermes Agent 深度解析:一个能自我进化的开源 AI 智能体到底强在哪? - CSDN博客 - 2026-04-13
  2. Hermes Agent vs OpenClaw:2026年两大AI Agent框架深度对比 - CSDN博客 - 2026-04-18
  3. MaxKB本地化部署对接阿里云DeepSeek大模型输出中断问题解决方案 - CSDN博客 - 2025-04-23

个人观点,仅供参考。个人技术观察,具体行为以官方文档为准。