文章摘要
通过并行使用多个Claude Code会话,作者重写了PostHog的SQL解析器,生成了1.6万行手写解析代码和5千行工具代码,实现了约70倍的速度提升。新解析器在几乎所有实际查询中与原版等效,仅对极少数特殊查询存在差异。
文章总结
好的,这是根据您的要求,对原文进行的中文重述,保留了核心细节,并删减了与主题无关的冗余内容。
标题:我几乎没看代码,就写出了一个快70倍的SQL解析器
在成功利用AI代理自动研究来提升查询性能后,作者尝试了一个更具挑战性的项目:用AI重写PostHog的SQL解析器。他并行运行了多个长时间的Claude Code会话,最终产出了一个约1.6万行“手工”编写的解析器代码、5千行工具代码和若干测试代码,性能提升了约70倍。
新解析器在处理所有实际查询时,效果与旧解析器完全一致,仅在极少数刻意构造的、语法怪异的查询上存在差异。
为什么PostHog需要自己的SQL解析器?
PostHog允许用户直接使用SQL访问数据,但需要将用户的SQL“转译”为底层的ClickHouse SQL。这样做是为了提供独立于物理存储逻辑的数据视图,方便在数据库层进行更改而不影响现有查询,同时还能加入性能优化和访问控制。在转译之前,必须先用解析器将SQL语句转化为抽象语法树(AST)。解析器是处理查询的第一步,直接面对不可信的输入,其产出的AST是后续所有操作(如访问控制、优化)的基础。
此前,PostHog使用的是ANTLR(一个开源解析器生成器)生成的C++解析器。ANTLR功能强大且灵活,但代价是运行时开销大。它通过一个通用的解释器来遍历图结构,而不是执行手写的解析函数,这导致了额外的抽象和间接层,性能不如手写的递归下降解析器。
AI辅助下的重写过程
借助AI,编写和维护一个手写解析器变得可行。作者并行测试了两种方法:
- 性能优先:目标是实现最快的解析器,采用递归下降和Pratt表达式解析循环,仅在必要时加入前瞻和回溯。
- 成功率优先:尽可能模仿ANTLR的行为,但将状态转换用显式代码实现,而非通用的图遍历。
最终,两种方法效果相当。作者的目标是让新解析器在所有实际查询上与旧解析器(作为“预言机”)完全一致,并尽可能接近那些刻意构造的查询。
开发与测试方法
- 测试驱动开发:利用已有的回归测试,以及通过基于属性的测试(PBT) 库Hypothesis自动生成SQL查询,来发现新旧解析器之间的差异。作者还编写了一个工具,能从ANTLR的语法文件自动生成SQL生成器,以产生更有趣的测试用例。
- 提示工程:为了解决AI修复代码时过于“脆弱”的问题(例如,只增加一层前瞻,但随后又需要两层),作者在提示中要求AI在修复前,先将语法文件和相关的C++源代码加载到上下文中。
- 持续测试与修复循环:作者让PBT在后台持续运行,将新的失败测试用例写入文件。AI代理(Claude)在空闲时获取这些用例进行修复。其他测试用例来源包括生产环境的匿名查询日志,以及让AI“深入思考边界情况”。作者还加入了代码覆盖率引导的测试用例生成,以覆盖更多语法结构。
- 最终循环:生成新失败用例 → 精简并加入回归测试 → 分析最佳修复方案(参考语法文件和C++源码) → 执行修复并记录摘要 → 运行回归测试确保通过 → 自动重复。
成果与性能
由于新解析器速度极快,作者可以在生产环境中以“影子模式”运行它,与旧解析器并行处理流量并比较结果。在测试了数百万次解析后,未发现任何差异。新解析器产生的AST和源码位置与旧解析器完全一致。
性能方面,在生产环境中,新解析器平均比旧解析器快454倍(标题中的70倍是基于作者笔记本的基准测试结果,生产环境中解析的SQL更长,且未命中解析缓存)。
总结与展望
作者认为,这次经历让他感到非常强大,能够用几天时间完成过去需要特定知识的人花费数月才能完成的工作。虽然代码并非手写,但这也不是简单的“氛围编码”,其使用的PBT和代码覆盖率引导的测试方法已接近解析器模糊测试的前沿水平。
作者推测,这种基于AI的方法可能会成为新的常态:解析器生成器提供“预言机”,然后由大语言模型“手工”编写一个高性能的解析器,并通过PBT/模糊测试来确保两者行为一致。最终产出的新解析器是一个“手工”编写的、以预测为主的递归下降解析器,核心采用Pratt表达式解析,在特定位置通过有限的前瞻探针和局部回溯来处理复杂情况。它完全由Claude Opus 4.7在2026年5月用Rust编写完成。
评论总结
根据评论内容,总结主要观点如下:
1. 对AI辅助编程方法的认可(正面) - 评论3:承认这是AI的良好应用,由技术娴熟者完成。"It was a good use of AI, done by someone with good technical skills." - 评论6:强调该方法并非"vibe coding",而是模型化的AI软件工程。"The key parts of this is how not vibecoded it is. Feels like a model of how you should do software with AI." - 评论9:认为LLM生成适合此类纯函数问题。"This is the type of problem for which LLM generation is great for." - 评论17:认为这是最令人信服的LLM辅助编程案例。"This must the most compelling look I’ve seen at how software might work with LLMs doing a ton of heavy lifting."
2. 对方法论的质疑与反思(中立/负面) - 评论3:担忧长期依赖AI会阻碍知识进步。"if everybody keeps going in this path, it will end up making everyone not advancing their knowledge at the pace they did before." - 评论16:质疑为何不直接使用编译器,而用随机代码生成加模糊测试。"What's wrong with the source language that it's better to use a sufficiently smart random code generator... than to create a sufficiently smart compiler?" - 评论4:质疑为何不直接使用现有SQL解析器。"why they don't use an existing fast SQL parser."
3. 对网站设计与用户体验的批评(负面) - 评论1:指出网站滚动功能被破坏。"you broke scrolling on your fancy website without noticing it" - 评论2:强烈批评网站设计。"I cannot believe they're sticking to their guns on this website design. It's awful." - 评论13:抱怨LLM集成导致性能问题(M4 Pro芯片卡顿)。"it just writing in the text input slowed down my m4 pro chip to less than 1 fps"
4. 对"70x"性能提升表述的质疑(中立) - 评论8:认为"70x"的表述具有误导性。"'70x' is always misleading."
5. 对"vibe coding"概念的哲学讨论(中立) - 评论18:认为这是"vibe coding"的工程化版本,但质疑严格量化的"vibe"是否还算是"vibe"。"once vibes are rigorously enforced are they 'vibes' anymore?"
6. 对方法可推广性的积极展望(正面) - 评论12:认为该方法可推广到算法证明与实现。"this setup could maybe let you just specify the proof of an algorithm and then let LLMs derive efficient implementations" - 评论14:分享类似成功经验(Python转Go,利用GitHub Actions测试)。"Spotting a loop like that is as satisfying as noticing you can walk your chess opponent into a smothered mate."