前天一个做机械设计的哥们给我发了条消息说他接了个新需求客户就给了几句话“底板长200宽120厚10四角倒R5中间挖个60×40的腰型孔另外再打四个直径8的沉头孔。”他一边吐槽客户抽象一边老老实实打开软件开始建模。我当时就回他这种需求现在已经有人用text-to-cad在做了你把这段话原封不动丢给模型它能把模型给你生成出来。他愣了半天问我这东西到底成熟没有能不能用在实际项目里。这个问题其实问到了点子上。text-to-cad并不是什么科幻概念也不是只有大厂内部才能玩的秘密武器。从2024年开始普渡大学团队发布了Text2CAD相关工作开源社区也陆续出现了基于CadQuery、OpenCascade的自然语言生成三维模型方案。它的核心逻辑非常朴素你输入一段自然语言描述系统把它翻译成一套结构化的CAD建模指令再交给几何内核去执行最终输出一个可编辑、可导出的参数化三维模型。这篇文章我不打算给你堆概念而是从一个实际动手的人角度把这东西的原理、选型、实操和踩坑都聊一遍最后你也能自己跑通一个小项目。1. text-to-cad的本质从口述需求到参数化模型1.1 建模方式的三个根本变化传统的CAD建模流程本质上是一个“人手动操作”的过程。设计师接收需求后在脑子里完成从文字到几何的转换然后通过鼠标键盘一步步在软件里画草图、加约束、拉伸、切除、倒角。这个过程有两个明显的瓶颈一是对操作者本身的建模经验要求高二是需求传递和实现之间存在大量信息损耗。你让客户手写一个需求文档他能写出一堆“大概”、“差不多”、“圆滑一点”这种模糊词汇然后你还要猜。text-to-cad改掉的就是这个链路。它的本质变化体现在三个层面从“人机交互”变成“语义交互”。以前你操作的是工具栏和命令面板现在你操作的是自然语言本身。描述得越精准生成结果越贴近需求。从“显式建模”变成“隐式建模”。以前每个特征都是你手动添加的现在模型自动规划出一个合理的建模顺序比如先画草图、再拉伸、再挖孔、最后倒角。从“单向执行”变成“可控迭代”。不需要重画整个模型如果你不满意某个尺寸直接在对话里说“把孔的间距改到30”系统可以帮你调整对应的参数。这三个变化叠加起来解决的是制造业、快速设计、教育场景里最头疼的问题建模门槛。你不需要先把SolidWorks学得滚瓜烂熟才能把一个简单零件做出来。它让“会说话的人就能建模”第一次变成了现实。1.2 一个关键问题为什么是代码而不是网格如果你关注过AI生成3D模型的方向可能会看到很多模型直接输出OBJ、STL、GLTF这类网格文件。但text-to-cad走的不是这条路它倾向于让大模型生成一段可执行的建模代码比如CadQuery脚本再由几何内核执行。为什么非要绕这一圈这里有个非常实际的工程原因网格模型是“死”的代码模型是“活”的。STL网格本质上是成千上万个三角形拼出来的近似表面工业软件拿到这种模型只能做可视化没法做CAM加工、力学仿真和参数修改。而CadQuery代码生成的模型底层是B-Rep边界表示几何有精确的曲面方程、完整的拓扑关系核心数据和SolidWorks、Fusion 360这类商业软件完全对齐。我打个比方你就明白了。网格模型像一张照片分辨率再高也就是像素点的集合你没法把它里面的“人脸”单独拿出来换个表情。而参数化代码模型像一份PSD源文件图层、路径、文字都还在你想改哪里就改哪里。制造业和工程设计要的是PSD源文件不是一张JPG。这就是text-to-cad坚持走“文本到程序化建模”路线的根本原因。1.3 两条技术路线我的选型思考目前开源社区里真正可落地的text-to-cad方案大致可以分成两条路线路线代表方案原理优点短板程序化代码生成CadQuery LLM、Text2CAD框架让大模型输出CadQuery或类似CAD脚本代码本地执行生成模型可编辑、可追溯、精确几何、与工业软件兼容对代码质量要求高复杂模型容易出错直接生成几何各种3D生成模型用扩散模型或GAN直接生成体素或网格效果直观适合概念展示、游戏资产精度低不可参数化编辑难用于加工我个人的看法是如果你做的是玩具、手办、游戏资产直接生成网格的方案完全够用但如果你面向的是机械加工、产品结构设计、钣金件设计哪怕它生成出来的网格模型长得再好看你也得自己重新建模一遍等于白干。所以我后续的实操分享全部基于“程序化代码生成”这条路线。它更麻烦但它是唯一能真正接进现有制造业流程的方案。2. 核心技术链路拆解自然语言如何变成CAD几何2.1 语言到指令大模型在里面扮演什么角色text-to-cad里的大模型本质上是做了一个“翻译器”的工作。它把自然语言转换成一套结构化的建模操作序列。举个具体例子当你输入“创建一个直径50的圆柱体”一个合格的生成系统内部会输出类似这样的结构化指令新建草图在XY平面放置一个圆心在原点、半径为25mm的圆选中该草图沿Z轴正方向拉伸30mm将结果命名为“圆柱体_01”这个过程对应到CadQuery里就是一段可执行的Python代码。大模型在这里承担了两个核心任务第一理解自然语言中的空间关系和几何语义比如“在中心”、“穿过”、“均布”、“倒角”这些词汇背后代表的约束条件第二把理解结果映射到具体的API调用上需要知道CadQuery里“倒角”应该用.fillet()还是.chamfer()挖孔应该用.cutThruAll()还是.hole()。很多人低估了第二个任务的难度。CadQuery虽然语法相对友好但它的对象模型、工作面切换、特征引用方式都是有讲究的。一个没做过CAD开发的人哪怕Python写得再溜第一次接触CadQuery也会被workplane()的坐标体系绕晕。大模型之所以能胜任这个任务靠的是两样东西预训练阶段见过的大量开源CadQuery代码以及Text2CAD类项目里专门做的指令微调数据。2.2 为什么Text2CAD论文要采用分阶段生成策略我读Text2CAD论文和源码的时候有个设计让我印象很深它不是让模型一股脑把整个模型的所有操作一次性输出而是采用了一个“从总体到局部”的分阶段生成策略。具体来说生成过程大致分了这么几步第一步是生成设计意图规划相当于先写个大纲说清楚这个模型由哪几个主要形体组成它们之间是什么关系第二步是生成基础形态也就是主体轮廓的草图、拉伸或旋转操作第三步才是在主体上叠加特征比如挖孔、开槽、加圆角、阵列等细节操作。这个策略背后的道理其实和人类建模习惯高度一致。一个成熟的设计师拿到需求后也不会一上来就去倒角他一定是先把毛坯外形拉出来再逐步细化。大模型直接生成长篇操作序列到了中间容易出现“累乘误差”——前面一步的坐标绕了后面所有特征跟着全歪。分阶段生成的好处是每一步生成的控制范围有限即使某一步出错了回溯和修正的成本也低很多。我建议你自己搭方案时也借鉴这个思路别指望一个提示词就让模型端到端输出一个完整复杂零件。2.3 训练数据是怎么来的合成数据闭环你可能会好奇用来微调text-to-cad模型的数据是哪来的。这里有一个非常聪明的做法合成数据闭环。他们是反向操作的——先写程序批量生成参数化的CAD模型并且记录下生成每个模型时具体的建模操作序列然后再把这套操作序列交给大语言模型让它“看图说话”把操作序列翻译成一段对应的自然语言描述。这样就有了大量“文本描述—建模操作序列”的配对数据。这个思路巧妙在哪它避开了人工标注三维几何数据的巨大成本。标注一张图片里的物体是什么已经够烦了标注一段三维操作序列对应的文本简直是要命。而合成数据可以无限生成、自动对齐质量还高度可控。我自己在做CadQuery代码生成的时候也借用了类似的办法拿一小批我手工写好的“描述—代码”对塞进提示词做few-shot示例效果比纯靠模型自己发挥稳得多。这也说明一个朴素的道理如果想让大模型输出靠谱的CAD代码你得先给它看一批靠谱的CAD代码长什么样。2.4 几何内核最后一步为什么OpenCascade是默认选择在程序化生成路线里大模型把代码吐出来只是完成了一半工作。后半段代码要在某个几何内核里真正执行生成精确的几何实体。目前绝大多数的text-to-cad开源项目不管是CadQuery还是FreeCAD的脚本接口底层都跑在OpenCascadeOCCT内核上。选择OpenCascade是有原因的。它是目前开源社区里最成熟的B-Rep几何内核支持完整的实体建模、布尔运算、倒角、 shell 等操作而且它导出的STEP文件是制造业的通用语言。CadQuery就是建立在OCCT之上的一个友好封装层把繁琐的内核API简化成了Workplane这种相对直觉的接口。你只需要记住这条依赖链就好自然语言 → LLM生成CadQuery代码 → CadQuery调用OpenCascade内核 → 得到B-Rep实体 → 导出STEP/STL。每一层都有明确分工后一层不关心前一层怎么来的只关心能不能正确执行。3. 实操记录用CadQuery加LLM跑通一个法兰盘3.1 环境准备别在安装这一步浪费太多时间我踩过的第一个坑就是环境安装CadQuery依赖OCCT从pip直接装虽然也能装但如果你用的是比较新的Python版本很容易碰到预编译wheel缺失的问题源码编译OBR一次没个半小时下不来。我后来学乖了直接用conda。我建议的环境准备分成三步conda create -n cadquery python3.10 -y conda activate cadquery conda install -c conda-forge cadquery -y用conda-forge渠道装的话会自动解决OCCT、numpy这些底层依赖的版本匹配问题。装完之后验证一下python -c import cadquery as cq; print(cq.__version__)能正常打印版本号说明环境OK。这一步别跳过我遇到过有人熬了两个小时装完结果import就报错白忙活。LLM这边你有两个选择一是直接调用商业API省心省力效果也最好二是本地部署一个7B或14B的代码生成模型配合Ollama这类工具来用适合对数据隐私敏感的场景。个人跑demo的话我建议直接用API把精力花在核心流程上等后面验证通了再考虑本地模型替换。3.2 完整案例一个带安装孔的法兰盘为了让你直观感受整个流程我跑了一个非常典型的机械零件法兰盘。需求描述是“外径120mm、内孔25mm、厚度8mm在直径100mm的圆周上均布4个直径10mm的安装孔”。这是一句任何机械设计师都能看懂的话我们来看看它是怎么一步步变成三维模型的。第一步写提示词。我的提示词模板包含三个要素角色设定、需求正文、输出约束。示范如下你是一位高级CAD工程师。请根据下面的自然语言需求生成一份CadQuery Python代码。 需求一个法兰盘外径120mm内孔直径25mm厚度8mm在直径100mm的圆周上均布4个直径10mm的安装孔。 约束单位使用毫米坐标系原点放在底面圆心使用CadQuery标准API最后用exporters.export导出STEP文件。第二步把大模型返回的代码拿过来执行。正常来说一份合格的结果长这样import cadquery as cq result ( cq.Workplane(XY) .circle(60) # 外径120 .extrude(8) # 厚度8 .faces(Z) .workplane() .hole(25) # 中心孔直径25 ) # 在直径100的圆周上均布4个直径10的孔 result ( result.faces(Z) .workplane() .circle(50, forConstructionTrue) .vertices() .hole(10) ) cq.exporters.export(result, flange.step)第三步在Jupyter里直接跑这段代码。CadQuery对Jupyter的支持很好result对象可以直接内嵌显示成三维预览。看到模型没问题后export出STEP文件丢到任意一款CAD软件里打开验证。我这里要特别说明一个细节代码里第二段用了circle(50, forConstructionTrue)再取.vertices()这实际上是先画一条直径100的构造圆然后取它的四个象限点作为打孔位置。这个技巧在CadQuery里非常常用但如果你不熟悉它的对象模型很容易想当然地用polarArray之类不存在的API。这也是为什么我说这类问题交给LLM处理特别合适——它见过足够多CadQuery代码知道那些“不那么直觉但官方推荐”的写法。3.3 提示词设计里的几个小心机提示词写得好不好直接决定LLM输出的代码一次通过率。我自己调了一段时间总结了几个很实用的经验。第一一定要明确单位。LLM训练语料里既有毫米也有英寸你不限定它就随机发挥。一个紧固件差0.1mm就是废品这个约束必须写死。第二要指定坐标系和放置方向。CAD建模里最恶心的问题就是方向歧义。“底板”可以放在XY平面也可以放在XZ平面你不说清楚模型生成出来面朝哪个方向全凭运气。我习惯在提示词里加一句“底面放在XY平面模型沿Z轴正方向生长”基本能保证方向预期。第三给出输出格式约束。让LLM直接调用exporters.export导出STEP文件可以省去你手动添加后处理代码的麻烦。STEP格式保留精确几何STL只是三角网格近似。加工、测量、装配都建议用STEP。第四如果模型复杂别一次生成全部而是分步对话。先让它生成主体轮廓你确认一下再继续加孔、加槽、加圆角。实践证明这种“分阶段多轮生成”的容错率远高于一句话生成全部。这个经验其实和Text2CAD论文里分阶段生成的思路一脉相承。3.4 一个更复杂的思路让LLM自己规划再写代码如果你是做真实项目我强烈建议你在写代码前多让模型输出一步“设计规划”。具体做法是在提示词里增加一段要求在写代码之前请先用JSON格式输出你的建模步骤规划包括 1. 基础形体用什么草图、拉伸多高 2. 主要特征挖孔、切除的位置和尺寸 3. 细节处理倒角、圆角的位置和数值 4. 建模顺序每一步依赖关系这看起来多此一举实际价值非常大。规划JSON相当于一个“施工方案”让你在LLM动手写代码之前有机会检查它的设计思路是否正确。比如你本来想要的是通孔它规划成了沉头孔你在这一步就能发现并纠正节省一整轮代码生成和调试的时间。我在处理稍微复杂的钣金件时这个步骤帮我避免过至少三次无效代码生成。4. 常见问题与排查技巧实录4.1 代码语法没问题但模型形状就是不对这是我在使用过程中碰到最多的一类情况。LLM生成的代码能顺利执行导出的STEP也能打开但模型长出来和需求描述完全不是一回事。最常见的原因有下面几个尺寸单位理解偏差。提示词里不写明毫米LLM可能在英寸和毫米之间摇摆不定。坐标方向反了。孔位分布是在顶面还是底面拉伸方向是正还是负不说明就会出问题。特征作用面不对。CadQuery里.faces(Z)和.faces(Z)差一个方向如果错选孔就打到反面去了。排查这类问题我的习惯是先在Jupyter里3D预览从多个角度观察模型再对照需求逐项检查尺寸和位置最后用result.val().Volume()算一下体积大体估算是否符合预期。比如外径120、厚8、内孔25的法兰盘理想体积大约是π×(60²−12.5²)×8约90500mm³如果差了一个数量级那肯定哪里搞错了。4.2 布尔运算失败和零厚度几何程序化建模里有个非常经典的问题叫“零厚度几何”。简单说如果两个实体刚好共面或者某个特征的边与另一个特征的边距离为0几何内核在做布尔运算时就会报错或者生成失败。举个例子你想在一个30mm宽的方块顶面正中切一个30mm宽的槽槽的边界刚好和方块的边界重合成一条线很多内核会认为这个操作无效因为它生成了退化边。这类问题一般从两个方向解决一是在提示词里明确要求“所有特征之间保留至少0.5mm的间隙或壁厚”让LLM从源头避开退化情况二是如果代码已经生成手动微调尺寸把特征边界往里缩一点点。我在微调时经常把尺寸从30改成29.8问题就消失了。这不算玄学是B-Rep建模里真实存在的容差限制。4.3 LLM上下文不够长复杂模型怎么拆大模型的上下文窗口虽然越来越大但真让它一口气生成一个包含几十个特征的复杂零件仍然容易出错。不是这里漏掉一个特征就是那里的坐标系错乱。我的处理办法是把模型拆成多个子部件分别生成最后再装配。举个例子一个完整的机箱设计我不会让LLM直接生成整个机箱而是先让它分别生成底板、侧板、前面板、后面板每个面板用独立提示词生成最后再用cq.Assembly把它们组装到一起。这个方法的好处很明显每个子任务的生成压力小正确率大幅提升坏了哪个子部件就重新生成哪个不用整体返工。这与软件工程里的模块化思想完全一致CAD代码生成同样是代码同样需要控制复杂度和粒度。4.4 排查速查表我把实操中遇到的高频问题整理成一个速查表方便你遇到了直接照着查。现象可能原因排查方法解决办法尺寸不对单位未限定检查提示词是否写明mm提示词强制声明“单位毫米”拉伸方向反了坐标系理解偏差在Jupyter中翻转视角查看提示词指定“沿Z轴正方向”孔打到了反面face选择方向错误检查.faces(Z)或(Z)切换面方向或调整workplane布尔运算失败零厚度几何、共面退化查看错误日志和几何报告微调尺寸避免共面生成代码不执行API调用错误运行Python检查traceback把报错信息回传LLM让模型修正特征遗漏上下文过长、注意力丢失比对需求描述与模型树拆分多轮生成导出STEP后软件打不开实体不闭合或拓扑异常用val().isValid()检查对实体执行fix()修复或重新生成4.5 一个被扎扎实实坑过的案例说一个我印象特别深的实际案例。有一次我让LLM生成一个“带12个均匀分布散热孔的圆形盖板”需求描述很明确12个孔均布。但第一次生成的代码里LLM用了.polarArray(12, ...)CadQuery旧版本里这个API的参数含义和我想的完全不一样结果12个孔沿着圆周均匀错了45度整体旋转偏移了半个孔位。代码没报错模型也能看但加工出来就是不对。这类问题最迷惑人的地方在于没有报错、没有警告纯逻辑错误。后来我学到的排查方法是生成完代码先做一个“几何数据抽检”。比如检查某个孔心的坐标值12个孔心的角度理论上应该是0、30、60、90度间隔排列如果首孔位置不对再看是不是起始角度参数出了问题。把合理性验证前置是text-to-cad落地过程中必须补上的一环别指望LLM一次输出就完全正确。5. 我的真实感受与后续扩展方向5.1 这东西到底能干什么不能干什么把text-to-cad玩了一段时间后我对它的能力边界有了比较清醒的认识。它目前能做得很好的是那些几何逻辑清晰、参数明确的机械零件和结构件。法兰盘、支架、外壳、齿轮、钣金折弯件这类“尺寸说话”的东西它能干得像模像样甚至某些场景下比我手动建模快五倍以上。但它也有很明确的局限。它对那种高度依赖美学判断和语义模糊性的造型设计比如消费电子产品的曲面外壳、汽车的流线型车身基本无从下手。原因很简单这类设计的关键信息“好看”、“有质感”、“曲线要流畅”无法被量化成参数自然也很难被转化成几何操作。所以我的判断是text-to-cad现阶段是一个面向工程效率的提升工具而不是替代设计师创造力的魔法棒。它更像一个“听写助手”你把脑子里的设计语言说出来它帮你快速变成可编辑的模型。5.2 我接下来准备做的三个扩展基于我目前的实践我给自己列了三个后续方向应该也对你有参考价值。第一个方向搭建私有知识库做RAG增强。我现在手头积累了十几个公司的标准件和常用件模型既有STEP文件也有对应的CadQuery代码。我准备把这些代码和说明文本向量化搭一个简单的RAG检索。这样以后LLM生成新部件时可以先检索到这个库里最接近的旧模型基于它做修改生成。这比每次从零生成靠谱得多也是把text-to-cad真正嵌入企业工作流的必经之路。第二个方向文本和手绘草图联合输入。文字描述几何信息其实并不高效经常是“说不清”。我打算把Sketch识别模型输出的二维线框数据作为额外上下文拼接到提示词里让LLM生成对应的三维特征操作。这一步相当于把“图文混排”的能力引入CAD生成链路对快速原型设计帮助很大。第三个方向自动校验加自动修复闭环。目前LLM生成的代码质量还不够稳定我计划写一个简单的自动校验脚本生成完代码自动执行、自动检查体积、重心、孔位数量发现异常自动把报错信息回传给LLM让模型自查并修复。这个闭环跑通后生成可靠性的问题会进一步缓解也是让非技术背景的人能放心使用text-to-cad的关键。最后再分享一个小技巧。如果你是第一次尝试别急着上复杂零件先拿一个最简单的块体加孔练手摸清整个“描述—生成—执行—检查”的循环节奏。等你熟练掌握提示词里的那些约束技巧后你会发现原来逼着客户写清楚需求自己就能少加半天的班。这可能是text-to-cad带来的最直接的红利了。