用 AI 造了一个等了 8 年的工具,他想说点真话

用 AI 造了一个等了 8 年的工具,他想说点真话

用 AI 造了一个等了 8 年的工具,他想说点真话 用 AI 造了一个等了 8 年的工具,他想说点真话 Modified April 22 他在日志里提到,他既让 AI 完整生成整个模块,也会在需要的时候亲手写 SIMD 指令并在 Compiler Explorer 里看汇编输出,完全取决于具体问题。 标准代码是绝大多数,手写的是例外。 但这个"标准化"是双刃剑。 对于项目里大多数普通代码,标准化是好事。 但每个项目都有它的核心难点,那些需要做非显而易见决策的地方,AI 的本能是把它"正常化",反而有害。syntaqlite 的提取流水线和解析器架构就是这样,Lalit 最后选择自己设计、自己写。 重构和生成一样快 他在日志里反复强调这一点: "如果你用 AI 在工业规模上生成代码,你必须持续不断地重构。如果不这样做,事情会立刻失控。" "每次大量生成代码之后,值得作为人类停下来问'这个丑吗',如果是,就做点什么。" 有时候 AI 能自己清理。有时候有一个大规模的抽象层 AI 看不到,但他能看到,他给出方向,让 AI 执行。 他的日志里写道:"审计加重构,两者配合效果惊人。" 如果你有品味,犯错的代价会大幅降低,因为你能快速重构。 大幅降低了学习新领域的成本 他举了一个很典型的例子:做格式化器的时候,他需要了解一种叫 Wadler Lindig 的算法。 Wadler Lindig 是一种"漂亮打印"(pretty printing)算法,让你能声明式地描述文档的排版方式,由打印器自动决定在哪里换行,而不是手动计算每行的宽度。 在格式化器设计的对话记录里,Claude 主动提出了"从一开始就用 Wadler Lindig 文档模型做宽度感知格式化",Lalit 能立刻参与权衡讨论,而不是先花好几天才发现这个方法的存在。 他对这类跨领域切换的总结是: "我对 C++/Android 性能非常熟悉,但对 Python/Go/Rust 工具完全不了解。有了 AI,这不是问题:基础是一样的,术语是相似的。我现在能在领域之间切换得非常快。" VS Code 插件也是类似的情况。 他对这套 API 完全陌生,但一小时内就有了一个能跑的扩展。 让 AI 充当代码库的"即时顾问" 他在日志里描述了一种很实用的用法: "你可以控制深入程度:表层概览用于快速复习,详细线性讲解用于深入了解,定向审计用于追查问题。" 当他切换上下文太多、忘了某个模块是怎么工作的,他可以直接问 AI:"给我讲讲这个组件",或者"审计这个 repo 里所有 unsafe 的用法"。 这种按需获取上下文的能力,在频繁切换任务的业余项目里格外有价值。 让项目变得更完整 没有 AI,他大概会发布一个核心功能可用、但边角料全缺的工具。 有了 AI,这些东西都做出来了:VS Code 插件、文档网站、crates.io(Rust 包)、PyPI(Python 包)、npm(JavaScript 包)、Homebrew(macOS 包管理器)发布、Zed 编辑器插件。 每一个单独拿出来都是一个周末项目。 更重要的是,他有了余力去思考用户体验。 他在日志里写道: "不只是'我应该解决什么问题',还有'什么错误提示最有用'和'怎么让这个真的简单易用'。" 具体落地的例子:类似 rustc 风格的多错误诊断(带"你是不是想写……"的建议)、快速修复代码操作、syntaqlite.toml 配置文件(让用户不用每次都写命令行参数)。 AI 没有只是让同一个项目变快,它改变了这个项目是什么。 AI 带来了什么代价 像老虎机一样让人上瘾 他用了一个很准确的比喻:发一个 prompt,等待,要么得到很好的东西,要么得到废物。 这个随机性本身就让人上瘾。 他在日志里写道: "我在某些时候感到上瘾,沉迷于它的'老虎机'特性,耗尽时间,从长远来看也耗损了健康。" 他发现自己会在深夜"再试一个 prompt",即使知道大概率没用。 沉没成本效应也在发挥作用:已经在这个任务上花了这么多时间,再试一次吧,换个说法也许就行了。 疲劳会让这个循环变得更糟。 他的日志里写道: "我对 AI 的精确度与我的疲劳程度成正比。当我精力充沛时,我能非常精确,效率很高。但当我疲惫时,我开始说'做 X 事情'而没有太多细节,AI 的输出会变得糟糕很多很多很多。" 在这种状态下,AI 其实比他自己写还慢,但很难从这个循环里跳出来。 失去对代码库的感知 他多次描述了一种感觉:突然意识到自己不知道代码里发生了什么。 不是不懂整体架构,而是那些日常细节,函数在哪里,谁调用谁,那些小决策是怎么积累成现在这个样子的。 他在日志里写道: "有好几次我'失去了'对代码库的感知,出现了令人惊讶的问题,我只能说'AI,请帮我调试',我讨厌那种感觉。" 更深的问题是:失去感知之后,你没法有效地和 AI 沟通。 他的日志里写道: "你失去了'正在发生什么'的心理线索,就无法有意义地、清晰地沟通,每次交流都变得更长更冗长,需要 Agent 做更多工作。" 本来可以说"把 FooClass 改成做 X",现在只能说"把那个做 Bar 的东西改成做 X"。 AI 要先猜 Bar 是什么,再猜它对应哪个类,有时候猜错了,问题变得更复杂。 他说这和工程师们抱怨"不懂代码的管理者提需求"是完全一样的问题,只是现在那个不懂代码的管理者变成了你自己。 他的解决方法是:每次 AI 实现完一段代码,立刻自己读一遍,主动问自己"我会怎么写这个"。 有一点值得注意:这个问题和"几个月前自己写的代码也会忘"有些类似,但 AI 让这个漂移发生得快得多,因为你没有经历最初打出那些代码时建立的肌肉记忆。 推迟了真正重要的决策 因为重构很便宜,他总是可以说"这个问题以后再处理"。 但推迟设计决策有一个隐性代价:代码库一直处于混乱状态,这会持续消耗他理清思路的能力。 他在日志里写道: "AI 让我拖延真正做关键设计决策,因为重构很容易,有好几次我能说'我以后再处理这个'。但与此同时,它腐蚀了我清晰思考的能力,因为代码库一直很混乱。" vibe coding 那个月是最极端的版本。 他理解问题所在,但如果他更早、更果断地做出艰难的设计决策,他本可以更快收敛到正确的架构。 测试带来的虚假安全感 500 多个测试让他感觉很踏实,AI 也让生成更多测试变得很容易。但他在日志里写道: "人类和 AI 都没有足够的创造力来预见你未来可能遇到的那些奇怪情况。如果你没有某种基本的基础,你将永远追着 bug 跑。" vibe coding 阶段的原型有 500 多个测试,照样彻底崩了。 重写时,他换了策略:投入精力做幂等性测试(同样的输入总是产生同样的输出),以及一个更关键的验证机制,写了一个 TCL 驱动程序,把 SQLite 自己的约 1390 个上游测试文件接进来,每条 SQL 语句同时跑真实 SQLite(sqlite3 prepare v2)和 syntaqlite 的解析器做对比,SQLite 接受的语句 syntaqlite 必须接受,SQLite 拒绝的 syntaqlite 必须拒绝。这能抓住手写测试永远发现不了的一类 bug。 AI 没有时间感 这是他观察到的一个更深层的问题。他在日志里写道: "模型没有时间感。它们看到代码库处于某种状态,是的,它们可以通过上下文/文档/记忆获得一些感觉。但它们感受不到时间,方式和人类不同。比如,我能告诉你使用一个 API 是什么感觉,以及它随时间的演变,以及为什么事情是现在这个样子。模型只能通过明确的记录来获得这些,而这样做的成本非常高。" 这和失去一个资深工程师很像。 他们携带的历史和上下文不存在于任何文档里,是真正的隐性知识,指导着周围所有人。 理论上可以把这些都写进文档,但这件事本身极其昂贵。 AI 可以帮起草这些文档,但因为没有办法自动验证它准确捕捉到了真正重要的东西,人还是要手动审查,依然耗时。 还有一个上下文污染问题:你永远不知道关于 API A 的设计笔记什么时候会影响到 API B。 代码库的一致性需要的不只是当前工作的上下文,还需要其他以类似方式设计的东西的上下文。 判断什么是相关的,恰恰需要机构知识本身才能提供的那种判断力。 什么时候 AI 好用,什么时候不好用 他总结出了一个很清晰的规律,沿着两个维度展开。 第一个维度:你对这件事的理解有多深。 当他对一件事已经理解很深时,AI 表现出色。他能立刻判断输出对不对,能快速迭代。 语法规则生成就是最清楚的例子,他在日志里写道:"Agent 团队的成功超出了我最疯狂的想象,能够在一个晚上完成所有工作。" 但前提是他先做了脚手架工程:重构项目结构让 Agent 能在不同文件上并行工作,写了一个差异比较脚本把错误分组成可操作的反馈。 然后还有不可避免的手动检查:"需要逐一检查每一个测试,发现了一堆问题(标志没有正确格式化,缺少字段名等)。" 当他能描述想要什么但还不完全懂时,AI 有用但需要更多投入。 学 Wadler Lindig 算法就是这种情况,他能判断方向对不对,能从解释里学到东西,但不能完全放手。 当他连自己想要什么都不清楚时,AI 从无用到有害。 项目架构设计就是最典型的例子。 他在早期花了好几周跟着 AI 走进死胡同,探索那些看起来有进展但经不起推敲的设计。 他说他有时候会想,那段时间如果完全不用 AI,直接自己想清楚,说不定反而更快。 第二个维度:答案能不能被客观验证。 他在日志里写道: "一个属性对于人类或 AI 来说越容易验证正确性,AI 就越擅长处理那些任务。" 代码实现有客观标准:编译通过,测试通过,输出符合预期。 API 设计没有。"这个 API 用起来舒不舒服"、"这个 API 能不能帮用户解决他们的问题",没有测试能回答这两个问题,所以 AI 在这里表现很差。 他在三月初花了好几天专门做 API 重构,手动修复任何有经验的工程师都会本能避开、但 AI 搞得一团糟的东西。 他用了一个物理学的比喻来总结这一切:在局部小范围内,物理定律看起来简单,符合牛顿力学。 但放大来看,时空会以你从局部图景里预测不到的方式弯曲。 代码也一样,在函数或类的层面,通常有清晰的正确答案,AI 在这里很强。 但架构是所有局部组件相互作用的结果,你没法靠把局部正确的部分拼在一起得到全局正确的系统。 知道自己在这两个维度上处于什么位置,是有效使用 AI 的核心技能。 最后 八年的念头,三个月做出来了。 但这个过程不是那种干净的成功故事。 他浪费了一整个月在 vibe coding 上,掉进了管理一个自己根本不理解的代码库的陷阱,最后付出了全部重写的代价。 他希望看到更多这样的文章:诚实的、有细节的、关于用 AI 构建真实软件的记录。 不是周末玩具,是那种要经历用户、bug 报告、以及你自己不断变化的想法的软件。 他的结论很简单:AI 是实现层面的力量倍增器,但是设计层面的危险替代品。 它能给你一个具体技术问题的正确答案,但它没有历史感,没有品味,不知道一个真实的人用你的 API 会有什么感受。 如果你把软件的"灵魂"外包给它,你只是会更快地撞墙。 原文链接: https://blog.qiaomu.ai/ai assisted coding crates.io 他在日志里提到,他既让 AI 完整生成整个模块,也会在需要的时候亲手写 SIMD 指令并在 Compiler Explorer 里看汇编输出,完全取决于具体问题。 标准代码是绝大多数,手写的是例外。 但这个"标准化"是双刃剑。 对于项目里大多数普通代码,标准化是好事。 但每个项目都有它的核心难点,那些需要做非显而易见决策的地方,AI 的本能是把它"正常化",反而有害。syntaqlite 的提取流水线和解析器架构就是这样,Lalit 最后选择自己设计、自己写。 重构和生成一样快 他在日志里反复强调这一点: "如果你用 AI 在工业规模上生成代码,你必须持续不断地重构。如果不这样做,事情会立刻失控。" "每次大量生成代码之后,值得作为人类停下来问'这个丑吗',如果是,就做点什么。" 有时候 AI 能自己清理。有时候有一个大规模的抽象层 AI 看不到,但他能看到,他给出方向,让 AI 执行。 他的日志里写道:"审计加重构,两者配合效果惊人。" 如果你有品味,犯错的代价会大幅降低,因为你能快速重构。 大幅降低了学习新领域的成本 他举了一个很典型的例子:做格式化器的时候,他需要了解一种叫 Wadler Lindig 的算法。 Wadler Lindig 是一种"漂亮打印"(pretty printing)算法,让你能声明式地描述文档的排版方式,由打印器自动决定在哪里换行,而不是手动计算每行的宽度。 在格式化器设计的对话记录里,Claude 主动提出了"从一开始就用 Wadler Lindig 文档模型做宽度感知格式化",Lalit 能立刻参与权衡讨论,而不是先花好几天才发现这个方法的存在。 他对这类跨领域切换的总结是: "我对 C++/Android 性能非常熟悉,但对 Python/Go/Rust 工具完全不了解。有了 AI,这不是问题:基础是一样的,术语是相似的。我现在能在领域之间切换得非常快。" VS Code 插件也是类似的情况。 他对这套 API 完全陌生,但一小时内就有了一个能跑的扩展。 让 AI 充当代码库的"即时顾问" 他在日志里描述了一种很实用的用法: "你可以控制深入程度:表层概览用于快速复习,详细线性讲解用于深入了解,定向审计用于追查问题。" 当他切换上下文太多、忘了某个模块是怎么工作的,他可以直接问 AI:"给我讲讲这个组件",或者"审计这个 repo 里所有 unsafe 的用法"。 这种按需获取上下文的能力,在频繁切换任务的业余项目里格外有价值。 让项目变得更完整 没有 AI,他大概会发布一个核心功能可用、但边角料全缺的工具。 有了 AI,这些东西都做出来了:VS Code 插件、文档网站、crates.io(Rust 包)、PyPI(Python 包)、npm(JavaScript 包)、Homebrew(macOS 包管理器)发布、Zed 编辑器插件。 crates.io 每一个单独拿出来都是一个周末项目。 更重要的是,他有了余力去思考用户体验。 他在日志里写道: "不只是'我应该解决什么问题',还有'什么错误提示最有用'和'怎么让这个真的简单易用'。" 具体落地的例子:类似 rustc 风格的多错误诊断(带"你是不是想写……"的建议)、快速修复代码操作、syntaqlite.toml 配置文件(让用户不用每次都写命令行参数)。 AI 没有只是让同一个项目变快,它改变了这个项目是什么。 AI 带来了什么代价 像老虎机一样让人上瘾 他用了一个很准确的比喻:发一个 prompt,等待,要么得到很好的东西,要么得到废物。 这个随机性本身就让人上瘾。 他在日志里写道: "我在某些时候感到上瘾,沉迷于它的'老虎机'特性,耗尽时间,从长远来看也耗损了健康。" 他发现自己会在深夜"再试一个 prompt",即使知道大概率没用。 沉没成本效应也在发挥作用:已经在这个任务上花了这么多时间,再试一次吧,换个说法也许就行了。 疲劳会让这个循环变得更糟。 他的日志里写道: "我对 AI 的精确度与我的疲劳程度成正比。当我精力充沛时,我能非常精确,效率很高。但当我疲惫时,我开始说'做 X 事情'而没有太多细节,AI 的输出会变得糟糕很多很多很多。" 在这种状态下,AI 其实比他自己写还慢,但很难从这个循环里跳出来。 失去对代码库的感知 他多次描述了一种感觉:突然意识到自己不知道代码里发生了什么。 不是不懂整体架构,而是那些日常细节,函数在哪里,谁调用谁,那些小决策是怎么积累成现在这个样子的。 他在日志里写道: "有好几次我'失去了'对代码库的感知,出现了令人惊讶的问题,我只能说'AI,请帮我调试',我讨厌那种感觉。" 更深的问题是:失去感知之后,你没法有效地和 AI 沟通。 他的日志里写道: "你失去了'正在发生什么'的心理线索,就无法有意义地、清晰地沟通,每次交流都变得更长更冗长,需要 Agent 做更多工作。" 本来可以说"把 FooClass 改成做 X",现在只能说"把那个做 Bar 的东西改成做 X"。 AI 要先猜 Bar 是什么,再猜它对应哪个类,有时候猜错了,问题变得更复杂。 他说这和工程师们抱怨"不懂代码的管理者提需求"是完全一样的问题,只是现在那个不懂代码的管理者变成了你自己。 他的解决方法是:每次 AI 实现完一段代码,立刻自己读一遍,主动问自己"我会怎么写这个"。 有一点值得注意:这个问题和"几个月前自己写的代码也会忘"有些类似,但 AI 让这个漂移发生得快得多,因为你没有经历最初打出那些代码时建立的肌肉记忆。 推迟了真正重要的决策 因为重构很便宜,他总是可以说"这个问题以后再处理"。 但推迟设计决策有一个隐性代价:代码库一直处于混乱状态,这会持续消耗他理清思路的能力。 他在日志里写道: "AI 让我拖延真正做关键设计决策,因为重构很容易,有好几次我能说'我以后再处理这个'。但与此同时,它腐蚀了我清晰思考的能力,因为代码库一直很混乱。" vibe coding 那个月是最极端的版本。 他理解问题所在,但如果他更早、更果断地做出艰难的设计决策,他本可以更快收敛到正确的架构。 测试带来的虚假安全感 500 多个测试让他感觉很踏实,AI 也让生成更多测试变得很容易。但他在日志里写道: "人类和 AI 都没有足够的创造力来预见你未来可能遇到的那些奇怪情况。如果你没有某种基本的基础,你将永远追着 bug 跑。" vibe coding 阶段的原型有 500 多个测试,照样彻底崩了。 重写时,他换了策略:投入精力做幂等性测试(同样的输入总是产生同样的输出),以及一个更关键的验证机制,写了一个 TCL 驱动程序,把 SQLite 自己的约 1390 个上游测试文件接进来,每条 SQL 语句同时跑真实 SQLite(sqlite3 prepare v2)和 syntaqlite 的解析器做对比,SQLite 接受的语句 syntaqlite 必须接受,SQLite 拒绝的 syntaqlite 必须拒绝。这能抓住手写测试永远发现不了的一类 bug。 AI 没有时间感 这是他观察到的一个更深层的问题。他在日志里写道: "模型没有时间感。它们看到代码库处于某种状态,是的,它们可以通过上下文/文档/记忆获得一些感觉。但它们感受不到时间,方式和人类不同。比如,我能告诉你使用一个 API 是什么感觉,以及它随时间的演变,以及为什么事情是现在这个样子。模型只能通过明确的记录来获得这些,而这样做的成本非常高。" 这和失去一个资深工程师很像。 他们携带的历史和上下文不存在于任何文档里,是真正的隐性知识,指导着周围所有人。 理论上可以把这些都写进文档,但这件事本身极其昂贵。 AI 可以帮起草这些文档,但因为没有办法自动验证它准确捕捉到了真正重要的东西,人还是要手动审查,依然耗时。 还有一个上下文污染问题:你永远不知道关于 API A 的设计笔记什么时候会影响到 API B。 代码库的一致性需要的不只是当前工作的上下文,还需要其他以类似方式设计的东西的上下文。 判断什么是相关的,恰恰需要机构知识本身才能提供的那种判断力。 什么时候 AI 好用,什么时候不好用 他总结出了一个很清晰的规律,沿着两个维度展开。 第一个维度:你对这件事的理解有多深。 当他对一件事已经理解很深时,AI 表现出色。他能立刻判断输出对不对,能快速迭代。 语法规则生成就是最清楚的例子,他在日志里写道:"Agent 团队的成功超出了我最疯狂的想象,能够在一个晚上完成所有工作。" 但前提是他先做了脚手架工程:重构项目结构让 Agent 能在不同文件上并行工作,写了一个差异比较脚本把错误分组成可操作的反馈。 然后还有不可避免的手动检查:"需要逐一检查每一个测试,发现了一堆问题(标志没有正确格式化,缺少字段名等)。" 当他能描述想要什么但还不完全懂时,AI 有用但需要更多投入。 学 Wadler Lindig 算法就是这种情况,他能判断方向对不对,能从解释里学到东西,但不能完全放手。 当他连自己想要什么都不清楚时,AI 从无用到有害。 项目架构设计就是最典型的例子。 他在早期花了好几周跟着 AI 走进死胡同,探索那些看起来有进展但经不起推敲的设计。 他说他有时候会想,那段时间如果完全不用 AI,直接自己想清楚,说不定反而更快。 第二个维度:答案能不能被客观验证。 他在日志里写道: "一个属性对于人类或 AI 来说越容易验证正确性,AI 就越擅长处理那些任务。" 代码实现有客观标准:编译通过,测试通过,输出符合预期。 API 设计没有。"这个 API 用起来舒不舒服"、"这个 API 能不能帮用户解决他们的问题",没有测试能回答这两个问题,所以 AI 在这里表现很差。 他在三月初花了好几天专门做 API 重构,手动修复任何有经验的工程师都会本能避开、但 AI 搞得一团糟的东西。 他用了一个物理学的比喻来总结这一切:在局部小范围内,物理定律看起来简单,符合牛顿力学。 但放大来看,时空会以你从局部图景里预测不到的方式弯曲。 代码也一样,在函数或类的层面,通常有清晰的正确答案,AI 在这里很强。 但架构是所有局部组件相互作用的结果,你没法靠把局部正确的部分拼在一起得到全局正确的系统。 知道自己在这两个维度上处于什么位置,是有效使用 AI 的核心技能。 最后 八年的念头,三个月做出来了。 但这个过程不是那种干净的成功故事。 他浪费了一整个月在 vibe coding 上,掉进了管理一个自己根本不理解的代码库的陷阱,最后付出了全部重写的代价。 他希望看到更多这样的文章:诚实的、有细节的、关于用 AI 构建真实软件的记录。 不是周末玩具,是那种要经历用户、bug 报告、以及你自己不断变化的想法的软件。 他的结论很简单:AI 是实现层面的力量倍增器,但是设计层面的危险替代品。 它能给你一个具体技术问题的正确答案,但它没有历史感,没有品味,不知道一个真实的人用你的 API 会有什么感受。 如果你把软件的"灵魂"外包给它,你只是会更快地撞墙。 原文链接: https://blog.qiaomu.ai/ai assisted coding Lalit Maganti 在 Google 做 Perfetto 项目,维护一个叫 PerfettoSQL 的查询语言。 Perfetto 是 Google 开发的性能分析平台,用来追踪 Android、Chrome 等系统的运行状态。 PerfettoSQL 是在它上面跑的查询语言,基本上就是 SQLite 加了一些扩展,让工程师能用 SQL 的方式去分析性能数据。 这个语言在 Google 内部有超过十万行代码,被各种团队广泛使用。 用的人多了,自然就有需求:格式化工具、代码检查、编辑器插件。 他去找开源社区的 SQLite 工具,结果一个能用的都没有,要么不够准确,要么太慢,要么根本没法扩展到 PerfettoSQL 的方言。 这个遗憾在他脑子里压了整整八年。 今年三月,他终于发布了 syntaqlite。 用了三个月,250 小时,全靠 AI 编程工具才做到。 他写了一篇很长的复盘,没有吹嘘,也没有装清醒。 这是目前关于 AI 辅助编程最诚实的一篇文章之一。 原文: 为什么 SQLite 的开发工具一直是空白 SQLite 是世界上部署最广泛的数据库,没有之一。 每一部智能手机、每一个主流浏览器、无数嵌入式系统里都跑着它。 但围绕它的开发者工具,一直是个令人困惑的空白地带。 devtools(开发者工具)在这里具体指三样东西: • formatter(格式化器):自动把 SQL 代码排版整齐,就像 Prettier 对 JavaScript 做的事 • linter(代码检查器):静态分析代码,找出潜在的错误或不规范写法 • language server / LSP(语言服务器):让编辑器能提供自动补全、跳转定义、错误提示等智能功能,TypeScript 在 VS Code 里的那种体验 Lalit 找过市面上的工具,要么格式化器会"吃掉"注释,要么 linter 不支持 SQLite 特有的语法,要么语言服务器功能残缺。 根本原因在于,这些工具的解析器都是"近似"SQLite 语法,而不是精确还原它。 为什么精确解析 SQLite 这么难? 通常一门语言要做开发工具,第一步是拿到它的正式语法规范,然后按规范写解析器。 但 SQLite 没有正式规范,它也不暴露解析器的 API 给外部使用。 更奇特的是,SQLite 内部实现根本不生成语法树,它直接从 SQL 文本编译成字节码,就像跳过了中间步骤。 这意味着,想做一个真正高质量的 SQLite 解析器,唯一合理的路是:钻进 SQLite 的 C 源码,把相关部分挖出来,重新组装成一个能生成语法树的解析器。 具体来说分三步: 1. 从 SQLite 源码中提取词法分析器(tokenizer,负责把 SQL 文本切成一个个词) 2. 提取语法规则,用 SQLite 自带的 Lemon 解析器生成工具,造出自己的解析器 3. 手动处理超过 400 条语法规则,逐一决定每条规则在语法树里对应什么节点 SQLite 的源码是出了名的难读,用极其紧凑的 C 风格写成。 Lalit 说他光是理解虚拟表 API(virtual table API,一种让 SQLite 能查询外部数据源的机制)就花了好几天,而他已经用这个 API 做了八年 Perfetto 了。 这种项目最可怕的地方在于:它同时满足"太难"和"太无聊"两个条件。 任何一个单独存在都还好,两个加在一起,动力就彻底死了。 还有一个额外的复杂性:他不想只做一个服务 Perfetto 的工具,他想让它对所有 SQLite 用户都有用,同时还要支持 PerfettoSQL 这样的方言扩展,而不需要 fork 整个项目。 这个设计目标让架构难度又上了一个台阶。 三个月的过程,分两个截然不同的阶段 第一阶段:一个月的 vibe coding 实验 2025 年底,他观察到 AI 模型的质量似乎有了一次明显的跃升。 Andrej Karpathy(OpenAI 联合创始人之一)当时说过一句话,他觉得说得很准: "编程 Agent 在十二月之前基本上不能用。模型的质量、长期连贯性和执行力有了显著提升,能够完成大型、长周期的任务,对默认的编程工作流造成了极大冲击。" 圣诞节期间,他给自己出了一道题:能不能用最极端的方式,完全靠 AI 把这个项目做出来? 他订了 Claude Code 的 Max 计划(每月 200 英镑),把自己定位成"半技术经理",几乎把所有设计和实现都委托给 Claude。 整个一月,他就这么干。 功能上最终到了一个还算能用的地方:一个用 Python 脚本从 SQLite 源码提取的 C 解析器,一个建在上面的格式化器,同时支持 SQLite 和 PerfettoSQL,还有一个网页演示环境。 但一月底,他仔细审查了整个代码库,结论很直接:完全是意大利面条代码。 他在项目日志里写道: "我很快就精疲力竭,开始接受太多随机代码。一旦搞乱了,不把它扔掉就很难恢复。" Python 提取流水线的大部分他自己都看不懂,函数散落在各个随机文件里没有清晰结构,有几个文件膨胀到了好几千行。 代码解决了眼前的问题,但永远不可能支撑他更大的愿景,更别说集成进 Perfetto 的工具链了。 唯一的收获:证明了这条路走得通,以及 500 多个可以复用的测试用例。 第二阶段:全部推倒,换语言,换角色 他做了两个决定。 第一,把所有代码扔掉,从零重写。 第二,把大部分代码库切换到 Rust。 原因很实际:C 语言会让格式化器、验证器、语言服务器这些上层组件很难写,而 Rust 可以让提取流水线和运行时用同一种语言,不用再在 C 和 Python 之间来回切换。 (词法分析器和解析器本身仍然保留 C,因为它们直接从 SQLite 源码提取。) 更重要的是,他完全改变了自己在项目里的角色。 他在和 Claude 的对话记录里,开头第一句话是: "我想要的工作方式是:我负责所有决策和方向,我来告诉你做什么。我不想让你规划,不想让你独立行动。清楚了吗?" 他把 AI 从"项目负责人"变成了"超级自动补全",套在一个更严格的流程里: 先做有主见的设计,每次改动都仔细审查,发现问题立刻修,投入精力建脚手架(linting、验证、非平凡的测试)来自动检查 AI 的输出。 核心功能在二月完成,最后的收尾阶段(上游测试验证、编辑器插件、打包、文档)在三月中旬完成,发布了 0.1 版本。 AI 真正做

在 小宇宙note 阅读完整内容