DeepAI Paper Hermes Agent 教程 Discord 明明发了代码,Hermes 却像没看见:message.txt 附件被静默吞掉的原因

Discord 明明发了代码,Hermes 却像没看见:message.txt 附件被静默吞掉的原因

在 Discord 里粘贴一大段代码时,很多人以为自己发的是“普通消息”。

但 Discord 可能会悄悄做一件事:把长文本自动转成附件。

文件名通常是:

message.txt

NousResearch/hermes-agent issue #12511 讲的就是这个坑:用户把大段代码或长文本直接粘贴到 Discord 输入框,Discord 自动生成 message.txt 附件;Hermes 收到消息事件后,只处理了输入框里的文本,没有正确读到附件内容。

结果就是:

用户以为 Agent 看到了代码,Agent 实际什么都没读到。

更麻烦的是,Discord 里没有明显报错。

用户看到的只是 Hermes 没回应,或者回应得像没看见上下文。


现场表现:PDF 能过,txt / py / html 反而不行

issue 里的用户后续测试很关键。

能正常通过的附件包括:

  • .pdf
  • .xlsx
  • image files

不能正常通过的包括:

  • .py
  • .txt
  • .html
  • .m

这说明问题不只是“Discord 附件没处理”。

因为某些附件类型是能走通的。

真正的问题藏在更底层:文本类附件的下载/解码路径。


第一层误会:不是附件路由没写

一开始看起来像 Hermes 没把 .txt 作为支持文档处理。

但评论里进一步定位后指出:

.txt 已经在 SUPPORTED_DOCUMENT_TYPES 里

而且 Discord adapter 里的 text injection path 本来应该能把文本注入给 Agent。

也就是说,逻辑上 Hermes 是准备处理 message.txt 的。

真正失败发生在:

附件字节还没成功下载回来。

真正根因:Discord 的 message.txt 使用 Brotli 压缩,aiohttp 解码炸了

评论中给出的关键日志是:

WARNING gateway.platforms.discord: [Discord] Authenticated attachment read failed for message.txt: 400, message:
  Can not decode content-encoding: br
WARNING gateway.platforms.discord: [Discord] Failed to cache document message.txt: 400, message:
  Can not decode content-encoding: br

底层 traceback 指向 aiohttp 解压:

TypeError: process() takes exactly 1 argument (2 given)

这个错误的链路是:

1. Discord 给 message.txt 附件返回:

   Content-Encoding: br

也就是 Brotli 压缩。

2. aiohttp >= 3.10 期望 Brotli 解压器支持:

   Decompressor.process(data, max_length)

3. brotlicffi 支持这个 2 参数签名。

4. 但环境里安装的是 Google 的 Brotli 包,它的签名是:

   Decompressor.process(data)

5. aiohttp 优先尝试:

   import brotlicffi as brotli

没有时 fallback 到:

   import brotli

6. 结果加载了不兼容的 Brotli,在处理 br 响应时崩溃。

所以,Hermes 不是“不想读 message.txt”。

它是在下载/解码阶段被 Brotli 兼容性坑住了。


为什么图片、PDF、xlsx 能过?

因为这些文件可能不是通过同样的 Brotli 文本附件路径返回。

评论里观察到:

PDF / xlsx / images go through uncompressed

所以它们不触发 aiohttp 的 br 解码问题。

这也解释了为什么用户会觉得很奇怪:

附件功能明明能用,为什么偏偏代码文本不行?

答案是:代码文本被 Discord 自动包装成 message.txt,并且这个下载响应走了 Brotli 压缩。


这个 bug 为什么容易误判成 Agent 没能力读代码?

因为用户的动作是“粘贴代码”。

用户脑中流程是:

我把代码发给 Agent → Agent 应该分析代码

但实际平台流程是:

粘贴大段文本 → Discord 自动生成 message.txt 附件 → Hermes 下载附件 → aiohttp 解压 br → 失败 → 内容没进入 Agent

中间任何一层失败,最终表现都是:

Agent 没看见代码。

如果没有日志,用户很难知道到底是:

  • Discord 没发;
  • Hermes 没收;
  • 附件类型不支持;
  • 附件下载失败;
  • 文本注入失败;
  • 模型没理解;
  • 还是 API 层出错。

修复方向:安装 brotlicffi

评论里给出的直接修复是:

Add brotlicffi to the messaging optional dependency.

因为 aiohttp 会优先使用 brotlicffi

它提供 aiohttp 需要的 2 参数签名:

process(data, output_buffer_limit)

受影响用户可以临时执行:

$VENV/bin/pip install brotlicffi
hermes gateway restart

或者 systemd 部署时:

systemctl restart hermes-gateway

评论中也说明,实测安装 brotlicffi 后,message.txt 能正常解压,并通过已有的 pending_text_injection 路径进入 Agent。


排查清单:Discord 贴代码后 Hermes 没反应怎么办?

可以按这个顺序查。

1. 看 Discord 是否生成了附件

如果消息旁边出现:

message.txt

说明你发出的不是纯 inline message,而是附件。

2. 看 Hermes Gateway 日志

重点搜:

message.txt
Can not decode content-encoding: br
Authenticated attachment read failed
Failed to cache document

如果看到这些,基本就是 Brotli 解码问题。

3. 检查环境里有没有 brotlicffi

$VENV/bin/pip show brotlicffi

没有就安装:

$VENV/bin/pip install brotlicffi

4. 重启 Gateway

hermes gateway restart

或:

systemctl restart hermes-gateway

5. 再发一段长代码测试

看 Hermes 是否能把 message.txt 内容读入上下文。


对 DeepAI API 中转站用户的边界说明

这篇问题发生在 Discord Gateway 的附件下载与解码层,不在模型 API 层。

所以不要把它误判成:

  • DeepAI API key 错;
  • DeepAI Base URL 错;
  • 模型不支持代码理解;
  • OpenAI-compatible API 没返回。

如果 message.txt 根本没被 Hermes 读进来,那么无论后端模型是 DeepAI、OpenAI、Gemini 还是其他 provider,模型都看不到那段代码。

DeepAI API 中转站能帮你统一的是模型调用入口:

Base URL / API Key / model routing

但 Discord 附件能不能下载、Brotli 能不能解码,是 Gateway 层的问题。


FAQ

为什么我在 Discord 粘贴代码,Hermes 没反应?

可能是 Discord 把长代码自动转成了 message.txt 附件,而旧版 Hermes 在下载/解码这个附件时失败。

为什么 PDF 和图片可以,txt 不行?

因为 message.txt 可能以 Content-Encoding: br 返回,触发 aiohttp / Brotli 解码兼容问题;PDF、xlsx、图片可能未走同样压缩路径。

这是 Hermes 不支持 txt 附件吗?

不是。评论指出 .txt 已在支持类型中,失败点更可能在附件读取/解码层。

临时修复怎么做?

安装 brotlicffi 并重启 Gateway:

$VENV/bin/pip install brotlicffi
hermes gateway restart

DeepAI 能解决这个问题吗?

不能。这是 Discord 附件下载/解码问题。DeepAI 只在内容成功进入模型调用层后才相关。


总结

#12511 的核心不是“Hermes 不会读代码”,而是:

Discord 把长代码变成 message.txt,Hermes 在 Brotli 解码这一层没拿到文本。

对 Gateway 型 Agent 来说,消息进入模型之前还有很多层:平台事件、附件下载、压缩解码、缓存、文本注入。

只要 message.txt 卡在其中一层,模型再强也只能面对一个空上下文。

Related Post

对象不是流:Copilot ACP 把 SimpleNamespace 塞进迭代器后的连锁崩溃对象不是流:Copilot ACP 把 SimpleNamespace 塞进迭代器后的连锁崩溃

Hermes copilot-acp 使用 claude-opus-4.7 时出现 SimpleNamespace object is not iterable,不是模型或 API Key 问题,而是 ACP adapter 把对象当成 stream iterable 处理。本文复盘 #16271,解释 acp://copilot 的 response 形态为什么不能靠猜。

Hermes 代理后访问网页被 Blocked?198.18.0.0/15 Fake-IP 被当成私网的排查Hermes 代理后访问网页被 Blocked?198.18.0.0/15 Fake-IP 被当成私网的排查

Clash、Mihomo、Sing-box、Surge 开启 TUN/Fake-IP 后,Hermes 访问普通网站却报 Blocked: URL targets a private or internal address?本文解释 198.18.0.0/15 RFC2544 网段、Python ipaddress.is_private、SSRF 防护误拦和 allow_private_urls 的安全取舍。

OpenAI-compatible API 报 unsupported_parameter:max_tokens 和 max_completion_tokens 为什么不能只看 Base URL?OpenAI-compatible API 报 unsupported_parameter:max_tokens 和 max_completion_tokens 为什么不能只看 Base URL?

自定义 OpenAI-compatible Base URL 调用 gpt-4o、gpt-4.1、gpt-5 或 o-series 模型时,为什么会报 Unsupported parameter: max_tokens?本文复盘 Hermes Agent #13901,解释 max_tokens / max_completion_tokens 不能只按 host 判断,而应按模型族和后端能力适配,并自然引导到 DeepAI API 中转站的统一接入场景。