文本转CAD技术实践:从自然语言到可编辑参数化模型 文本转CADtext-to-cad是我近半年一直在折腾的方向。说句实话两句话就能生成3D模型的AI工具现在遍地都是但绝大多数生成的是“看起来像”的三角网格离真正能加工、能装配的机械零件差着十万八千里。text-to-cad最大的不同是它不输出模型本身而是输出一段参数化建模代码——你在对话框里描述一个零件它给你返回能直接跑的建模脚本跑完就是带完整几何特征的实体模型能改尺寸、能导STEP、能进CAM走加工流程。这篇文章不聊PPT就从技术路线、数据语料、完整实操、评估避坑这些维度把我一路踩过来的经验摊开讲清楚。适合正在做CAD二次开发、想用LLM提效的机械工程师也适合对程序化建模感兴趣的技术玩家。1. 技术主线为什么“生成代码”才是文本转CAD的正确姿势1.1 三条技术路线的取舍早期做文本转3D大家第一反应都是“让AI直接吐出模型几何”。按输出形态可以分三类第一类是生成三角网格Mesh典型做法是从文本特征直接回归顶点坐标和面片索引第二类是生成体素Voxel把三维空间切成立方体格子让模型去填充第三类是生成点云再拟合成曲面。这三条路线的通病是一样的输出是一堆离散几何没有特征树、没有参数约束后续想改一个孔的直径就得重新生成一遍更不用说拿去出工程图。输出形态可编辑性几何精度工业可用度三角网格差只能整体变形低曲面光顺差基本不可用体素差分辨率受限低基本不可用点云曲面拟合差参数难挂接中极少用于实际程序化建模代码好参数全保留高特征精确高所以真正能落地的解法是把问题从“几何生成”转换成“程序合成”让LLM直接写CadQuery、OpenSCAD这类程序化建模脚本。比如描述一个“六边形法兰盘中心孔直径8mm六个螺栓孔直径4mm法兰外径40mm”模型输出的是一段几十行的Python代码里面有变量定义、有特征调用、有布尔运算。执行这段代码得到的CAD实体自带特征树想改外径就改变量想加孔就加一行feature。这条路线的本质是“让模型写施工图而不是让模型当泥瓦匠”。1.2 代码生成路线的四大优势第一是可编辑性。设计工作从来不是一次到位的甲方说改就改是常态。生成网格模型改一个圆角半径可能要重新训练或者手动拖拽顶点生成代码则只需要改一个数字重新执行脚本即可。第二是可验证性。代码可以被静态检查、被沙箱执行、被几何校验三个环节每个都能自动化把关。而网格模型只能靠人肉眼去看基本做不到自动化质量门禁。第三是参数化继承。机械设计讲究的是特征复用一个带孔阵列的标准底板改改尺寸就能适应新场景程序化代码天然就是参数化模型。第四是和现有工具链无缝衔接。CAD软件、CAM软件、PLM系统都认STEP/IGES这类标准格式代码生成后一导就进去不需要中间转换的折腾。1.3 为什么LLM能写CAD代码这里要解释一下底层原理很多人以为这是个“奇迹”其实是个工程问题。LLM本质上是一个极度擅长模式复用的序列预测器它见过海量编程代码学到了变量命名、函数调用、结构控制这些语言规律。程序化建模脚本本身就是结构化极强的代码语法固定、API清晰、逻辑线性。当你把任务限定到“用CadQuery画一个带孔的方板”这个范围时模型不需要理解真正的物理空间它只需要学会在正确的语法位置填入正确的参数即可。可以把这理解为“给一个通用翻译官装上机械设计辞典”的过程。语言模型像翻译官知道怎么组织句子CadQuery的文档和示例代码就是辞典教会它“切孔”“圆角”“拉伸”这些设计意图对应的代码模式。两者一结合文本就变成了可执行的几何约束。有一个关键点需要说透LLM对“精确数字”的感知能力其实很弱。tokenizer会把数字拆成不规则的token63这个数可能被切分成“6”和“3”模型很难学到“63mm”意味着六十多毫米的连续长度语义。所以纯靠生成代码去卡尺寸往往是八九不离十但精确不到可加工级别。这就需要引入后续的“执行-校验-修正”闭环。这个话题后面实操部分会专门展开。2. 数据与语料文本到CAD模型最容易被低估的环节2.1 程序化CAD模型从哪里来很多做这个方向的团队前期最大的瓶颈不是模型选型而是数据。要让LLM学会从文本映射到建模代码前提是得有大量“文本-代码”配对样本。工业里现成的配对数据几乎没有但程序化CAD模型库是有的某开源CAD数据集合里就包含几百万个机械实体模型而且每个模型的构建脚本刚好是参数化代码。这个“刚好”很关键既给了你代码样本又给了你几何结果两样都是训练要用的。但原始数据不能直接用我踩过的坑是从数据清洗开始的。我当时的做法分四步走。第一步是过滤无效脚本跑一遍完整执行执行失败的直接扔掉。这一步能去掉大概三分之一的脏数据。第二步是剔除形状异常的模型比如编译通过但产出体积极度离谱的——box参数里出现负数、拉伸高度为零之类的。第三步是做语义筛选用规则把建模逻辑特别简单的样本剔除例如只有一条box命令、没有任何特征操作的模型。第四步是去重很多模型库里的零件只是尺寸不同、逻辑相似全量训练会让模型过拟合到少数几个结构上去重后数据多样性反而更好。最终留下来的有效数据大概只有原始库的两到三成但质量高一个数量级。2.2 文本描述怎么造有了程序化模型和对应代码下一个问题是文本描述从哪来。自己写几千条标注不现实我的做法是“反向生成模型增强”两条腿走路。反向生成的核心思路很简单模型不擅长文本生成CAD代码但很擅长给一段代码写自然语言注释。你把代码脚本丢给LLM让它用自然语言描述这个零件的外观特征、关键尺寸、功能猜测就得到了一条初始文本。这一步可以用大模型批量跑成本低速度快。但反向生成有个明显问题描述质量飘忽有时候像说明书有时候像废话。所以接下来要做增强。我把初始描述喂给一个更强的大模型让它把描述重写成三种风格一是参数化风格明确写出“底板长60宽40厚3四个圆角半径2”二是功能化风格写成“用于连接两个管路的法兰底座”三是要素化风格写成“具有四个均布孔的矩形板孔间距30mm”。三种风格混在一起训练模型在推理时对不同措辞的鲁棒性会提高很多。最后还要做一次质检抽样每批生成数据里抽50条人工过一遍重点看尺寸描述是否与真实几何一致、有没有“左”和“右”这种方向性错误。不抽样检查的话LLM自己编出来的错误描述会被当成标准答案模型越训越歪。2.3 微调与数据混合技巧数据准备好后微调这一步我推荐用指令微调LoRA低秩适配的方案。所谓LoRA就是把原始大模型的参数全部冻结只在旁边加一小撮可训练的低秩参数矩阵。好处是显存占用低、训练快、不容易灾难性遗忘。我更愿意用“给通用翻译官装行业词典”这个类比来解释翻译官本身的语法能力不动只训练机械术语这块的适应层。用下来的体感是只用一个中等规模的LoRA适配器生成的代码质量就能超过直接调通用大模型加长篇提示词的效果。数据混合比例也要留意。纯CAD代码数据会让模型变成一个“只会写建模脚本的专才”但对用户各种口吻的泛化能力差。我的经验是训练语料里70%是CAD配对数据25%是通用代码任务数据再留5%的对话数据保持模型的自然语言交互能力。温度参数在训练时设低一点推理时反而可以适度提高到0.7左右增加生成多样性便于同一个描述产出多个候选供筛选。3. 实操全流程从一段自然语言到可编辑的STEP文件3.1 环境与工具链先把我一直在用的工具链列出来都是开箱即用的东西。CadQuery是程序化建模库Python API可以直接生成STEP格式是做这条路线的主力。OpenSCAD可以作为备选方案它对建模过程的表达更接近CSG但特征化程度不如CadQuery。沙箱执行用容器隔离加资源限制这一步不能省因为LLM生成的代码不可信指不定给你来个死循环或者制造一个巨大实体把磁盘塞满。推理服务用vLLM部署开源模型吞吐量比原生推理高几倍批量生成时感受明显。环境安装不算复杂但有几个版本坑值得提醒。CadQuery建议装带条件依赖的完整版因为部分高级特征需要依赖OCC内核库OpenSCAD如果用命令行模式注意环境变量要指向自带的可执行文件。容器沙箱我用了轻量方案CPU限制1核、内存限制1GB、超时5秒正常建模脚本几毫秒就能跑完所以5秒超时已经非常宽松了。3.2 端到端推理流程与校验循环text-to-cad的推理不能是“生成一次就完事”必须做成“生成-执行-校验-修正”的闭环。我的完整流程是这样的用户输入自然语言描述系统先把它组装进一个固定模板模板里明确要求LLM用CadQuery语法、必须给出参数化变量、不得省略特征列表。生成的代码进沙箱执行执行输出与报错信息一起返回。如果没有报错继续做几何校验比如实体体积是否大于零、包围盒尺寸是否符合描述。校验不通过就把错误信息反馈给模型让它重新生成。这个循环最多跑三到四次超过就放弃并返回失败原因。用伪代码把核心逻辑写出来方便你照着搭def generate_cad(prompt, retries3): code llm.generate(CAD_PROMPT_TEMPLATE.format(prompt)) for attempt in range(retries): report sandbox.run(code, timeout5) if report.success and geometry_check(report.bbox, prompt): return code, report code llm.generate( FIX_PROMPT_TEMPLATE.format( original_promptprompt, last_codecode, error_msgreport.error ) ) return None, report这个循环的价值在于把“模型犯错”转化为“可管理的重试成本”。LLM生成代码的首次成功率实测大概在60%到70%但经过一次修正后能到85%以上两次修正后基本稳定在90%以上。也就是说真正卡住系统的不是模型能力而是你愿不愿意多写这一层校验逻辑。3.3 真实案例拆解带四个圆角孔的矩形底板用一个实际例子把整个流程串起来。假设用户输入“设计一个矩形底板长60mm宽40mm厚3mm四角有R2圆角四个安装孔直径6mm孔中心距边缘5mm。”模型生成的CadQuery代码大致长这样import cadquery as cq L, W, H 60.0, 40.0, 3.0 corner_r 2.0 hole_d 6.0 margin 5.0 half_l L / 2 - margin half_w W / 2 - margin plate ( cq.Workplane(XY) .rect(L, W) .vertices() .fillet(corner_r) .extrude(H) ) plate ( plate.faces(Z) .workplane() .pushPoints([ (half_l, half_w), (half_l, -half_w), (-half_l, half_w), (-half_l, -half_w), ]) .hole(hole_d) ) cq.exporters.export(plate, plate.step)这段代码执行后得到的是圆心位于四角圆角范围内的四个孔孔中心到边缘的距离是5mm圆角半径2mm整体形状正确。但如果我没有校验循环模型第一次生成时很可能会把pushPoints里的坐标写成(L - margin, W - margin)这种绝对坐标那样所有孔都会挤到右上角一个象限里去。这种错误静态检查看不出问题代码能跑、几何能生成但语义完全错误。只有几何校验环节去检查四个孔中心两两之间的距离是否符合矩形分布才能抓出来。3.4 参数化自校正与导出讲到参数化还有一个实用技巧在生成的代码末尾加一段自检代码让CadQuery自己把实体的体积、包围盒尺寸、面数打印出来。这样校验逻辑就不需要依赖外部几何分析工具了直接解析输出字符串即可。我的习惯是让模型遵循约定在代码末尾打印一段JSON格式的实体报告用正则提取出关键字段失败就自动进入修正流程。导出格式方面国内机械加工和设计评审链条上STEP是最稳的中间格式几乎所有CAD与CAM工具都认。CadQuery导出STEP是在cq.exporters.export(plate, plate.step)这行代码里完成的。注意导出的坐标单位默认是毫米这是机械设计里的标准惯用单位不需要额外转换。如果需要做渲染预览CadQuery也可以直接导出SVG三视图方便快速核查形状。4. 评估与避坑怎么判断一个text-to-cad系统“真的能用”4.1 三层评估体系模型训完了怎么量化判断“它到底行不行”单纯看代码能不能跑完全不够因为能跑的代码可能语义完全错误。我搭了一套三层评估体系每一层解决一个问题。评估层方法解决的问题执行成功率代码在沙箱中能否成功产出几何实体是否具备基本语法与建模能力几何对齐度生成实体与描述中关键尺寸的误差体积、包围盒、孔数是否准确理解了尺寸与特征语义匹配度多视角渲染图与文本做多模态相似度计算是否真正符合用户的形状意图第一层的执行成功率用一个固定测试集每条文本生成3次只要有1次能成功执行就算通过。这个指标决定系统有没有“下限”。我实测的项目里从0到能跑到稳定90%以上主要靠数据清洗和控制生成时的温度参数。第二层的几何对齐度让模型生成同一描述下的多次输出检查孔的个数、位置分布、包围盒尺寸是否符合描述。这个指标对尺寸漂移类问题很敏感。第三层的语义匹配度把生成的STEP渲染成六视图与输入文本计算相似度分数虽然对CAD这种抽象形状来说不够精确但作为快速筛选信号足够用。4.2 高频故障与排查实录我把自己遇到的故障按频率排了个序前几个具有很高的复现率。故障现象根因排查思路生成代码语法错误LLM生成的括号不匹配、变量名不一致静态检查报错回传修复重试3次执行超时/死循环模型写出了while真循环或异常递归沙箱强制超时5秒内存限制1GB尺寸严重漂移数字token切分导致精确数值感知弱在prompt里列出参数表生成后做数值校验特征方向错误孔开在反方向、拉伸方向反了检查生成实体的面法向与开孔方向代码能跑但特征丢失模型“忘记”了描述中的部分特征用结构化prompt把特征清单逐条列出尺寸漂移这个坑要多说几句。LLM对数字的“感知”是离散的不像几何内核那样连续。我见过最典型的一个案例要求“孔间距18mm”模型生成了“hole(18)”——它把“间距18mm”理解成“孔直径18mm”了。这个错误的级别非常隐蔽因为代码能执行、模型也正确生成了一个孔只是语义被偷换了。我的应对办法是强制prompt使用结构化参数声明把尺寸变量单独拎出来声明而不要在特征函数里裸写数字# 正确写法 hole_diameter 6.0 hole_spacing 18.0 # 使用变量进行特征操作这种做法本质上是在“给数字做语义锚点”变相降低模型对数值的误用概率。另一个通行的办法是生成后用正则提取所有数字与预期尺寸表做交叉验证一旦发现越界数值就触发修正或直接丢弃。4.3 工程化心得沙箱、批处理与速度优化工程化落地时还有几个非技术问题的经验。沙箱的安全约束不能只靠超时我见过一次模型生成的代码在循环里反复拉伸实体一瞬间给磁盘写入了几个G的临时数据。所以我现在的沙箱会在网络、磁盘写入、CPU时间三个维度同时加限制禁网、禁大文件写入、限定CPU配额。这个组合目前没有再出现过安全事故。批处理场景下vLLM的吞吐量优势非常明显。单条推理延迟可能不比原生推理快但并发请求上来之后单位时间生成条数能提升三到五倍。我在做批量评估时会先用vLLM一次性生成100条候选代码流水线并行执行校验效率很可观。推理时的prompt模板也值得反复打磨不要用“请生成一个……”这种开放式指令要明确约束“只输出Python代码使用CadQuery库变量定义放在代码开头”。实测下来明确约束能让执行成功率提高近20个百分点。5. 落地场景与下一步扩展5.1 真正有需求的场景text-to-cad的价值要落在具体场景里才看得出来。第一类是3D打印创客场景很多人脑子里有想法但不会建三维模型口语化描述配合生成可编辑参数模型能大幅降低创作门槛。第二类是非标自动化设备设计比如夹具、防错工装这类零件结构相对标准化但尺寸频繁变动的场景把“生成-校验-修改”做成闭环后每次变动省下的建模时间以小时计。第三类是标准件选型和零件复用用自然语言描述特征去检索既有CAD库里的相似模型比按文件名翻找高效得多。第四类容易被忽略但我觉得潜力很大设计规则的自动化校验。结合LLM生成的参数化特征与几何校验逻辑可以在设计早期就判断出“壁厚过薄不适合注塑”“孔距过近容易导致应力集中”这类规则类问题。这本质上是把文本到CAD从“生成器”扩展成了“设计审查助手”。5.2 从单轮调用到多智能体协作目前我的实践还是单轮“文本进-代码出”为主但下一步毫无疑问是往Agent化走。具体说就是让LLM不再一次性生成完整模型而是先规划建模步骤再分步调用建模工具每做完一步就做一次几何检查发现偏差自动回退再试。这更符合真实设计流程里“先定轮廓、再加特征、最后做修饰”的节奏也能显著降低单次生成的压力。另外一个值得探索的方向是与仿真分析工具打通。参数化模型天然能挂接材料属性生成后直接进有限元分析然后把仿真结果反馈给LLM形成一个“设计-验证-迭代”的自动化循环。这个方向一旦跑通机械设计里的很多重复性工作会被真正替代。最后分享一个我个人的体会不要被“大模型能理解三维空间”这种说法迷惑。它并不能它只是在按统计规律拼接代码一切几何正确性都依赖你搭的那层执行校验闭环。所以做这个方向与其追逐更聪明的模型不如把精力投在“数据质量”和“校验闭环”上。把执行成功率和几何校验做到90%以上哪怕基座模型不那么大这套系统也能在真实生产环境里稳稳立住。