Header logo.
极北人工智障
主页逐年标签自述RSS

2024

2024 年最大的事情可能是中间失业了一个多月。

在上一年(也就是 2023 年)年底的时候,就感觉公司有奇奇怪怪的问题,CEO 自己因为签证的关系回不了瑞典,公司好像没钱了,但似乎是在找投资人谈。当时就在想要不要开始找新工作,但是一方面有拖延症,另一方面又觉得这样的节点撂挑子不太好。

接着到 2024 年初,我开始一边练习 Elixir,一边盘算投简历(实际并没有投多少)。这段时间 CEO 还表现得像往常一样,时不时地跟我们开会,时不时地甩来一些思路混乱的设计让我们实现。终于到 3 月底,公司宣布没钱了,要让我和另外一个码农离职。

中间涉及了一些法律问题,工会介入。于是公司在 4 月初的时候取消了 3 月底的解雇,重新走程序解雇了一遍……实际的效果是 5 月、6 月照常工作,7 月是所谓的「花园假期」(garden leave) 不必工作但是工资照付。其实这几个月也没多少事情,而且也知道即使想推动大的改动,时间也不够了(另一个码农当时在家看孩子,工作时间减半;何况公司的气氛也不对),所以捣鼓了一些 OpenAI 的 API,用 streamlit 写了一个聊天机器人;了解了一下 DDD;还看了一些讲「成功的产品团队如何运作」的书,比如 Inspired

之后 7 月份闲着也是闲着,给公司用 AnythingLLM 搭了一个 LLM + RAG 的小聊天机器人。部署之后一直不稳定,可能是它里面的 parser 不够稳健吧。

7 月底之后,按道理工会给发 80% 的薪水。但第一步是要在劳动局网站登记失业,我当时精神有点崩溃,晚了两天才去登记。所以那两天的钱拿不到。我登记之后隔了几天,劳动局的大姐打电话问我有什么工作经验、会做什么。讲完之后,大姐如释重负地说:「太好了,你这情况,不需要我局提供培训、指导。」

领钱之前又遇到了小小的阻碍。工会说查了我的纳税记录,中间缺了几个月,所以不能确信我申报的工时是准确的。找老板聊了一下,她又找了会计,隔了一两个星期改正了错误,又通知了工会,这才在 8 月下旬拿到钱。

而且实际的钱是按周发放的,每周需要在工会的失业金网站填「本周无业的天数」,每月在劳动局网站填至少 6 个申请的岗位。

那段时间一直很忐忑,改了简历的文本(还让 ChatGPT 润色了一番),好好捯饬了一下 LinkedIn。同时还不停地写码,作为手艺人,手不能停。这段时间总共投了 38 个岗位,只拿到了两个面试。但 9 月初入职的这家公司并不是投简历拿到的,而是 2022 年聊过一次的公司。公司做的事情刚好也是 LLM + RAG 的系统,玩 Streamlit 和 AnythingLLM 的经历意外地起到了帮助。


2024 年年初的时候是给自己定了一些目标的。比如开始打羽毛球、攀岩,隔天跑步。只有跑步大体坚持了下来,但是也并没有频繁到隔天跑一次。要学开车,但并没有。要瑞典语流利,但并没有投入多少时间和精力。要打开社交圈子,但下半年变得无比自闭。要进一家更好的公司,这一点倒是做到了。

2024 年年初还列了几个想做的小产品,年中还拍着胸脯说要帮朋友写一个她能用到的小工具。但一件都没做成。

第一个错误是 mission creep。打比方说,想做一个凤凰,但是发现做凤凰好难,于是想不如先做一个大雁练手。如此一来,实际动手做的只是一个鹌鹑,但连鹌鹑都没做完。继续沿用这个比喻的话,更好的做法可能是先做凤凰的爪子,而不是放弃凤凰,去做大雁。

另一个错误是企图在做东西的同时学新技术,企图一石二鸟。能一石二鸟固然好,但如果同时有两个目标,人一犯懒就会优先做简单的那个。相对于「做新东西」,学习,也就是临摹已有的东西,显然更容易。虽然宣称是在用 Elixir/Phoenix 写东西,但实际上是花了很多时间学 Elixir 和 Phoenix。(写 Elixir 的手感毫无疑问是美妙的。但是怎么用 Elixir/Phoenix 写出自己实际想要的效果,却需要重新拧一遍脑袋里的螺丝,相当伤脑筋的。)优先做困难的事情比较好。


始料未及的事情是今年又读了一大堆励志文献。比如 Cate Hall 的文章「如何更有主观能动性」(How to be More Agentic),比如 Shreyas Doshi 的「要提高主观能动性」(High Agency),再比如「高效能人士的七个习惯」。更始料未及的是,意识到里面的道理都还挺对的。

另外一本很重要的书是许成钢的「制度基因:中国制度与极权主义制度的起源」。我还没看完,但是这本书的框架实在太厉害了,推荐大家都看看。

静态网站生成器

这个 blog 一直是用自己写的静态网站生成器 (Static-Site Generator),从一堆 Markdown 文件里生成 HTML,再用 git 推到 Cloudflare Pages 上。

之前的生成器是 Python 写的。本来一直能用,然而去年有一天,一个 dependency 不知怎么回事坏掉了。(有可能是因为电脑上有几个版本的 Python 在打架吧。)不是什么大问题,创建了一个新的虚拟环境,重新装一下 Markdown 的库就又能跑了。又过了一阵子,生成 feed 的库里面有一行代码开始报错说「缺一个参数」。奇妙的是我这段时间根本没动过那写代码。

于是大过年的,决定用 Go 写了一个新的。其实还是有一些小问题的,比如 CSS 什么的。

上一版的 blog 生成器花了一星期。这一版的用了 3 天时间,但是实际写码的时间只有 11 个小时。中间用了很多 GitHub Copilot。

试图直接把一堆 Python 甩给 Copilot 让它「翻译」成 Go,但是它只是生成了一个简单的文件夹结构和一些并不重要的函数。

但是很多具体的功能,很多时候写个开头,一路按 tab 就行了。比如排序、regex、读写文件,都是它直接生成的。

该选哪些库也是 Copilot 教我的,比如用来解析 Markdown 的 goldmark,用来生成 feed 的 gorilla/feeds。这两个库实际用起来感觉也比 Python 的两个库更舒服。

而且我心想,既然都重写了,比如干脆加上语法高亮和 Mermaid 的支持,幸好 goldmark 的扩展都有现成的。

我之前一直用中文的楷体来表示强调,因为斜体汉字太难看了,手段是手动加 CSS。所以这次还试图写一个新的 goldmark 扩展,找个特殊符号,在解析的时候替换成 <span class="kai">。但是有点复杂,Copilot 提示的做法都不能用,直接跑去读 goldmark 的代码对照,好像 Copilot 生成的一些函数用法已经 deprecated 了。于是后来放弃了。

Go 本身写起来就挺舒服的,再加上 Copilot 的助推,整个过程相当 pleasant。不过,虽然确实需要检查生成的代码,看它是不是在做正确的事,但在脑袋里形不成什么深刻的印象。

「殖民三百年」

最近想起来刘晓波曾经说过的「殖民三百年」,今天从网上找到了这样的出处,据说是 1988 年的采访:

金鐘是這麼問劉曉波的:「什麼條件下,中國才有可能實現一個真正的歷史變革呢?」劉曉波回答:「300年殖民地。香港100年殖民地變成今天這樣,中國那麼大,當然需要300年殖民地,才會變成今天香港這樣。300年夠不夠?我還有懷疑。」

1988 年看来,香港自然是一个发达的城市。然而移交之前,港英政府的政治架构是服务于殖民者的,其施政风格一直是「行政领衔」(executive-dominant),民主制约并不存在。总督兼任立法会主席,立法会一半议员是「官守议员」,由政府官员兼任。另一半「非官守议员」由总督任命。

香港移交之前,港英政府试图加大民主参与。但是大陆官方极力反对。

1997 年移交之后,香港政治机器服务于殖民者的性质是没有变的,只是宗主国从英国变成了中国而已。而秉承「专业精神」的施政团队,换了老板依然兢兢业业,娴熟地运用旧殖民者留下的行政和法律工具,服务新的殖民者。

比如说,雨伞运动、占中等示威期间,特区政府用来逮捕并公诉示威者的法律工具「公安条例」(Public Order Ordinance) 是 1967 年港英时代颁布的。

大陆政府没有信守「基本法」的承诺是确凿的事实。但港英政府没有向香港人赋予民主也是确凿的事实。

实际上,民主本来就不是「被赋予」的。且不论殖民主义这种剥削制度的利弊,幻想「被殖民三百年之后,就成为文明国家」是不成立的。只要是被殖民,三百年不行,八百年都不行。

自己的政治建设是要自己做的。

翻看两年前的代码

现在又开始试着用 Go 写一些小东西。于是买了一个 Web Development With Go 的教程。视频教程的标价是很贵的,于是犹豫不决。看来看去之时,翻到页面最下面,发现还有一个只卖电子书的选项,才 60 刀,于是果断下单。感觉这门课的主创真是定价的人才。

买书之前觉得其实不用任何教程,一边用 ChatGPT 一边看文档,照样可以做出自己想做的东西来。但实际做起来,才发现要收集、整理的信息是很庞杂的。自己通过不断试错、get your hands dirty 还挺花时间的。

而且有可能会犯自己意识不到的错误。

比如看这本书里的代码,发现他很 unorginal 地用了 MVC 架构。(但是 uoriginal 是有 unorginal 的好处的,就是整个东西会更 predictable 一些。)所有接触数据库的代码都在 models 里,数据库连接是在 main 函数里创建的。每次读写数据库,都是把数据库连接传到 models 函数里。数据库连接一直到程序退出才关闭。

然后想起两年多以前写的 Go,发现自己是在每次查询的时候,连接数据库、查询、关闭连接。每查询一次,就要这么折腾一下。当时怎么没意识到打开、关闭数据库是很 expensive 的。

当时还困惑,为什么每次打开某个页面,列出来的数据总是少开头的两行,有可能就是某次查询的时候数据库喘了……

看来这两年其实没白过吧。

一些想法

记得 2015 年的一个周末,那时还在北京。一共四个人在西北三环的一家砂锅粥店吃饭,有 J 和 X,当然当时还有前妻。

年份和地点记得不是很确凿。说是 2015 年是因为记得当时还在 N 报社上班,之所以说是砂锅粥店,是因为 N 社旁边不远处有个同名砂锅粥店,我还蛮喜欢。(老板是潮汕人,早先还可以用比特币结账。) J 提出要吃饭问想去哪儿,我不明就里可能就提了这家店的名字。这次会面我总会想起,每次想起就查一下地图。西北三环那个犄角的内侧,一直有一家「蟹老宋」,并没有砂锅粥店的名字。但当时确实是在西北三环的那个犄角。

一边吃一边聊,J 问我那时都在通过什么渠道获取信息。我不明就里,直率地说,我正在「收缩」自己的信息摄取,越来越觉得新闻也好、公共事件也好,没什么关系。J 君语塞,我当时恐怕还蛮迟钝的,丝毫没有感觉到冷场。回家路上前妻告诉我,J 想和你聊,其实是看能不能把你挖过来。后来才知道 J 那时正在策划一个好友分享新闻链接的社交产品,产品形态有点像「即刻」。

之后不久,我从 N 社辞职。没做什么后面的打算,就是觉得不想再继续干下去了。用现在的话说可能是叫 burned out 加「政治性抑郁」。然而 that's not something I want to say, because that doesn't sound like something I would say. 一个原因是现在每天讲英语的时候,很多词尽管知道字面的意思,但如果不是确切知道 “how it cuts”,我是不想说的。另一个原因是对 N 社印在纸上的词感到可疑,对汉人知识界的一些词也时常感到有距离。

同一段时间,我的一个微信群里聚集了很多有趣的、年轻的朋友。虽然记不清对话发生的背景了,但是我记得跟朋友 M 有一次讲,感觉人生每一步都是在「逃跑」。

这种感觉一直持续了很多年。现在回想起来,之后经历的若干次更大的挫折,其实都可以追溯到那次砂锅粥谈话。但很奇怪,有一次问过前妻记不记得那次吃饭,再后来也问过 X 是不是记得这样一件事,两人都说毫无印象。

之所以又想起这件事,是因为上周或者上上周自己出去跑步,停下脚步的时候突然觉得此刻挺好。意识到自己已经有一阵子没觉得自己在「逃跑」或者「收缩」了。此刻 “I am”,自己在做的事情是 to be 或者说 être。这状态不是很好,但也不是很坏。是一个 state of being。

「脑后」

仔细一看聊天记录,这已经是 8 个月之前聊过的事情了。

Bakhuvud 意思是后脑勺。

但是有次跟朋友聊到,“ha i bakhuvudet” 瑞典语的意思是 “keep something in mind”,也就是记着那件事。但汉语里类似的表达「抛诸脑后」就是要忘掉那件事了。

还有一个读小说发现的。

“Lämna” 直译成英语是 “leave”,“ut” 则是 “out”。

但是小说里的这句话是 “För henne är det ett svek att lämna ut intima detaljer.” 正确的理解翻译成中文是「在她看来,把私密的琐事 晾出来 是一种背叛。」有种「家丑不可外扬」的意思。

但是英语的 “leave out” 就变成了「省略」的意思了,愣是照着字面字字对应地置换成英语,“For her, it is a betrayal to leave out the intimate details.” 听起来就像是在说,聊家长里短的破事,所有细节都不能从叙事中删除。

所以瑞典语的 lämna ut 是「把情节晾到外面」让公众看见,英语的 leave out 是「把情节丢到『叙事』的外面」不提也罢。

结论:

Words are treacherous!