
做CAD开发这几年我每周几乎都会碰到同一种需求对方甩过来一句“做一个底座120乘80厚度10四角打四个直径10的孔”然后等你把三维模型交过去。以前人得老老实实打开CAD软件画草图、标约束、拉深度运气好十分钟运气不好重新改尺寸就是一轮返工。现在text-to-cad要解决的就是这件事——让这一段自然语言直接变成可编辑的三维CAD实体而不是一张渲染图更不是一堆没法改的网格面片。这篇文章我把这个方向的思路、技术选型、最小可跑通的方案以及踩过的坑都整理一遍。适合三类人看机械结构工程师想做设计自动化的开发者还有那些被重复建模烦到想偷懒的朋友。1. 先把text-to-cad这件事想清楚1.1 它到底在解决什么问题text-to-cad的完整含义是“从自然语言文本生成CAD模型”。听起来和“文生图”“文生3D”很像但骨子里完全不是一回事。文生图要的是视觉上的像文生3D要的是看一眼能用的白模而CAD要的是精确的几何尺寸、特征树、约束关系、可修改的参数最终还要能出工程图、加工制造。一句话概括text-to-cad的核心目标不是“看起来对”而是“制造上能用”。我见过不少朋友一开始理解就跑偏以为输入“一个花瓶”它就应该吐出一个水灵灵的花瓶模型。真实场景里更常见的输入是“M6沉头孔四个均匀分布在直径60的圆上”或者“法兰外径80内径40厚度8六个均布孔直径6.5”。这种描述充满了精确数字和工程语义不是感性描述而是参数表。所以要解决的需求本质上是两件事。第一是理解从模糊的、夹杂口语和工程术语的自然语言里提取出实体类型、尺寸、位置、约束关系。第二是生成把这些提取出来的信息转成CAD系统能识别的建模操作最好是带参数历史的那种而非一次性网格。这两件事单独看都不算新但组合在一起就比较麻烦。语言理解是自然语言处理的活儿几何建模是CAD内核的活儿中间还隔着一层“如何把语义变成几何操作”的鸿沟。text-to-cad正是为这道鸿沟搭桥。1.2 为什么“生成代码”比“直接生成模型”更靠谱当年这个想法刚出来的时候主流直觉是训练一个神经网络从文本直接回归出体素、点云或者SDF场。后来大家发现这条路越走越窄。原因很简单端到端生成的东西通常是一堆离散点或者一个带噪网格来之不易也无法在CAD软件里编辑。你拿一个STL三角网格去做工程变更等于让裁缝拿着一块石头改西装。真正过得硬的做法是让模型生成程序化建模指令——也就是CAD脚本或者参数化建模操作序列。这个选择背后的逻辑很实际。至少有三点让我坚持这条路线第一可编辑性。脚本是文本参数是变量想改尺寸就改数字想改特征就改代码改完重新执行一次即可。工程上最珍贵的就是“改得动”。第二精度。脚本让CAD内核去算几何圆弧就是圆弧、平面就是平面、圆柱面就是圆柱面全部是精确的解析曲面而不是成千上万个三角形模拟出来的假曲面。第三LLM的特性。大语言模型训练的时候见过大量的代码和结构化文本让它们输出JSON、脚本、函数调用远比让它们从无到有发明一串顶点坐标靠谱。换句话说模型做“翻译”很擅长做“几何发明家”很不擅长。我常拿一个生活类比文生3D像是让AI用笔画一张桌子看着神似但尺寸靠猜text-to-cad是让AI写一张木工下料单老师傅照单子就能加工出一张能用的桌子。CAD领域要的是下料单不是画。2. 核心技术路线拆解2.1 一条能落地的处理链路自然语言 → 中间表征 → CAD脚本我的习惯是先画一条清晰的处理链路再动手写代码。目前我个人认为最稳的text-to-cad落地链路是四段式自然语言输入先交给大语言模型做语义抽取得到一份结构化的中间表征。这份中间表征建议用JSON因为它结构清晰、LLM不容易胡写、程序也好解析。然后把这份JSON交给一个自己写的执行器翻译成目标CAD软件的动作序列最后在CAD软件里执行并导出标准格式。为什么要加一道“中间表征”直接让大语言模型输出CAD脚本不行吗我试过效果时好时坏。问题在于CAD API往往很长很绕模型记不住精确的函数签名也要碰运气才能蒙对参数顺序。稍微错一个括号、写错一个属性名脚本直接跑不起来。而且不同CAD软件脚本长得天差地别绑定太死没有复用价值。如果让模型只输出一份结构简单的JSON事情就变得可控多了。JSON里只需要“有哪些实体、尺寸多少、放在哪里、做什么布尔运算”这些是人类语义层面的东西大语言模型学得很好。真正和CAD API打交道的脏活交给执行器这一层代码是死的、可测的、保证不会语法错。这套方案最明显的胜出点在于分工大模型负责“懂人话”代码负责“懂CAD”。两边各做各擅长的部分中间用JSON当翻译本谁也不用强行越界。2.2 中间表征怎么设计才不容易翻车中间表征设计是整个链路最关键的地方。设计得好后面执行器写起来省一半力气设计得不好你就会整天收到“非法JSON”、“缺少必要字段”、“布尔运算目标引用不到”之类的报警。我的设计原则可以概括成三句话先原子后组合、尺寸显式化、运算顺序显式化。先原子后组合的意思是不要指望模型一次“想出来”一个复杂的带圆角带孔带加强筋的零件。而是让它先定义出若干基础实体比如块、圆柱、圆锥、圆环再定义一堆布尔运算把它们合并或者切掉。这个思路对应的是最经典的参数化建模流程先拉伸出一个毛坯再在上面打孔、挖槽、加筋。尺寸显式化就是要避免“大一点”、“薄一点”这种模糊词出现在JSON里。所有几何参数必须给具体数值。遇到用户说“薄一点”怎么办我目前的处理方式是让模型给一个合理默认值并在JSON里加一个confidence字段标记该尺寸是用户明确给的是推导出来的。这样一来后处理的人一眼看得出来哪里可能需要二次确认。运算顺序显式化则是很多人容易忽略的坑。模型输出的JSON如果先执行了差集再执行并集和先并集再差集结果可能完全不同。所以中间表征里必须包括一个有序的operations列表每一步是加料还是减料顺序必须严格按照建模逻辑。这里给你一份我常用的最小JSON Schema不算严谨但足够干活{ units: mm, primitives: [ {id: base, type: box, size: [120, 80, 10]}, {id: hole_1, type: cylinder, radius: 5, height: 10} ], operations: [ {op: union, target: scene, source: base}, {op: difference, target: scene, source: hole_1, location: [10, 10, 0]} ] }正常情况下我们会在原始描述里多给一条约束所有未指定的圆孔方向默认为垂直向下或垂直于对应平面。因为工程对象里绝大多数孔都是垂直于加工面的把它做成默认规则能减少一半的语义歧义。2.3 校验回路让模型自己先审一遍大语言模型这东西谁用谁知道它总会偶尔给你来点惊喜。比如把直径60写成半径60把“四个孔均布”理解成排成一排。我的做法是加一道双向校验回路。第一道是对大模型输出的JSON做语法和合法性校验。解析失败就打回去让模型重新生成。缺失关键字段比如没有operations也要打回去。这一步干的就是“挡掉语法错误和低级幻觉”。第二道是几何层面的理性校验。执行器解析JSON后先估算体积和用户描述的常识对照一下比如一个120x80x10的板体积应该是96000立方毫米减去四个孔之后大约是92858立方毫米。如果生成模型实测体积差得离谱那一定哪里出了问题直接中断并交给模型自纠。这一步听起来麻烦但实际收益很大。CAD模型生成不像网页生成错一毫米不会显示成乱码而是默默变成一个错误零件。如果能在建模阶段就把量级错误拦住后面就能少摔好多次跟头。3. 实操搭一个能跑通的text-to-cad最小方案3.1 工具选型与整体结构“最小方案”的意思是用最少的代码先把链路跑通以后再加功能。我的建议是大语言模型API选一个支持结构化输出的当前主流模型就好执行器用Python写三维内核用某款开源的脚本化CAD软件来承载。我这么说是有原因的。大模型承担的是语义解析每次调用输出JSON不需要做真正的几何计算。执行器做的是把JSON翻译成脚本化CAD软件能听懂的命令这个时候Python的灵活性就很关键。开源脚本化CAD软件则负责最终把脚本变成精确的三维实体。这一套下来每一层都各司其职整体验证起来非常快。整体结构大概是这样def text_to_cad(user_input): cad_json parse_to_json(user_input) # 调大模型得到结构化描述 validate_json(cad_json) # 语法和字段校验 script generate_script(cad_json) # Python执行器转成CAD脚本 execute_in_cad(script) # 在脚本化CAD工具里建模并导出这段伪代码对应了整条链路的核心骨架。我自己开发的时候会在generate_script这个函数里加很多日志打印出每一步生成的几何操作。因为一旦出问题你能立刻知道是模型理解错了还是执行器翻译错了排查效率高出不少。3.2 用结构化提示词约束大模型输出我见过很多人让大模型自由发挥结果当然是花样百出。既然前面已经定了中间表征格式提示词就应该把模型“关”在一个固定的JSON框架里。我通常会在系统提示词里写四类内容角色定义、输出格式、单位约定、兜底规则。角色定义一般是“你是一个机械设计助手负责把用户的需求解析为结构化JSON”。输出格式直接贴上JSON模板并且强调只能输出JSON不许解释、不许加Markdown代码块标记。单位约定设为毫米并且提示所有尺寸默认是毫米。兜底规则则是“如果用户描述缺少尺寸给出一个合理的工程默认值并在对应字段里标注来源”。提示词里我对尺寸来源字段的要求最细。我们取一个字段名比如size_source它有“user”和“inferred”两个值。用户明确说的填user模型猜的填inferred。这招在后续人工复核时极其好用。有一次批量建模很多孔的深度是模型猜的后处理的人只筛选inferred字段瞬间就定位到所有需要确认项省了不少事。另外还有个小技巧让模型在返回JSON前先“自我复述”一遍关键尺寸。比如在JSON里增加一个summary字段把“底板120x80x10四个孔直径10位于四角”这种话写出来。因为复述的过程会强迫模型重新过一遍语义能明显降低尺寸漏掉和错位的概率。3.3 执行器与几何验算当大模型吐出JSON之后就轮到执行器干活了。执行器的逻辑其实很简单遍历primitives创建基础实体遍历operations按照顺序做布尔运算或者移动操作。我推荐把执行器写成“图元解释器运算执行器”两个类。图元解释器负责把JSON里的box、cylinder、cone翻译成脚本化CAD软件的基础图元调用。运算执行器负责把union和difference翻译成对应的布尔运算。这样不管将来换CAD内核还是换JSON格式都只改一层不会牵一发动全身。下面是我常用的一段核心逻辑示意def generate_script(cad_json): lines [] for prim in cad_json[primitives]: lines.append(create_primitive(prim)) for op in cad_json[operations]: lines.append(create_boolean(op)) return \n.join(lines)这里面的create_primitive和create_boolean每个工具各不相同但接口只要稳定后面非常省心。几何验算是很多demo里被忽略的一步但恰恰是最值得做的。以开头那个例子的底板为例毛坯体积120乘80乘10等于96000立方毫米每个孔直径10、半径5、深度10体积就是π乘5的平方乘10约785.4立方毫米4个孔合计约3141.6最后模型的实际体积大约是92858立方毫米。执行器跑完我们可以让脚本化CAD软件返回实体的体积属性把这个值和理论值对比。误差在1%以内说明布尔运算执行成功误差大了几乎可以断定某个孔没切上或者切漏了。这个验算动作看起来死板但它能自动筛掉大量低级错误比人眼盯屏幕可靠多了。4. 常见翻车现场与排查经验4.1 尺寸老是错不是数值错而是单位错我在实测中遇到最多的一类问题是尺寸整体差了1000倍。比如用户说“外径80毫米”生成的模型实测尺寸是0.08毫米。为什么会这样因为默认情况下有相当一部分开源建模工具把数值理解成“单位制内部量”而大模型有时会在JSON里漏掉units字段或者跑偏成米制。我的排查方法很简单第一件事永远看JSON里的units字段。第二件事看summary复述里有没有“毫米”字样。两处都没问题再看执行器里有没有偷偷做单位换算。单位错误是低级错误但低级错误最坑人因为它不报错只是成品静悄悄小一千倍。我的对策是在提示词里写死“所有输出单位为毫米”并在JSON Schema里把units设置为必填字段合法的值只有mm这一种。校验时如果units不是mm就直接打回。粗鲁但有效。4.2 坐标和布尔运算引发的消失面与飞孔还有一种极常见的问题孔没打在板上飞在半空中或者布尔运算失败导致整个零件消失。原因多半出在坐标基准不一致。大模型理解的“孔位于左上角位置”和CAD脚本化工具默认的坐标系原点根本不是一个概念。你说“左上角”它认为那是X负Y正你说“四角均布”它不知道角上还要留出边距。后来我在prompt里强制增加一条规则所有几何位置必须以零件最小包围盒的XY平面为基准原点取零件中心并且孔位坐标必须是相对零件的坐标不是绝对世界坐标。这样一改大量位置错误瞬间消失。布尔运算出问题也同样常见。原因通常是操作顺序不对或者是差集的目标引用错了。比如你想切孔JSON写成了union或者把hole的实体直接加进去孔就变成一个凸起圆柱。我建议把布尔运算和几何实体的定义彻底分离这样模型只需要关心“哪些部分留着、哪些部分干掉”不用去猜具体API的运算名。4.3 生成结果没法编辑导出格式不对有个朋友拿我给的方案去试兴奋地跑出一个零件接着就傻眼了导出的是STL网格拿到CAD软件里只能当哑巴模型看尺寸也改不了。这个问题根子上是因为脚本化CAD工具默认导出格式往往是STL但你真正交给生产线的应当是STEP或者原生参数化文件。解决办法是执行器负责一键导出多种格式至少包含STEP和原生脚本格式。STEP是国际通用的CAD交换格式能保留B-rep精确曲面别人拿过去能切开、能延伸。原生脚本格式则保留了建模全过程随时可以改参数重新生成。只有STL只适合3D打印或者做渲染预览。所以排查任何“不能编辑”问题第一步就是看导出后缀。是STL就别抱怨不能编辑换STEP再看。4.4 问题速查表备查我把自己踩过的坑整理成一张速查表挂在项目文档里协作的时候很管用。异常现象最可能原因排查方向对应解法零件整体小/大1000倍单位制冲突查看units字段强制mm并校验必填孔不在实体上坐标基准不一致检查位置字段定义改用相对坐标默认平面零件变成两个体布尔运算失效检查布尔类型运算实体与目标实体分离孔变凸台union/difference写反检查operation顺序用模板限制可用op类型JSON解析失败模型输出多余文本检查返回内容系统提示词强制纯JSON网格模型不可编辑导出了STL查看导出文件后缀改为STEP原生脚本尺寸是猜的心里没底缺少来源标注检查size_source标注inferred字段方便复核这张表不解决所有问题但能把你从深夜调试的崩溃边缘拉回来。5. 应用场景、人群与边界5.1 哪些场景真的受益我发现text-to-cad最立竿见影的场景不是复杂精密设计而是“标准件变参数”这种重复劳动。比如法兰盘、安装支架、基座板、电机座这类零件结构形式固定只有尺寸和孔位变化。传统流程是每次重新建模现在一句话改参数就能出新模型效率完全不在一个量级。创客和3D打印用户也很适合。很多玩家脑海里有个大概形状直接描述出来几分钟后就能得到可打印的STL。不用学繁琐的建模软件需要的只是把需求说清楚。早期概念设计阶段也很实用。工程师在方案阶段往往只需要一个大致的装配布局确定空间够不够、孔位对不对得齐。这个阶段用text-to-cad快速出草模比手动建模快得多而且后续还能继续迭代参数。5.2 短期内别指望它干什么看得清边界才不会被失望绊倒。现在的text-to-cad在下面几类问题上还远谈不上替代人工第一自由曲面和艺术造型。“做一个像水滴一样的曲面外壳”这种需求靠程序化形状拼装很难做出来还是要靠曲面设计软件手工操作。第二大型装配体。比如整台设备几十上百个零件之间的装配关系、运动约束、干涉检查这已经超出“从文本生成模型”的范畴属于系统工程不是一句话能解决的。第三有严苛制造约束的零件。生成的模型可能几何上正确但CAM工艺上不合理比如孔间距太近导致壁厚不足或者加强筋位置不利于模具脱模。这类问题需要制造知识把关目前模型显然还做不到。text-to-cad的定位更像是一位“手速很快的建模助理”而不是“资深结构工程师”。它能帮你把头脑里的想法快速变成三维草稿但最终能不能下车床、能不能开模具仍然需要人来判断。按照我个人的使用习惯现在最顺手的工作流是口述需求生成第一版模型然后打开脚本化CAD工具调整关键参数确认没问题后再导STEP给结构同事评审。一次两次可能没有感觉用多了你会发现真正为你省时间的不是建模那十分钟而是后续少改的那好几轮。如果你的工作里也有大量“换个尺寸重新画一遍”的需求text-to-cad这个方向非常值得你花一个周末把最小链路搭起来再下结论。