用 Claude 重写 SQL 解析器,性能暴涨 70 倍:程序员做的不是写代码,而是搭建验证闭环
一个惊人的技术突破
PostHog 工程师 Robbie Coomber 最近完成了一项令人瞩目的工作:他使用多个并行运行的 Claude Code 会话,成功重写了 PostHog 的 SQL 解析器。最终成果是 16K 行"手工"编写的解析器代码、5K 行工具代码、几千行测试代码,以及约 70 倍的速度提升。
在生产环境中,新解析器的性能表现更为惊人——平均比之前的解析器快了 454 倍。
原文链接:https://posthog.com/blog/sql-parser
为什么 PostHog 需要一个 SQL 解析器?
PostHog 允许用户直接使用 SQL 访问数据。但用户输入的 SQL 会被转译成原始的 ClickHouse SQL,这样做有三个目的:
- 呈现一个与数据库物理布局无关的数据逻辑视图
- 让数据库层的变更不会破坏现有查询
- 添加性能优化和访问控制
大多数 PostHog 工具(产品分析、会话回放、错误跟踪)都使用 SQL 编写查询,它们都经过相同的转译过程。但在转译之前,需要将 SQL 转换成 AST(抽象语法树),这就需要解析器。
关键点:解析器是第一个接触查询的组件,它操作的是不受信任的输入。下游的所有东西(如访问控制和优化)操作的都是它生成的树。
ANTLR 的强大与局限
PostHog 原本使用 ANTLR 生成解析器。ANTLR 是一个开源解析器生成器,只需以声明式的方式在 .g4 文件中提供语法,它就会生成大部分解析器代码。他们使用的是 C++ 版本。
ANTLR 功能强大且灵活,但代价是它对访问到的每个 Token 都要进行更多处理:
- 将语法规则编译成 ATN(本质上是一种带栈的非确定性有限自动机)
- 在运行时让通用的解释器遍历这个图
- 支持任意动态前瞻,当存在多种可能的备选路径时,必须同步模拟每一种解释
尽管优化程度极高,但这种基于图遍历的解释器在速度上永远无法与手工编写的递归下降解析器相媲美。
AI 编码的真相:不是"写代码",而是"搭建验证闭环"
这是本文最核心的洞察。
Robbie Coomber 坦言,这并不像告诉 Claude"用 Rust 编写一个新解析器,不要犯错"那么简单。实际上,Claude 犯了很多错误,让他一直怀疑这样的重写是否可能。
他的目标很明确:确保新解析器在所有实际查询中与现有的 C++ 解析器完全一致,并在人为构造的查询中尽可能地接近。
测试驱动开发的三种武器
1. 基于属性的测试(PBT)
他使用 Hypothesis 库进行基于属性的测试。原理很简单:定义代码的一些属性以及它接受的输入,Hypothesis 会尝试生成不满足该属性的输入。
具体来说,新解析器的属性就是与 oracle(现有的 C++ 解析器)一致。输入是一个 SQL 查询,Hypothesis 将尝试找到一个 SQL 查询,使得新解析器与 oracle 的处理结果不一致。
为了生成有趣的 SQL 语句,他与 Claude 合作编写了一个工具,基于 ANTLR 语法文件自动生成 SQL 生成器。
2. 提示工程
Claude 经常做出"脆弱的修复"——比如通过添加一个 Token 的前瞻来修复某个具体问题,但随后又发现其实需要两个 Token 的前瞻。这可能是因为上下文窗口达到上限而不得不进行压缩,导致 Claude"忘记"了实际的语法或参考解析器是什么样子。
解决方案是:告诉 Claude 在编写任何代码来修复特定的分歧点之前,立即将语法文件和相关的 C++ 源代码加载到上下文中。
3. 影子模式
由于新解析器的运行速度快很多,他可以在生产环境中以"影子模式"运行循环,同时继续使用现有的 C++ 解析器,并报告是否存在任何差异。
与生产环境的查询日志进行对比时,他之前只测试过约 5 万个查询。在影子模式下,他能够快速测试数百万次解析,而且未发现任何偏差。仅过了几个小时,他就将生产流量切换到了影子模式(同时启用了 0.1% 的"反向影子")。
迭代循环
最终的迭代循环是这样的:
- 从 PBT、真实语料库、回归测试和"深入思考边缘情况"生成新的失败测试
- 将这些失败案例的精简版本添加到不断扩充的回归测试列表中
- 深入思考最佳修复方案,尽可能采用通用解决方案,并查阅语法规则和 C++ 源代码以了解参考解析器是如何处理该问题的
- 实施修复,并生成一段简要的总结供人工操作员阅读
- 运行回归套件,确保一切测试均通过
- 自动重新运行循环
新解析器的技术细节
从形式上讲,新解析器是一款"手写"的、以预测性递归下降为主体的解析器:
- 搭载 Pratt 表达式核心
- 配备一个 LL(2) 游标(在特定位置通过有界且不消耗资源的前瞻探测进行扩展)
- 针对少数需要决策的情况,保留了局部有序选择式试探回溯能力
- 完全由 Claude Opus 4.7 生成,使用 Rust 语言编写
- 于 2026 年 5 月开发完成
对行业的启示
AI 编码的新范式
Robbie Coomber 用几天时间就完成了一项专业人员可能需要花费数月才能完成的工作。但他强调,虽然他没有亲手编写任何代码,但这绝不是"凭感觉编写的代码"。
他的 PBT 配置基于语法文件生成输入,并采用覆盖率来引导生成过程,这在解析器模糊测试领域已经相当接近最先进水平。
解析器生成器的未来?
这个问题值得深思。Robbie Coomber 猜测,使用基于 AI 的方法将成为一种新常态:
解析器生成器将提供 oracle,然后大型语言模型(LLM)会利用 PBT/模糊测试并通过"手工"调整来构建性能更高的解析器,使其与 oracle 的处理结果相匹配。
这意味着未来的工作流程可能是:
- 使用 ANTLR 等传统工具生成一个正确但可能不够快的"oracle"解析器
- 用 LLM 生成一个高性能的手写解析器
- 用 PBT/模糊测试确保两者行为一致
- 部署高性能版本
程序员的真正价值
这个案例清晰地表明:AI 时代程序员的核心竞争力不在于写代码的能力,而在于搭建验证闭环的能力。
具体来说,程序员的价值体现在:
- 定义正确的属性:知道什么是对的,比知道怎么写代码更重要
- 设计测试策略:如何系统地发现错误
- 调试与修复:理解错误的根源,指导 AI 做出正确的修复
- 架构判断:在多种方案中选择最合适的一个
结语
PostHog 的这次 SQL 解析器重写项目,不仅是一次技术上的成功,更是对 AI 辅助编程本质的一次深刻探索。它证明了:
- AI 可以大幅提高编码效率,但不是简单地替代程序员
- 验证闭环的重要性不亚于代码本身
- 传统工具(如 ANTLR)与 AI 可以形成互补而非竞争的关系
对于 AI 从业者、开发者和创业者来说,这个案例提供了一个清晰的路线图:不要问 AI 能帮你写什么代码,而要问你能不能为 AI 搭建一个足够强大的验证系统。
本文基于 PostHog 官方博客文章整理,原文链接:https://posthog.com/blog/sql-parser
译者:平川 | 策划:Tina