
1. 从一句话到三维模型text-to-cad 到底在解决什么问题第一次听到 text-to-cad 这个词我的反应是这不就是把“用嘴画图”这件事往前推了一大步吗。传统建模流程里不管是做机械零件、建筑构件还是简单的产品外壳你都得先打开软件然后一根线一根线地画草图、拉伸、倒角、打孔。一个熟练的工程师画一个带孔法兰盘可能只要五分钟但一个不会建模的人哪怕脑子里已经把形状想得很清楚了面对那些密密麻麻的工具栏还是会直接懵掉。text-to-cad 要干的事情就是把这层操作门槛直接抹掉——你用自然语言描述你想要的东西系统帮你生成对应的三维模型文件。这个方向最近热度上来的原因其实很实在。大语言模型对文本的理解能力已经足够强了强到可以把“一个边长 50 毫米、中心有个直径 10 毫米通孔的立方体”这种描述拆解成结构化的参数。而另一边CAD 领域本身有一套非常成熟的参数化建模逻辑像 OpenSCAD、CadQuery 这类基于代码的建模工具天生就适合被程序调用。两边一对接text-to-cad 的雏形就出来了。它解决的核心问题不是“让设计师失业”而是让那些有想法但不具备建模技能的人能够快速把脑子里的东西变成一个可以看、可以改、可以导出的三维文件。适合关注这个方向的人其实比想象中多。做硬件创业的早期需要快速验证外观和结构不可能每个想法都找结构工程师画一遍做教育或者科普的想让学生直观理解几何关系用文字生成模型比手把手教软件快得多还有一类是做自动化脚本的开发者他们需要批量生成一些标准件模型比如不同尺寸的螺丝、垫片、支架用 text-to-cad 的思路可以写个循环直接批量出图。我自己最开始接触这个方向就是因为要做一个模拟项目需要生成几十个不同规格的简单零件模型手动画实在受不了才想着能不能用代码加自然语言的方式来解决。需要提前说清楚的是text-to-cad 目前的能力边界还比较清晰。它擅长的是那些可以用参数和简单几何操作描述清楚的模型比如方块、圆柱、孔、槽、倒角这些。你要是让它生成一个复杂的曲面汽车外壳或者带精细纹理的艺术品那基本不现实。所以这篇文章讨论的范围也集中在参数化、规则化的三维模型生成上这也是目前最实用、最容易落地的场景。2. 整体设计思路为什么是“文本解析 代码建模”这条路线2.1 核心架构的选型逻辑把 text-to-cad 拆开来看它本质上是一条流水线输入是自然语言输出是三维模型文件中间需要经过“理解”和“执行”两个大阶段。理解阶段负责把一句话变成结构化的建模指令执行阶段负责把指令变成实际的几何体。这两个阶段的技术选型直接决定了整个系统好不好用、稳不稳定。我试过几种不同的组合方式最后发现最靠谱的还是“大语言模型解析 代码化建模工具执行”这条路线。为什么不用端到端的深度学习直接生成模型呢因为那样生成的结果不可控你没法保证它生成的孔真的在中心也没法保证尺寸真的按你要求的来。而用代码建模工具比如 OpenSCAD 或者 CadQuery每一个几何操作都是确定性的你给它参数它就给你精确的结果。大语言模型在这里的角色更像一个翻译官把人类模糊的语言翻译成精确的代码而不是直接去画图。这个选型还有一个好处是调试方便。如果生成的模型不对你可以直接看中间生成的代码一眼就能看出是哪个参数理解错了还是哪个操作顺序有问题。端到端模型你只能看到最终结果不对但不知道错在哪改都没法改。对于实际项目来说可调试性比炫技重要得多。2.2 为什么选择代码化建模而不是直接操作 CAD 软件有人可能会想为什么不直接让程序去操作 SolidWorks 或者 AutoCAD 的界面呢技术上不是不行但稳定性太差。图形界面软件本来就不是为程序自动化设计的你模拟鼠标点击、菜单选择稍微换个版本或者换个分辨率就可能失效。而且这类软件通常很重启动一次就要几十秒批量生成的时候效率极低。代码化建模工具就轻量多了。OpenSCAD 本身就是一个命令行工具给它一个脚本文件它几秒钟就能输出一个 STL 或者 DXF 文件。CadQuery 基于 Python可以直接在脚本里做循环、条件判断生成参数化模型特别方便。这些工具的设计初衷就是“用代码描述几何”和 text-to-cad 的需求天然匹配。我实测下来用 OpenSCAD 生成一个中等复杂度的零件从解析文本到输出文件整个流程可以控制在一分钟以内这个速度对于交互式使用来说已经足够了。2.3 文本解析层的设计要点文本解析是整个流程里最不确定的一环因为自然语言本身就有歧义。用户说“一个圆盘”直径是多少厚度是多少中间有没有孔这些信息如果缺失系统就得做合理的默认假设或者主动追问。我的做法是在解析层设计一套“参数槽位”机制把常见的建模要素提前定义好比如形状类型、尺寸参数、位置关系、布尔操作等。大语言模型的任务就是把这些槽位填上填不上的就用默认值。举个例子用户输入“一个直径 80 毫米、厚度 5 毫米的圆盘中心有个直径 20 毫米的孔”。解析层会输出类似这样的结构化数据形状是圆柱外径 80高度 5中心有一个圆柱形孔孔径 20贯穿。这个结构化数据再交给代码生成层转换成 OpenSCAD 的 difference 操作。整个过程里大语言模型不需要知道 OpenSCAD 的语法它只需要把参数提取出来就行。这样做的好处是即使以后换一个建模工具解析层的逻辑不用大改只需要换代码生成层的模板。注意解析层一定要做参数校验。用户可能说“直径 80 毫米的孔”但忘了说圆盘多大这时候如果直接生成孔可能比圆盘还大。我的做法是加一层合理性检查比如孔的外径不能超过圆盘外径的 80%厚度不能为负数等等。这些检查规则看起来简单但能挡掉大部分低级错误。3. 核心细节拆解从一句话到可用的三维模型3.1 自然语言到结构化参数的映射规则这一步是整个系统里最需要打磨的地方。大语言模型虽然聪明但如果不给它明确的指令它输出的格式会非常随意。今天给你返回 JSON明天给你返回一段描述性文字后天可能直接给你一段 Python 代码。所以必须用严格的提示词来约束它的输出格式。我的做法是定义一个固定的 JSON Schema里面包含几个核心字段shape_type形状类型比如 box、cylinder、sphere、dimensions尺寸参数用键值对表示、operations布尔操作列表比如 difference、union、position位置偏移。然后给大语言模型几个示例让它照着格式输出。实测下来只要示例给得够清楚模型输出的稳定性可以做到 95% 以上。这里有个细节值得展开说尺寸参数的单位处理。用户可能说“5 厘米”也可能说“50 毫米”还可能说“大概两寸”。前两种可以直接换算成统一的毫米单位最后一种就需要做模糊匹配。我的处理方式是维护一个常用单位的换算表遇到“寸”这种模糊单位默认按英寸处理同时在返回结果里标注“单位已按英寸换算如有偏差请手动调整”。这样既保证了自动化又给了用户修正的机会。3.2 代码生成层的模板设计结构化参数拿到之后下一步就是生成实际的建模代码。这一步的核心是模板。以 OpenSCAD 为例一个带孔圆盘的模板大概长这样difference() { cylinder(h {height}, d {outer_diameter}, center true); cylinder(h {height} 2, d {hole_diameter}, center true); }模板里的{height}、{outer_diameter}这些占位符会被解析层输出的实际数值替换掉。这样做的好处是代码生成逻辑和具体的几何操作是分离的。你要加一个新的形状类型只需要写一个新的模板不用改解析层的逻辑。模板设计有几个经验性的原则。第一所有尺寸参数都要有默认值防止某个参数缺失导致代码报错。第二布尔操作的顺序要固定比如先做 union 再做 difference避免因为顺序不同导致结果不一致。第三生成的代码里要加注释标明每个参数对应的是用户描述里的哪一部分方便后续排查问题。3.3 参数计算与单位换算的实操细节单位换算是很多人容易忽略但实际很关键的一步。我踩过的坑是用户说“一个 2 英寸的立方体”解析层直接提取了数字 2但忘了单位是英寸结果生成了一个 2 毫米的立方体小了 25 倍多。后来我在解析层加了一个单位识别模块专门处理这类问题。具体的换算逻辑是这样的首先识别用户输入里的单位词常见的包括毫米、厘米、米、英寸、英尺。然后根据单位词确定换算系数比如 1 英寸等于 25.4 毫米1 厘米等于 10 毫米。最后把所有尺寸统一换算成毫米再传给代码生成层。如果用户没有明确说单位默认按毫米处理同时在输出结果里提示“未检测到单位已按毫米处理”。还有一个细节是尺寸的合理性检查。比如用户说“一个直径 10 毫米、高度 500 毫米的圆柱”这个比例明显不正常更像是一根细杆而不是圆柱。我的做法是加一个长径比检查如果高度和直径的比值超过 20就提示用户确认是否输入有误。这个检查不一定会拦住所有错误但至少能让用户意识到可能有问题。3.4 输出格式的选择与转换生成的模型最终要输出成什么格式取决于用户拿来干什么。如果是要 3D 打印STL 是最通用的选择。如果是要做进一步的结构分析可能需要 STEP 或者 IGES 格式。如果只是想在网页上预览那 OBJ 或者 GLTF 更合适。我的做法是默认输出 STL因为它的兼容性最好几乎所有的 3D 打印切片软件和模型查看器都支持。同时提供一个选项让用户可以选择输出其他格式。OpenSCAD 本身支持直接导出 STL 和 DXF如果要输出 STEP就需要借助 FreeCAD 的命令行工具做一次转换。这个转换过程会稍微慢一点大概多花十几秒但对于需要精确几何信息的场景来说是值得的。提示STL 文件本质上是一堆三角面片它不包含参数化信息。也就是说一旦导出成 STL你就没法再回去改尺寸了只能重新生成。所以如果用户可能需要反复调整建议同时保留生成的脚本文件方便后续修改。4. 完整实操流程从零搭建一个可用的生成管道4.1 环境准备与工具安装先说一下我用的工具组合。核心是三个东西一个能调用大语言模型的接口、OpenSCAD 的命令行版本、以及一个用来串联流程的 Python 脚本。大语言模型我用的是通用的文本生成接口不绑定特定厂商这样换起来方便。OpenSCAD 直接从官网下载安装包安装完之后把可执行文件路径加到系统环境变量里这样在命令行里直接敲openscad就能调用。Python 环境需要装几个库requests用来调接口json用来处理结构化数据subprocess用来调用 OpenSCAD 命令行。如果你用的是 CadQuery 路线那就需要额外装 CadQuery 库它依赖比较多建议用 conda 来管理环境省得折腾依赖冲突。安装完成之后先做个简单的验证。在命令行里执行openscad --version如果能正常输出版本号说明环境没问题。然后写一个最简单的 OpenSCAD 脚本比如就一个立方体用命令行跑一下确认能生成 STL 文件。这一步看起来简单但能挡掉很多环境配置的问题。4.2 解析层的实现与调试解析层的代码结构大概是这样先定义一个提示词模板把用户输入和输出格式要求拼在一起发给大语言模型。然后接收返回的 JSON做一轮格式校验和参数补全。最后输出一个标准化的参数字典。提示词的设计很关键。我试过几种不同的写法最后发现最有效的是“角色设定 任务描述 输出格式 示例”这个结构。角色设定让模型知道自己是一个 CAD 参数解析器任务描述告诉它要提取哪些信息输出格式用 JSON Schema 来约束示例给两三个覆盖不同形状类型的案例。这样写下来模型输出的稳定性明显提高。调试的时候我建议先把解析层单独跑通不要急着接代码生成。找十几个不同复杂度的描述从最简单的“一个立方体”到稍微复杂的“一个带四个安装孔的矩形板”逐个测试解析结果。把解析出来的参数和你的预期做对比看看哪里理解错了然后针对性地调整提示词。这个过程可能要反复几轮但磨刀不误砍柴工解析层稳了后面的流程才靠谱。4.3 代码生成与模型输出的完整链路解析层输出参数字典之后代码生成层的工作就相对机械了。根据shape_type找到对应的模板把参数填进去生成 OpenSCAD 脚本。然后调用命令行执行这个脚本输出 STL 文件。这里有个实操细节OpenSCAD 的命令行调用格式是openscad -o output.stl input.scad。-o指定输出文件后面跟输入脚本。如果脚本里有错误OpenSCAD 会在命令行里输出错误信息但不会生成文件。所以调用完之后要检查一下输出文件是否存在不存在就说明生成失败了需要把错误信息抓出来给用户看。我一般会在生成脚本之后先做一个语法检查用openscad -o /dev/null input.scad跑一遍确认没有语法错误再正式生成。这样能提前发现大部分问题避免生成到一半失败。整个链路跑通之后从用户输入到拿到 STL 文件大概需要 30 秒到 1 分钟主要时间花在大语言模型的推理上。4.4 一个完整案例生成带安装孔的矩形板拿一个实际例子走一遍完整流程。用户输入“一块 100 毫米长、60 毫米宽、5 毫米厚的矩形板四个角各有一个直径 6 毫米的安装孔孔中心距离板边 10 毫米。”解析层输出的结构化参数是形状类型为矩形板长 100宽 60厚 5操作列表里有一个“打孔”操作孔的数量是 4孔径 6位置是四个角边距 10。代码生成层拿到这些参数生成对应的 OpenSCAD 脚本。脚本里先用cube生成矩形板然后用四个cylinder做差集运算每个圆柱的位置根据边距计算出来。这里有个计算细节孔的中心坐标。矩形板如果以中心为原点那么四个角的孔中心坐标分别是(50-10, 30-10)、(50-10, -(30-10))、(-(50-10), 30-10)、(-(50-10), -(30-10))。这个计算逻辑要写在代码生成层里不能指望大语言模型去算因为它算数容易出错。我的做法是让解析层只输出“边距 10”这个参数具体的坐标计算由代码生成层的 Python 脚本来完成这样更可靠。生成的脚本跑完之后得到一个 STL 文件。用模型查看器打开确认尺寸和孔位都对。如果不对就回去看生成的脚本检查是哪个参数出了问题。这个排查过程通常很快因为脚本是透明的一眼就能看出问题所在。5. 常见问题与排查技巧实录5.1 解析结果不准确怎么办这是最常见的问题。用户说“一个圆柱”模型可能默认给了一个直径 10、高度 10 的圆柱但用户心里想的是直径 50、高度 100。这种信息缺失导致的偏差靠模型自己猜是猜不准的。我的处理方式是加一轮“确认追问”如果解析结果里有关键参数缺失就生成一个追问让用户补充。比如“检测到您没有指定圆柱的直径和高度请补充这两个参数或者回复‘使用默认值’”。还有一种情况是模型理解错了。用户说“一个带孔的方块”模型可能理解成方块上有一个圆柱形凸起而不是一个孔。这种语义歧义需要通过提示词来约束明确告诉模型“孔”对应的是 difference 操作不是 union。我试过在提示词里加一句“所有‘孔’、‘洞’、‘开口’都对应布尔差集操作”效果很明显。5.2 生成的模型尺寸偏差排查尺寸偏差通常来自三个地方单位换算错误、参数提取错误、代码模板错误。排查的时候按这个顺序来先看解析层输出的参数值对不对如果参数值就错了那就是提取或换算的问题如果参数值对但生成结果不对那就是模板的问题。单位换算错误我遇到过一次用户说“2 米长的杆”解析层提取了数字 2但单位识别模块没认出“米”结果按默认的毫米处理生成了一个 2 毫米的杆。后来我在单位识别模块里加了一个常见单位列表并且做了大小写不敏感匹配这个问题就再没出现过。代码模板错误相对少见但一旦出现就比较隐蔽。比如模板里的圆柱高度忘了加center true导致圆柱的底面在原点而不是中心在原点打孔的位置就会偏。这种问题只能靠仔细检查模板来解决建议每写一个新模板都先用简单参数跑一遍确认几何关系正确。5.3 复杂形状生成失败的应对策略复杂形状失败的原因通常是操作步骤太多或者布尔运算的顺序有问题。比如用户要一个“带倒角的方块上面有一个沉头孔”这涉及倒角、打孔、沉头三个操作顺序错了结果就不对。我的做法是把复杂形状拆成多个简单步骤每一步生成一个中间模型最后再做合并。这样即使某一步失败也能快速定位问题。另一个策略是限制单次生成的复杂度。如果解析层检测到操作步骤超过五个就提示用户“当前描述较为复杂建议拆分成多个简单模型分别生成”。这个限制看起来降低了能力但实际上提高了成功率用户体验反而更好。5.4 常见问题速查表问题现象可能原因排查方法解决方式模型尺寸明显偏小或偏大单位换算错误检查解析层输出的参数值确认单位识别模块是否正常工作孔的位置不对坐标计算错误检查代码生成层的坐标计算逻辑修正坐标计算公式布尔运算结果异常操作顺序错误检查生成的脚本里操作的先后顺序调整模板里的操作顺序生成失败无输出文件脚本语法错误用openscad -o /dev/null做语法检查根据错误信息修正脚本解析结果缺少关键参数用户描述不完整对比输入描述和解析输出加追问机制让用户补充注意每次修改提示词或模板之后一定要用一组固定的测试用例回归一遍。我吃过亏改了一个提示词想让某个案例更准结果另一个原本正常的案例反而错了。回归测试能帮你发现这种“按下葫芦浮起瓢”的问题。6. 进阶优化与扩展方向6.1 提升解析准确率的几个实用技巧提示词工程是提升准确率最直接的手段。我总结下来有几个技巧比较管用。第一在提示词里明确列出所有支持的形状类型和操作类型让模型知道可选范围。第二给每个参数定义明确的类型和单位比如“直径数值单位毫米”。第三加一句“如果信息不足请输出 null 而不是猜测”这样模型不会瞎编参数。另一个技巧是少样本学习。在提示词里放三到五个示例覆盖不同的形状和描述风格。示例不用多但要有代表性。比如一个简单形状、一个带孔的形状、一个带多个操作形状。实测下来加了示例之后解析准确率能从 70% 左右提升到 90% 以上。6.2 批量生成与参数化模板的结合text-to-cad 的一个高价值场景是批量生成。比如你需要一百个不同尺寸的法兰盘手动一个个描述太慢了。这时候可以结合参数化模板先定义一个法兰盘的模板然后用一个 CSV 文件列出所有尺寸组合脚本读取 CSV 自动生成所有模型。这个流程里自然语言描述只需要用一次用来生成初始模板后面的批量生成完全靠参数驱动。我做过一个模拟项目需要生成 50 个不同规格的支架。做法是先写一个支架的 OpenSCAD 模板把长度、宽度、高度、孔径这些做成参数。然后写一个 Python 脚本循环读取参数列表每次替换模板里的占位符调用 OpenSCAD 生成 STL。整个过程不到五分钟50 个模型全部生成完毕。如果手动画一个下午都画不完。6.3 与现有工作流的集成思路生成的模型最终要融入实际工作流才有价值。如果是做 3D 打印生成的 STL 可以直接拖进切片软件。如果是做机械设计可能需要把模型导入到 CAD 软件里做进一步编辑。这时候输出格式的选择就很重要STEP 格式比 STL 更适合后续编辑因为它保留了精确的几何信息。另一个集成思路是把 text-to-cad 做成一个服务通过接口调用。比如在内部工具里加一个按钮点击之后弹出输入框用户输入描述后台调用生成管道几秒钟后返回模型文件。这样非技术同事也能用不需要懂任何建模知识。我试过用简单的 Web 框架搭了一个原型前端就是一个输入框加一个预览区域后端跑生成管道整体体验很流畅。6.4 当前方案的局限与应对必须承认当前这套方案在处理复杂曲面、自由形状、精细纹理方面基本无能为力。它擅长的是规则几何体对于艺术造型类的需求还是得靠传统的多边形建模或者雕刻软件。所以定位要清晰text-to-cad 是效率工具不是万能工具。它解决的是“快速把简单想法变成模型”的问题不是“替代专业建模师”的问题。另一个局限是对模糊描述的处理能力有限。用户说“一个好看的杯子”这个“好看”没法量化系统就不知道该怎么生成。我的做法是引导用户把模糊描述转化成具体参数比如“杯口直径 80 毫米、高度 100 毫米、带手柄”。如果用户坚持用模糊描述那就只能给一个默认的基础形状然后让用户手动调整。我在实际使用中最大的体会是text-to-cad 的价值不在于完全自动化而在于把建模的起点从“空白画布”变成了“一个大概正确的初始模型”。哪怕生成的模型只有 70% 符合预期剩下的 30% 手动修改也比从零开始快得多。这个效率提升对于快速原型验证来说已经足够有价值了。