AI / LLM

群聊收录该什么时候处理,从逐轮、按天到等讨论停下来

2865 字约 10 分钟

摘要机器人把 QQ 群聊整理成论坛帖子,多久交给大模型处理一次?先后试过逐轮收录、每天两批和等讨论停下来再收,用一个月的真实聊天做了模拟和回放,比较调用次数、等待时间和被切断的讨论。

我在做的论坛有一个功能,机器人会把 QQ 群聊整理成论坛帖子,我叫它“收录”。在另一篇文章里我记录过,大模型的花费主要取决于调用次数,而不是消息条数。这自然带出下一个问题,既然调用越少越好,那么什么时候调用一次最合适。

最初的做法是逐轮收录,每 10 分钟或每攒到 30 条消息就切一轮。它有两个明显的毛病,一天要调用九十多次,还常常把一场正在进行的讨论从中间切成两半。

按天汇总的想法

白天 8 点到 18 点,这个接口的价格翻倍,而群里最热闹的恰好就是白天。那天晚上我冒出一个念头,能不能每天集中收录一次,用整天的消息一起处理,收完在群里发一条汇总,@ 对应的人并附上帖子链接。

助手先帮我把利弊摊开了。好处有四点。

  • 全部放到夜里跑,白天那部分的花费直接减半。
  • 一次拿到整天的消息,可以在真正的空档处下刀,让一场讨论尽量完整地留在同一段里。
  • 一个问题当天后来的回答和补充,在同一段里就能看到,不用先发帖、过几轮再回头更新。
  • 机器人说话少了,一天一条汇总,比每轮都可能发回执更不容易触发风控。

代价也有四点。

  • 消息要先存到磁盘上,群聊原文会落在跑机器人的那台电脑里。
  • QQ 的图片链接几个小时就失效,第二天早上再取就取不到了,所以消息一到就得把图片转存到论坛。
  • 少了“当场指给提问的人一个旧帖”的能力,这是我很看重的功能,得等到第二天。
  • 汇总消息要重新设计,一天可能有十几个帖子,@ 太多会很长。

我权衡之后决定先做。最终的流程是消息到了就写进文件,撤回也记一行;每天 18 点和凌晨 4 点各收一批,两批都是夜间价;早上 8 点每个群发一条汇总,没有新帖子的群不发。

一批消息要先切成若干段,每段最多 50 条。切的时候先找消息之间隔得最久的地方下刀,再把相邻的小段并起来,免得夜里零星几条各占一段。

通俗比喻:剪录音带要在没人说话的地方下刀

一盘很长的会议录音,要剪成几段分给不同的人整理。如果随便按时长剪,很可能刚好剪在某个人说到一半的地方。更好的做法是找录音里停顿最长的地方剪开,每一段里的对话尽量完整。

每一段前面再附上几句上一段的结尾,接话的人就不会不知道前情。这里每段前面都会带上 20 条上下文。

先不花钱,用假的模型把 3586 条消息空跑了一遍,切成 95 段,平均每段 38 条。聊得密的时候,约三分之一的段是在间隔不到 1 分钟的地方切开的,只能靠每段前面带的上下文接上。

再用真实的模型试了两小段。一段是讨论密集的白天,242 条消息收出 9 个帖子、23 条回复,花了 16.3 积分,平均每条 0.067 积分。另一段是晚上的闲聊,302 条消息一个帖子也没收,只花了 4.6 积分,平均每条 0.015 积分。我翻了原文,确认那一段确实都是闲聊。

夜里没人看着,出错怎么办

按天批处理意味着大部分时间没人盯着。第一次真实回放时,连续 4 段都在生成途中被对方断开了连接,如果当时是线上,这 4 段最多 200 条消息就丢了。

所以我把“出错以后怎么办”写成了明确的规则。原则很简单,服务暂时用不了,这一段就留着稍后重收,只有这一段本身有问题才丢掉。

情况处理方式
大模型断开连接、回答没传完、返回 5xx隔 30 秒、2 分钟、5 分钟各重试一次
重试仍然失败,限流排满 10 分钟,令牌失效,或当天额度用完这一批先停下,这一段留在文件里,10 分钟后接着收
论坛连不上、返回 5xx,或本机的嵌入模型没开机同上,停下等待
思考撞上输出上限、输出不是合法的 JSON、请求本身有问题丢掉这一段,继续下一段,因为再试多半还是一样,白花积分

还有两个细节。每次接着收之前,先确认论坛和嵌入模型都能连通,再去调大模型,否则积分花了,发帖时才发现论坛不通,重收还要再花一遍。已经发出去的帖子靠幂等键识别,重收不会重复发。

半天才上论坛,还是太慢

按天汇总上线之后,我又去问助手,能不能做得更接近实时一些。消息平均要等七八个小时才会出现在论坛上,这让我不太满意。前提是额度消耗尽量少,收录效果也不能变差。

这一次助手没有凭感觉估,而是用导出的主群记录(10 月 1 日到 16 日,平均每天 1733 条)在本地做了模拟,不调用大模型,只数调用次数和切口。

做法每天调用次数每天在讨论中间切开消息等多久才被收录(中位数)
每天两批(当时的做法)4742七八个小时
群里安静 30 分钟就收,或攒到 150 条6049约 50 分钟
群里安静 20 分钟就收,或攒到 100 条6453约 37 分钟

一个反直觉的发现是,“每天两批”也一样会切断讨论。主群太活跃,一批里每段最多 50 条,每天本来就要在讨论中间切 42 次左右。所以实时收录并没有让情况明显变差,调用次数只多了三成。

额度也不是瓶颈。主群有 49% 的消息出现在白天,改成实时以后这部分要按两倍价,每天的花费会涨,但仍然只占每周额度的一小部分。真正要权衡的是收录的效果。

只看时间会收出很碎的轮次

我看到表格后提了一个问题,如果半小时后有人发了一条,之后又过了半小时都没人说话,这一轮岂不是只有一条消息,也要调用一次大模型吗?

一个会浪费调用的场景

下午 3 点 10 分,有人在群里问了一句话,没人回应。3 点 40 分,规则判定“已经安静了 30 分钟”,于是为了这一条消息,把收录标准、版块、标签和正在跟进的帖子全部重新读一遍。

助手确认,只看时间确实会这样。模拟里这种不到 10 条就收的轮次,平均每天有 8.2 次。于是加了一个条数下限,规则变成三条,每 10 分钟检查一次各群。

  1. 群里已经安静 30 分钟,并且攒了至少 20 条,全部收走。不够 20 条的接着等,合进下一轮。
  2. 群里已经安静 30 分钟,而最早的一条已经等了 3 小时,不管几条都收,免得一个没人接话的提问一直压着。
  3. 一直没有安静下来,攒到 150 条时,在最早的 75 条里找隔得最久的地方切开,前面的先收,后面还在聊的继续等。

模拟还顺带发现了原规则的一个漏洞。“攒到 150 条就切”有时会切出只有一两条的一轮,所以又补了一条,切口前面至少要有 20 条。加上这些之后再模拟一遍。

每天两批只看时间时间加条数
每天调用次数476053
不到 10 条就收的轮次(每天)—8.20.4
每天在讨论中间切开424944.6
消息等待时间中位数七八个小时50 分钟41 分钟,九成在 2 小时内

下限需要到 20 条才有明显效果,再往上加帮助不大。副作用也很清楚,这个规则对一直断断续续慢慢聊的群有点吃亏,只要每次间隔都不到 30 分钟,又攒不到 150 条,就得等到群里安静下来才收。这种情况很少,消息也不会丢,所以我没有为它再加规则。

用同一天回放对照

规则写好之后,我让助手把主群 10 月 11 日全天 1729 条消息,用两套规则各回放了一遍,并把中途出错的情况也算上。

每天两批讨论停下来就收
段数 / 大模型调用次数45 / 6450 / 70
新帖 / 回复 / 更新20 / 91 / 521 / 94 / 3
被丢掉的输出项42
输入 / 输出 token236k / 223k260k / 212k
积分112.7(全按夜间价)147.7(白天收的按两倍价)

两边收出的帖子里有 17 个是同一个问题或话题,标题几乎一样。各自多出来的两三个,也都是同一类群聊内容。同一种做法跑两次,帖子数本来就会差一到四个,所以这点差别在模型自身的波动范围内。按同样的价格折算,新做法大约是 111 积分,原来是 113,多出来的花费全部来自白天的两倍价。

这次回放多花了一倍的钱

助手一开始不小心把基准那一遍同时启动了两份,发现后停掉了一份,但只停掉了外层的脚本,里面的回放进程还在继续跑。结果两种做法各跑了两遍,一共花了约 280 积分,是预告的 150 的将近两倍。统计结果不受影响,每份数据只来自一次完整的运行,但这笔钱本可以省下。之后它改成先确认没有旧进程还在跑,再启动新的。

最后选了哪个

综合下来,我选了“安静 30 分钟并攒够 20 条,或最早一条等满 3 小时,或攒到 150 条”这套规则。大多数消息在一小时内就能出现在论坛上,调用次数只比每天两批多三成,在讨论中间切开的次数也只多了一成多。

收得越快,还有一个附带的好处。群里有人问了论坛上已有答案的问题,机器人能更早地把刚收录的帖子推给他。至于周末要做的历史导入,不需要赶时间,仍然按每天两批的切法跑,调用更少,讨论也切得更完整。

两个群都打开之后,估计一天 250 到 300 积分,约占每周额度的 10%。换成更强的模型要贵三倍,一天将近三成,没有采用。

评论