第九十章 密码仓库
林知行在工位上敲了四十分钟代码,什么也没写出来。
光标停在第三十七行,闪烁着。他盯着屏幕,脑子里跑的不是代码逻辑,是赵鸣岐的话。每一句都像段注释,挂在思维的边缘,删不掉。
"你没有退路。所以你是最听话的棋子。"
他把手从键盘上拿开,靠在椅背上。旁边的工位空着,孙雯去开会了,赵远今天没来。整层办公区安静得只剩下空调的嗡嗡声和远处某个人敲机械键盘的哒哒声。
屏幕上的代码编辑器开着,是一个数据校验模块的框架。他今天应该把这个模块的初版写完,明天交给程浩review。程浩会在他的代码上加几行注释,改两个变量名,然后在周报里写"完成数据校验模块核心逻辑"。
这是规矩。他知道。
但他写不下去。
下午四点半,沈渡在内部通讯软件上给他发了条消息:明天下午三点,灯塔项目技术选型预会,你来准备一下可信度评分模块的技术现状汇报。
林知行看了一眼,回了两个字:收到。
沈渡又发了一条:PPT控制在十页以内。
林知行回:明白。
对话框安静了。沈渡没再说什么。
林知行盯着那两条消息。"灯塔项目"——沈渡上周在饭局上提过,是教育AI核心推荐引擎的重构,激进派的旗舰工程。"技术选型预会"——意味着这个项目要正式启动了。而他被安排做技术现状汇报,等于是在所有人面前展示:可信度评分模块的成果,是灯塔项目的基础。
样板工程的执行者,给旗舰工程铺路。
赵鸣岐说得对。沈渡在加注。
六点二十分,林知行关掉电脑,背上包,刷卡出了灵犀大楼。
外面的天还没完全黑。六月的北京,日落要到七点以后。阳光从西边斜过来,把中关村大街的玻璃幕墙染成橘红色。人流从各个写字楼里涌出来,汇入地铁站的入口,像一条条支流汇入主河道。
林知行没有往地铁站走。他往反方向走了两百米,拐进一条小巷,在一家便利店门口停下来。
他掏出手机,打开浏览器,输入:github.com。
页面加载出来。右上角是Sign up的按钮。
他点了一下。
注册页面弹出来。用户名、邮箱、密码。三栏空白的输入框,等着他填。
林知行站在便利店门口,手机屏幕的亮度自动调到了最低——天色暗了,但还没黑透。他把亮度手动拉到最高,开始填写。
用户名那一栏他想了三秒。不能用真名,不能用任何和灵犀有关的名字,不能用他之前开源仓库用过的ID。他打了一串字符:anon-cs-2024。anon是anonymous的缩写,cs是credit score的缩写,2024是年份。
邮箱他用了一个临时邮箱服务——十分钟前刚注册的,地址是一串随机字符@tempmail.com。
密码他设了十六位,大小写字母加数字加符号。
Create account.
页面跳转。欢迎界面弹出来,空白的,什么都没有。一个全新的账号,没有任何历史记录,没有任何关联。
林知行看着那个空白的主页,忽然有一种奇怪的感觉——像是换了一张身份证。旧的那张写着"灵犀科技外包工程师",灰色工牌,角落工位,审批人是沈渡。新的这张什么都没写,干净得像一张白纸。
他退出浏览器,把临时邮箱的验证邮件删掉,然后关掉手机屏幕。
便利店的自动门开了又关,有人进有人出。林知行站在门口,把手机放回口袋,往地铁站走去。
回到青旅已经七点半。六人间里只有两个人,一个在上铺戴着耳机看视频,另一个在下铺睡觉。林知行洗了把脸,坐到自己的床铺上,打开笔记本电脑。
他先打开了一个文件夹——里面存着他这两个月在灵犀写的所有代码的本地备份。不是灵犀的源代码,是他自己写的那些模块的独立版本。每次提交代码到灵犀的内网仓库之前,他都会在本地留一份。不是刻意的,是习惯。方小满以前说他有"备份强迫症",他不否认。
他找到可信度评分模块的核心算法文件。三百多行代码,是他花了一周写的。去掉灵犀的数据接口调用、去掉内部API的依赖、去掉和公司平台绑定的部分——剩下的是一套纯粹的评分逻辑。
分场景评分框架、数据质量评分方法、多维度权重计算、决策日志生成。
这些代码不依赖灵犀的数据,不依赖灵犀的平台,不依赖任何公司的资源。它们是他在排课系统、在开源项目、在灵犀的实战中一步步积累出来的技术方法论。
沈渡说"你的开源项目依赖灵犀的数据验证"。他说得对,但只对了一半。灵犀的数据让他的算法在真实场景里跑通了,但算法本身的逻辑不来自灵犀。它来自他——来自他在小城蹲点观察奶茶店老板的那些下午,来自他被周睿打回方案后补论文的那些深夜,来自他在中期评审会上被批评"越位"后复盘的那些凌晨。
算法是他的。灵犀只是碰巧让他有了一个验证算法的地方。
林知行花了一个小时,把核心算法文件重新整理了一遍。去掉了所有灵犀特有的数据格式,替换成通用的开源数据接口。去掉了所有内部文档的注释,重写了README的技术说明。去掉了所有可能暴露身份的信息。
最后,他在仓库根目录新建了一个文件:README.md。
他盯着那个空白的文档,手指放在键盘上,停了很久。
上次写开源仓库的README,是在小城。那时候他写的是技术说明——怎么安装、怎么使用、怎么贡献代码。那时候他不知道"开源"这两个字的重量。他以为开源就是把代码放在网上,让别人用。
然后沈渡让他把代码撤了。
"七成重合。你知道这意味着什么吗?"
他知道。意味着他的算法和灵犀的版本有太多相似之处。意味着灵犀可以用知识产权的名义把他的代码从网上抹掉。意味着在法律上,公司有权这么做。
但法律和道德不是一回事。
他开始打字。
README.md的第一行是项目名称:credit-score-lite。
下面是项目简介。他写得很短:
可信度评分的精简实现。适用于需要对AI生成内容进行可信度量化和解释的场景。
然后是技术说明、安装方法、使用示例。这些都按标准的开源文档格式写的,没什么特别的。
特别的是最后一段。他在文件末尾加了一个"Background"部分。
他打了一段话,看了一遍,删掉,重新打。又看了一遍,又删掉。第三次打完,他没有再删。
这个项目的思路来自我在灵犀科技工作时的经验。开源的原因很简单:我不希望有用的技术被锁在一家公司的服务器里。
两句话。没有点名任何人,没有点名任何部门,没有点名任何项目。但对知情者来说,意思很清楚。
"灵犀科技"——四个字。
他盯着这四个字看了很久。上次他在开源仓库里提到灵犀,是被沈渡发现后当天撤下的。那次他用的是真名,代码和灵犀的版本有七成重合。
这次不一样。这次他用的是匿名账号,代码已经去掉了所有灵犀的依赖,只剩纯粹的算法逻辑。从法律上讲,这套代码是他的原创,不侵犯任何人的知识产权。
从道义上讲——他不知道。他只知道,如果这套算法只存在于灵犀的服务器里,它就永远是沈渡的筹码。但如果它在开源社区里,它就属于每一个用它的人。
包括他自己。
他点击了Create repository。
页面刷新。一个全新的仓库出现在屏幕上。空的,只有一个README.md文件。
credit-score-lite。
他看着这个名字,忽然想起了小城的那个仓库。那个仓库叫"AI-credit-score",有1200个star,然后被他亲手撤下了。代码删了,star没了,只剩下Fork记录里别人的备份散落在GitHub的各个角落。
那些备份他找不回来。但他可以重新开始。
上传代码花了一个小时。网速不快,青旅的Wi-Fi信号在九点以后会变差——住客们都回来了,带宽被分成了六份。林知行把笔记本电脑放在膝盖上,靠在墙上,等着进度条一点一点往前爬。
上铺的人换了姿势,床架嘎吱响了一声。下铺的人还在睡,呼吸声很轻。
进度条走到100%。上传完成。
他刷新了仓库页面。代码文件出现在目录里,README渲染成了格式化的文档。一切看起来都对。
他看了看star数:0。
他又刷新了一次:还是0。
他把笔记本电脑合上,放在枕头旁边,躺下来盯着上铺的床板。
这是正常的。一个匿名账号上传的新仓库,不会有人注意到。GitHub上每天新增几万个仓库,绝大多数都不会被人看到。他需要时间。也许几天,也许几周,也许永远不会有人star。
但他不着急。代码放在那里,就像种子埋在土里。什么时候发芽,不取决于他,取决于有没有人路过,看到它,觉得它值得star。
他闭上眼睛。脑子里还是赵鸣岐的话,但声音变小了,像隔了一层玻璃。
第二天醒来的时候,他先看了手机。
GitHub的通知栏有一个红色的小圆点。他点进去。
star:3。
三个star。不知道是谁点的,匿名账号没有关注者,仓库也没有出现在任何推荐列表里。也许是路过的人,也许是搜索引擎带来的流量。
他刷新了一下页面,看了看star的用户列表。三个头像,三个他不认识的ID。
正常的。开源社区的冷启动就是这样的。大多数仓库的第一个star来自随机流量,不是有意的关注。
他关掉手机,起床洗漱。
接下来的三天,林知行的生活表面上和之前没什么两样。白天在灵犀上班,写代码、开会、改周报。晚上回青旅,看技术文档,偶尔改几行credit-score-lite的代码。
沈渡在周三约他吃了一次饭,聊的是灯塔项目的技术选型。林知行听着,偶尔提几个问题,大多数时候沉默。沈渡没有察觉什么异常,只是说了一句:"你最近话少了。"
林知行说:"在想技术方案。"
沈渡点头,没再追问。
周三晚上,林知行回青旅后打开GitHub,star从3涨到了7。他看了看新增的star用户列表,没什么特别的。
周四晚上,star涨到了11。
周五晚上,star涨到了15。
增长很慢,但没有停。像一条细流,不大,但一直在流。
周五深夜,林知行躺在床上,用手机刷GitHub。他已经养成了习惯——每次打开页面,先看star数,再看star用户列表,然后看Fork数,最后看有没有新的Issue。
今晚的star数是17。Fork数是2。Issue数是0。
他往下滑,滑到star用户列表。新出现的两个头像吸引了他的目光。
第一个头像他很熟悉。ID是zhao-mingqi,头像是一个黑白的分子结构图。赵鸣岐的GitHub账号。林知行之前在比赛时看过他的主页,记得这个头像。
赵鸣岐star了这个仓库。
林知行盯着那个star按钮看了几秒。赵鸣岐知道这个仓库是他的吗?也许知道,也许不知道。README里没有写作者的名字,但技术圈不大,能把"可信度评分"和"灵犀科技"联系在一起的人,应该能猜到。
但赵鸣岐没有发Issue,没有Fork,只是默默地star了一下。像他在走廊里递纸条一样,不动声色。
林知行继续往下看。第二个头像他也很熟悉。ID是jiangyi_product,头像是一张短发的侧脸照,逆光,看不清表情。姜意的GitHub账号。她之前在林知行的开源项目里留过评论,他记得这个ID。
姜意也star了这个仓库。
林知行的手指在屏幕上停了一下。姜意不像赵鸣岐那样经常用GitHub。她的star更像是一种表态——我看到了,我支持。
两个star。两个知情者的信号。
他想看看沈渡的头像有没有出现在列表里。他知道沈渡的GitHub ID——shen_du_ai,头像是一个蓝色的神经网络图。他之前在沈渡的主页上看到过。
他把star列表翻到了底部。二十多个头像里,没有shen_du_ai。
沈渡没有star。
林知行关掉GitHub,把手机放在枕头旁边。
他不知道该怎么理解这件事。沈渡也许还没看到这个仓库。也许看到了,但没有star。也许看到了,故意不star。
他不知道。他也不打算去猜。沈渡不是一个可以用算法推演的人。
他闭上眼睛。脑子里浮现的是赵鸣岐star的那个头像——分子结构图,黑白的,冷静的。然后是姜意的头像——短发侧脸,逆光的,模糊的。
两个人的star,像是两封没有署名的信。
他不知道信里写了什么。但他知道,有人看到了他埋下的种子。
周六中午,方小满发来一条微信。
"你又搞开源了?"
林知行正在青旅楼下的小餐馆吃面。他放下筷子,拿起手机,打了几个字:"你怎么知道?"
方小满回:"姜意姐发了条朋友圈,截图了一个GitHub仓库页面,配文'支持一下'。我一看仓库名就知道是你。"
林知行愣了一下。他没想到姜意会发朋友圈。她的朋友圈他看不到——她设置了三天可见,而且他们之间的共同好友不多。方小满能看到,大概是因为他们之前加过微信。
他回:"你认得出来?"
方小满回:"credit-score-lite,可信度评分精简版。除了你谁会做这个?"
林知行没回。方小满说得对。这个仓库的技术方向太特殊了,和他在灵犀做的模块几乎完全重合。任何知道他在灵犀做什么的人,看到这个仓库名就能猜到作者是谁。
方小满又发了一条:"不怕灵犀找你麻烦?"
林知行打了几个字,删掉,又打了几个字,又删掉。最后他回了一句:"上次撤代码是沈渡让我撤的。这次我用匿名,他查不到。"
方小满秒回:"你变了。以前你不会偷偷搞事。"
林知行看着这条消息。方小满的语气不像是批评,更像是陈述。他说的是事实——以前的林知行不会这么做。以前的林知行会把代码直接放在自己的账号上,用真名,用自己的头像,因为那时候他以为开源就是把东西放在网上,让别人用。
然后他被现实教育了一课。
他想了很久,回了一句:"不叫偷偷搞事,叫分布式备份。"
方小满没有再回。也许是去忙了,也许是在想怎么回。
林知行把手机放在桌上,继续吃面。面条有点坨了,汤也凉了。他不在意,继续吃。
窗外是六月的阳光,照在人行道上,白得刺眼。街上的人来来往往,每个人都在走自己的路,没人注意到小餐馆里有个人正在吃一碗凉了的面。
他想起方小满说的"你变了"。
也许吧。以前他不会这么做。以前他以为,只要技术够好,只要代码够干净,就能被公平对待。现在他知道了,公平是一个奢侈品,不是每个人都能买到。
但他可以用别的方式。
代码可以被撤下,star可以被清零,署名可以被删除。但算法的逻辑不会消失。它存在于代码里,存在于文档里,存在于每一个读过它的人的脑子里。
只要还有一个人记得这套算法的思路,它就不会被真正抹掉。
这就是分布式备份的意义。
不是偷偷搞事。是在不同的地方,留下相同的记忆。
林知行把碗里最后一口面吃完,放下筷子,拿起手机。GitHub的通知栏又亮了。他点进去。
star:21。
新增的四个star里没有shen_du_ai。
他关掉手机,起身结账。
走出小餐馆的时候,阳光从正上方照下来,把他的影子压得很短,几乎看不见。
他往灵犀大楼的方向走去。明天周一,还有代码要写,还有PPT要做,还有灯塔项目的技术选型会要开。
棋子的路还要继续走。但棋子在暗处,已经埋下了自己的种子。
(本章完)