让 AI 写 3D 模型,这个开源库最多把代码缩到 1/6
Sand3D 不让模型直接丢给你一团难改的网格,而是用短 Python 程序描述零件、关节和装配关系。它适合把 3D 原型先做成能复查、能继续改的草图。
让 AI 做一个 3D 原型,最容易出现的尴尬不是它做不出来。
而是它给你一张看起来挺像那么回事的渲染图,或者一坨能打开的网格;你下一句说“孔距改成 50 毫米、边角再圆一点、这个门要能转”,事情马上又回到人工找模型、找面、猜坐标。第一张图交差了,第二次修改才刚开始受罪。
这两天冒出来的开源项目 Sand3D,想解决的不是“再生成一个 3D 模型”。它让模型把对象写成短 Python 程序:零件有名字,关系有名字,能动的地方也有名字。项目在 11 月 11 日抓取时已有 1,783 Star,一周增长超过 1,500 Star。
它最值得看的地方,是把 AI 生成的结果从“看起来像成品”,拉回“人和下一轮 Agent 还能接着改的工程草图”。本文没有独立安装或跑性能测试,下面的数字、图和示例都来自项目官方 README;我们只把它翻成一个更实际的问题:什么时候该让 AI 直接出图,什么时候更该让它把 3D 写成代码。
先别急着看效果图,先看模型留下了什么
大多数文生 3D 工具的强项,是把一句描述变成一张能看的东西。做游戏概念、汇报配图、情绪板,它们很有价值。但一旦任务变成一个产品壳体、一个可打印支架、一个要进机器人仿真的装配件,光有网格就不够了。
因为后面会不断出现这种句子:把左边两个孔再拉开一点;门只开到 110 度;抽屉要沿 X 轴走;导出给网页看一份,导出给仿真再来一份。你真正需要保存的不是某一帧三角面,而是“这个东西由哪些部分组成,以及这些部分怎样相互约束”。
Sand3D 的办法很朴素:轮廓、实体、切割、圆角、坐标系、关节、装配,都变成一组 Python 调用。官方给出的洗衣机例子只有 38 行、827 token。柜体、滚筒、门、抽屉、旋钮分别有名字;门铰链、滚筒旋转、抽屉滑轨和旋钮转动也被明确写出来。

图:Sand3D 官方 README 的洗衣机装配示例。图中 38 行和 827 token 为项目方示例,不是本文实测。
这不是把 CAD 术语换一个包装。对模型来说,“门”比一堆顶点友好得多;对人来说,“door_hinge,0—143°”也比重新从面选择里找轴省心。下一轮你要改的,终于有一个能叫出名字的入口。
它为什么要把词表压小
项目方给出了一张 token 对比图:同一个零件,用 Blender Python、CadQuery、FeatureScript、Articraft SDK 描述时,分别需要 Sand3D 的 4.0 倍、2.3 倍、6.0 倍、2.0 倍 token。换成更谨慎的人话:这是一项官方比较,不等于任何任务都能稳定省下同样的 token;但它说明作者在刻意给模型减负。

图:Sand3D 官方 README 的 token 对比。柱子表示其他语言相对 Sand3D 的 token 倍数,比较口径以项目方页面为准。
这件事和“代码越短越优雅”不是一回事。大模型做 3D 的难点,常常不在会不会写 for 循环,而在它得同时记住一长串 API、坐标换算、前后对象之间的引用。如果描述一个小支架已经塞满上下文,模型很容易把第一个孔位忘掉,或者为改一个圆角把原来的结构拆散。
Sand3D 的 README 称整套 API 约 3,600 token,可以放进上下文;它还刻意让零件、边和面通过名字访问,而不是靠手算坐标。对 Agent 来说,这意味着提示里可以少一层“先读十份文档再猜接口”的摩擦;对团队来说,代码审查时也更容易问出一句像样的话:这个 bracket 的孔为什么在这里?
当然,短词表不自动等于正确模型。尺寸、公差、材料、受力、装配干涉,依然需要人来定义和复核。它减少的是表达和迭代的摩擦,不是替你承担工程责任。
先从一个小支架开始,不要一上来造整台机器
官方给的最小例子很适合看清它的工作方式:先拉出一个带圆角的矩形板,在指定网格位置打孔,再给边倒圆,最后导出。

图:Sand3D 官方 README 的 bracket 示例渲染。它展示的是一个可由短程序重新生成的零件。
import sand3d as s3d
def bracket(w=80, d=40, t=6, hole_d=6.6, pitch=50):
plate = s3d.extrude("plate", s3d.rect(w, d, r=4), t)
s3d.hole(plate, hole_d, on=s3d.grid(2, 1, pitch, 0))
s3d.fillet(plate, 1, edges="top")
return plate
s3d.export(bracket(), "bracket.glb")
如果你想把它交给 Coding Agent,别只说“做个 3D 支架”。把那些会改变结构的条件一次交代清楚。下面这段不是官方 prompt,是基于 README 能力整理的任务简报:
用 Sand3D 写一个可导出的墙面安装支架。
需求:底板 80×40×6 mm,四角圆角 4 mm;
两个直径 6.6 mm 的安装孔,孔距 50 mm;
把底板、孔位和圆角分别命名;输出 GLB 与 STL。
先给出部件和参数清单,再写最小可运行的 Python 文件。
不要凭感觉补充承重、材料或公差;缺少这些条件时,把它们列为待确认项。
这里最有用的不是“用哪个模型”,而是把尺寸、可变参数、输出格式和不能瞎猜的条件写出来。AI 生成的 3D 一旦要进入下游,最怕的就是它自作主张把“看起来合理”当成“可以生产”。
哪些地方它很对,哪些地方先别上头
Sand3D 适合的,是结构相对明确、还会反复改的原型:给 Web 演示导出 GLB,给 3D 打印做一个起点,给机器人或仿真先搭一个有部件层级的对象,或者让产品和工程师在同一份参数化草图上对齐。
它不太适合的也很明确:如果你的目标只是一个氛围图,传统文生 3D 往往更快;如果你的目标是受认证约束的正式工程图,还是应该回到团队已经验证过的 CAD、材料与审核流程。Sand3D 最像一块中间踏板——先把模糊描述变成可讨论的结构,再把真正严肃的校核交给该做的人和工具。
官方列出的导出格式很宽:GLB、URDF、USDA、IFC、OBJ、STL 都在内。但格式多不代表信息没有损失。README 也写得很诚实:IFC 导出不带关节;.rvt 只能由 Revit 自己写。你如果最终要交付到一个严格的工业 CAD、建筑 BIM 或制造流程,先把这条导出链路拿真实文件验一遍,别把“能导出”误读成“下游完全接得住”。
还有一个现实边界。这个库的安装入口是:
pip install sand3d
但它依赖 bpy 的版本组合,官方支持 Python 3.11 和 3.13,也特别提示 Python 3.12 与 Intel Mac 有兼容限制。第一次用它,最好的任务不是让 Agent 一口气建一整套复杂装配,而是先跑一个小支架,导出一份 GLB 或 STL,打开检查尺寸和孔位,再决定要不要把它接进你的正式流程。
我会把它看成一层“让 3D 能被 Agent 认真对待的中间语言”。它不替代设计师,也不替代 CAD 工程师;它把模型从一张好看的结果图,变成一份下一轮还能读、还能改、还能追责的程序。
当你的 AI 已经能生成一个 3D 物体时,你更在意它第一眼像不像,还是三天后还能不能把那两个孔改对?
—— 小岛 AI