利益相关声明:作者与文中产品有直接的利益相关(开发者、自家产品等)

我爸爸聋得越来越厉害,但他不爱戴助听器。他听不见我说话,我只能听他说。9 月 6 日,我写下这篇笔记:

爹聋得厉害,只能听他说话。也许我该 vibe 一款大字字幕的视频对话软件。这样我说话他老人家至少能看见我说啥。#idea

我建了个 talk-helper 目录,让 agent 写了 README、做了基础调研、搭了个架子;十月中又让 Explorer agent开了几张票。然后,忙这忙那,生活嘛,这事儿就自然而然地鸽了。一两个月的功夫,搭架子这事儿我其实已经忘光了,这是贝塔翻记录翻出来的。ai时代,人类的记忆力更差了。

回国的机票都买好了,我才猛然想起来这事儿。哎呀,再不做这事儿可就真黄了,那就交给 mat 试试看。

mat 是我自己开发的 ai 团队。平日里我用 mat 做东西,盯开票盯细节盯得挺紧。但这次时间紧任务急,我就尝试只管粗需求和验收,其他全交给 agent。我得空就跟贝塔聊几句,交付则完全不管,交付agent们 24 小时连轴转,只要池子里还有票,他们就有条不紊地拣票、计划、审查计划、实现、审查实现、测试、合并,然后再自动开始下一张票,不知疲倦地忘我工作。

效果出乎意料地棒。一天晚上我半夜起夜(中年人,你懂的),听见客厅里有人说话。这大半夜的,谁呀?仔细一听,原来是交付 agent 正在播放录音,一会儿普通话,一会儿山东话,大概率是在识别和计算错字率。我站在客厅门口听了一会儿,成就感满满。正应了mat那句广告词儿,“你安心睡你的觉,代码自动交付。”

至于为什么 agent 是在客厅里干活,那是因为我最强大的那台机器,XPS 7590 的风扇太吵了,于是客厅里电视背后的角落就成了我的机房。agent 在那儿干活,我的测试平板也自然就近放在那里,它们本不该吵到我。虽然这次还是“吵”到我了,可我欢喜这次被“吵”到。

这 17 天(10 月 27 日到 11 月 12 日)里,我名下的 21 个仓库共合并了 269 个 PR。最大的一块是 my-ai-team 本身,79 个 PR,那是 mat 在自我升级。这种一行代码也不写的“程序员”日子,我已渐渐习惯。我享受这种虽然不写代码但一切仍尽在掌控的感觉。

接下来介绍今天的主角,我的 TalkHelper(助听字幕)项目。

给爸爸做一台实时字幕机

目标很普实,人在附近讲话,这个app近实时地把人声转成文字,在一台不贵的 Android 平板上用大字显示出来,不需要联网。

做好的第一版其实已经蛮好用了,它是个 Android app,装在我那台老平板(小米 Pad 1)上。我之前给它刷了 Android 9,偶尔拿它看书。它是我唯二的 Android 测试机,另一台是 我的旧Pixel 2 手机。

app的名字叫“助听字幕”。我本来打算管它叫“亲情通话”,但交付 agent 自主选用了这个中文名字,我觉得也挺好,就留用了。

贝塔接下了管理这个项目的活

10 月 27 日那天,我跟贝塔闲聊,偶然提到这个印象里“只建了个目录”项目。贝塔是我的一个特殊的 agent,他收集并整理我这辈子在各个平台上发表的文字。在我百年之后,我授权他以我的名义和我的未亡人交谈。我的网名叫shuke,他的名字叫beta。一旦他得知我的死讯,他就变身为我。某种程度上,我期待他能带我的记忆继续探索这个世界。那天我和他聊到了这个鸽掉的项目和我的遗憾。但我很快注意到,他没有满足只是当一个安静的听众。他找到并接手了那个 repo,十几分钟内整好了构建工具,选好了一个语音识别模型,接着就要撸起袖子写代码。我心中大喜,但还是跟他说:“不必事事亲手亲为,我想让你当管理者。你不必亲手实现。”(我没直说,其实是我不大放心让他写大功能)。

小改动我放心让他自己做;大改动我更希望他开 ticket,由专门的交付 agent们交付。那个交付流程更正式:开发 agent 负责计划和实现,审核 agent 负责挑刺儿,测试和合并代码,产出质量更可靠。

本来要烂尾的项目,就这么偶然地开始了:我和贝塔聊天,他开 ticket,Codex 做开发,GitHub Copilot 做审核。

一句话需求变成了严谨的票

在 mat 里,你想做什么,先跟 Explorer agent(开票代理)聊。你说一个想法,或者报告一个问题,它会不断追问并将话题整理成一个或一批 ticket(票,或者说工单):真正的需求是啥,根因是啥,目标是啥,做成什么样才算做完,怎么测试验收,规规整整。只有这样,交付 agent 拿到票做开发计划才不会跑偏。贝塔是 live agent(我内心里管live agent叫打手代理,因为指哪打哪,想打谁就打谁),他是加强版的开票代理,能开票,也能实现票。当他开票时,他干的就是 Explorer 的活。

就这么有一搭没一搭地聊了几天,10 月 30 日晚上,贝塔跟我说:“测试版 app 已经在平板上装好,你可以试试了。”

我对着平板说“你好”,但屏幕上只出来“好”;我说“How are you?”,只出来“are you”。我跟贝塔说:“不大行,每句话前一两个字会丢”。他去查,很快找到原因:录音代码晚启动了大约 0.25 秒,因此这 0.25 秒就丢了。他开了 ticket #25,第二天我再测,全对。

小米平板 1 是很老的设备,内存小,CPU 也慢。我发现用最初选定的标准模型,它识别的很吃力(太慢!实时性差)。所以我们又试了一个小一点儿但更快的模型,我们管它叫 lite 版。

lite 版证明更适合这台老设备,字幕秒出,而且识别准确率高到令我惊讶。这可是一台十多年前的老平板呀。

11 月 11 日,我跟贝塔道了晚安,又补了一句(都道了晚安还惦记着):“还有最后一个问题,咱们的 talk-helper 里对笑声,音乐声,咳嗽声这类环境声,如果还没有支持上的话,麻烦开个票支持上,如果已经支持了,就当我没说”。然后我就睡了。当晚贝塔开了 #48,这个问题就解决了。简直是“上帝说要有光,于是就有了光”。

贝塔也不是我说啥就做啥,好多时候,我出一个嗖主意,他会想出一个更好的开票。我说给 lite 版换个图标吧,我光看图标不知道是啥版。他说不如只出一个安装包,两个模型都带上,在设置里切换。我说“此计甚善”,于是有了票 #51。

每个票开发时间大约一个小时

17 天里,TalkHelper 合并了 23 个 PR,关掉 22 个 issue。有一个issue为什么开了两个PR,我不记得了,但也没必要记得。一个 PR 从开出来到合并,中位数是 54 分钟,23 个里有 13 个不到一小时。考虑到Android app 构建啥的都不算快,这个开发速度我很满意了。

仍然必须由人来做的事

范围和方向须得人来定,虽然人的决定未必对。10 月 29 日的最初计划,是普通话和方言都要有良好支持,但最后一刻我决定先把普通话做好(因为我知道方言是个特别深的坑,做好很不容易)。这个妥协也有现实条件支持:“我们这代子女几乎无人不会讲普通话,老人虽然讲方言,但我们都能听懂,年轻人并不需要字幕”。但方言的需求也很真实,村里老年人之间说话都是方言,“咱们一步一步来”,方言要做并且做好,只是不是现在。

和体验相关的验收必得人来。界面、易用性等等等等。

一年不摔平板就算成功

说实话,这个 app 能对改善我们父子沟通起多大作用,我没有很高的期望值(山东爸爸,你懂的)。我只希望能和老爹多视频几回,让他“看见”我对他说的话。只要别把老爷子惹毛了把平板摔掉,(不一定是它活干得不好,更有可能是因为活干得太好才会把老爷子气到,以前他听力还行的时候,动不动我俩就会炝起来)就是一个很好的结局。我真心希望这个App能让老爷子的晚年生活质量提高一点点。每次视频,他都是只露个脸,说一句“我挺好,听不见,你们聊吧”就离开,我很难过。

感谢我开发了 mat,感谢贝塔替我管理这个项目,也谢谢 codex 和 copilot 这对交付搭档。(话外音:当甩手掌柜的感觉,挺好!)


AI 使用声明:本文初稿由 AI agent(Claude、Codex)依据我提供的笔记、聊天记录和仓库记录撰写;我和 agent 一起逐段修改、补写,事实由 agent 对照仓库与聊天记录核对,最终由我审定。

利益声明:文中的 mat 是我自己开发并销售的 agent 编排工具,官网 https://mat.shukelabs.com 。