给儿子做了个乐高生成器,第一版提示词就出了能跑的版本。真正耗掉接下来几天的,是另一件事:让模型给出的搭建方案在真实塑料积木上真的立得住。

打开网易新闻 查看精彩图片

家里那箱乐高是混装的,套装早就拆散,说明书也找不到了。儿子每次问“我能搭什么”,都答不上来。现在他对着积木堆拍一张照片,几分钟后就能拿到几个只用照片里那些积木的搭建方案,配可旋转、可缩放、可打印的 3D 分步说明。

这套东西叫 Mister Blocks。没有用框架,就是几个跑在 Vercel 上的无服务器函数,用普通 Node 写,MongoDB 存会话,Cloudflare R2 存图片和 PDF,3D 视图用 three.js。接口按流程分成三段:识别照片得到零件清单,按清单生成一个模型,再用对话改模型(比如“改成拖车”),改完照样过同一套检查。

识别这一步,模型看照片后返回结构化 JSON。每个零件有编号(B 开头是砖、P 开头是板、W 开头是轮子)、以凸点为单位的尺寸、以板为单位的高度和颜色。数错了可以在对话里纠正,比如“2×4 的有 48 块”,清单会重新对齐,同时不破坏模型已经在用的那些编号。

设计这一步,模型拿到清单后返回一个模型:每个零件放在网格上(x、z 以凸点计,y 以板计,一块砖高 3 板),并标明属于第几步。

问题就出在这。语言模型的第一版答案经常“几乎对”。在乐高里,“几乎对”意味着有块砖悬在半空。

所以每个模型在给人看之前都要过一遍检查器。它是一个普通的 JS 文件,服务器和浏览器加载的是同一份,页面显示的和服务器接受的不会打架。它查的都是会让成品在手里散架的事:

  • 每个零件都得被凸点接住——零件底部的格子要落在下方某物的凸点上,或者直接放在桌面上;斜面只有顶排有凸点,检查器也知道这一点。
  • 没有两个零件占同一块空间。
  • 只能用清单里真有的零件,种类要对,且每块只能用一次。
  • 轮子要能转:轮胎区域内部不能有东西低于底盘,自己轮胎上方的挡泥板除外。

检查器用大白话返回问题,这些文字直接回传给模型。循环最多跑三轮,实际大多数模型一两轮就过。这个循环对质量的帮助,比任何提示词调优都大:模型很擅长修一个被具体点名的问题,却很不擅长提前避开所有可能的问题。

第二个意外出在步骤上,不在模型上。一个模型最终形态完全合法,按给定顺序却可能搭不出来——比如第 3 步放的一块砖,只靠第 5 步才出现的一块板托着,那你在第 3 步就只能干举着它。

于是加了第二道处理,逐步走一遍:每一步的新零件,必须能扣在已经搭好的东西上,或者站在桌面上。不满足就把托着它的那块零件提前到这一步,就像真人搭积木时会先把板盖在它要压住的零件上。把零件往前挪不会破坏更早的步骤,更晚的步骤只会多出支撑,所以这一遍可以反复跑到不再变化为止。

提示词里还有一节规则,是从真实搭建里攒出来的,大多来自儿子那辆卡车。比如能用的底盘长这样:两排轮板并排,用一条两格宽的板条连起来,每组轮子上方各放一块挡泥板并向外错一个凸点,甲板压在挡泥板加中间一块砖上。这条规则出现之前,生成的车很多甲板直接压在轮胎上。

3D 查看器是一个小的 three.js 文件,搭建页、指南和打印视图共用。每块砖都带一点光泽和高亮边,看起来像塑料而不是扁平的盒子。拖动旋转,滚轮缩放,可以一步一步走;点列表里的某一步,那一步的零件亮起,其余淡下去。每份指南都能打成小册子或存成 PDF,打开过的指南离线也能用。

手边没积木堆也能用文字描述。几个例子:带机械臂的波士顿动力 Spot,150 块、13 步;海绵宝宝的海菠萝屋,237 块、18 步;保时捷 Mission S,965 块、73 步,另有一个 69 块的快版本;Mega Dragonite,1315 块、121 步。大型雕塑走另一条路径:先用椭球、肢体和管状体描述 3D 形状,再填进标准砖、铺在底板上,补上明确的支撑直到立住,最后过同一套凸点检查。

成本方面,每个方案要几分钟,API 调用花几美元。每次调用的 token 和费用都记进 MongoDB,另有按访客的每日限额和全站每日预算,忙起来的一天不会变成一张意外账单。

网站免费,拍下你的积木堆就能看它给出什么。这是个非官方粉丝项目,乐高是乐高集团的商标,该集团不赞助也不背书这个站点;Spot、海绵宝宝、保时捷和宝可梦归各自所有者,这些是粉丝作品。