Claude逆向重写Direct2D:18万行Vibe Code实录

一个困扰20年的技术难题
Paint.NET 是 Windows 平台上广受欢迎的免费图像编辑软件,由 Rick Brewster 独立维护开发已超过 20 年。长期以来,这款软件无法在 Linux(通过 WINE 兼容层)上正常运行,最大的拦路虎就是 Direct2D —— 微软的 2D 图形渲染 API。
Direct2D 是微软在 Windows 7 时代引入的硬件加速 2D 图形渲染 API,属于 DirectX 技术家族的一部分。它取代了早期的 GDI/GDI+ 渲染管线,能够充分利用 GPU 进行抗锯齿文本渲染、矢量图形绘制、图像特效处理等操作。Direct2D 的 API 表面积极为庞大,包含数百个接口和数千个方法,还内置了一套完整的图像特效库(如模糊、色彩矩阵、混合模式等),每个特效背后都涉及精密的数学算法。这正是 WINE 项目长期无法完整实现它的根本原因——工作量过于巨大,且需要精确还原每一个渲染行为。
而 WINE(Wine Is Not an Emulator)本身是一个已有 30 多年历史的开源兼容层项目,旨在让 Linux 和 macOS 用户无需 Windows 许可即可运行 Windows 应用程序。它并非虚拟机或模拟器,而是在运行时将 Windows API 调用翻译为 POSIX 系统调用。经过多年持续开发,WINE 已经能够较好地支持 Win32 API、部分 DirectX 3D 渲染(通过 DXVK 等项目转译为 Vulkan)以及许多常见的 Windows 程序。然而,Direct2D 的支持一直是其显著短板——WINE 的 Direct2D 实现仅覆盖了该 API 的一小部分功能,远不足以运行深度依赖它的应用程序。
据 Paint.NET 作者 Rick Brewster 在官方论坛发布的说明,Direct2D 在 WINE 上的支持始终不完善,而且几乎不可能被完整实现。更棘手的是,Paint.NET 的架构深度依赖 Direct2D,无法简单地"关闭"它。这意味着 Linux 用户长期以来只能望而却步。

如今,这个困扰多年的难题迎来了一个出人意料的解决方案:Paint.NET 内置了一套从零开始、净室逆向工程(clean-room reverse-engineered)重写的 Direct2D,专门在 WINE 环境下启用(通过 /wine 参数触发)。这套代码封装在 PaintDotNet.Windows.Direct2D1.Managed.dll 中。
AI独立完成的18万行代码
真正引发技术圈关注的,是这套 Direct2D 重写的"作者"—— Rick Brewster 明确表示,这项工作由 AI 助手 Claude 完成,"没有它,这件事根本不可能发生,也永远不会发生"。
这套代码的规模相当惊人:约 18 万行代码。作为对比,Brewster 提到 Paint.NET 项目其余部分约为 70 万行,而这是他花了 20 多年时间积累的成果。换句话说,Claude 在相对短的时间内生成的代码量,达到了一个成熟软件项目四分之一的体量。
更值得关注的是,这不是简单的样板代码生成。Direct2D 的重写涉及大量图形算法的逆向工程,尤其是其内置特效库(built-in effects library)的实现,需要精确还原各种数学公式。Brewster 对 Claude 在这方面"相当聪明且不知疲倦的逆向工程工作"表示印象深刻。
净室逆向工程为何重要
所谓"净室逆向工程",是一种在法律上更为安全的软件重实现方法——不直接抄袭原始代码,而是通过分析行为和接口,重新独立实现相同功能。这种做法在开源社区(如 WINE 项目本身)中被广泛采用,以规避知识产权风险。
这一策略最早可追溯到 1980 年代 Compaq 对 IBM PC BIOS 的逆向工程——那次具有里程碑意义的工程催生了整个 IBM PC 兼容机产业。其经典流程是:一组人员("分析团队")研究原始软件的外部行为、输入输出关系和公开文档,然后编写功能规格说明;另一组完全独立的人员("实现团队")仅根据这份规格说明编写全新代码,从未接触原始源代码。这种"隔离墙"设计在美国版权法下被广泛认可为合法行为,因为版权保护的是代码的具体表达而非其背后的功能思想。WINE 项目本身就是净室逆向工程的典范产物——整个项目从未使用过任何微软的源代码。
在本案例中,用 AI 来执行这类工作,既需要理解目标 API 的行为规范,又要产出全新的实现代码。Claude 在这里扮演的角色,实际上相当于同时承担了传统净室逆向工程中分析团队和实现团队的双重职责。
Vibe Coding的真实体验:信任与风险并存
Brewster 在描述这次开发过程时使用了一个当下流行的术语——vibe coding(凭感觉编程)。这一概念由 OpenAI 联合创始人 Andrej Karpathy 在 2025 年 2 月首次提出,描述了一种全新的编程方式:开发者不再逐行编写和审查代码,而是用自然语言向 AI 描述意图,接受 AI 生成的代码,通过运行结果来判断是否正确,遇到错误就把错误信息贴给 AI 让它修复。Karpathy 将其描述为"完全向 vibes 投降,拥抱指数级增长,忘记代码的存在"。这个概念迅速在开发者社区引发热议,支持者认为它极大地降低了编程门槛,批评者则担忧它会产生大量难以维护、存在安全隐患的"黑箱代码"。
Brewster 坦率地承认:"这些代码大部分是所谓的'vibe coded'。我的意思是,它并没有经过彻底审查,更多是'相信我兄弟'的风格。我根本不可能审查 18 万行代码,那实在太多太多了。"
这种坦诚揭示了当前 AI 辅助编程的一个核心矛盾:产出速度远超人类审查能力。当 AI 能在短时间内生成数万行代码时,传统的代码审查流程已经难以为继。开发者被迫在"信任 AI"和"逐行验证"之间做出权衡。Brewster 的案例恰好同时印证了 vibe coding 的两面性——它确实解锁了前所未有的生产力,但也引入了前所未有的不确定性。
Claude的表现:天才与缺陷并存
Brewster 对 Claude 表现的描述极具画面感:"有时候,Claude 以 10 个刚刚挣脱束缚的爱因斯坦级天才 10x 程序员的狂热在工作。而其他时候……嗯,就没那么理想了。"
他举了几个需要"照看"(babysit)AI 的具体例子:
- 资源管理错误:Claude 一度没有正确处理引用计数对象的 COM 等价
AddRef()操作。COM(Component Object Model,组件对象模型)是微软在 1993 年推出的二进制接口标准,至今仍是 Windows 系统编程的基石——Direct2D、DirectWrite、Media Foundation 等现代 Windows API 全部基于 COM 构建。COM 对象采用手动引用计数进行生命周期管理:每个对象维护一个内部计数器,调用AddRef()时计数加一,调用Release()时计数减一,当计数归零时对象自动销毁。这种机制看似简单,实则是 Windows 开发中最臭名昭著的错误来源之一——忘记调用Release()会导致内存泄漏,多余的Release()则会导致悬空指针和程序崩溃,而在复杂的对象图中追踪每一次引用传递更是极易出错。这也解释了为什么 Brewster 需要特别纠正 Claude 在这方面的处理。 - 糟糕的设计决策:Brewster 提到他不得不"敲打"(slap)Claude 几次,纠正一些非常糟糕的设计或架构决策。
这些细节说明,尽管 AI 能够完成海量工作,但在系统级编程、底层资源管理和整体架构设计上,仍然需要经验丰富的人类工程师全程把关。AI 在模式匹配和代码生成方面表现出色,但对于需要全局系统思维的底层问题——如对象生命周期管理、线程安全、内存模型等——仍然缺乏可靠的判断力。
对AI辅助编程的三点启示
这个案例为当下火热的 AI 辅助编程提供了一个真实、可信的参照样本,尤其难得的是它来自一位有 20 年经验的资深独立开发者,而非营销宣传。
第一,AI 能够攻克"不可能完成"的任务。 一个困扰 Paint.NET 多年的技术障碍,在 AI 的帮助下得以突破。这类需要大量重复性、模式化工作的逆向工程任务,恰恰是 AI 的强项。Direct2D 拥有数百个接口和方法,逐一实现它们对任何个人开发者来说都是不切实际的工作量,但对于 AI 而言,这种高度结构化的重复性工程正好落在其能力的甜蜜点上。
第二,规模带来审查困境。 18 万行未经充分审查的代码进入生产环境,这本身就是一个值得警惕的信号。Brewster 也明确将此功能标记为"极度实验性"(extremely experimental),这是一种负责任的态度。软件工程界一直有"每千行代码的缺陷密度"这一度量标准,即便是高质量的商业软件,每千行代码也平均存在 1-25 个缺陷。18 万行未经充分审查的代码意味着可能潜藏着数百甚至数千个 bug,其中一些可能涉及安全漏洞。这对传统的质量保证体系提出了严峻挑战。
第三,人类的角色正在转变。 从"编写代码"转向"引导、纠错和把关"。Brewster 扮演的更像是一个技术总监或架构评审者,而非一线编码者。他的经验依然不可或缺——正是这些经验让他能够识别出 COM 引用计数的错误和糟糕的架构决策。这种角色转变也意味着,未来开发者的核心竞争力可能不再是写代码的速度,而是系统设计的眼光、问题诊断的直觉,以及判断 AI 输出质量的能力。
结语:AI负责产出,人类负责判断
Paint.NET 的这次 WINE/Linux 支持尝试,是 AI 编程能力的一次生动展示,也是其局限性的诚实记录。它证明了 AI 可以在专业开发者的引导下完成极具挑战性的系统级工作,同时也提醒我们:在庆祝生产力飞跃的同时,代码质量、可维护性和安全性的隐患不容忽视。
对于开发者社区而言,这或许预示着一种新的开发范式正在成型——AI 负责产出,人类负责判断。而如何在两者之间建立可靠的信任与验证机制,将是未来软件工程需要认真面对的课题。当一个人能够借助 AI 在数周内完成过去需要一个团队数年才能完成的工作,软件开发的经济学、组织形态乃至质量标准都需要被重新定义。
相关推荐

Unsloth v0.1.802更新:自动压缩、局域网远程访问与Dynamic v3.0量化
Unsloth发布v0.1.802-beta版本,带来自动上下文压缩解决长对话爆缓存问题,新增局域网远程访问功能支持跨设备使用,同步发布Dynamic v3.0量化方案提升模型精度超10%,并全面适配NVIDIA、AMD、Apple Silicon、Intel多平台硬件。

AI Agent成本优化实战:一小时省下百万美元的工程智慧
Databricks工程团队仅用一小时消除每年100万美元的AI Agent无效支出。本文深度解析Agent成本失控的根源、可观测性驱动的优化方法,以及模型分级、上下文精简、缓存去重等关键策略,为团队提供AI成本治理的实践指南。

FDA如何在Databricks上构建AI就绪的数据底座
深入解析FDA如何借助Databricks for Government平台,在保障联邦级安全合规的前提下,构建统一的湖仓架构与AI就绪数据底座,破解遗留系统数据孤岛难题,为药品监管和公共卫生AI应用奠定基础。