catchup: a lazy morning brief for group chats, on a laptop with no internet
Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady Submission 🦥 This is a submission for the Hacktoberfest Open-Source AI Challenge Week 3: Slow and Steady What I Built catchup reads a WhatsApp chat export and gives you a short brief: what the chat was about, what got decided, and which questions are still open. it is for the group chat you skipped last night and don’t want to scroll. the lazy part: you export once, run one command, and read three lines instead of two hundred messages. it runs on a small open-weight model (Gemma 3 1B, GGUF, through llama.cpp). nothing leaves the machine. this project was built fully autonomously by an AI coding agent on my behalf. i did not write the code myself.
Hacktoberfest 开源 AI 挑战赛第三周:稳扎稳打提交 🦥 这是我为 Hacktoberfest 开源 AI 挑战赛第三周“稳扎稳打”所做的提交。我构建了 catchup,它可以读取 WhatsApp 的聊天导出文件并为你提供简短摘要:聊天的主题是什么、决定了什么,以及还有哪些悬而未决的问题。它是为你昨晚错过且不想翻阅的群聊准备的。所谓“懒人”之处在于:你只需导出一次,运行一条命令,就能读到三行内容,而不是两百条消息。它运行在一个小型开放权重模型(Gemma 3 1B, GGUF,通过 llama.cpp)上。没有任何数据会离开你的机器。该项目完全由 AI 编码代理代表我自主构建,我本人并未编写代码。
Demo https://maybesomeone-arc18.github.io/catchup/demo/ the page runs the rules-only brief in your browser (paste an export, no upload). the Gemma output is precomputed from the CLI and shown as it came out, including where it is wrong. Code https://github.com/MaybeSomeone-arc18/catchup How I Built It the model does not decide what matters. plain rules do: a parser reads the export, drops system lines, joins wrapped lines, flags media. a scorer picks the load-bearing lines: question marks, question words, dates and times, plan words, your name. Gemma 3 1B gets only those lines and writes at most three short lines of prose. a checker compares every name, number and date in the answer with the chat. if something is not in the source, the answer is thrown away and a plain extractive brief is printed. stack: Python, llama-cpp-python 0.3.36, Gemma 3 1B instruct Q4_K_M. 15 unit tests for the parser, scorer and checker.
演示地址 https://maybesomeone-arc18.github.io/catchup/demo/ 该页面在你的浏览器中运行仅基于规则的摘要(粘贴导出内容,无需上传)。Gemma 的输出是预先通过命令行界面计算出来的,并按原样显示,包括其中错误的部分。代码地址 https://github.com/MaybeSomeone-arc18/catchup 我是如何构建它的:模型并不决定什么重要,简单的规则才是关键:解析器读取导出文件,删除系统行,合并换行,标记媒体内容。评分器挑选出关键行:包含问号、疑问词、日期时间、计划词汇以及你的名字的行。Gemma 3 1B 只接收这些行,并撰写最多三行短文。检查器会将答案中的每个名字、数字和日期与聊天记录进行比对。如果答案中包含源文件中不存在的内容,该答案会被丢弃,并打印出一份简单的提取式摘要。技术栈:Python, llama-cpp-python 0.3.36, Gemma 3 1B instruct Q4_K_M。包含 15 个针对解析器、评分器和检查器的单元测试。
What I measured 4 hand-written chats (3 to 19 messages), on a 2-core, 2 GB RAM sandbox: 3 of 4 Gemma briefs passed the source check. 1 was rejected and replaced by the template. 7.1 s median, 8.8 s max per brief. then i read the 3 passing briefs against the chats myself. one was vague but fine. two had wrong claims. for example it wrote that Ma called Didi, when Rohan did. it also turned “finalising the plan” into “finalising goals”. so the checker does what it says: it stops invented names and numbers. it does not stop a 1B model from mixing up who did what. a brief can pass and still be wrong. the other result surprised me. on the exam chat, the rules-only brief in the demo (the five rule-picked messages, verbatim) was more useful than the Gemma summary. it kept “deadline moved to wednesday 6 pm” and “does wednesday’s test cover unit 5 as well?” word for word. the model dropped both.
我的测试结果:在 2 核、2 GB 内存的沙箱环境中,对 4 个手写聊天记录(3 到 19 条消息)进行了测试:4 个 Gemma 摘要中有 3 个通过了源检查。1 个被拒绝并替换为模板。每个摘要的中位数耗时 7.1 秒,最大耗时 8.8 秒。随后,我亲自对照聊天记录阅读了那 3 个通过的摘要。其中一个比较模糊但尚可,另外两个包含错误陈述。例如,它写道“Ma 给 Didi 打了电话”,而实际上是 Rohan 打的。它还将“确定计划”变成了“确定目标”。因此,检查器的作用正如其名:它能阻止虚构的名字和数字,但无法阻止 1B 模型混淆谁做了什么。一个摘要即使通过了检查也可能是错误的。另一个结果让我感到惊讶:在考试聊天记录中,演示中仅基于规则的摘要(即通过规则挑选出的五条原始消息)比 Gemma 的总结更有用。它逐字保留了“截止日期移至周三下午 6 点”和“周三的考试也涵盖第 5 单元吗?”,而模型将这两条都丢弃了。
Why Does Open Innovation Matter? group chats are private. with an open-weight model the chat stays on your own machine, with no server and no account. it costs nothing to run, today or later, so a lazy tool does not turn into a subscription. the checker only works because i can see and control the whole pipeline. i can swap the model file, tighten the check, or drop the model and keep the rules. with a closed API i could not guarantee the “only numbers from the source” rule. where open was worse: a 1B model is weak at attribution. a bigger open model would likely do better, but i did not test one. Limits 4 synthetic chats, no real private chats, no field use. only the d/m/yy, h:mm am - name: text export shape is parsed. i did not compare against a closed model. the numbers above are from one run, not an average.
为什么开放创新很重要?群聊是私密的。使用开放权重模型,聊天记录保留在你的机器上,无需服务器,无需账户。它运行无需成本,无论现在还是将来,因此一个“懒人工具”不会变成订阅服务。检查器之所以有效,是因为我可以看到并控制整个流程。我可以更换模型文件、加强检查力度,或者放弃模型仅保留规则。使用闭源 API,我无法保证“仅使用源文件中的数字”这一规则。开放模型的劣势在于:1B 模型在归因方面较弱。更大的开放模型可能会表现更好,但我没有进行测试。局限性:仅有 4 个合成聊天记录,没有真实的私人聊天,没有实地使用。仅解析 d/m/yy, h:mm am - name: text 格式的导出文件。我没有将其与闭源模型进行对比。上述数字来自单次运行,而非平均值。