跳到正文

BettaFish

一个舆情分析系统:几种研究型智能体被刻意安排互相辩论,好让最后交出来的不只是某一个模型的观点被写长。

Screenshot of BettaFish
编辑截图, 28 Sep 2026BettaFish ↗

这是什么

一个从零写起的多智能体系统,读取舆情并为此写出一份报告。你描述想知道什么,一个爬虫集群就铺向三十多个社交平台——包括评论区——同时几种专用智能体从不同角度处理这些材料:查询引擎、处理视频与图片的媒体引擎、挖掘你提供的私有数据库的洞察引擎、主持智能体之间辩论的论坛主持人,以及负责拼接产出的报告引擎。它自托管、跑在 Docker 里、接受任何 OpenAI 兼容模型,并且自 2024 年 7 月起就是公开的。

谁做的学生,主页把中科大(USTC)和北邮(BUPT)列为所在机构;他的后一个项目也在这个档案里。两个仓库值得放在一起看:这一个自 2024 年 7 月起就公开,贡献者名单有 42 个名字,有六个打了 tag 的正式版本,README 标题旁还挂着三个带推广链接的赞助商 logo。他还用一套自动化 agent 处理外部贡献——仓库里几乎每一条维护者回复都以「Agent automated reply on behalf of the maintainer」开头,而且这些回复不是敷衍确认:它们会复现 PR、跑测试套件、给出分级的具体结论。

制作过程

7 个阶段
  1. 01

    它是什么,以及为什么以一条鱼命名

    项目叫「微舆」,谐音「微鱼」,README 解释了这个名字:斗鱼是一种体型很小、漂亮且相当好斗的鱼,象征「小而强大,不畏挑战」。它做的事是把你用日常语言提出的问题,变成一份建立在舆情之上的研究报告。一个爬虫集群横跨三十多个国内与国际平台——微博、小红书、抖音、快手都在其中——并且越过帖子进入评论线程,因为意见大多真正住在那儿。README 列出六项相对同类工具的优势;其中属于架构而非宣传的是:一层复合分析,把微调模型与统计模型和语言模型混在一起用,而不是把所有事情都交给语言模型;一条多模态路径,能解析短视频并提取天气、日历、股票行情这类结构化信息卡;以及一种把舆情数据与私有业务数据库对接的机制,让企业能把外部情绪和内部数字放在一起读。仓库里附的样例是一份武汉大学品牌声誉分析报告,完整运行的视频在 B 站。

  2. 02

    「论坛」机制,最值得抄的那部分

    最有辨识度的是 README 所说的 agent 论坛。项目不是跑一个智能体、给一段提示词、然后要一份报告;它给不同智能体不同的工具集和不同的思考习惯,并单独引入一个主持人模型,其职责是在它们之间组织一场有结构的辩论。写明的目的是防止一种几乎困扰所有单模型产出的失败:共用同一个模型和上下文的智能体,会收敛到同一种解读,而用四份相同观点拼出来的报告,并不比用一份拼出来的更好。在中间放一个主持人、其职责是让分歧浮现并被处理而不是被抹平,是对一个通常靠改提示词措辞来应付的问题所做的一种廉价结构性修正。这个档案里它的后继项目把同一种直觉推得更远——干脆不再试图得出结论,转而模拟一整个人群——而这里的 README 已经指向那个方向:它把目标写成成为通用的数据分析引擎,并指出只要改动智能体的工具与提示词,就足以把它变成金融市场的分析系统。

  3. 03

    一年只有一颗星,然后十一月的某一周

    这个仓库在本档案里不太一样的地方,是它自己公布增长曲线,而这条曲线就是故事本身。有记录的第一天,2024 年 7 月 5 日,1 颗星。到 2025 年 8 月底是 272 颗——十四个月,一条近乎平直的线,而项目全程都是公开的。然后十月:月初 674 颗,31 日 2,082 颗。接着 11 月 1 日 2,994 颗,之后那一周几乎是垂直的——3 日 6,097、4 日 10,802(单日涨 4,705),8 日 21,983。七天约一万九千颗星。到 11 月底越过 29,000,此后曲线落回平常形态:2025 年底 32,941,三月底 39,556,六月底 41,501,现在 42,308。关于作者的报道把这件事说成「公开后一周涨两万星」——周是对的,时间点则有误导:真正点燃它的那次发版,发生在仓库开启十六个月之后。

  4. 04

    六个版本、九个 tag,以及一个「并非那个版本」的版本

    共有六个正式发布:2025 年 9 月 1 日 v1.0.0,11 月 4 日 v1.1.0——正是单日涨星最多的那天——四天后的 v1.2.0,11 月 28 日 v2.0.0,12 月 9 日 v2.1.0,以及 12 月 23 日 v3.0.0。六个版本对应九个 tag。仓库还置顶了一个 2026 年 7 月开的中文 issue,是一份常见问题解答,而它的第一个回答就是关于「最新版」这个词的警告:最新已发布版本仍是 v3.0.0,而 main 分支比它多出四十四个提交,两者不能当成同一个东西。报问题时被要求附上 `git rev-parse HEAD` 的输出,而不是写「最新版」,因为这个词现在有两种都说得通的意思。同一页还记录了一个 GraphRAG 模块曾经合入、后来被回退,当前 main 不包含它——并附上合入、回退和后续 PR 的链接。

  5. 05

    维护者用 agent 回复 pull request

    这个仓库最有辨识度的地方不在代码里。维护者在 pull request 和 issue 下的回复,几乎每一条都以「Agent automated reply on behalf of the maintainer」开头,而且这些回复不是确认收到——它们是评审。agent 会检出贡献者提出的那个确切提交,与合并基点比对,跑仓库的测试套件,然后报告发现,结论有分级、也很具体。它既接受也拒绝:在一个加入路由网关、声称项目全部七个引擎都会走它的 PR 上,agent 回复说核心主张没有成立,因为报告引擎导入的是它自己的配置对象,而不是这个补丁所修改的那个。在一个报告严重 SQL 注入的 PR 上,agent 回复说它无法建立从来源到汇点的利用路径,因为涉及的值来自硬编码的内部映射而不是用户输入,而且所提的修复在仓库钉死的数据库库版本上根本跑不起来。在第三个关于 pickle 反序列化的修复上,它认可方向、同时指出不安全的加载函数仍在前面被调用,所以漏洞并没有真正消除——贡献者表示同意。用模型给贡献做分诊已经不新鲜;在一个四万两千星的项目里,把评审文字不加删改、标明出处地公开出来,是另一回事。

  6. 06

    一个 42 位贡献者的项目会收到什么

    1,039 次提交,来自 42 个账号。作者本人占 402 次;接下来三位分别是 301、63 和 53,也就是说有一位分量很重的第二维护者,而不是一堆顺手提交。有 199 次提交来自没有关联账号的身份,也就是设置了 git 名字但没和 GitHub 对应上的人。从 PR 队列进来的东西大多不是新功能:一个 PDF 导出的路径穿越修复,报告主题 `../../tmp/pwned` 这样的值同时被插进了文件名和 `Content-Disposition` 头;给已发布的 Docker 镜像加上 SBOM 与来源证明,而这位作者在发现公开仓库本来就默认附加来源证明之后,公开更正了自己的描述;还有容器仓库、star 图表维护和赞助商链接的修缮。安全报告并非全部被接受,其中一条并不是真的漏洞,而 agent 直接这么说,没有为了和气而合并。这个体量的项目,大部分贡献带宽都花在「别人真正跑起来之后才会坏」的那些事上。

  7. 07

    它留下了什么

    有两样东西把这个仓库和它之后的那一个连起来。第一样是具体的:后继项目所演示的那次舆情模拟,其种子文档就是在这里生成的一份报告——同一所大学,先被这套系统分析,再被下一套系统模拟。第二样是「如何记录自己的制作过程」上的差异。这一个有 1,039 次提交,其中九次带共同作者尾注,三次署名 Claude;后继那个有 59 次提交,其中二十六次带 Claude 的尾注。同一个人、同一种帮助的披露,从不到百分之一的提交,变成了将近一半。两个仓库都没有解释这个变化,而它之所以可见,只是因为提交尾注是元数据而不是正文:没有人需要下决心把它写下来。

相关档案

全部档案 →