即刻App年轻人的同好社区
下载
App内打开
小盖fun
7关注639被关注2夸夸
做有意思的事情。
小盖fun
2天前
Codex 的一个隐藏玩法。

发现了 Codex 的一个隐藏玩法,可以帮我彻底删除 Mac 里的某个软件。

如果你最近电脑老提示存储空间不够,尤其是这两年装过很多 AI Agent 产品的朋友,可以试一试我这个方法。

我家里的 MacBook 是三年前买的。当时觉得就是家用,256G 怎么都够了。

没想到今年 AI 火了之后,冒出来大量 Agent 产品,而且很多都是客户端形态。所以这段时间,我在电脑上装了不少新应用。

但这些应用大多也就是尝鲜,试过之后基本就卸载了。

前阵子更新 macOS,我突然发现磁盘空间不够了。之前这台电脑从来没出现过这种情况。

我看了一圈应用列表,明明已经把那些不用的软件都卸载了,但空间还是不够。最后没办法,甚至把微信和飞书都删了,才勉强更新成功。

结果今天系统又提醒我存储空间不足。我就纳闷,那些软件不是早删了吗,空间到底去哪了。

然后我很偶然打开了一个 MD 文档。结果发现打开方式那一栏里,居然还挂着几个我早就卸载掉的 AI 软件。

我一下就感觉不对劲了。于是直接问 Codex,这些软件是不是没有删干净。

果然,没有卸载干净。紧接着,我又让它帮我检查了一下我最近卸载过的几个软件,然后释放出来将近 4G 的空间。

后来我干脆又把印象里装过的几个软件名也丢给了 Codex。结果,Codex 又找到了 6G 多的无用文件。

哎,现在很多 Agent 产品,为了保证运行稳定,会默认装很多底层环境。比如 VM、Chromium、Container、模型缓存、本地索引等等。

有些 Agent 为了实现浏览器操作能力,甚至会自己带一整套 Chromium 环境。

所以我们表面上看,好像只是装了一个聊天软件。实际上电脑里,很可能塞进去的是一个小型 AI 工作站。

Mac 的卸载,很多时候我们只是把应用拖进废纸篓。这种方法其实远远不够。

因为真正占空间的东西,还藏在各种 library、container、cache 甚至虚拟机目录里。

普通人其实根本不知道去哪找。所以我建议以后干脆让 Codex 把这些活全接管了。它会自己一路扫描、定位、分析依赖、删除残留文件。

最后硬生生又给我腾出来接近 20G 存储空间。
22
小盖fun
2天前
这两年,我常常有这样的感觉:在一些争论面前,与其喋喋不休费力的沟通和表达,还不如及时沉默下来,优雅的结束对话。

当一次沟通,已经让人觉得疲惫和无力之时,其实我再怎么解释,也无济于事。

如果共识至关重要,那结束对话之后,我可以冷静下来,基于新的信息,重新梳理思考。

如果共识一点也不重要,那就让一切随风而去就好,你俩又不是一起过日子,人家爱咋咋,关你啥事。

很多时候,尊重不同便是互相之间的体面。没必要非要谁说服谁,成熟不就意味着我们可以从不同的视角,理解不同的人。

话不投机半句多,把有限的时间,用于提升自己,做自己的事情,这比喋喋不休,但又毫无意义的找共识强太多了。

就像哈佛大学教授茱莉亚·达尔说的那样,我们可以通过自身成长,使得无法达成一致的事情,变得微不足道。
10
小盖fun
3天前
我得给所有零基础、想学 Claude Code 的朋友,推荐一个交互式的学习教程,叫 Zero to Claude Code。

这个教程挺有意思。它跟我们惯常见到的视频教程不太一样,是一个交互式的学习网站。

打开之后有点像玩游戏,跟着上面的文字说明一步一步操作,在做中学。

比如它让我们敲某个命令,我们就跟着敲。敲完之后它会把效果展示出来,我们立马就明白这个命令是干嘛的。

中间也会穿插一些小测验,看看到底有没有真的理解某个知识,或者某个命令。大概就是这么个体验。挺有趣的。一点都不会犯困。

地址在这里:

zero2claude.dev

话说 Claude Code 目前主要有两种玩法。一种是通过 Claude 的客户端,Claude 客户端集成了 Chat、Cowork 和 Code 三个产品,这里基本不需要碰命令行,打开应用就能用。

但缺点是 Claude 客户端没办法修改模型,只能用 Anthropic 官方的。

另一种则是在终端里使用,这是目前更主流的方式。

第二种我之前写过简单的教程,写完发现一个问题:没有计算机基础的同学还是会吃力。而且卡点出现得特别靠前。

还没轮到配置模型的 API Key 这些,光是要在终端里把 Claude Code 装上,很多人就已经犯难了,打开终端看到一堆命令行,根本不知道从哪儿下手。

再往后,在终端里操作文件、文件夹,靠的也都是命令行。

可绝大部分普通用户压根没接触过命令行,大家早就习惯了图形界面,鼠标点一点就行。突然掉进命令行的世界,几乎每一步都可能卡住。

所以我看完这个交互式教程,最认可的不是它讲了 Claude Code,而是它没有默认大家已经会用终端。

我们最近在给同事讲 Claude Code,也摸索出一个规律:千万别一上来就讲 Claude Code。

得先把常用的 Terminal 命令讲明白,再往下讲 Claude Code,大家才能跟得上。

这个教程走的就是这个思路,它给的是一条真正从零开始的学习路线。它大致可以分成几个递进式的部分。

第一部分是打基础,讲命令行本身。一开始会从几个最关键的概念入手,比如文件、文件夹、路径,以及终端到底是什么。

紧接着就是一批最常用的命令,比如:

- pwd,看自己当前在哪个文件夹
- ls,看这个文件夹里都有什么
- cd,进入某个目录
- mkdir,新建文件夹
- touch,新建文件

诸如此类。这一部分内容的目标其实很简单,就是让大家熟悉终端的概念,以及常用命令。

第二部分是在这个基础上,慢慢引入一些软件开发常用的概念。

当然,如果用 Claude Code 不是为了做软件开发,这一部分也可以先跳过。

它会讲到什么是代码,常见的几种编程语言大概都擅长干什么,版本控制为什么重要,怎么把本地的项目推到 GitHub 上。

同时,也会讲网站背后大概发生了什么,浏览器和服务器之间是怎么对话的,URL 每一段是什么意思,状态码在说什么,API 又是怎么把一组功能开放出来给人调用的。

我们还会用 curl 在终端里真发一次 HTTP 请求,带上参数、请求头,看一眼返回的数据长什么样,遇到报错又该怎么看。

第三部分是 Claude Code 的进阶,也是整个教程的重头戏。

讲到这里,Claude Code 已经不只是终端里一个一问一答的助手了。

这一部分会讲 Skills、MCP,还有 sub-agent、Hooks、headless 这几种模式。

Skills,是把一件常做的事教给它一次,以后它就能照着做,不用每回都从头交代。MCP,是让它连上我们手头的其他工具和数据,不再是一座孤岛。

Sub-agent,是它忙不过来的时候,能分几个帮手出去同时干。Hooks 和 headless,是让它在没人盯着的时候,也能自己跑起来。

这些东西凑到一起,Claude Code 就从一个陪聊的助手,变成了一个真能扛事的帮手。

我觉得只要有耐心跟着走,零基础的同学一定能学会。

这个教程我真心推荐所有零基础的同学去试一试。视频教程的好处我以前讲过,直接、省事。

但这个又往前走了一步。没人喜欢被动地听课,尤其 Claude Code 这种特别讲究动手的东西,最好就是 step by step,自己一步一步做下来。

不过这个项目目前也有缺点。我感觉它的界面做的很难看,如果界面再好看一点就完美了。

再就是当前不支持中文,不过大家可以装一个浏览器的翻译插件,这个问题好解决。
646
小盖fun
4天前
做了一个Vibe Writing的小工具,超级好用。

用智谱新发的高速模型,做了一个AI写作的小工具,感觉对我非常有用。 简单说,它可以像补全代码那样,补全文章的下一句话,只要按Tab键就行。

右侧可以把这篇文章要参考的资料传上去,作为 Context。左边就是写作区,我开始一句一句地写。

写完一句,光标停在那,它会根据上下文,自动给出补全建议。

如果我认可它的补全结果,直接敲下 Tab 键,这句就接上了。这才是我想要的 AI 写作工具。

补全的内容我可以随时改。觉得它接得不好,改掉就行。

我也可以在它补全之前先给一段提示词,把我的文风 DNA 喂给它,让它顺着我的语气来写。这些都能做到。
00:07
74
小盖fun
9天前
讲 Harness 最透彻的一个演讲。

这应该是我看到过的、关于 Harness Engineering 最透彻的一次分享,推荐大家看一下。

视频链接:podwise.ai

整场演讲就 20 分钟,IBM 的工程师 Tejas Kumar 用一个例子,挺巧妙的把 Harness 的价值讲清楚了,通俗易懂。

整场分享的观点其实就一句话,模型只是大脑,真正让 AI 进入真实世界工作的是 Harness。

这句话经常听到,但通过这个例子,能直接看出来为什么是这样。

把我的笔记分享出来,希望对大家有启发。

1
让一个没有怎么做 Harness Engineering 的 Agent 去给 Hacker News 上的帖子点 upvote。流程看起来非常简单。

打开链接,如果没登录就跳到登录页,登录后再返回帖子页面,点一下 upvote,任务结束。

但裸模型的 Agent 碰到登录页就不知道怎么办了。它搞不定登录,却稀里糊涂告诉用户任务已经搞定,upvote 成功。

实际上根本没点,Agent 撒谎了。去年大家但凡用过 Agent,一定碰到过类似的情况。

面对这个问题,把提示词写得再细,或者换一个更强的模型,都未必管用。问题在于这个 Agent 根本没有 Harness。

说到这里,顺带讲一下到底什么是 Harness。

其实可以这么理解,Harness 就是包裹在模型外面的一整套基础设施。一个完整的 Harness 一般包含下面这几部分。

1)工具注册表,决定模型能调用哪些工具。

2)上下文管理,控制哪些信息继续留在上下文里,哪些信息该压缩或丢掉。

3)护栏,给 Agent 运行过程设定边界,比如最多执行多少轮、最多调用多少次工具,或者遇到异常状态就立刻停止。

4)Agent Loop,让模型一轮一轮地观察、思考、调用工具、接收结果。

5)验证步骤,任务结束后核对结果到底有没有真的完成。

为什么需要这层东西?因为模型不像程序那样,给定输入就一定沿着固定路径执行。

它可能正常完成任务,也可能中途跑偏、忘记目标、误判状态,甚至任务都失败了还声称自己搞定了。

Harness 的作用,就是在模型外面加一层确定性的控制系统。哪些工具能调用,任务什么时候该停,上下文怎么压缩,结果到底算不算完成,都交给确定性的代码来管理。

像 Claude Code、Cursor、Codex 这些产品,都是 Harness 包裹起来的 Agent。它们之所以好用,不全是因为背后接的模型聪明,更因为外面这层基础设施做得比较到位。

2
回到刚才的案例。开始在 Agent 外面一层一层加 Harness。

先加两层最基础的运行控制。

一层是迭代上限。一个没有任何约束的 Agent,很容易陷入死循环。有时候碰到卡点,它会反复点同一个按钮,然后在一个死循环里绕不出来。

Harness 可以给 Agent 设一个明确的运行边界。比如执行轮数超过阈值,就直接中断,标记失败。这样至少能保证,一个失败任务会在可控成本内结束。

另一层是上下文管理。浏览器返回的 HTML 本来就长,几轮工具调用日志一叠加,上下文窗口很快就塞满了。

一旦塞满,Agent 就开始被自己的历史淹没,越往后越糊涂,连最初的目标都记不清。

Harness 可以定期压缩历史上下文,只保留对下一步决策还有价值的信息。这样就可以避免 Agent 因为上下文过长,被历史信息拖垮的问题。

加完这两层后,Agent 至少开始变得可控。但还有一个更关键的问题没有解决。它说任务完成了,这件事系统怎么才能确认是真的。

3
所以下一层的 Harness,就是要解决 Agent 结果验证的问题。

之前的流程中,Agent 跑完一圈任务回来说搞定了,系统也就默认任务真的已经完成。

但其实模型说自己完成,很可能是幻觉,跟它实际做了什么是两码事。

所以这层 Harness 要做的事,就是把判断权从模型的单一输出,转移到对真实执行记录的核查上。

在 Hacker News 的例子里其实很简单,加一层单独的验证逻辑就行。任务结束后,Harness 再跑一轮额外的验证,从执行过程中的工具调用历史里看一遍。

它访问了哪些 URL,点了哪些按钮,DOM 状态有没有真的发生变化。如果 DOM 变了,比如 upvote 按钮被点亮,任务就算成功。

如果没变,那任务肯定执行失败了,不管模型最后怎么总结。

这一步看起来简单,但其实是所有 Agent 必加的环节。模型自己说什么不重要,重要的是有一套任务是否完成的标准。

我知道,很多人面对 Agent 不靠谱的第一反应是模型不够强。但很多时候问题真不在模型。

再聪明的模型,只要没有一个机制去核对它到底有没有完成,这事就无解。

4
有了验证之后,再回头解决 Hacker News 登录的问题。前面那些 Harness 策略,不管是迭代上限、上下文压缩还是验证步骤,都是在给 Agent 本身加约束、加监督。

但登录需要 Agent 像人一样,真的可以输入用户名和密码,完成登录这一步。

具体做法是,Harness 在每一轮循环里,单独检查一下浏览器当前的 URL。如果发现当前页面进入了登录态,就不再把控制权交给模型,而是触发预先写好的登录逻辑。

这段逻辑完全不依赖模型推理,而是确定性的程序执行,从环境变量里拿账号密码,定位到输入框,填进去,点提交。

登录成功之后,把浏览器导回原来的页面,再把控制权交还给 Agent,让它继续做原来的任务。

整个过程,Agent 完全不知道发生了什么。它只是发现自己刚才在 A 页面,现在还在 A 页面,但身份状态变了,可以继续往下走了。

这个设计背后有一个很重要的认知,不是所有事情都该让模型来做。

模型适合处理开放问题。需要理解、判断、泛化的场景,它很强。但登录不是。

更准确的说法是,Harness 在这里做了一件事,识别出哪些场景是模型不擅长的,然后用代码把这些场景接管掉,做完之后再把世界恢复到模型能继续发挥的状态。

加上这一层之后,整个 Agent 终于能跑通了。同样的模型,同样的 prompt,没有任何改动,但它现在可以稳定地打开 Hacker News,跳到登录页,登录,回到原帖,点 upvote,确认完成。

从一个连登录都过不去的 Agent,变成一个能跑通完整流程的 Agent。

5
回过头看这四层 Harness,会发现一个挺有意思的事情。

第一层迭代上限,处理的是会不会失控。第二层上下文压缩,处理的是能不能跑完。

第三层验证步骤,处理的是有没有真的做成。第四层登录接管,处理的是哪些事情根本不该让模型自己做。

这四层加起来,做的其实是同一件事。用确定性的工程系统,去约束和支撑一个非确定性的模型。

这就是为什么模型是大脑,Harness 是身体这个说法成立。

模型本身只负责推理,但真实世界是一个由状态、权限、页面、网络和异常流程组成的系统。只有推理能力,是无法稳定进入真实工作流的。

Harness 做的,是把这些复杂性重新收敛成模型能够稳定处理的运行环境。

这个例子最值得琢磨的一点是,从头到尾,Agent 的模型没换,Prompt 没改,改的全是它外面的执行框架。

但 Agent 的表现,已经从一个连登录都过不去的系统,变成了一个能稳定跑通完整流程的 Agent。

这件事翻译过来就是,很多时候,真正决定 Agent 稳定性的,其实是 Harness。

模型进步当然重要。但很多 Agent 的问题,并不是模型能力问题。

更重要的是,Harness 不是玄学。它是一整套可以被拆解、被测试、被优化的软件工程问题。
28
小盖fun
13天前
AI Coding 很容易踩的一些坑。

AI Coding 工具正在同时被过度低估和过度吹捧。

关于 Vibe Coding,看到的都是类似的说辞:编程已经没有门槛,用自然语言说出自己的想法,就能够写出一个软件。

另外一方面,真正用 AI 写过成体系代码的工程师都会发现,AI 确实非常强,但它也容易把代码库变成一坨没人敢动的屎山。

前段时间在 AI Engineer 大会上,资深工程师 Matt Pocock 做了一个分享,标题挺反共识的,叫 Software Fundamentals Matter More Than Ever。

软件工程基本功在 AI 时代不仅没过时,反而比以前更值钱了。

这句话第一眼看上去像是老工程师的精神胜利法,但听完他的论证再回头看自己用 AI 写代码踩过的坑,会发现讲的全是实话。

下面我分享一下我的感受。

1
很多人对 Vibe Coding 的理解是,随性地跟 AI 聊,用自然语言表达想法。哪里有 bug 或者跑不通,继续让 AI 改就行,反正 AI 已经很强了。

如果只是做一个小工具,用户量不大,那这套打法绝对没问题。但如果你想做的是一个大中型系统,那完全就是另外一回事了。

懂代码的人深入看一眼就会发现问题。Vibe Coding 第一遍 AI 生成出来的代码还行。第二遍质量下降一点。

第三遍更差。几轮下来代码库的可维护性会变得很差,逻辑散落、命名混乱,连 AI 自己再回来读都得绕半天。

《程序员修炼之道》这本老书里有个词准确地描述了类似的现象:软件熵。

熵增是宇宙基本规律,万事万物都倾向于变得混乱。软件也一样,每次改动只盯着眼前这一处,不考虑整个系统的设计,代码就会一点点烂下去。

AI 生成代码的速度比人快十倍,这意味着熵增的速度也快了十倍。

Vibe Coding 这套打法的底层假设是一句话:代码很便宜。但这个假设错得离谱。代码从来不便宜,烂代码反而比以前更贵了。

为什么这么说,因为 AI 在好代码库里能跑得飞起,在烂代码库里寸步难行。

想象两种场景。一种是代码库结构清晰、命名一致、模块边界明确,AI 接到任务能很快找到该改哪里、不会改坏什么。

另一种是代码像一锅乱炖,同一个概念有三种叫法,逻辑散落在十几个文件里,AI 每次改动都得先猜半天,改完还经常牵一发动全身。

在第一种代码库里,AI 是杠杆,把产出放大十倍。在第二种代码库里,AI 是放大器,把混乱放大十倍。

这就是整件事的核心:AI 是复杂度放大器,不是复杂度清洁工。

那问题来了。既然 AI 会天然放大复杂度,那真正该做的事情是什么?

答案是主动给代码库加秩序。

这时候。那些老掉牙的软件工程原则和方法,在 AI 时代不是变得过时了,而是第一次变成了真正的生产力。

2
很多人用 AI 写代码的第一感觉是,怎么 AI 做出来的不是我想要的。

明明指令也下了,要求也说了,做出来的东西就是差点意思。然后再补一句 Prompt 调整,再差点,再补一句,几轮下来开始怀疑人生。

软件这行有句老话,没人真正知道自己想要什么。

解决方案有两个,都是开工前的功夫。

第一个叫 Grill Me。

AI 反过来盘问你。Prompt 简单到就一句话:围绕这个计划的每个细节相关地审问我,把设计树的每个分支都走一遍,把依赖关系一个个理清,直到我们对要做的事达成共识。

这个仓库在 GitHub 上拿了一万三千多颗星,可见多少人有同样的痛点。

实际用起来什么效果,AI 会问你四十个、六十个、有时候一百个问题。问到后来自己都觉得烦,但就在这种烦中,原本以为想清楚了的需求,会被它逼出一堆没考虑到的角落。

《人月神话》的作者曾经讲过一个观点:两个人一起设计一个东西,他们之间会有一个看不见的共同理解,那个理解不在任何文档里,就在两个人的脑子里。

如果这个共同理解没建立,两个人各自走各自的方向,最后做出来的东西必然对不上。

人和 AI 之间也一样。你以为说清楚了,AI 以为听明白了,其实双方脑子里想的根本不是同一个东西。

Grill Me 干的事就是把这个隐形的共识显形化,让双方的脑子在动手之前先对齐。

第二个方法叫 Ubiquitous Language,通用语言。

这是 DDD 里的老概念。DDD 是什么,我不展开了,不熟的同学可以去搜一下。最近 Vibe Coding 比较多,我又再次意识到十年前学的 DDD 有多重要。

举个例子。一个电商项目,运营那边把订单叫做单子,客服那边叫订单,技术那边在代码里写 Order,数据库表叫 trade_record。这次 Prompt 用了订单,AI 就写一个 order_service。

下次 Prompt 用了交易,AI 又写一个 trade_handler。过几轮回头看代码,发现同一件事在三个文件里有三种命名,调用关系绕来绕去。重构一次得改半天。

通用语言的做法很简单,维护一个 Markdown 文件,列清楚项目里所有关键概念的精确定义,哪些词不要用,命名规则是什么。然后让 AI 每次工作前先读这个文件。

效果挺明显的。观察 AI 的思考过程会发现,术语对齐之后,AI 想问题的方式都不一样了,输出更精准,写出来的代码命名也更一致。

把这两件事放一起看,会得到一个挺反直觉的结论:和 AI 协作里最贵的成本,不是写代码的时间,是消除歧义的时间。

前面花十分钟跟 AI 对齐清楚,后面能省两个小时的返工。这笔账怎么算都划算。

但人有种本能,看到 AI 能写代码,就想赶紧让它开始写,先跑起来再说。

这种心态在 AI 时代会被反复教训。

3
意图对齐之后,下一步是怎么让 AI 实际干活。

这里有两个关键的节奏控制方法,垂直切片和 TDD。

先说垂直切片。

很多人用 AI 的姿势是这样的:给我做一个任务管理系统,要有用户登录、任务列表、提醒、协作。

然后 AI 开始一通生成,前端、后端、数据库、接口,一口气出来几十个文件。

这种打法有点像先横着铺架构,前端、后端、数据库、接口都先摆出来,再一层层往里填。问题是哪一层都没填完,哪一层都跑不通,想验证某个具体功能能不能用都不知道从哪儿下手。

更靠谱的打法叫垂直切片。

从一个具体的用户场景切入,比如用户能创建一个任务并在列表里看到它。

围绕这个场景,从前端的按钮到后端的接口到数据库的存储,竖着打通一条完整链路。这条链路能跑通了,再做下一片。

这么做的好处特别实在。每一片代码量都不大,能看懂 AI 在做什么。

每一片做完都有一个能演示的成果,业务价值看得见摸得着。出了问题改动范围有限,不会牵一发动全身。

用得好的人都在做精细手术,一片一片地打通。用得差的人都在让 AI 拿电锯推楼,看起来气势大,结果一片狼藉。

切片切对了方向,每一片里面也不能让 AI 一通乱写。这里就要用到 TDD,测试驱动开发。

AI 写代码默认是一种很冒进的状态。给它一个任务,它会一口气写一大堆代码,写完才想起来要不要类型检查一下,要不要跑个测试。

这时候已经晚了,错误已经扩散到很多地方,找起来非常痛苦。

《程序员修炼之道》里有句话说得贴切,反馈的速度就是你的速度上限。反馈跟不上代码生成的速度,迟早翻车。

TDD 干的事是给 AI 装一个限速器。先写一个测试描述期望行为,让 AI 实现这个测试能过的最小代码,跑通,再写下一个测试。

AI 被强制一小步一小步走,每一步都有验证,跑偏了立刻就能发现。

这里有个心态上的变化值得说说。以前是人写代码再补测试,测试是写完之后的事情。

现在更像是人设计测试和行为,AI 去把实现填满。测试从事后检查变成了事前约束,从安全网变成了方向盘。

AI 不缺速度,AI 缺的是约束。约束是人加的。

4
活动现场,Matt 问现场的程序员,有多少人觉得自己比以前更累。台下很多人举手了。

AI 不是号称可以提高效率吗,怎么用了 AI 反而更累。

原因其实很简单。AI 产出代码的速度,已经超过了人脑处理这些代码的速度。能写出来不等于能看懂,能跑通不等于能维护。

而代码库的组织方式,直接决定了这种过载有多严重。

如果代码库里全是浅模块,AI 写得越多,人需要装进脑子的东西就越多。

每个模块接口都不一样,调用关系绕来绕去,想看懂 AI 改了什么,得把整张地图重新理一遍。AI 在跑,人在喘。

解法是回到一个老概念,深模块,Deep Modules。这个概念出自斯坦福教授 John Ousterhout 写的《软件设计的哲学》。

什么叫深模块。一个模块对外暴露的接口越少越简单,内部封装的复杂度越多,这个模块就越深。

举个例子。要发邮件,深模块的做法是对外就一个函数 sendEmail(收件人, 主题, 正文),调用方填三个参数就完事。

这个函数里面要做的事其实一大堆,连服务器、认证、组装邮件头、处理重试、关闭连接,但这些细节全部藏在模块内部,外面看不见。

浅模块的做法是把这些细节一个个暴露出来,对外给六七个函数,调用方得自己按顺序调用。

注意,深模块不是说一个函数里塞很多东西,那是反面教材。

深模块讲的是整个模块对外的接口少而干净,内部该拆几十个小函数就拆几十个小函数,但拆出来的小函数是模块内部的事,不暴露给外面。

AI 天生爱生成浅模块。让它写代码,它倾向把内部步骤一个个变成对外函数,看着 DRY,实际上把内部复杂度泄露给了调用方。

深模块的好处是人可以把模块内部当成灰盒看。接口设计清楚了,行为有测试盖着了,里面怎么实现的日常不用盯每一行,需要的时候再掀开看。

这部分脑力就省下来了,省下来的脑力放在更上层的事情上,模块边界画得对不对,接口够不够清晰,整体架构有没有走样。

人的大脑能装的东西是有限的。AI 把代码生产速度推上去之后,这个有限性就成了瓶颈。

深模块的本质是给大脑减负,让人不用把整个系统的复杂度都装进脑子才能干活。

到这里,AI 时代开发者的角色就清楚了。

AI 是手脚极快的实施兵,能把活干得又快又多。但实施兵需要有人指挥,得有人在更上面盯着系统该往哪儿长。这个人就是开发者。

这种分工下,开发者每天该投入的不是敲键盘的时间,是想清楚系统该怎么设计的时间。

写到这儿,开头那个反共识的结论可以收一下了。

AI 正在把程序员从代码工人推向系统设计师。生成代码这件事,AI 已经接手了大半。

人剩下的价值集中在四件事上:画清楚模块边界,控制系统的熵增,设计反馈的回路,统一整个系统的语言。说到底是一件事,管理复杂度。

会写 Prompt 只是入门,能管复杂度才是真本事。

5
前面这些原则,通用语言、垂直切片、TDD、深模块,单拎出来没有一条是新的。每一条都能在二十年前的工程书里找到出处。

这正是这场分享真正想讲的事。

Matt 在开场说过一句话,这场 talk 是讲给那些觉得自己的技能在 AI 时代不再值钱的人听的。

台下很多是干了十年、十五年、二十年的开发者,看着 AI 一夜之间能写代码,会下意识觉得自己被淘汰了。

但他要表达的其实不是替老工程师找补。他真正想讲的是另一件事。

即便 AI 的能力已经这么强,写代码的速度这么快,那些过去几十年攒下来的软件工程原则,仍然需要被一代一代的开发者认真学习、认真理解。

这些原则不是历史遗产,是真正构成判断力的基石。没有这些基石,就驾驭不了 AI 写复杂代码。

AI 时代有一件事翻转了。以前稀缺的是手快的人,能一晚上撸出来一个原型的程序员很厉害。

AI 把手快这件事变成了基础设施,稀缺性整个反转过来,反转到了对代码的驾驭上。

所以这场分享真正想说的是,AI 不是让软件工程让这门功课变得比以前更重要。

老工程师过去几十年学的那些东西没白学,年轻开发者今天该学的那些东西也没法跳过。

AI 能帮人写代码,帮不了人去理解什么是好代码。

编码容易,测试也容易。架构、设计和品味,才是真正有价值的事。
1057
小盖fun
14天前
左耳朵耗子去世三周年。早上醒来,我收到了日历提醒。

也是在三年前的今天,我们本来约好了见面交流,没想到发了微信消息,再也没有回音。

于是,我决定在每年的这个时候,写点什么,来追忆这位倔强、浪漫又给人力量的技术人。

对于很多工程师而言,当下很难再找到一位像他那样,执着于技术,又接地气的榜样。

这年代从来不缺鸡汤,也不缺榜样。但能理解普通工程师的困境,还能指出一条可行道路的人实在太少了。

站在舞台中心,侃侃而谈的很多成功者们,他们根本不知道人们并不像他那样拥有众多优越条件,他们根本不理解普通人的难。

左耳朵耗子的去世,让我想到另一种审视生命的视角。我们可以试着思考:死后希望别人怎么评价自己。

这并不是说要刻意在意外界的看法,而是逆向的帮我们更清楚地认识到,什么才是自己真正珍视和追求的。

当下互联网上的信息太多了,但能历久弥新的着实是少数。我相信左耳朵耗子的很多话,即使过了多少年你再读,仍能从中汲取到力量和方向感。

我一直认为,理解和实践一个人的人生观和做事观,便是对他最好的怀念。

曾经,我和他做过一次连麦直播,今天我想把这个直播中,最打动我的观点写出来,供大家阅读。

以下以左耳朵耗子的口吻转述。

创业几年的反思

创业还是很难的,很多人可能觉得我已经有很多资源,会有比较大的势能。

不是那样,包括我现在公司也还有很多各种问题,所以其实都还是挺不容易的。

但是我的人生信条是条件受限是好事。

这个信条会引导我去想一些更重要的东西。比如很多公司可能想怎么样拿投资,现在我在想的是,怎么样能让我们的公司不拿投资,自己成为一个能盈利的公司,能成为一个真正的公司,不是被人包养需要寄养的一个公司。

其实大家也可以去思考,这个世界其实并不完美,你会遇到很多很多让你很无助的事情,我也经历过工资发不出来,自己掏钱给团队发工资的时候,我一晚上睡不着觉,也经历过。

但是我想说的就是,所有的路都是可以走的,不用担心。

但不是纯靠坚持,关键是你一定要去想方法,想更好的、更优的解,这个事很关键,千万不要使蛮力,没有太大意义。这是我创业学会的第一个道理。

方法会比努力更重要,所以我们不加班,如果团队在加班,我觉得我们肯定方法不对。

我创业学会的第二个道理是关注你的重点,不追小兔子。能让你分心的事情太多太多了,你不知道你前面那座城池有多高。

因为你从来没见过,一路上都会有很多很多的小兔子来找你。你一看,这个兔子好看,我来追一下,那边又有一只蝴蝶,你就忘了你未来要去哪。

这两个东西我觉得挺重要,这也是我创业这几年来受到最大的两个教训。我觉得跟我们的人生也是很相通的。

技术不是用来写 CRUD

低代码会不会颠覆外包公司?这是一个很有意思的话题(注:当时 AI 还未崭露头角,很多人担心低代码会替代自己的工作)。

过去一段时间,云计算,更多是对企业运维侧工作的变革。特别是 IaaS PaaS,它做的都是技术侧的事情,比如怎么管理计算资源,怎么做好监控。

我相信,未来云计算肯定是要慢慢向业务渗透的,因为有一部分业务是可以标准化的。

从这个角度看,外包公司可能会被颠覆。很多中小公司并不一定需要一个特别复杂、定制化的产品,它们的需求是可以快速使用。

而快速使用、开箱即用类的产品,有两类。第一,SaaS。像项目管理软件、聊天软件、销售软件这类的产品,企业没有特别多的定制化需求,标准化的产品就够用了。

第二,低代码。通过低代码,企业可以搞定一些简单的定制化类的需求。

很多外包公司我觉得还是缺少思考。一个人,一家公司,如果不思考的话,那颠覆你的往往不是不是这些云计算、低代码这些技术,而是什么都有可能颠覆你。

因为你只是在按部就班地做事,别人让你做啥你就做啥,你没有去想更多。

客户说我要一匹更快的马,你就去训马了,而不是想着做个汽车。

这是外包公司最大的问题,他们没有任何的话语权,客户让他干啥他就干啥。而绝大多数客户,绝大多数时候是不知道自己想要什么的。

低代码肯定会替代一部分简单的 CRUD 类的工作,但我觉得我们技术人员本应该去干更高级的事情,而不是纠结这些。

我想说的是,技术不是用来写 CRUD 的,技术是用来创新的,这一点大家要理解。

如果你只是把业务流程给数字化、代码化,那即使在大公司里,你本质也是做外包。

不要觉得在大公司里就不是做外包,我给你讲,你很有可能是在给那些运营做外包。

要理解,真正的技术是要拿来做创新的,你要去颠覆点什么,要去创造点什么。

基础知识的意义

我一直强调要学好基础底层技术。两个原因,第一,你得知道原理,知道某个技术它是怎么运作的。

不要着急,有的人可能会说今天学了也没什么用,你还是要坚持学,因为你慢慢会发现,很多东西都是相通的。

第二,当遇到一些比较难解的问题时,你学到的这些知识就会派上用场。

这些难解的问题会让你跟别人拉开差距,懂基础和不懂基础的人,他们的思考完全是在两个层面。

不懂基础知识的人,他就在那瞎搞,这里试一下,那里试一下。运气好,碰巧解决了,但也不知道怎么回事。而懂基础的人,他可以很快理解大概是怎么回事。

我举个例子,Linux 操作系统有时候我们会感觉写硬盘很慢,但我想说,写硬盘其实不慢,因为它有 Page Cache。

你写硬盘,其实也是写在操作系统的内存,然后内存在一点点换页换到硬盘上。

很多中间件,比如 RocketMQ、Kafka,都会使用到 Page Cache 技术。只要 Page Cache 玩得好,那系统性能也会不错。

还有像 TCP 原理。有些时候网络连接会闪断。从 a 节点到 b 节点,中间经过了很多设备,你怎么排查故障?如果你懂原理,那就会容易些。

第一,你先看看 TCP 的状态,如果是 time wait 的话,那就是我主动断开连接;如果是 close wait 的话,那就是对方主动断开连接。你看状态就能有一个基本的判断。

第二,如果没有看到连接建立的话,你需要使用抓包的方式,像什么 tcpdump、wireshark 之类,用这些工具,就能很快定位问题。

如果你不懂基础知识,那你很可能就不知道怎么使用这些工具。而没有这些工具,解决那些问题,你估计就得使用蛮力了。

如何完成早期的技术积累?

很多人觉得我已经完成了自己的技术积累,已经开始探索马斯洛需求层次理论上层的事情了。是这样子。

很多人知道我的时候,我已经有点名气,我已经去了阿里、亚马逊,反正稍微有点成就。

所以你并不知道我刚开始出来是去了工商银行,他们给我分了套房子。我父母是下岗工人,每个月两个人加起来就 200 块钱工资,我是 600 块钱,我们一家三口 800 块钱。

但当时,我不要了,全部都不要了,我要出去到上海做外包。

到上海的时候我拿 1500 块钱的工资,租房 900 块钱,然后一顿饭要吃 15 块钱,你们算一算,一天的生活费我只够吃一顿饭,而且我还得自己做饭。

公司说出差一天有 30 块钱的出差补贴,而且出差还管饭,所以我必须得出差。一出差,我的收入就好很多。

那时,我无时无刻都在想着,我要去更好的地方。那时候我们封闭开发,周一到周六全部待在开发中心,家都回不去。

即便这样我也要去学习,周日我也要出去面试,去改变自己。因为那种没有技术含量的事情,我知道再做 100 次,也依旧没有任何未来。

老实说,我跟那些外包公司极度不和,我跟老板吵架,我甚至跟甲方的行长吵架你们相信。

因为我把事情做完了以后就在那看书,那个行长过来说,大家都在这外包,你为什么要在这看书?

我说我看的又不是闲书,我看的是技术书籍,你凭什么不准看?你安排活给我做就好了,你管我看不看书?我就跟他吵架。

后来我选择职业或者工作的时候,我宁可被公司开掉,也要去做有价值的东西,我从一开始的初衷就是这样子。

并不是说今天功成名就了,我才这样选;而是我一直都在这么选,所以我才会有今天的成就,大家要理清楚这里面的因果关系。你不这么选,你永远不可能成为这个样子,明白吧?

现在我做公司也类似,有些项目我不接就不接了,我要接项目的话,也可以把自己做成一个外包公司,一年也有几个亿,但是有什么意义呢?我设想是十几个亿的事情。

刚才有人跟我说我做的事情太大了,有点不可能。这就对了,因为绝大多数人都不敢想,他们想一想就觉得这事不可能,就离开了,所以我没有太多的竞争对手,明白吗?

因为绝大多数人都不敢想,他们一想他们觉得我做不到,就傻掉了,他们自己就给自己思维框架里面就设了一座墙,因为连尝试他都不敢尝试。

至少我敢尝试,失败了又能怎么样呢?反正我不会后悔。我未来老了以后,四五十岁看我这段时间我至少试过失败、至少试了一个牛逼的事情。

那你们呢,自己的人生你连试都不敢试,想都不敢想。人,最可怕的是不敢想。不好意思,讲得稍微有点激动。

996 没有成长怎么办?

“毕业两年,现在公司里头都是 996,日常的业务需求做不完,感觉自己在这个公司没有什么成长,学习也没有多少时间,是不是应该考虑换工作了。”

对于这个问题,我想问,大家想过没有,你找工作的目的是啥?

任何事情我们都得回到目的上,如果找工作的目的是为了找碗饭吃,不让自己饿死的话,那 996 这些我觉得都顺其自然就好,因为这是让你不饿死的一条路。

如果你找工作的目的是为了实现自我价值,那假使现在的公司不能帮你达到这样的目标,你就应该勇敢寻找能够帮你达到目标的公司。

比如,我以前是在银行里,从甲方跑出来,房子都不要了,我就是为了实现自我价值,所以我选择公司的标准就是这个公司可不可以帮助我实现自我价值。

这是互相成就的一个事,我跟我的团队的员工也是这样说的:你成就我,我成就你,这是双向的事情。

所以我觉得换不换工作问题在于,你得问一问自己,你想要什么?如果你想要的是提升自我,那就应该去找能够成就你的公司。

那些公司也会问你,你能成就我啥?这就是一个相互交换的过程。当我们不断去索取的时候,我们也需要给予。

我贡献价值,反过来,我希望公司也能给我价值。这是互相交换。

大家都是在签合同,是雇佣关系,而不是什么劳动关系,不是说是我为你工作,我就是你的人,不是卖身关系,这是个相互合作的关系。

所以,如果不能达到目的,我建议你不要去,公司也需要很好的人。好的机会从来都是给好的人,不会给不好的人。

35 岁危机

我在一些群里,40 岁程序员的群,然后还有些 35 岁以上程序员的群。

我觉得那些群我连一天都不想看,太无聊了,里面就是各种八卦,我不知道为什么这些中年人天天都喜欢聊八卦,今天看见这个社会热点又怎么样,那个热点又怎么样。

我觉得是这样的,不要觉得 35 岁、40 岁会是一个坎。我今天也在写代码,有句话是这么说的:人不是因为变老了才没有热情,而是因为没有热情才会变老。

有的人说我老了,我学不动了。不是的,因为你学不动,你才变老了;不是你老了,你才学不动。

这个世界上有大量这样本末倒置的因果关系的逻辑,如果你学得动,或者你还对这个事情充满憧憬,有想法,愿意去奋斗的话,70 岁你都不老。

像我今天这个样子,我也不觉得我老。我觉得很多年轻人可能还不如我,他们在 20 多岁、30 多岁,可能就已经放弃了自己的人生,我今天还没有放弃。所以, 35 也好, 40 也好,不用去想这个数字的事。

大公司和小公司的权衡

其实无论大公司也好,小公司也罢,只要你用心观察都能学到东西,但你不用心什么都学不到。

大公司最大的问题就是一个萝卜一个坑,你就只能干你那一小个环节,你就是他的零件。所以很多人觉得大公司里面学不到东西,反而在小公司里可以做一个面的事情,能学得更多。

其实不是这样。到大公司里面,我觉得有三个东西是可以学得到的。

第一,组织管理。大公司组织的运作方式、体系化的管理方式,怎么调动那么多人来完成一个事;

或者一些思维方式,为什么他要做这个而不是做那个。这是大公司跟小公司不一样的地方,因为大公司有资源,可以去试错,试过很多很多错误。

第二,怎么挣钱,大公司怎么挣钱的。

第三,大公司里面的一些高手是怎么工作的。因为大公司里我觉得应该是有这个世界上最好的人。

比如这个世界上最好的运营、最好的产品经理、最好技术人员,都在阿里、亚马逊、谷歌这样的一些公司。

所以你进去要去找大公司里面那些聪明的人,跟他学,就像你打羽毛球下象棋一样,你必须要找高手学。

就这三个东西,在大公司里面我觉得是最有价值的。

但相比公司的大小,更关键是你有没有跟那些聪明人在一块。

你到大公司,也是要看你的朋友圈,这是一个非常非常重要的观点,你跟什么样的人在一起,决定了你怎么样成长;你跟什么样的人在一起,你就会被影响成什么样的人。

所以有的小公司也不一定不能成长,关键是你有没有跟对人?他的格局够不够?

对我影响最大的书

对我影响比较大书是《Rework》。我被它里面所有的想法,严重洗脑了。书里面讲条件受限是个好事,因为条件受限可以倒逼你抓重点,倒逼你做自动化,倒逼你简化。

我突然就想起我以前买不起书,那个条件受限的时候就必须要用更聪明的方式去学习,因为你买不起书,所以你必须要画知识图,全部都是在条件受限。

要是我条件不受限,可能我就不会这么样,我就会去买书,最后书堆着都没法看。还有一个观点,就是挠自己的痒处,自己觉得不爽了自己要去改变它。

所以我觉得这个世界上很多能创业的人,或者说是能改变世界的人,一定是不能忍的人。

各位,如果你今天什么事都能忍,你想一想还是忍了,我不去抗争了,你一定不会成为这个世界的厉害的人,你一定没有什么利益的噱头。

这个世界是属于那些不能忍的人的,因为你不能忍了你才会想去改变它。

知道吗?各位。从你身边的一点点小事开始,你觉得不能忍了,不能抱怨了,你决定行动起来,改变点什么,这时候,你就会琢磨怎么才能更好。所有的东西都是从不能忍开始的。

如果你什么都能忍,那对不起你一定是韭菜。我看过的很多好的产品经理,他们都是不能忍,都是各种不能忍。

所以他们就可以做得很好。不能忍的人一般标准很高,就是这样子。
310
小盖fun
16天前
归根到底还是自控力太差了。

一个曾经共过事的朋友,特有才华。他写文章很扎实,妙句连连。

记得一起上班那阵,他开玩笑跟我讲,他是他们村明朝以来第一个考上名牌大学的。

人确实很聪明,也实诚,但有个缺点是自律能力不大好。

我俩共事时,他经常整晚整晚地刷剧,碰到喜欢的电视剧,这哥们钻进去之后能看一晚上,第二天上班就没精神。

后来我发现他上班时间看小说,不过公司管理没那么严格,对他也很信任,结果他滑向了另外一端,产出急剧减少。

去年下半年,他从上家公司离职,准备自己做点事情。我还觉得挺好。

但昨天再聊起来,他说没啥进展,在家里一个人很懒散,提不起精神,睡醒就 10 点多了,然后吃个午饭,又犯困,反正也不知道怎么回事,一天就过去了。

哎,自控力太弱了。

我见过好几个这样的同事,才华连连,但就是自控力差,自己把大把时间都挥霍一空。

我在完美世界时也如此,那会儿工作不多,领导要求不高。

本来这是好事,结果我却平白浪费了两年时间。悔恨不已。那是我人生的一段垃圾时间。
22
小盖fun
17天前
MiniMax 研究员写的模型故障排查文章简直太精彩了,推荐所有对大模型机制感兴趣的朋友都看看。

我们团队内部一直在提倡一个词,叫小题大做。意思是面对一个具体的小问题,把它当成一个小接口往里钻,深度复盘,最后往往可以优化掉整个系统的某些隐患。

感觉 MiniMax 这次的复盘正是这种工作方式的标本。希望国内能有更多这样的文章。

整体是怎么回事?我跟你解释一下。

时代少年团是内地一个非常红的男团,队长叫马嘉祺。社区里有人发现,问 MiniMax 的大模型时代少年团队长是谁,模型明明知道这个人,能流畅说出他的生日、毕业院校、所属团体,但就是写不出嘉祺这两个字。要么绕开不写,要么只写出马嘉两个字。

我当时看到这 Case,就想到前两天我要给一个朋友写贺卡的时候,发现自己提笔忘字。因为好久不手写文字,很多字肯定自己认识,但就是不知道怎么写了。

MiniMax 模型遇到的事情,正好是同一个逻辑。

1
让模型介绍一下马嘉祺,它能流畅说出对方 2002 12 12 日生于河南省郑州市,毕业于中央戏剧学院音乐剧专业,2018 年随时代少年团出道。这些信息掌握得相当完整,对这个人是有记忆的。

但反过来,问它时代少年团队长叫什么名字,模型就开始磕巴。前面的马字能写出来,到嘉祺这两个字就卡住,要么跳过去,要么换成别的字。

模型对一个词的理解能力和生成能力,并不一致。

而且不止嘉祺一个例子。

这种感觉就像一个人想说一句话,话到嘴边却换成了意思相近的别的表达。模型并没有胡说八道,它是真的卡住了。

以前我们对 AI 的印象,是它的能力像一锅整体的汤,问什么答什么,强弱也很均匀。这个 Case 让我们看见模型内部其实有非常清晰的分工。模型理解一个词和把它输出出来,并不是完全同一条路径。

当然这不代表两者完全无关,真正的语义推理还是发生在中间的 Transformer 层里,只是这次问题主要集中在输出端。

2
那到底是哪里出了问题?

大模型说话的时候,用的并不是我们理解里的字和词。在文字真正进入模型之前,会先经过一个叫 Tokenizer 的东西。它会把一句话切成一个个 Token。这个东西有点像介于单字和词语之间的零件。

比如苹果可能是一个完整 Token,你好也可能是。而一些出现频率低的组合,则会被拆成更小的 Token 分别处理。

MiniMax 团队最先怀疑的就是这一层。嘉祺这两个字平时单独出现的频率不高,会不会是被拆成了嘉和祺两个 Token,其中一个没训练好?

结果一查,问题并不在这里。

MiniMax 团队发现,嘉祺没有被拆成嘉和祺两个字,而是被 tokenizer 当成了一个完整 Token。它的编号是 190467。

这件事听起来有点反直觉,但原因并不复杂。

Tokenizer 在生成词表的时候,会用一种叫 BPE 的方法。可以先把它简单理解成一种统计打包规则:如果两个字经常连在一起出现,系统就会倾向于把它们打包成一个更大的词块。

所以,越是在网上经常被连着写的名字,越可能被合成一个完整 Token。

嘉祺就是这样。单看嘉和祺,这两个字都不算特别高频。但放在马嘉祺这个名字里,它们在网上经常一起出现,于是就被打包成了一个完整 Token。

这反而引出一个更怪的问题。既然嘉祺是一个完整 Token,那模型应该认识它才对,怎么还会写不出来?

团队再去检查模型对这个词的理解,结果完全正常。预训练阶段,嘉祺在模型内部的语义邻居是亚轩、千玺、肖战、王一博这些常见的中文人名,聚类合理,向量分布也正常。模型脑子里很清楚嘉祺是个人名。

那问题到底出在哪?

3
到这里 MiniMax 团队换了一个角度去看。

在大模型内部,有两组关键参数,分别处在模型的进口和出口。

进口处那一组叫 vocab embedding。它负责把每一个进入模型的词条翻译成模型内部的语义信号。出口处那一组叫 lm_head。它负责把模型内部已经形成的语义状态,重新翻译回具体词条,决定最终输出哪个字。

真正的推理和理解,发生在两端中间那一大堆 Transformer 层里。但这次 MiniMax Case,问题主要出在出口端。

MiniMax 研究员比对了模型在后训练前后这两组参数的变化,结果对比非常说明问题。

进口端的 vocab embedding 几乎没动。也就是说,模型对嘉祺这个词的理解能力完整保留。这解释了为什么模型还知道马嘉祺是谁。

这件事其实有它的道理。神经网络反向传播的时候,越靠近输入端的参数,收到的梯度越弱。

再加上像嘉祺这种低频词,本身就很少在训练数据里出现,输入端几乎收不到关于它的有效更新信号。结果就是 vocab embedding 这一层天然稳定,不容易被改写。

但出口端的 lm_head 变化巨大。嘉祺对应的输出参数方向漂移得非常厉害。这意味着,模型脑子里依旧知道嘉祺是一个人名,但是它的手已经忘了怎么写出这两个字。

漂移到什么程度?MiniMax 检查了 lm_head 里嘉祺这个词的语义近邻。预训练阶段它周围还是亚轩、千玺、肖战这些正常中文人名。后训练之后,邻居里开始涌进一堆奇怪的东西,比如 tool call 标记、文件操作符号、英文乱码字符串。

一个原本待着中文人名的区域,硬是被各种特殊符号挤进来污染了。

4
这个发现还顺便带出了一个意外收获。

MiniMax 团队内部一直挂着一个没解决的问题。让模型用日语回答,它经常莫名其妙混入俄语字符。

最严重的一次测试里,俄语字符的出现率高达 47%。这种现象一直被归类为小语种语言混杂,原因说不清。

这次深度复盘彻底把这些问题串在一起了。词表里被改写得最厉害的那批词条,40% 以上是日语口语词。

日语词的输出位置漂移之后,和俄语等其他语言的字符在向量空间里挤到了一起。模型一开口想说日语,结果调用到的是隔壁的俄语字符。

过去很多人会把大模型想成一个整体。好像 AI 一旦胡说八道,就是它突然变笨了,或者突然疯了。

MiniMax 这次像是给模型做了一次 CT。

它第一次很具体地展示出来,AI 输出层面的很多怪现象,未必是整个模型出了问题。很多时候只是局部参数空间发生了漂移,某些 Token 的出口向量磨损了。

模型脑子里依旧知道那个概念,但就是说不出来。这一刀下去,AI 身上的那层神秘感能被拆掉一大块。

那么后训练阶段为什么会把这些词条的出口零件挤压变形?

答案要再往上游追一层,问题出在词表本身。

词表是从海量互联网爬虫数据里统计出来的。算法的目标是让任何文本都能被高效切分,所以只要某个词条在爬虫数据里频繁出现,它就会被保留下来,不管它有没有正经的语义价值。

这就埋下了一个隐患。互联网爬虫语料和后训练用的高质量对话语料,根本不是一回事。

MiniMax 在排查中列了一份词表里最容易出问题的词条清单,看完会发现里面充满了各种互联网角落里的怪东西。

比如日语网页里常见的客套模板,参考にしてみてください,意思是仅供参考,是日本博客和论坛文末高频出现的套话。

再比如中文 SEO 垃圾词,那种为了搜索引擎排名而被反复堆砌的词。除此之外,还有 LaTeX 论文格式标记、维基百科源码里的模板符号等等。

这些东西有一个共同点。它们在互联网爬虫数据里的出现频率高到足以挤进词表,但在正常人和模型对话的场景里,几乎不会被用到。

模型进入后训练阶段,喂进来的数据基本上都是高质量对话样本。这些边缘词条几乎完全消失。

结果就是,整个词表里大约 5% 的词条,在后训练阶段几乎没作为输出目标被练习过,出口参数发生了明显的漂移。

它们开始在向量空间里和邻近 Token 互相挤占。倒霉的是,那些坐在它们旁边的正常词条,比如嘉祺,也被殃及,写不出来了。

5
MiniMax 最后的修复方案,也非常简单。

团队构造了一份全词表复读数据。把整本词表 20 万个词条全部打乱,每次抽 8000 个组成一段乱序文本,配上一句指令,请重复以上内容。模型的工作就是原样抄一遍。

总共生成 500 条这样的对话,每个词条至少作为输出目标被练习了 20 次。

数据量极小,效果惊人。日语混淆率从 47% 直接降到 1%。马嘉祺这个名字也终于能完整写出来了。整个词表里所有词条的出口参数,相对预训练时期的相似度,平均维持在 0.999 以上,最低也还在 0.97 左右。

故事讲到这里,可能有人会以为这是 MiniMax 一家的特殊问题。其实并不是。

这种现象在学术圈有个专门的名字,叫 Glitch Token,翻译成中文大约是故障词条。从 2023 年开始,研究者就发现 GPT-3、GPT-4o 上有大量类似词条。

MiniMax 这次复盘最有价值的地方,是发现了一种和 Glitch Token 高度相似、但成因完全不同的新现象。经典 glitch Token 是预训练阶段就没学好的 Token,模型从一开始就不认识它。

而马嘉祺这种情况,预训练阶段明明学得好好的,模型对它有完整的理解,是后训练阶段被慢慢挤坏的,最后丢失了输出能力。

值得一提的是,Anthropic 在发布 Opus 4.7 时也明确说过,新版本对 Tokenizer 做了调整。MiniMax 的文章里也提到了这个细节,并推测背后可能有相似的考虑。这至少说明,词表设计这件事,整个行业头部都在重新审视。

这个结论真正的分量在这里。

过去行业默认的理解一直是,Pretrain 负责学习世界知识,SFT RLHF 只是调整回答风格、对齐人类偏好。但这次 MiniMax 等于告诉大家,后训练本身也会重塑模型底层的 Token 空间,会真实地改写模型内部的表达结构。

原本正常的 Token,也可能在这个过程中被悄悄推向异常状态。

马嘉祺不是一开始就坏掉的。他是在后训练阶段,被慢慢遗忘掉的。

这就是小题大做的力量。一个具体的问题,往里钻得够深,最后撬动的是整个系统的认知。

国内的大模型团队里,能把这种过程公开写出来的,太少了。希望以后能多一些。
13
小盖fun
17天前
很喜欢这句话里说的做事的概率逻辑:

你做的任何单个“赌注”大概率会失败。成功来自于不断下注,并在每个下注上全力以赴。成功的概率会随着你下注越多、每次执行得越好而提高。

这些年创业,做了蛮多事。有的彻头彻尾失败了,有的取得了些成绩。失败的那些事,也不全是失败,它为我们后面做的事情打下基础。

所以,我觉得失败并不是什么一文不值的失败。相反,如果畏首畏尾,害怕失败而不敢启动一件新的事情,那才是彻底的失败。
24