我用 Rust 构建的 AI PHP 引擎通过了 17% 的 PHP-src 测试,能够渲染 WordPress
几天前,我看到我的终端打印出一个 26 KB 的 WordPress 首页 — <title>Phargo 测试网站</title>,块库 CSS,"你好,世界!" 从 SQLite 数据库中提取,并且在底部有一个干净的 </html>。输出毫无特色,唯一不同的是:提供这个输出的 PHP 引擎包含 0 行后 PHP 的实际源代码。它是一个用 Rust 编写的从零开始的解释器。这是我需要你认真思考的部分:我不知道 Rust。我从来没有写过词法分析器。如果没有在另一个标签中阅读维基百科文章,我无法向您解释 “树遍历评估器” 是什么。如果你在聚会上逼问我 PHP 的垃圾回收器是如何工作的,我会假装接到一个电话。这个引擎叫做 Phargo,我对它的贡献大致上是瞄准。一个 AI 写代码。我把它指向一个目标,像中世纪的国王审阅海图一样,认真点头,但完全不理解,然后输入现代软件开发中最有力的短语:“看起来不错,继续。”实验:激进诚实作为构建系统 现在每个人和他们的室内植物都有一个 AI 构建的项目,每一个都有一个无法反驳的声明:“它有效!”对谁有效?写它的 AI?在第四次尝试时录制的演示?所以整个实验建立在一个想法上,借鉴了从 Bun 团队在真实世界测试套件上运行他们的 JavaScript 运行时的观察:不要让 AI 给自己评分。PHP 带有自己的测试套件 — 约 22,000 个 .phpt 文件是由 PHP 内部团队三十年来编写的。我没有编写这些测试。AI 也没有编写这些测试。这些测试编码了语言的每一个被诅咒的角落,从 DateTime 夏令时数学到 var_dump() 对浮点数的确切输出。那个套件是神谕。记分板运行所有测试,通过每次运行后自动生成通过率。这个数字不能被抚平、协商或调动情绪。bug40261.phpt 要么通过,要么不通过。当前得分:22,037 中的 3,844 — 整个上游 PHP 测试套件的 17.4%。在你对 17% 哈哈大笑之前:现实的上限大约在 40-45% 之间,因为剩下的套件测试的是显然不在范围内的 C 扩展(GD,curl,SOAP,intl,MySQL 驱动程序……)。在实际的竞技场内,爬升非常真实 — 它开始时为零。作为人类的我的循环几乎是尴尬地薄:AI 在整个语料库上运行失败直方图,以找到它可以实际修复的最大失败测试集,它实现了这个东西,它运行了 ~22,000 个测试的记分板(大约 7 分钟的风扇噪音)。如果数字上涨:提交,推送,重复;如果数字下降:我可以说我的另一句话,"嗯,这个有回归,请再看一次。”就这样。这就是工作。我已经达到了最高水平的委托,我也不感到抱歉。神谕无法贿赂。然而,过程却在我面前撒谎。早期,及格率以一种让人感到不对劲的方式停滞不前。整个类别的测试 — 显然简单的测试 — 一直以与预期输出看起来相同的差异失败。我盯着那些差异,就像一个人盯着两张在找不同的拼图中完全相同的照片,发现不了任何东西。差异是不可见的,因为它从字面上看是不可见的:回车符。测试语料库是在 Windows 上使用 CRLF 行结束符检出的,而我们的记分牌逐字逐字比较输出。PHP 自己的测试运行器在比较之前会规范化行结束符。而我们的没有。这意味着过程在行结束符上悄无声息地失败了语料库中的每一个多行测试,并且已经持续了几周。只需一行规范化代码。成百上千的测试瞬间变成绿色。这个教训在项目上铭刻:测量你的测量。你的神谕只有在将你与之连接的管道诚实时才是诚实的。我们现在准确地按照 run-tests.php 的方式进行规范化,而自那以来,每一个可疑的停滞都首先触发了同样的一个问题 — 引擎是否错误,还是记分牌在撒谎?PHP 的测试套件是一个带有自述文件的地雷场。这里没有人告诉你关于运行其他人 22,000 文件测试语料库的事情:其中一些文件是炸弹。不是恶意的 — 而是意外的。在古老内存错误的回归测试中分配荒谬结构的测试,扩展到无穷大的生成器测试,测试只是在 PHP 自己小心围起来的 CI 中运行过。我是通过所有伟大发现被发现的方式发现这一点的:我的开发机器硬重启了。不是“程序崩溃。”不是“终端冻结。”整个计算机变黑并重启,因为一个生成器测试让我们的引擎像一个没有刹车的火箭推进购物车一样吞噬了家里的每一个字节的 RAM。后果使引擎变得偏执,老实说,它的偏执表现得很好:一个上限全局分配器 — 无论测试多么创造性,引擎都物理上无法分配超过 6 GiB;一个步数限制,因此无限生成器....
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡