text-to-cad实战:从自然语言到参数化建模的关键链路
先说个结论text-to-cad 绝不是一个能让你躺着等模型成形的“魔法输入框”。作为常年跟图纸、加工厂和三维模型打交道的人我第一次看到这类工具时也兴奋过但实际跑通几个零件场景后发现——文本只是最外面一层壳真正决定成败的是它背后的参数化检索、程序化生成和几何约束处理。这篇内容我按自己踩过的坑来写尽量把原理、选型、实操和避坑串成一条能直接落地的经验链路。1. 把text-to-cad拆开看文本只是壳参数化检索与程序化生成才是核1.1 三种底层原理决定了这个功能能不能用现在市面上号称 text-to-cad 的项目不少但拆开看底层其实只有三条技术路线它们的可靠性差异非常大。第一种是“语义检索 零件库匹配”。系统把语言描述转成检索条件去一个预置的三维模型库或参数化零件库里找最接近的货。比如你说“M6内六角圆柱头螺钉”它能在库里捞出对应的模型。这种方案最稳定因为输出空间是有限的、可控的本质上是个带语义理解的搜索框。但代价是只要超出库的范围它立刻失效。你跟它说“一个带弧形加强筋的异形支架”库里没有它就只能给你拼凑一个四不像出来。第二种是“程序化生成 参数搜索”。系统把 CAD 建模过程预先写成一个个模板函数比如“板类零件”“回转体零件”“钣金折弯件”每个函数有若干参数长、宽、高、孔径、孔距、倒角半径。文本输入进来后模型做两件事先判断属于哪个模板再抽取参数填进去。这种方案比第一种灵活得多也能覆盖不少真实场景但它的天花板在于模板数量。模板之外的设计系统只能强行匹配到最近的模板结果就是模型看着像实际上根本不是你要的东西。第三种是“大语言模型直接生成 CAD 脚本”。这是当前讨论最多、最有想象力的一条路。模型不再查库而是直接写一段 CadQuery、OpenSCAD 或 FreeCAD Python 脚本然后由脚本引擎执行、生成三维实体。这条路线理论上覆盖无限几何实际效果也最不稳定。模型可能生成一段压根没法执行的脚本也可能执行成功但尺寸完全不对更常见的是生成了一个“看起来对、拿去加工必废”的实体。我为什么要先讲这三条原理因为很多人踩坑都是从“不知道自己在用哪条路线”开始的。你用第一种工具去解决第三种问题当然会失败你用第三种工具去处理本来可以模板化的标准件那就属于杀鸡用牛刀还容易翻车。1.2 为什么自然语言做不到“直接挤出”几何体新手往往会有一个误解CAD 软件里“拉伸凸台”就是一个命令那我说“把这块板往上拉伸 10 毫米”模型不应该直接执行吗实际上自然语言和几何内核之间隔了好几层目前没有哪种大模型能真正做到“无缝直出几何实体”。原因很简单CAD 内核本质上只理解一类东西——带拓扑关系的边界表示B-rep或者是参数化特征树。它不理解“上面”“适当”“结实一点”这些自然语言里的模糊概念。语言模型要把文本先翻译成一系列确定性的建模指令选哪个平面、画什么草图、用什么约束、做拉伸还是旋转、布尔运算怎么走。这个过程只要有一个词产生歧义几何结果就天差地别。举个最常见的例子。你说“带法兰的圆管”模型首先得决定法兰在管道端部还是中间是圆盘形法兰还是一圈凸台法兰外径和管道外径什么关系如果提示里没写清楚它只能猜。这一猜两个结果可能完全不是同一个零件但文本和文本之间看起来没什么区别。所以在实操中我必须反复提醒text-to-cad 的本质不是“语言生成几何”而是“语言被翻译成一段确定的程序化建模流程”。你越早把这句话刻在脑子里就越不会对它抱有不切实际的期望也越知道该怎么设计提示词。2. 选型前先回答三个问题不然技术选型全是玄学2.1 输出格式你要的是网格还是实体很多人在跑通“文本到模型”后特别兴奋但冷静下来第一个要问的问题就是我要的是什么样的三维数据如果你只是做展示、渲染、动画或者放进游戏引擎那 STL、GLTF 这种网格格式就够了。网格只有三角面片没有几何拓扑两个面是否属于同一个实体、能不能被车床加工它完全不关心。这类需求下文本生成网格的难度低得多生成结果也更容易“看起来好看”。但如果你要做 CNC 加工、3D 打印、装配干涉检查那就必须要实体格式最典型的是 STEP 文件或者原生 CAD 格式。STEP 里保留的是 B-rep 边界表示面与面之间是连通的拓扑关系后续下料、编程、仿真都能接着用。无数人拿着漂亮的 STL 模型给加工厂结果就是加工编程前必须重新建模因为网格根本没法生成准确的刀路。所以选型第一件事就是想清楚输出 STEP 还是输出 STL这直接决定你要选哪一类工具也决定你对生成质量的要求有多高。2.2 可编辑性给你一个死模型等于没做第二个问题更关键生成结果是“一个模型文件”还是“一段可改参数的脚本”纯文本生成完给你一个 STEP 文件这属于一次性交付。设计过程中孔径从 6 毫米改成 8 毫米怎么办板厚从 8 改成 10 怎么办死模型只能重新生成一遍而重新生成又是一个全新的随机过程结果可能和你上一次改的面目全非。如果输出是 CadQuery 或 OpenSCAD 脚本情况就完全不同了。孔径是一个变量改一行数字重新执行脚本几何体跟着变。这就是程序化建模的最大价值模型不是结果而是生成结果的方法。我现在做类似实践时几乎只认“输出脚本再执行到模型”的链路。哪怕最开始多花点时间也值得。因为后续修改、参数化、版本管理全都建立在“代码即设计”这个基础上。这不是理论洁癖而是被一次性死模型反复坑过后的本能反应。2.3 稳定性模型生成一段“能跑的脚本”远远不够还有个问题最容易忽略。大模型的确能生成一段语法正确、能跑通的 CAD 脚本但这不代表脚本生成的几何是对的。CAD 脚本里几乎每一行都需要精确的数值和坐标。LLM 本质上是概率生成它很可能把“板宽 100”写成“板宽 1000”少一个零“孔间距 50”写成“孔间距 5”生成一个孔壁直接穿透的废件。脚本能执行但结果不能用这类隐藏问题比脚本报错更可怕因为它不报错你不会第一时间发现。所以选型时必须问自己这个系统有没有内置的验证环节比如几何边界检查、尺寸容差检查、特征数量检查。如果没有那你就得自己在外部搭一套校验流程。我后面会专门讲这个这里先记住一句话不能用“能不能跑通”来判断 text-to-cad 的效果要用“跑出来的模型对不对”来判断。3. 主流实现路线的适用边界哪有银弹只有交换3.1 路线 A预置模板 参数填充快但窄这条路线在不少开源项目里都有影子它们挂着 text-to-cad 的牌子实际做的是把用户输入映射到一组预设零件族里。典型的就是板类件、标准件、简单回转体。它的优点是快得惊人基本上文本一输入零秒出结果。因为它根本不做复杂推理就是分类和填参数。产品经理做方案展示的时候这类工具非常出彩。但它在真实设计流程里非常脆弱。我试过让这种工具生成“带椭圆沉台和四个螺纹孔的底板”它给我把椭圆沉台替换成了圆孔螺纹孔全部变成了通孔。原因很简单沉台和螺纹孔不在它的预设参数里系统只能用最接近的模板凑合。最坑的是它表面上看起来还挺像你不仔细查根本发现不了。如果你的业务范围刚好在它的预设集之内比如你就是反复生成板类和回转体零件那它是效率神器。但一旦设计需求超出模板边界我建议直接换路线别在它上面死磕。3.2 路线 B大模型直出脚本灵活但需要围栏用 CadQuery、OpenSCAD、FreeCAD 这类脚本化建模工具是目前最值得投入的方向。它能覆盖的几何范围近乎无限因为任何能用代码表达的模型都能生成而代码表达能力本身没有上限。但“没有上限”的另一面是“没有默认可信度”。模型写出来的代码经常会有这些毛病用了不存在的函数或者参数类型拿错了草图没有完全约束导致几何漂移该倒圆角的地方没倒不该倒的地方乱倒单位假设错误做出的东西放大或缩小了 25.4 倍特征顺序反了先打孔后拉伸孔被实体填满。所以走这条路架构上必须给“自由发挥”加围栏。围栏包括三样一是限定建模工具的 API 子集只让模型使用经过验证的少数函数二是预设单位、坐标约定和常见材料参数三是在代码执行前和几何导出前各做一轮自动断言。我自己的体会是一旦把这三层围栏搭好这条路线的成功率能从“随缘”提高到“可发布”的水平。这个过程没有捷径可走每一条围栏都是用失败堆出来的。3.3 路线 C多模态图片输入和文本转CAD的关系还有个很容易混在一起说的东西图片转 CAD。比如你给模型一张零件照片或一张工程图让它建模。这当然很有用但严格说它和 text-to-cad 不是同一条链路。文本转 CAD 是基于自然语言描述图片转 CAD 涉及视觉理解、位图到矢量草图转换、特征识别复杂度和失败模式都不一样。有些工具把两者合在一个入口输入口既可以写文字也可以传图片但内部处理完全不同。你在评估效果时不要把二者的表现混在一起看否则会得出错误结论。4. 实操复盘从一句“带四个通孔的矩形铝板”到 STEP 文件4.1 环境准备和工具链组合理论说完了来一段真实可复现的实操。我选 CadQuery 作为演示工具因为它比 OpenSCAD 更接近传统 CAD 的建模直觉支持二维草图、拉伸、打孔、倒角、布运算还能直接导出 STEP。最简单的环境是 Python 3.10安装 cadquery 和它的导出依赖。如果你熟悉 CQ-editor那更直观可以一边执行脚本一边看模型。我平时用命令行配合 pytest 做批量验证交互检查放 CQ-editor。这里先给一个最原始的文本描述 “一块长 100、宽 60、厚 8 毫米的矩形铝板在四个角附近各打一个直径 6 毫米的通孔。”如果你直接把这个描述扔给大模型它会很高兴地给你生成一段代码。但问题来了四个角附近到底多远算附近如果孔中心距板边只有 2 毫米那这板加工出来孔边就崩了。这就是典型的“自然语言模糊地带”。4.2 第一轮生成能跑但并不可用来看一段模型可能生成的代码也是我现实中见过非常典型的第一版import cadquery as cq plate ( cq.Workplane(XY) .box(100, 60, 8) .edges(|Y) .fillet(10) ) plate ( plate.faces(Z) .workplane() .rect(80, 40, forConstructionTrue) .vertices() .hole(6) ) cq.exporters.export(plate, plate.step)这段代码能跑也能导出 STEP但它有几个问题。第一它对四边都倒了 10 毫米圆角根本不是“矩形铝板”而是一块四角倒圆的板虽然倒角本身可能也是你需要的东西但提示词里没提模型自作主张加了。第二孔的位置在 80×40 矩形的四个顶点上也就是孔中心距板边分别是 10 毫米和 10 毫米在加工上勉强可以但也非常靠近板边如果孔径再大一点就废了。第三四个孔没有一处提到“均布”而模型实际上做了对称分布这种“多做一点”在有些场景下是好事在另一些场景下就是灾难。这段代码暴露了 text-to-cad 的核心问题模型在“补全你没说但看起来合理的信息”而这恰恰是设计里最不能容忍的“擅自决定”。4.3 第二轮修正把模糊描述变成强制约束于是我改用带约束的提示词同时自己也手动校正脚本把它当成“模型生成 人工约束”的协作过程。下面是更合理的版本import cadquery as cq L, W, T 100.0, 60.0, 8.0 D 6.0 edge_margin 12.0 plate cq.Workplane(XY).box(L, W, T) pts [ (-L/2 edge_margin, -W/2 edge_margin), ( L/2 - edge_margin, -W/2 edge_margin), (-L/2 edge_margin, W/2 - edge_margin), ( L/2 - edge_margin, W/2 - edge_margin), ] plate ( plate.faces(Z) .workplane() .pushPoints(pts) .hole(D) ) cq.exporters.export(plate, plate_with_holes.step)这个版本把边缘距离明确定义成 12 毫米孔的位置由变量控制。后续改板宽、板长、孔径都只需要改上面的变量不需要重写几何逻辑。这就是“程序化建模 参数化”的威力。如果要把这套流程半自动化地交给 LLM我通常会把这一类约束写成断言嵌在生成脚本里让模型在生成时就带着边界意识。比如断言所有孔中心到板边缘距离不小于 10 毫米孔径不小于板厚的 0.8 倍否则直接报错。4.4 导出和验证STEP 文件的不可视化检查导出 STEP 本身只是一行代码难的是确认这个 STEP 是真正的实体而不是错乱拓扑。我常用的验证手段分三层第一层基本信息检查。用 CadQuery 重新读取导出的 STEP确认面数、边数、体积与理论值接近。体积计算公式是 100×60×8 减去四个圆柱孔体积能对上就说明布尔运算没有明显问题。第二层可视化人工确认。把模型丢进 CQ-editor 或者 FreeCAD 里看一遍重点看有没有破面、穿透、薄片。第三层与实际工艺条件对照。拿铝板来说孔边距能不能满足最小边距要求孔间距是否满足螺栓安装空间这个已经不是几何问题而是工艺判断但它必须嵌进验证流程。text-to-cad 到这里才算真正接上了“可用”的下限。5. 工程级落地的五个常见坑代码生成也躲不掉5.1 单位体系毫米、英寸、米的无声切换CAD 领域最经典翻车事故就是单位弄错。大模型从训练数据里学到的东西不统一有些例子用毫米有些用英寸有些用米。结果就是它可能在同一个脚本里一部分尺寸按毫米、一部分按英寸最后模型整体比例完全失调。我在验证脚本时一定会先算整体包围盒再对比输入描述里的关键尺寸。如果长 100 的板最后包围盒变成了 2540那十有八九是英寸和毫米差了 25.4 倍。所有自动化流程里单位校验必须放在最早的一步。5.2 坐标约定Z 轴向上还是 Y 轴向上机床坐标系、CAD 软件坐标系、3D 打印切片坐标系经常不一致。CadQuery 默认用 Z 轴向上的右手系很多 CAM 软件则沿用笛卡尔机床坐标Y 轴向上或 Z 轴向上各有各的产业习惯。这类问题不会让脚本报错但会导致模型在软件里“躺着”或“倒着”。看似小问题放到装配里就是方向全乱。所以提示词里我习惯固定写清楚“使用 CadQuery 默认坐标系Z 轴向上长度沿 X宽度沿 Y厚度沿 Z。”让模型不要在坐标方向上自由发挥。5.3 圆角和倒角的顺序陷阱在 CAD 建模里圆角是一个“后置特征”它会在已有实体边缘上切出圆弧过渡。如果你在打孔之前就给边倒了圆角然后孔位又刚好落在圆角附近后续特征顺序就会产生非常诡异的结果。大模型天生不擅长控制特征顺序它经常把圆角倒角放在建模最前面导致后面所有布尔运算都基于一个已经光滑化的毛坯结果经常是加工上无法实现的圆角链。我自己的守则是把倒角、圆角、表面处理全部放到模型主体和切割特征做完之后再统一执行。这个顺序不写进提示词你后面一定会在模型里发现莫名其妙的弧形缺口。5.4 非流形几何和自相交面这是程序化建模里最隐蔽的坑。模型可以生成出非流形拓扑也就是两个实体只在一条边或一个点上相连这样的模型在物理世界中不存在但在数学描述里可以存在。加工路径计算、切片软件一遇到这种模型就崩或者静默生成错误刀路。我常用的排查方式是检查体积一致性、用网格分析工具跑一次自相交检测。尤其当文本描述里出现“交叉”“贴合”“相切”这类语言时要格外小心。语言模型非常喜欢把两块板“放”在一起而不是“布尔合并”在一起而工程上你需要的是真正的合并实体不是表面碰在一起的两个独立体。5.5 特征命名和参数继承最后是个偏软件工程的问题。大模型生成脚本时经常给特征起无意义的变量名比如 a、b、c、d或者同一模型里同一个参数被硬编码了七八次。后续你哪怕只改一个尺寸也得在脚本里翻半天还容易漏改。这看起来不影响首版生成但影响的是长尾迭代。一个文本转 CAD 工具如果真的要在设计流程里长期用必须约定变量命名规范和参数集中管理。我会在提示词里强制要求所有尺寸参数集中在脚本顶部用带语义的名字比如 plate_length、hole_diameter而不是硬编码散落全文。6. 进阶工作流把 text-to-cad 从玩具变成工程入口6.1 先解析意图再映射参数而不是一步到位很多人用 text-to-cad 的做法是输入一句话期望模型直接吐出一个完整模型。这种“一步到位”的模式看似效率最高实际上最容易坏。更稳的做法是拆成两段先让大模型做意图解析把自然语言拆成“零件类型 关键尺寸 特征列表 加工工艺约束”再拿着这张结构化的参数表去填充或者生成 CAD 脚本。比如一句话“底板 100 长 60 宽 8 厚四角孔孔直径 6孔边距大于 10。”第一段解析后得到零件类型矩形板外部尺寸100×60×8特征4 个通孔直径 6位置约束孔中心距板边不小于 10第二段再把这张表映射到 CadQuery 脚本参数是确定性的模型不需要自己发挥。这样子做即使大模型换了一个版本解析结果有细微差异也不会导致三维几何部分完全重写。意图解析和几何生成解耦以后调试成本直线下降。6.2 给生成的脚本加断言和回归测试脚本化建模最大的优势是可以测试。我会在生成的脚本里嵌一层“验证断言”Exec 执行后立刻检查from cadquery import exporters result plate bbox result.val().BoundingBox() assert abs(bbox.xlen - 100) 1e-6 assert abs(bbox.ylen - 60) 1e-6 assert abs(bbox.zlen - 8) 1e-6 assert len(result.faces(Z).workplane().holes()) 4这种断言本身就是给大模型的“护栏”。如果一次生成的模型不符合要求系统直接报错并让模型根据报错信息迭代修正形成一个小闭环。很多看起来“偶尔灵光”的 text-to-cad 项目本质上只缺这个闭环只要补上成功率立刻上一个台阶。6.3 把文本生成的零件放进装配体单个零件能用之后下一步就是装配。文本转 CAD 不只应该生成单个实体还要能生成与装配环境匹配的相对位置。比如生成一块安装板同时生成四个定位销孔和安装孔坐标系必须和装配基准对齐。这里我推荐把装配约束写进提示词和脚本模板里。比如让模型生成零件时永远把底面放到 Z0 平面中心放到原点安装孔按对称坐标布局。这样后续进装配体时不需要再做额外坐标变换。别小看这一点很多“单零件没问题、装起来全歪”的问题就是把坐标系约定忽略了。6.4 把整个 pipeline 做成数据管线而不是一次性脚本等到你把上述流程跑顺以后我建议用工程化的方式把它封装起来输入一个设计需求描述输出一个可追溯的 CAD 脚本产物。一条比较成熟的 pipeline 大致是用户输入自然语言意图解析映射到参数表触发参数化模板或生成脚本执行中自动断言导出模型文件记录全部参数和输出路径。这样每次生成出来的模型都有据可查修改哪个参数都能追溯到源头。我在实际项目里用过一个比较朴素的实现方式用 FastAPI 包装一个接口输入一段自然语言描述内部调大模型做意图解析再执行 CadQuery 脚本最后返回 STEP 下载链接和几何验证报告。整套链路跑通以后它从一个“玩具”变成真正可以给设计团队用的小工具。7. 给新上手的人几个建议如果你正准备进入 text-to-cad 这个方向我的建议是别急着追模型版本先把基础链路打通。第一步准备一个参数化建模工具CadQuery 或 OpenSCAD 都行。第二步自己手写十个常见零件的程序化建模脚本比如垫片、法兰、安装板、支架、轴承座。第三步再让大模型在这些脚本基础上做文本映射。你会发现有了这些固定模板大模型的成功率会高非常非常多因为它不需要从零生成几何只需要做参数识别和填空。另外一个可能反直觉的经验是提示词写得越“啰嗦”越好。不要只写“一个带孔的法兰”要写“外径 50内径 20厚度 10六个安装孔均布在直径 40 的圆周上全部倒角 1 毫米”。文本转 CAD 不是聊天机器人它不需要你留白让它发挥你需要的是让它严格执行参数。文本在这里的本质是“约束描述”不是“创意描述”。最后分享一个我的习惯无论模型生成的模型看起来多漂亮最终落到加工厂和装配现场之前我都会亲手在 CQ-editor 里过一遍关键尺寸和特征顺序。不是不信任工具而是 CAD 这个领域里“看起来对”和“真正能用”之间的距离往往比想象中大得多。text-to-cad 真正成熟的那一天应该是它能主动告诉你它“做了什么决定”“为什么这样决定”的那一天而不是只顾着把模型甩到你面前的那一天。