一张10×10的表格,100个格子,每个格子都是一个独立的研究智能体。你在行里填"Stripe",在列里填"谁是CEO",点下运行,智能体就自己上网搜索,把答案和来源填进格子。GridMind 这个项目把电子表格变成了智能体矩阵,演示地址和代码都已公开。
![]()
想法挺讨巧,算账就不那么讨巧了。100个格子,每个格子要一次大模型调用做规划、一到两次搜索、再一次大模型调用出答案。Groq 免费档大约每分钟30次请求,Tavily 每月给1000次搜索额度。一次兴冲冲的"全部运行",就能吃掉这个月相当一部分配额,而且第一行还没跑完,429 就开始往外冒。
作者不想掏钱,于是任务变成了一件事:让免费额度撑得久一点。最后落地的只有四个小改动,没有一个是聪明办法。
限流器要坐在限额下面
第一个改动最直白:别发得比服务商允许的更多。实现是一个滑动窗口,大约20行代码。两个细节值得说:Groq 的限流值设成25,不是30。贴着线跑,时钟偏差加上一两次重试就会把你顶过去。另外每次等待结束前加一点随机睡眠,避免上百个等待中的任务在同一时刻集体醒来、一起冲卡。
失败之后按成年人的方式重试
有限流器也照样会撞上429或503。重试采用带抖动的指数退避,并且尊重服务端返回的 Retry-After——服务器告诉你等多久,就信它。只有瞬时错误才重试:408、429、5xx 和超时。撞上自己设的每日调用预算不属于瞬时错误,重试只是白烧时间,所以它抛的是另一个不可重试的异常。
同一个问题别问两遍
这一条省得最多。在一张关于公司的表里,同一行的格子问的几乎是同一件事。搜"Stripe CEO"和搜"Stripe chief executive",结果基本一样,钱是白花的。所以搜索和页面读取都走一个带 TTL 的小缓存,默认一小时。真正起作用的是在途去重:十个格子同时问同一件事,只有第一个真的发出去,其余的都等它的结果。
普通缓存在这里帮不上忙。点"全部运行"的瞬间,所有相同请求都在任何一个完成之前就发出了,缓存里还什么都没有。共享那个尚未完成的调用,才是解法。共享调用失败,失败也一起共享,坏结果不会被写进缓存。
付费额度只用一次,并且留个地板
Tavily 好用,所以每个格子的第一次查询给它,第二次查询转给免费的 DuckDuckGo。一个格子从花两次额度变成花一次。此外还有一个计数器,每月到900次就停,这样永远不会在跑到一半时撞上1000的墙。Tavily 报错或预算用尽,搜索就悄悄回落到 DuckDuckGo,结果差一点,但表格还能填满。
DuckDuckGo 本身也经常被限流。对第二次查询来说这没关系,落空就返回空列表,智能体拿现有的东西继续干活;对第一次查询来说,落空就是真错误。
这套东西没解决什么
作者自己列了三条:
- 所有限流器和计数器都在内存里,按实例计算。跑两个 API 实例,等于在无意中把限额翻了一倍。要做全局就得用 Redis 计数器,这一步还没做。
- 回落意味着答案质量不稳定。用 DuckDuckGo 摘要填出来的格子,可能比用 Tavily 填出来的更单薄。
- 25、40、900 这几个数是凭感觉和服务商公布的限额定的,没有做过压测。
没有一样是花哨东西。一个限流器、一个重试、一个共享在途工作的缓存、一份带回落机制的预算。但合在一起,就是100个智能体的表格能跑在一套零成本配置上的原因。想看限流器怎么工作,打开演示里任意一个格子看它的 trace,智能体做过的每次搜索都列在那里。
特别声明:以上内容(如有图片或视频亦包括在内)为自媒体平台“网易号”用户上传并发布,本平台仅提供信息存储服务。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.