Text-to-CAD实战:从自然语言到参数化3D模型的完整流程
1. 为什么“text-to-cad”突然成了硬需求先别急着把它当成又一个昙花一现的AI噱头。我在制造业和设计软件领域泡了十来年最近半年被同行问得最多的问题就是用一句话描述一个零件真的能直接生成可编辑的三维模型吗先说结论能而且不是玩具级的“样子货”。所谓 text-to-cad就是通过自然语言输入让程序直接产出参数化CAD模型比如带特征树、可改尺寸的STEP/原生工程文件而不是传统意义上用文本生成一张图片或者用文本生成一个粗糙的网格体。它解决的核心痛点是设计师和工程师大量重复性建模工作——或者更准确地说是“明明脑子里有清晰结构但手跟不上”的那部分效率损耗。一套完整可落地的 text-to-cad 流程现在主要覆盖三类人。第一类是我这样的机械设计/结构工程师做非标件、夹具、钣金支架时与其在软件里拉伸、切除、倒角来回切工具不如直接描述第二类是仿真和工艺工程师需要快速验证某个结构是否可制造、可装配不需要为一个简单零件花费半小时建参数模型第三类是搞制造业自动化的开发者想把“设计意图”直接导入到参数化建模环境和自动排产流程里。这技术目前更多是辅助角色但趋势已经很明显它正在把“设计意图表达”从手势操作中解放出来。下面我想从核心原理、工具链选择、完整实操流程、踩坑经验这四个维度把这件事讲透。2. 这玩意儿背后的原理其实没有那么玄2.1 从“语义到几何”本质是约束求解很多人以为 text-to-cad 是类似文生图的“扩散模型输出一堆点云”这个理解偏差很大。工业界能用的技术路线核心是“把自然语言转换成参数化特征指令”再交给约束求解器去生成模型。打个比方你告诉建模师傅“给我做一个直径30mm、厚度5mm的法兰盘中心打一个直径10mm的通孔”师傅脑子里会拆解成“圆柱拉伸直径30×高5”、“打孔拉伸切除直径10”——text-to-cad 系统干的就是这个拆解。它内部有两个关键模型协同语言理解模型通常是大语言模型微调版负责把自然语言拆解成结构化的建模指令序列比如“创建草图平面→绘制圆→拉伸凸台→切除”。几何约束求解器负责把指令执行成带尺寸、带特征树、参数可改的CAD实体模型。这个链路和文生图完全不同。它不追求“看起来像”而是追求“尺寸对、特征全、能修改”。所以工业验证过的方案里输出的原生CAD模型往往比渲染图更重要。2.2 为什么不能直接用通用LLM生成STEP文件有个坑很多新手会踩直接让通用大模型“写一份STEP文件”或者“给我生成一段CAD代码”。且不说STEP文件本质是EXPRESS语言描述的交换格式手写极易产生拓扑错误——就算模型背下了格式输出的模型也难以参数化修改。通用LLM生成的往往是一次性的“死模型”改一处尺寸就得重新生成。核心原因在于CAD建模的灵魂是“特征历史”。你看一个正规的.prt或.sldprt文件里面有拉伸、切除、圆角、阵列的特征树每一步都记录着基准面、草图、尺寸约束。没有这个特征树一个圆柱体就只是一坨B-rep表面几何工程上几乎不可用。因此目前主流方案都是“代码生成中间表示”路线比如生成对应开源CAD内核的Python脚本CadQuery / build123d / OpenCascade或生成某个商用CAD软件的宏命令比如SolidWorks的宏API然后脚本执行动态重建模型。这样生成的模型自带参数化逻辑改一个变量整条特征链随之更新。2.3 模型选型通用大模型 vs 专用微调模型做这个方向的开发者常纠结到底用什么模型做语义解析我的实测结论是通用大模型具备较强代码能力的那种在高层次理解上强专用微调模型在“稳定输出合法建模命令”上强。通用大模型的好处是能理解复杂描述比如“一个带四个安装孔的方形底座孔距50mm底部有加强筋”它能综合语义和常识推理出大致拆解缺点是有时会“自由发挥”生成长度不定的代码要么漏掉某个特征要么使用了内核不支持的API出错率不低。专用微调模型用大量CAD脚本语料微调过的好处是输出格式极稳定可能90%以上的一次生成都能直接通过语法检查缺点是理解复杂语境的能力稍弱需要你把需求描述得更加结构化。我的建议是直接用通用大模型但加上强约束提示词、输出Schema、以及后置的代码校验修复循环。千万别一上来就去微调专用模型——数据准备和训练成本高投入产出比未必划算。3. 实操准备先搞清楚你要走哪条技术路线3.1 一条最推荐的轻量级技术栈工具选型直接决定你后续的踩坑数量。我这两年反复换方案最后留存下一套相对稳定的组合语言模型通道调用国内可用、具备较强代码生成能力的通用模型API或者用开源的代码大模型本地部署看你是否介意数据出内网。中间表示层CadQuery 或 build123d这两个是Python原生的参数化CAD库运行在OpenCascade内核之上生成的模型可以导出STEP/STL也能桥接到FreeCAD做进一步操作。执行校验层本地执行生成的Python脚本捕获异常并自动把错误信息回灌给模型让模型自我修正。这一步非常关键是提升成功率的胜负手。后端处理层将成功生成的STEP模型做可视化预览可以用 trimesh pyvista也可以用FreeCAD的图形界面确认无误后归档。这套组合最大优势是把“模型生成”和“几何内核运行”彻底分离。语言模型只负责写代码实际建模由OpenCascade完成出现几何错误跑不起来模型会收到报错信息再修正而不是生成时凭空想象。3.2 环境搭建与依赖细节环境搭建看着简单实际有不少坑。给个可复现的步骤按顺序操作# 建议用虚拟环境避免Python包相互污染 python -m venv cad_env source cad_env/bin/activate # Windows下是 cad_env\Scripts\activate # 核心依赖 pip install cadquery build123d # 可视化与格式处理 pip install trimesh pyvista numpy # 如果你要本地跑开源模型再加 # pip install transformers torch安装完成后建议先跑一个最小用例验证内核是否可用import cadquery as cq result ( cq.Workplane(XY) .box(50, 30, 10) .faces(Z) .hole(8) ) # 导出STEP cq.exporters.export(result, test.step)这里要注意CadQuery 的依赖 OpenCASCADE 是较大的二进制包国内源有时拉取失败建议直接使用阿里云或清华的 pip 镜像源。首次导入cadquery会比较慢需要加载内核库这是正常现象。另外 Windows 环境下最好用 Python 3.10 或 3.11某些版本在 Python 3.12 上存在二进制兼容问题我踩过这个坑白白折腾了一个下午。3.3 提示词结构设计直接抄作业的模板既然核心是让语言模型生成 CadQuery 脚本你在提示词里给出的约束越明确产出越稳定。我长期使用的一套提示词模板亲测有效你是一个专业的CadQuery参数化建模专家。请根据以下产品描述生成一段CadQuery Python代码。 要求 1. 使用 cadquery 库导入方式为 import cadquery as cq 2. 所有关键尺寸必须变量化定义在代码顶部变量名要有意义 3. 优先使用 fromPoint/center 定位避免使用绝对坐标魔法数字 4. 建模逻辑必须清晰分步骤操作先主体后特征 5. 不得使用 cq.importers 或 cq.exporters 6. 最后一行将结果赋值给 result 产品描述 {用户输入内容}这个模板解决了我曾面临的三大痛点变量不提取导致模型不可参数化、模型自作主张使用不支持的导入函数、代码结构混乱导致报错后难以定位。用模板后一次成功率提升非常明显。4. 完整实操从自然语言到可编辑STEP模型4.1 冲突描述从“一句话需求”到“结构化指令”很多教程止步于“一句话生成模型”但真实项目哪有这么简单。实际需求往往是“一个L型安装支架长边100mm、短边60mm、宽40mm、厚度5mm长边上有两个直径8.5mm的安装孔孔距离边缘20mm短边末端有一个直径12mm的半圆凸台。”这算中等复杂度。完整操作流程如下我以一个实际案例走一遍第一步先将自然语言转成结构化参数表。这一步可以让语言模型先输出一个JSON参数清单再据此生成代码而不是描述完直接生成代码。这样做的好处是人类可检查参数错误能在早期发现。第二步用模板提示词将参数表与描述传给模型生成脚本。第三步本地执行生成的脚本。如果抛异常把完整traceback回灌给模型让它自行修正循环最多5次。第四步模型成功后导出STEP再用可视化脚本快速渲染一张预览图人工确认尺寸与拓扑。我把上述流程整理成一个可复用的Python框架核心执行循环如下——这样你后续换模型接口或换内核时只改很少的代码import subprocess import re CLAUDE_CODE ... # 或者任意模型的接口封装 def generate_and_fix(prompt, max_attempts5): for attempt in range(max_attempts): code get_model_output(prompt \n请现在开始生成代码。) # 清理可能的markdown围栏 code re.sub(r^(?:python)?\s*|\s*$, , code, flagsre.MULTILINE) with open(generated_model.py, w) as f: f.write(code) try: subprocess.run( [python, generated_model.py], checkTrue, capture_outputTrue, timeout60, ) print(f第{attempt1}次尝试成功) return code except subprocess.CalledProcessError as e: error_msg e.stderr.decode(utf-8, errorsignore) print(f第{attempt1}次失败错误{error_msg[:300]}) prompt f\n\n你的上一次代码执行失败错误信息如下\n{error_msg}\n请修正后重新输出完整正确代码。 raise RuntimeError(超过最大尝试次数生成失败)4.2 案例演示电子设备外壳的生成我们用一个真正产品级的案例验证手持设备外壳。已知条件主体尺寸120×60×20mm壁厚2mm内部分布4个直径3mm的定位柱底面有USB接口开槽长12mm、宽6mm位置在短边正中偏右10mm顶部四个角做R5的圆角。建模思路拆解主体壳体用box拉伸然后抽壳shell壁厚2mm。定位柱用workplane偏移到内底面添加圆柱体。USB开槽用“布尔减运算”或拉伸切除。圆角用edges()选择顶部周边线执行fillet。这些在CadQuery里实现并不算复杂但让模型一次性全部写对并不容易尤其是抽壳方向很容易写反。实际运行结果模型第一次尝试就在“抽壳方向”上犯错了生成了一个外壁壳体而不是带内腔的壳。我把报错和预期结果回灌后第二次它就正确实现了——这也是“反馈修正循环”的核心价值所在。可视化确认时我一般直接用 pyvista 渲染检查关键看三点壁厚是否均匀、特征是否完整、安装孔位置是否正确。这一步不要省主要是过滤模型“语法正确但几何错误”的情况。4.3 参数化能力让模型可复用而不是一次性的做工程的人最看重“改参数重新生成”的能力。一个text-to-cad流程如果每次都从头生成一个新模型那还不如不用。所以我在提示词里强制要求“所有关键尺寸变量化”就是为了让生成脚本天然具备参数化属性。比如外壳脚本的主要参数L 120.0 # 外壳长度 W 60.0 # 外壳宽度 H 20.0 # 外壳高度 T 2.0 # 壁厚 R 5.0 # 四角圆角半径后续只要改这几个数字再执行一次脚本新模型秒出完全不用再和模型对话。这就从一个“生成器”变成了一个“参数化模板”这对批量生成系列化零件比如不同尺寸的仪表壳体非常有价值。注意有些模型生成的代码会把变量写在中间某一行或者直接在函数参数里填数值。你需要在反馈修正时强制要求变量集中在文件头部。这一步影响到项目后续可持续性务必盯紧。5. 常见问题与排查技巧实录5.1 语法正确但几何错误的三大典型症状症状一抽壳方向反了。CadQuery的shell()方法默认向内部抽壳但当你先做了圆角或倒角后再抽壳可能出现几何退化。排查方法将抽壳操作尽量提前在圆角/倒角之前完成。症状二面选择歧义。faces(Z)这类面选择器是基于边界框最值定位的当模型有多个凸台、圆顶结构时模型可能选错面。排查方法改用明确的workplane偏移或者用faces(tag...)预先打标签。症状三布尔运算重叠阈值问题。两个实体恰好贴合时OpenCascade有时会因容差问题产生破面。排查方法给配合面留0.001mm的间隙或重叠量这是工程建模中很实用的习惯。5.2 让语言模型稳定输出的四个技巧技巧一把“少样本示例”直接放进系统提示词。给模型看一个完整的输入-输出示例对比说一百遍“你要生成CadQuery代码”都管用。我一般放两个示例一个是简单主体一个是带孔和圆角的组合特征。技巧二限制输出格式。要求模型必须输出python代码块并且代码块内不得包含注释中的“示例”字样。这些细节能把HTTP传输时的转义问题降到最低。技巧三关键术语中英对照。对某些模型中文“圆角”可能被理解为“圆形倒角”但英文“fillet”则更准确。提示词中同时给出中文描述和英文对应关键词能明显减少怪异生成结果。技巧四明确禁止模型调用外部文件。有些模型会自作聪明地尝试读写本地文件这在自动化执行流程中非常危险必须在系统提示里禁掉。5.3 模型对复杂装配体描述的局限性单零件场景下text-to-cad 的成功率已经可以做到比较理想。但涉及装配体比如“一个底座加4个螺栓加2个垫片”模型往往会犯两个错误一种是把所有零件合并成一个实体另一种是零件之间完全没有装配约束关系。目前比较务实的做法是装配体按“单零件逐个生成再用外部装配工具组合”来处理。生成单个零件时保留统一的坐标系基准约定比如都把底面原点放在 (0,0,0)后续在FreeCAD或商业软件里施加配合约束即可。夸大text-to-cad目前能承担的水平没好处你如果一开始就幻想一句话生成一套减速器装配体大概率会失望。6. 从个人效率工具到业务落地的几条经验6.1 真实场景下的预期管理务实地说text-to-cad目前最适合的场景还是单一几何体为主、特征数量适中、描述清晰的结构件。那些高度依赖曲面造型、自由曲面、复杂分型线的外观件纯靠文字描述很难表达到位这类任务建议老老实实用传统建模。这就像文字生成图片一样如果你用文字描述一个抽象概念会有很多种解读但描述“一个红色圆圈”则几乎不会出错。CAD任务同理特征越规则、参数边界越清晰成功概率越高。6.2 数据安全和内网部署考量如果你的项目涉及产品预研或非公开结构把图纸描述发给外部大模型API有泄露风险。建议优先考虑私有化部署代码大模型显存需求大约在16GB以上7B量级或48GB以上更大参数。实际体验中7B级别的模型在通用语义理解上略逊但加上完善的反馈修正循环后最终成功率差距并不算悬殊。另一个思路是采用“本地模板库小型改写模型”的混合架构维护一份常见特征安装孔、法兰、卡扣、加强筋的CadQuery代码库模型只需将自然语言映射到已有模板和参数。这种方式数据不出内网生成稳定性反而更高。6.3 往前一步从文本生成到逆向优化最近我在试验的方向是让text-to-cad不只是“文本到模型”而是“文本到满足约束的模型”。即除了输入描述系统还能从仿真结果中读取应力分布然后自动调整壁厚或增加加强筋再重新生成模型。虽然目前这个链路还比较粗糙但思路是通的既然模型的输出是参数化脚本那么脚本中的变量就能成为优化变量。这让text-to-cad有机会成为设计优化闭环中的一个执行器而不是一个孤立的生成工具。7. 最后再分享一条实操感受text-to-cad真正让人上头的瞬间不是模型第一次跑通而是两个月后你拿到一张变更通知单、上面写着“主板厚度从1.6mm改成2.0mm整机外壳所有卡扣位置随动偏移”时你发现自己只需要在参数化脚本里改一个数字重新执行一遍几秒钟就输出了新版3D模型和STEP文件。这种效率提升就是这项技术最实在的价值。我个人的建议是不要等工具成熟了再学现在就开始把日常工作中重复度最高的那几个零件类型尝试用text-to-cad流程重构一遍参数化模板。这条流程可能一开始不如你用鼠标点得快但一旦跑通它后续的复用价值会远远超过你最初的那点学习成本。工具会不停迭代但“用自然语言描述设计意图、再由参数化脚本驱动模型”这个思路会是长期不变的趋势。早点动手你积累的模板库和踩坑笔记会变成别人追不上的存量优势。