1. 从一段文字到三维模型text-to-cad 到底在解决什么问题第一次听到 “text-to-cad” 这个说法我脑子里蹦出来的画面是对着电脑敲一句“给我画一个 80×60×40 的法兰盘中心开直径 30 的通孔四角各一个 M8 沉头孔”然后 CAD 软件自己把模型建好、把工程图摆好、把 STEP 文件导出。这个画面放在五年前基本属于科幻但放到现在它已经是一条能跑通的技术链路了。text-to-cad 的核心就是把自然语言描述转换成 CAD 可识别的几何模型最终产出 STEP、GLB、STL 这类通用格式文件。它解决的问题很具体。传统建模流程里一个简单的支架零件从打开软件、选基准面、画草图、标注尺寸、拉伸、打孔、倒角到导出文件熟手也要十几分钟新手可能半小时还在纠结草图有没有完全约束。而 text-to-cad 想干的事是让“描述需求”这一步直接变成“拿到模型”这一步把中间重复性的鼠标操作压缩掉。适合关注它的人其实挺广做机械设计的工程师想快速出概念模型做 3D 打印的玩家想省去建模门槛做产品原型的团队想快速验证结构甚至做具身智能、机器人仿真的开发者也需要批量生成标准件模型来搭场景。这里要先厘清一个容易混淆的点。text-to-cad 不是“AI 帮你画图”这么简单它背后牵扯到三层东西自然语言理解层负责把一句话拆成结构化的几何参数几何内核层负责把这些参数变成真正的 B-rep 实体或网格格式转换层负责把结果导出成 STEP、GLB、STL 等不同用途的文件。这三层任何一层出问题最后拿到的模型就是废的。我见过太多人以为接个大模型 API 就完事了结果生成的模型根本没法在 CAD 里做后续编辑原因就出在几何内核这一层被忽略了。所以这篇内容我打算按实际落地的顺序来讲先讲整体方案怎么设计、为什么这么选再拆核心细节和参数怎么定然后给一套能直接参考的实操流程最后把我踩过的坑和排查经验整理出来。不管你是想自己搭一套还是想评估现成工具能不能用应该都能找到能直接抄的部分。2. 整体方案设计与技术选型思路2.1 为什么不能只靠大模型“硬生成”几何很多人第一反应是既然大模型能写代码那让它直接输出一个 STL 的顶点坐标不就行了我试过这条路结论是走不通。STL 本质是一堆三角面片的集合一个稍微像样的零件动辄几千上万个三角形让语言模型逐个吐出顶点坐标既不稳定也没法保证拓扑正确——面片之间可能有缝隙、法线可能反了、实体可能不封闭。更致命的是这样生成的模型是“死”的你没法改一个孔的直径只能重新生成一遍。正确的思路是让大模型输出“建模指令”而不是“建模结果”。也就是说模型负责把自然语言翻译成一段结构化的、可执行的建模脚本真正干活的还是几何内核。这个思路的好处是几何的正确性由成熟内核保证大模型只负责它擅长的语义理解部分职责边界清晰出错也容易定位。2.2 三种主流技术路线的取舍目前能落地的路线大致有三种我做个对比方便你按自己的场景选。路线核心做法优点缺点适用场景代码驱动型大模型生成 CadQuery/OpenSCAD 脚本内核执行几何精确、可参数化、易版本管理依赖模型写代码能力、复杂形状易翻车机械零件、标准件、参数化模型特征映射型预定义特征库模型输出特征组合与参数稳定、可控、结果可预测只能做库内覆盖的形状批量标准件、企业内固定品类网格生成型直接生成或检索网格再后处理形状自由度高精度差、难编辑、难转 STEP概念展示、3D 打印摆件我的建议很明确只要你的目标是工程可用优先走代码驱动型。CadQuery 基于 OCCT 几何内核产出的就是真正的 B-rep 实体能直接导出 STEP后续在 SolidWorks、中望 CAD 这类软件里还能继续编辑。OpenSCAD 更轻量但它是基于 CSG 的导出 STEP 需要额外转换精度和拓扑质量不如前者。特征映射型适合企业内部做标准化但通用性差不适合作为通用方案。2.3 格式选择STEP、GLB、STL 各管一段这三个格式经常被混着用其实分工很清楚。STEP是工程交换格式存的是精确的边界表示B-rep有完整的曲面和拓扑信息文件里一个圆柱就是一个圆柱不是一个近似它的多面体。它是 CAD 之间交换数据的标准你从 text-to-cad 拿到 STEP丢进任何主流 CAD 软件都能继续改尺寸、加特征。缺点是文件大、解析慢、不适合直接渲染。STL是 3D 打印和快速渲染的老朋友只存三角网格没有单位、没有颜色、没有拓扑关系就是一个“壳”。它的好处是几乎所有切片软件、渲染器都认坏处是精度靠网格密度堆而且转回 STEP 基本等于重新建模——网上那些“STL 转 STP”的工具本质是重新拟合曲面复杂模型转出来一堆碎面根本没法用。GLB是 glTF 的二进制版本主打轻量和 Web 友好带材质、带层级、带动画适合在网页里做预览、做交互展示。它同样基于网格精度不如 STEP但胜在加载快、生态好前端 three.js 直接就能读。所以一个完整的 text-to-cad 流程通常是内核产出 STEP 作为“母版”再按需派生出 STL 和 GLB。STEP 是源头另外两个是下游产物。我见过有人反过来先有 STL 再想转 STEP那条路走起来非常痛苦能避开就避开。2.4 整体架构长什么样把上面的思路串起来一套可用的 text-to-cad 系统大概是这样分层的输入层接收自然语言做意图识别和参数抽取必要时反问补全缺失尺寸。规划层把抽取出的参数组织成建模步骤序列决定用哪些特征、按什么顺序做。生成层把步骤序列渲染成 CadQuery 或 OpenSCAD 脚本。执行层调用几何内核执行脚本拿到实体对象。校验层检查实体是否有效封闭、无自交、体积合理不合格就回退重试。导出层按目标格式导出 STEP、STL、GLB并做必要的网格化处理。这个分层不是纸上谈兵它的实际价值在于每一层都可以单独替换和调试。比如你觉得参数抽取不准就换更强的语言模型觉得几何老出错就在校验层加规则。如果全揉成一坨出了问题你连从哪查都不知道。3. 核心细节解析与实操要点3.1 自然语言到结构化参数提示词怎么设计这一层是整个系统的入口也是最容易被低估的地方。用户说“一个带四个孔的板”这句话里缺了太多信息板多大、多厚、孔多大、孔在哪、孔是通孔还是沉头。指望模型一次猜对不现实所以提示词设计要分两步走。第一步是抽取已知参数让模型输出 JSON字段固定。比如{ part_type: plate, length: 100, width: 60, thickness: 5, holes: [ {type: through, diameter: 6, position: [10, 10]}, {type: through, diameter: 6, position: [90, 10]} ] }第二步是检测缺失字段并追问。如果用户没说厚度系统不应该瞎猜一个值就往下走而应该回一句“板厚是多少”。这个交互设计看起来简单但能极大降低废品率。我的经验是宁可多问一句也不要生成一个尺寸离谱的模型因为用户改一句话的成本远低于他拿到错模型再重新描述一遍的成本。提示词里还要明确单位。工程里毫米和米差一千倍模型默认按毫米走但用户可能说“10 厘米”这时候要在抽取阶段就统一换算成毫米别留到后面。3.2 建模脚本生成CadQuery 为什么是首选CadQuery 的语法接近自然语言模型生成起来不容易跑偏。举个实际例子上面那个带孔板对应的 CadQuery 脚本大概是这样import cadquery as cq result ( cq.Workplane(XY) .box(100, 60, 5) .faces(Z) .workplane() .pushPoints([(10, 10), (90, 10)]) .hole(6) ) cq.exporters.export(result, plate.step)这段代码读起来几乎就是“在 XY 平面上放一个 100×60×5 的盒子在顶面打两个直径 6 的孔”。模型只要理解了参数含义生成这种脚本的准确率相当高。相比之下如果让它直接写 OpenSCAD 的difference()嵌套稍微复杂一点就容易括号对不上。这里有个关键技巧在提示词里给模型几个 few-shot 示例。我一般会放三到五个覆盖常见特征的例子——拉伸、打孔、倒角、阵列、旋转体——模型照着例子的风格写格式稳定性会明显提升。别小看这几个例子它比写一大段“请你输出合法的 CadQuery 代码”这种空泛指令有用得多。3.3 几何校验别跳过这一步脚本执行完拿到实体很多人直接就导出了这是大坑。几何内核偶尔会产出“看起来对但实际有问题”的实体比如面片之间有微小缝隙、法线方向反了、实体自交。这些问题在预览里可能看不出来但一进切片软件或者一进 CAD 做布尔运算就炸。校验至少要查三件事实体有效性调用内核的isValid()之类接口确认是合法实体。体积合理性算一下体积跟预期量级对比。一个 100×60×5 的板体积应该在 30000 立方毫米左右如果算出来是负数或者大得离谱肯定有问题。包围盒尺寸确认长宽高跟输入参数一致防止单位换算或者坐标搞错。校验不通过就回退到生成层重试重试时把失败原因塞回提示词让模型知道上次错在哪。一般重试两三次就能收敛如果一直失败说明这个描述本身有歧义该回去追问用户了。3.4 格式导出的参数细节导出这一步看着简单参数没设对照样出问题。导出 STEP 相对省心CadQuery 的exporters.export直接就能写注意选对单位就行。导出 STL 要关注网格精度也就是线性偏差和角度偏差。偏差设太大圆柱变成多边形设太小文件爆炸。我的经验值是线性偏差取 0.01 到 0.05 毫米角度偏差取 0.1 到 0.5 弧度具体看零件尺寸。一个直径 10 的孔线性偏差 0.05 已经足够圆了。导出 GLB 则要额外处理材质和层级。如果只是做预览给个默认灰色材质就行如果要做产品展示可以在导出前给不同面赋不同颜色。GLB 的网格精度可以比 STL 更宽松因为它主要用来看不用来打印。提示STL 和 GLB 都是从 STEP 派生出来的不要拿 STL 去反推 STEP。一旦你手里只有网格想回到精确实体代价是重新建模。4. 完整实操流程与关键环节实现4.1 环境准备与依赖安装先把地基打好。我用的组合是 Python CadQuery 一个语言模型接口。CadQuery 的安装推荐用 conda因为它的几何内核依赖比较重pip 装有时候会缺库。conda create -n text2cad python3.11 conda activate text2cad conda install -c conda-forge cadquery pip install openai装完先跑个自检确认内核能用import cadquery as cq box cq.Workplane(XY).box(10, 10, 10) print(box.val().Volume())能打印出 1000 就说明环境没问题。这一步别省我见过有人折腾半天以为是代码问题结果是内核没装好。4.2 参数抽取模块的实现参数抽取我封装成一个函数输入是用户那句话输出是结构化字典。核心是提示词我一般这么写EXTRACT_PROMPT 你是一个 CAD 参数抽取器。从用户描述中提取零件参数输出 JSON。 字段包括part_type, length, width, thickness, holes数组每个含 type/diameter/position。 单位统一为毫米。缺失的字段不要猜留空并在 missing 里列出。 用户描述{user_input} 拿到返回后先检查missing字段。如果非空就把缺失项拼成一句追问返回给用户。这个“追问”环节是很多 demo 忽略的但它是产品能不能用的分水岭。4.3 脚本生成与执行参数齐了之后把参数字典和 few-shot 示例一起塞给模型让它输出 CadQuery 代码。这里有个安全考虑不要直接 exec 模型生成的代码。稳妥的做法是限制可用的函数白名单或者用受限的执行环境。虽然模型一般不会写出恶意代码但工程上该有的边界要有。执行拿到实体后立刻做上一节说的三项校验。校验通过进入导出环节。4.4 一次完整的端到端跑通记录我拿一个真实例子走一遍。输入是“做一个 120 长 80 宽 6 厚的底板四角各一个直径 8 的通孔孔中心距边 10 毫米。”参数抽取结果{ part_type: plate, length: 120, width: 80, thickness: 6, holes: [ {type: through, diameter: 8, position: [10, 10]}, {type: through, diameter: 8, position: [110, 10]}, {type: through, diameter: 8, position: [10, 70]}, {type: through, diameter: 8, position: [110, 70]} ] }生成的 CadQuery 脚本import cadquery as cq result ( cq.Workplane(XY) .box(120, 80, 6) .faces(Z) .workplane() .pushPoints([(10, 10), (110, 10), (10, 70), (110, 70)]) .hole(8) ) cq.exporters.export(result, base_plate.step) cq.exporters.export(result, base_plate.stl, tolerance0.02) cq.exporters.export(result, base_plate.glb)执行后校验体积约 120×80×6 减去四个孔的体积算下来在 56000 立方毫米上下包围盒 120×80×6全部对上。导出三个文件STEP 丢进中望 CAD 能正常打开并继续编辑STL 丢进切片软件尺寸正确GLB 在浏览器里预览正常。整个流程从输入到拿到文件大概十几秒。4.5 批量生成时的工程化处理单件跑通不难难的是批量。如果你要生成一整套标准件比如几十个不同规格的法兰、支架就得考虑并发和缓存。我的做法是把参数抽取和脚本生成的结果按输入文本做哈希缓存同样的描述第二次直接命中缓存省掉模型调用。导出环节可以并行但几何内核不是线程安全的得用进程池而不是线程池。另外批量场景下建议把每个零件的参数、脚本、校验结果都落库方便追溯。哪天发现某个模型有问题能直接查到当时用的什么参数、什么脚本而不是两眼一抹黑。5. 常见问题与排查技巧实录5.1 模型生成失败或结果离谱的排查表现象可能原因排查方向解决方式脚本执行报错模型写了不存在的 API看报错行号提示词里补该 API 的正确用法示例实体校验不通过布尔运算产生碎面检查孔位是否超出边界加边界检查孔位必须在板内尺寸差十倍百倍单位没统一检查抽取结果单位抽取阶段强制换算成毫米圆柱变多边形STL 精度太低看导出 tolerance调小线性偏差到 0.02 以下STEP 打不开导出时实体无效先跑 isValid校验通过再导出孔的位置全错坐标系理解偏差确认原点定义提示词里明确原点在左下角这张表是我实际踩坑攒出来的基本覆盖了八成以上的常见故障。遇到问题先对号入座能省很多瞎试的时间。5.2 几个容易忽略的实操心得第一个心得提示词里的示例要覆盖“边界情况”。比如孔位贴着边、厚度特别薄、长宽比特别大这些情况模型容易翻车。你在 few-shot 里放一两个这种例子它就会学着处理。第二个心得校验失败时的重试要把错误信息喂回去。只说“重新生成”没用要说“上次生成的实体无效原因是孔位超出了板的边界请修正”。模型拿到具体反馈第二次成功率会高很多。第三个心得STEP 是母版别丢。很多人图省事只存 STL结果后面要改尺寸只能从头再来。STEP 文件不大存着不亏。第四个心得复杂零件拆成多个简单零件再组合。让模型一次生成一个带几十个特征的复杂件失败率极高。拆成几个简单件分别生成再用布尔运算拼起来稳定得多。这跟人建模的思路其实是一样的先做毛坯再做特征。5.3 关于格式转换的那些坑STL 转 STEP 这件事我再强调一遍能不做就不做。市面上那些转换工具原理是重新拟合曲面简单模型还行复杂模型转出来一堆碎面根本没法编辑。如果你的流程里出现了“先有 STL 再要 STEP”的需求说明上游设计有问题应该从源头就产出 STEP。GLB 的坑主要在材质和坐标系。不同工具导出的 GLBY 轴朝上的和 Z 轴朝上的都有前端加载时如果不统一模型会躺倒。我的做法是导出时统一成 Y 轴朝上前端就不用额外旋转。5.4 性能与成本的平衡语言模型调用是主要成本。一个零件从抽取到生成大概两到三次调用。批量生成时能缓存的就缓存能合并的请求就合并。几何内核执行本身很快瓶颈基本都在模型调用上。如果对成本敏感可以考虑用更小的模型做参数抽取只在脚本生成时用大模型这样能省不少。另外导出 STL 和 GLB 时网格精度不要盲目调高。我见过有人把 tolerance 设到 0.001结果一个简单零件导出几百兆渲染直接卡死。够用就行打印件 0.02 到 0.05 完全够预览件 0.1 都行。6. 这套东西后续还能怎么扩展跑通基础流程之后能扩展的方向其实不少。一个方向是接入尺寸标注和工程图生成模型建完直接出三视图和标注省掉在 CAD 里摆视图的功夫。另一个方向是接入约束求解让用户改一个尺寸相关特征自动联动更新这就有点参数化设计的味道了。再往深了走可以结合装配体生成。现在做的是单个零件如果能描述“把这三个零件装在一起孔对孔”让系统自动算配合关系、生成装配体那价值就上一个大台阶。不过这块难度也大涉及配合约束的自动推断目前还不太成熟。还有一个我觉得挺实用的方向是和 3D 打印切片流程打通。模型生成完直接调切片引擎输出 G-code用户描述完就能打印中间一步都不用点。这个链路技术上已经可行主要看你怎么把各个环节串顺。我个人在实际操作中的体会是text-to-cad 现阶段最靠谱的定位是“快速出概念模型和标准件”别指望它一次生成复杂曲面零件。把它的能力边界摸清楚用在合适的地方效率提升是实打实的。那些需要精细曲面、复杂倒角、自由造型的活还是老老实实手动建模更稳。工具是拿来省力的不是拿来给自己找麻烦的。