一次「This conversation is too long」死循环排查:压缩摘要的 provider 缺 key

举报
yd_282927746 发表于 2026/10/30 08:21:04 2026/10/30
【摘要】 每轮都报同一句「对话太长」,token 数在 266517 和 266571 之间来回跳。日志里真正的原因是 summary_auth_failure:压缩要调辅助模型写摘要,而那个 provider 没有 key,于是压缩永远失败、下一轮再触发、再失败。附定位命令、三处配置修复和一个 max_tokens 的坑。

症状:每一轮都在同一句话上撞墙

用 Agent 写代码写到下午,对话突然开始反复报同一句:

This conversation is too long (266571 tokens)

诡异的是它并不是"报一次就结束",而是每轮结束都报,数字在 266517 和 266571 之间来回跳。看起来像在重试,但重试之后 token 数没降下来——说明压缩根本没生效。

继续往下翻日志,真正的原因写在另一行:

WARNING agent.context_compressor: compression aborted
         failure_class=summary_auth_failure

summary_auth_failure ——摘要(summary)的鉴权失败。也就是说:上下文压缩这一步,调不动用来写摘要的模型。

先搞清楚压缩链路

Agent 的上下文管理和大多数人的直觉不一样:它不是一个"到上限就丢老消息"的滑动窗口,而是一个两段式过程:

  1. 上下文增长到阈值(我这里是 192k,留了余量给下一次响应)时,触发压缩;
  2. 压缩不是简单截断,而是把前面的对话交给一个辅助模型,让它写成一份结构化摘要,然后用摘要替换掉原始消息。

第 2 步是关键:压缩本身是一次模型调用。所以压缩能不能成功,取决于"辅助模型"这个 provider 配置得对不对。

我的配置里是这样:

auxiliary:
  compression:
    provider: clinepass     # ← 名字在,但 key 不在
  vision:
    provider: clinepass
  title_generation:
    provider: clinepass

clinepass 这个 provider 的历史配置靠环境变量 CLINE_API_KEY。而这台机器上这个变量从来没设过——主对话用的是另一个走网关的 provider,独立配置、能用;辅助模型这一路是空壳。

于是就出现了最难受的形态:

  • 主模型调用正常,对话能继续;
  • 压缩触发 → 辅助模型找不到 key → 抛鉴权错误 → 被归类成 summary_auth_failure;
  • 因为压缩失败,会话仍然处于超限状态;
  • 下一轮请求进来,又超限 → 再触发压缩 → 再失败。

死循环就这么形成了,而且每一轮都在消耗真实 token。

为什么它不直接报错停下

从设计上看,压缩失败时选择"不中断对话"是合理的:丢了压缩还能靠裁剪硬撑,中途终止对话反而更糟。但这里的问题是失败被降级成了警告,只写进日志,UI 上只看到"太长了"这种笼统提示。真正的 failure_class 藏在 logs/agent.log 里。

所以排查第一步永远是:别信 UI 上那句话,去日志里找 failure_class。

定位过程(3 分钟)

# 1. 看日志里真正的失败分类
grep -n "failure_class\|compression aborted" ~/.hermes/logs/agent.log | tail -20

# 2. 看辅助模型配的是哪个 provider
hermes config get auxiliary.compression.provider
hermes config get auxiliary.vision.provider
hermes config get auxiliary.title_generation.provider

# 3. 看那个 provider 的 key 到底在不在
hermes config get providers.<name>      # 或直接看 .env 里对应的 *_API_KEY

第 3 步几乎一击即中:provider 名字写着一个需要 XXX_API_KEY 的服务,而环境里根本没有这个变量。

修复:把辅助模型指向一个真的能用的 provider

三个辅助用途(压缩、视觉、标题生成)都要换,别只改压缩——不然下次是图片识别或会话标题先炸。

hermes config set auxiliary.compression.provider custom:cpamp
hermes config set auxiliary.vision.provider custom:cpamp
hermes config set auxiliary.title_generation.provider custom:cpamp

custom:<name> 指向已经在 providers: 下配好 base_url 和 key 的网关,这样辅助调用和主对话共用同一套凭据,不会再出现"主能用、辅不能用"的割裂。

注意两点:

  • 不要直接手改 config.yaml,Hermes 会拒绝写自己的配置文件,用 hermes config set;
  • 配置是热加载的,改完不需要重启进程,下一轮就生效。

改完验证一下:

# 用同样的模型和 key 打一次最小请求,确认不是空响应
curl -s -X POST "$BASE_URL/chat/completions" \
  -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"model":"<你的模型>","max_tokens":300,"messages":[{"role":"user","content":"说 OK"}]}'

附带的第二个坑:推理模型的 max_tokens

第一版验证时我把 max_tokens 设成 40,直接收到:

HTTP 500: empty response content

不是鉴权问题,是推理模型(带 thinking 的那类)会先花 token 思考,40 个 token 全被思考吃掉,正文为空,网关就判成空响应。验证连通性时 max_tokens 至少给 300,不然会把"模型能通"误判成"模型不可用",绕一大圈。

已经在死循环里了怎么办

修复配置只对下一轮生效,当前这个会话已经超限且压缩失败,最简单的是开新会话;如果不想丢上下文,先把关键结论手抄出来,或者把摘要需要的材料导出成文件,在新会话里再喂回去。

复盘清单

检查项 说明
辅助模型独立可用 压缩/视觉/标题三个用途各配一个真实可用的 provider,别只配主模型
日志看 failure_class UI 的"太长了"没信息量,summary_auth_failure 才是线索
token 数是否在反复横跳 反复出现且不下降 = 压缩一直失败,不是正常重试
配置改动用 CLI 直接编辑 config.yaml 会被拒写
验证连通性别省 max_tokens 推理模型给 40 会得到 empty response content

这类问题的麻烦之处在于它伪装成"上下文太长",而实际是辅助链路的凭据问题。看到"压缩失败"四个字,第一反应应该是去查辅助 provider,而不是急着删历史消息。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0)

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。