在 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 卡在其中一层,模型再强也只能面对一个空上下文。