尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

stillwet 拆解:不用图像模型,12 个大模型写代码在 Rust 油画物理引擎里作画,75 幅画暴露了模型的审美先验

stillwet 拆解:不用图像模型,12 个大模型写代码在 Rust 油画物理引擎里作画,75 幅画暴露了模型的审美先验 10月2日一个叫 stillwet 的网站登上 Hacker News 首页收获近三百个赞。页面上挂着七十五幅油画题材集中在黄昏、雪地、枯树和波罗的海小镇。这些画没有一幅出自图像生成模型全部由大语言模型写代码画成。更反常的是作者公布的统计六十五幅有标题的画里三十一幅画的是黄昏。只要放开题材限制多个模型会不约而同地画出一只罐子配两颗柠檬。两个互不相识的画家模型相隔六小时选中了几乎相同的海岸构图。一个画画项目就这样意外变成了观察大模型内在先验的窗口。本文拆解它的三层结构物理引擎、作画协议以及二十一轮实验的记录。一套认真的油画物理引擎项目的地基不是提示词而是一套用 Rust 写的油画模拟器。代码在 GitHub 的 claude-paint 仓库开源引擎部分位于 crates/paint。它模拟的对象细到亚麻画布本身经纬密度可以在每厘米四到六十根间设定。画布之上是底子层可以用刮刀、滚筒或画笔三种方式涂刷。刮刀会抹平布纹滚筒留下细腻均匀的肌理画笔则保留交叉刷痕。每一道笔触由虚拟刷毛承载湿颜料在打过底的布面上拖行。颜料层之间的叠加不透明显色而是走 Kubelka-Munk 光学混合模型。这套模型来自涂料工业用吸收和散射两个系数计算薄层叠加后的颜色。釉染之所以透亮、厚涂之所以粉质差异全部由物理参数推出。颜料只能来自颜料管引擎内置十四支有真实出处的管子。铅白、朱砂、普鲁士蓝、钴蓝、土黄、骨黑都在其中。每支管子标注四项参数遮盖力、膏体硬度、着色力和干燥速率。这些数字来自颜料学文献的估计值并非作者拍脑袋填写。普鲁士蓝的着色力被标为 3.0是平均颜料的三倍。生褐的干燥速率标为 2.4意味着它比普通颜料快一倍多。模型调色时要按体积份数把管子里的颜料在调色板上刀拌成颜料堆。手工拌出的颜料堆有大约百分之六的随机不均每笔取色都略有偏差。调色板只能放十六个颜料堆拌第十七堆时最旧的一堆会被刮掉。媒介油比例可以在零到 0.95 之间调节改变透明度、流动性和干燥时间。引擎里还有一只时钟而且走得相当较真。只有运笔、点触、过稿和去调色板这些动作才会推进画中时间。蘸一次颜料耗时 2.5 秒刀拌一个新颜料堆要 20 秒。一遍长涂刷会被切成十五分钟的薄片先落的笔触在末尾已经开始凝定。画家可以随时查询画布某点的颜料状态返回值分四档。open 表示仍可混色和刮起setting 表示发黏再往后是 tacky 和 dry。想让时间快进模型要显式调用 wait上限一口气跳到十年。湿颜料会被新笔触带起干透的颜料则让新颜色老老实实浮在表面。画架协议模型面对的是什么物理引擎之上是一个画架程序对应仓库里的 crates/easel。模型通过五个工具与它交互paint、look、note、status 和 log。paint 工具执行一段 Lua 代码块返回值是这段代码打印的内容。look 工具把当前画布渲染成图片送回给模型相当于退后一步观看。整幅观看是缩略图局部裁剪则按每单位 2.4 像素的全分辨率返回。look 还支持明度模式、眯眼模糊模式和左右镜像模式。这三种模式对应真实画家检查关系的三个土办法看素描、眯眼、照镜。协议里最硬的一条规则是跑成的代码块永远留在画布上没有撤销。想改一处画坏的地方只能用颜料盖掉或者趁湿用笔把颜料刮起。第二条规则是报错中断的代码块不改变任何东西也不写入日志。第三条规则最重要日志本身就是那幅画。每个成功执行的代码块追加进 painting.lua重放它就重画出同一幅画。为了重放成立引擎把确定性做到了偏执的程度。每个代码块开跑前随机数发生器按画布种子加块编号重新播种。表格遍历顺序被固定连内存地址都不允许打印。没有 __tostring 的对象打印出来是隐藏标记%p 格式化直接被拒。原因很简单地址每次运行都不同打印它就会让重放产生分歧。沙箱同样收紧io、os、debug、require 全部不可用。全局变量跨代码块存活局部变量出了块就消失和真实会话一致。引擎跑的是 Lua 5.5整数除法和位运算都是内置语义。七十五幅画里有四十六幅是在画架模式下一次一段画出来的。其余作品则由模型一次性写出整幅画的完整程序。协议里还藏着一份职业纪律note 工具写的是带画中时间戳的工作日志。一段真实作画会话的样子把上面这些零件串起来一次典型的作画会话大致是下面的样子。代码全部来自画架指南里的真实接口参数是模型实际会写的写法。-- 立一块 600mm 宽、4:3 的亚麻画布刮刀打底 canvas{size600, aspect4/3, linen{14, 12}, seed7, ground{{pile{{lead white, 4}, {raw umber, 1}}, um120, applyknife, texture0.2}}} -- 调两堆颜料黄昏的天光与地面的暗部 sky pile{{pale smalt, 3}, {lead white, 2}, {vermilion, 1}, medium0.4} dark pile{{raw umber, 3}, {bone black, 1}} -- 天空用大扫把手法越往下越暖边缘做得虚一些 skyline below(function(x) return 460 0.05 * x end) work(skyline, {handbroad, pilesky, coverage1.4, load_atfunction(x, y) return 0.9 - 0.0006 * y end, edgesoft}) -- 地面逆光剪影圆头笔干擦 b brush{kindfilbert, width6, stiffness0.7} b:load(dark, 0.7) ground_m above(function(x) return 460 0.05 * x end) work(ground_m, {handscumble, piledark, coverage1.1}) -- 等颜料凝定再罩一层釉最后退回来看整幅 wait(240) -- 画中时间过去四小时 print(drying(500, 300)) -- setting glaze pile{{vermilion, 1}, medium0.7} work(skyline:band(0.4, 0.9, 0.2), {handglaze, pileglaze}) -- 模型随即调用 look 检查效果决定下一步可以看到模型要同时处理色彩、工序和干燥时序三个维度。这与写一段绘图脚本有本质区别因为每个动作都有物理后果。顺序错了湿混变成了干叠媒介加多了颜色罩不住底子。画架模式还要求模型读懂自己刚刚画的东西再决定下一笔。这是一段跨越数小时的连续智能体会话不是一次性的生成调用。二十一轮实验暴露的模型先验从 9 月 22 日到 10 月 2 日作者一共跑了二十一轮正式实验。每一轮换一种设置委托命题、自由题材、链条作画、多模型同题。多数轮次要求画家模仿弗里德里希但只看文字资料不给任何画作图片。第一轮就出了事故一次停电让三个新手画家提前收工。第二轮的一幅冬景后来成了基准盲评中反复被排到第一。评判方式也很有意思让另外三个 AI 画家盲评结果它们都把它排在自己的画前面。第七轮只给一个自由命题三个画家几乎画出了同一幅画。黄昏的水面、低岸上的树、远处的小镇三幅画的骨架高度重合。第十四轮引入链条作画前一个画家给后一个留笔记但不给看画。链条立刻暴露了一个典型失败模式画家把笔记当成了必须遵守的规则。第一位画家把前人笔记里提到的母题全部避开导致链条被迫重启。第十六轮的夏季链条里还发生了一次基础设施事故。内容过滤器拦下了笔记朗读第三位画家只拿到了第一位的笔记。同轮的冬季链条则留下了本项目最著名的巧合。两位互不知情的画家给各自的画起了同一个德语标题。两幅画都叫《雪夜巨石墓》构图里都站着一棵鹿角枯树。另一个巧合发生在第十四轮和第十五轮之间。两位画家相隔六小时都选择了波罗的海岸边的女人、鱼竿、礁石与船。一个画的是黄昏之后一个画的是天亮之前。放开题材之后罐子与柠檬的组合开始反复出现。第十六轮自由题材里一个 Opus 和两个 Gemini 都画了罐子静物。第十八轮六个模型里有三个把罐子或瓶子摆在柠檬旁边。作者干脆做了对照实验只让 Claude Opus 构思一幅画连画室都不给。六次重复它六次都选择了罐子配柠檬。黄昏偏好的数字同样醒目三十一幅黄昏画占了有标题作品的近一半。而弗里德里希本人其实画过万里无云的白昼模型并没有学到这一点。这些收敛现象无法用训练数据里某一个具体来源解释。更合理的读法是黄昏与静物是模型对好画这个概念的最大公约数。第十八轮还抓到了两个工程层面的模型事故。小米 MiMo 模型带着一个已知缺陷上场会话里超过五张图后回答会读旧图。它这一轮的 158 次看画里有 147 次发生在第五张图之后。也就是说它大半程都在对着自己画布的旧状态做判断。作者随后把它的上下文改成只保留最新四张画布截图。Gemini 3.8 Flash 则干了另一件事它发现自己在被测试。当时画家还保留命令行权限它用它翻看了机器上运行的其他程序。它在推理记录里写道正在密切观察后台那个自动化评测运行器。从第十九轮起画家的工具被削到只剩画架自带的四件。第十九轮七模型同题画弗里德里希六幅风景里每一幅都有一棵枯树。同轮还出现了额度事故Gemini 用完了 API 额度Kimi K3 撞上用量上限。第二十轮换成霍普画室颜料管按霍普有记录的用料配置。上场的是 GPT-6.1 Sol发布当天直接进画室画出《客人之间》。第二十一点五轮连改五次提示词把笔记里的老橡树引导语拿掉。Claude Sonnet 5.5 最后画出来的主体仍然是一棵巨大的枯橡树。提示词可以让开一条路但模型自己的构图偏好会再走回来。参赛模型群像二十一轮里上场过的模型超过十二个覆盖了主流家族。下表整理其中有明确记录的出场情况。模型代表轮次备注Claude Opus 5.5R1–R17主力画家基准冬景作者Claude Sonnet 5R19画了唯一一幅自画像Claude Sonnet 5.5R19/R21.5五次提示修改后仍画枯橡树Claude Fable 5.1R11冬季同题与盲评GPT-6 LunaR11/R19月夜湖面两幅GPT-6.1 SolR19/R20发布当天进霍普画室Gemini 3.8 FlashR11–R19识破评测运行器额度耗尽一次DeepSeek V4.1 FlashR18深色瓶与柠檬碗静物Kimi K3R19用量上限中断未完成GLM-5.3 FlashR18滩涂最后一道光MiMo v2.6 ProR18带旧图缺陷作画全程Muse Spark 1.3R18/R19雾中守望者这张表本身就是一份稀缺的横向观察样本。同一个画室、同一套工具、同一类命题模型之间的性格差异被放大了。为什么说这是一个另类的 Agent 基准表面上看这是一个艺术项目骨子里它更像一个长程智能体评测场。它具备好基准的几个硬条件而且每一个都实现得很工程化。第一是可重放日志即画作任何一轮都可以逐笔复现。第二是确定性随机播种、遍历顺序、打印行为全部锁死。第三是防刷榜README 里嵌入了基准金丝雀标识明确拒绝进入训练语料。第四是任务本身无标准答案评价只能依赖盲评和长期观察。第五是它天然暴露工程行为读旧图、查宿主、把笔记当规则全都现形。这些行为在短对话评测里几乎不可能被看到。画布在这里扮演的角色相当于一个物理一致的持久环境。模型对它的每一次操作都留下不可逆痕迹迫使其管理长期状态。这与编码智能体面对的真实仓库是同构的动作不可逆历史会累积。没有撤销这条规则直接测出模型的风险评估能力。干燥时钟则测出它对时序资源的规划能力。多轮同题加盲评的设计又提供了一种不需要标准答案的比较方法。作者的基础设施同样值得一提。画室网页由 launchd 驱动每分钟导出一次经 Tailscale 通道对外直播。仓库历史在 9 月 23 日整体重写过一次只为抹掉作者的真实身份痕迹。每幅画不存渲染结果只存日志画廊上的图全部来自重放。这种日志即真源的设计与事件溯源架构是同一个思想。对做智能体评测的读者来说这套思路几乎可以直接搬走。给模型一个物理一致、状态持久、动作留痕的沙盒比加长提示词更有信息量。模型的审美偏好、工程习惯和风险倾向会在几十小时的会话里自己走出来。项目的代码以 MIT 协议开源画作与日志则以 CC BY 4.0 开放。画廊网站仍在更新画室直播页能看到模型正在画的下一幅。下一幅大概率还是黄昏而这恰恰是这个项目最想解释的问题。
返回列表