1. text-to-cad 是什么,这玩意到底能干什么
第一次听到 text-to-cad 这个词的人,大概率会把它理解成“用一句话让 CAD 软件自动画图”。说实话,这个理解方向没问题,但只讲对了三分之一。当前社区里讨论的 text-to-cad,更多是指把自然语言描述自动转换成可编辑、可加工、可再参数化的三维模型,而不是简单地把文字渲染成一堆三角形网格。
我最早接触这个方向是帮一个机械制造团队做前期选型评估。他们手里有大量老图纸的纸质说明,希望让工人直接说一句“直径20的孔,深度15,均布4个”,系统就能在三维模型里把特征建出来。项目最后没有完全落地,但那次调研让我把 text-to-cad 这条路从原理到工程化走了一遍,踩了不少坑,也积累了一套相对成熟的判断标准。这篇博文就把我看到的、验证过的、还没验证但方向靠谱的内容,一次讲清楚。
text-to-cad 真正解决问题的场景有三类:一是把口语化或非结构化的需求快速变成三维模型,减少从需求到建模的等待时间;二是让不懂传统 CAD 操作的人也能参与早期设计,比如产品经理直接描述一个外形;三是把大量重复性建模工作半自动化,比如根据文字参数批量生成标准件或族库。
适合看这篇文章的人,主要是机械设计师、结构工程师、工业软件开发者、自动化脚本爱好者,以及正在评估 AI 辅助设计流程的团队负责人。如果你对参数化建模有一点基础,阅读起来会非常顺畅;即使你只是听说过 CAD,我也尽量把概念掰开讲。
2. text-to-cad 的核心逻辑与三条主流技术路线
想要真正理解 text-to-cad,不能只把它当成“AI 魔法”。任何称得上实用的系统,背后都要回答一个问题:自然语言里那些模糊、省略、隐含的信息,如何被转换成无歧义的几何参数和特征树?这比想象中难得多。
2.1 从语言到几何:中间必须有一个“参数桥梁”
最早我想当然地认为,只要用大模型把用户输入翻译成一堆坐标点,就能生成模型。实际做下来发现,坐标点只是低层次的表达,真正有用的是参数化建模语言里的“特征”,比如拉伸、旋转、打孔、倒角、阵列。一句话“在板上开四个间距40的孔”,落在模型里不是四个坐标点,而是一个“孔特征”加上“线性阵列”的参数定义。
所以整套系统的核心不是把文字转成网格,而是把文字转成一组结构化的参数指令。这组指令的格式可以自定义,但必须包含三样东西:特征类型、几何参数、特征之间的约束关系。
我用一个最小示例来说明。用户输入:
一个半径5的圆柱,高度20,底面放在原点。期望的中间指令大致是:
Feature: Cylinder Parameters: radius=5, height=20, placement=(0,0,0)这就是“参数桥梁”。后面的建模引擎读到这段指令后,自动生成一个可编辑的参数化模型,而不是一个固定的网格。这条路径最大的好处是:模型后续可以改参,可以装配,可以出工程图,加工时也不会因为网格误差出问题。
2.2 路线一:规则加正则表达式的轻量方案
最朴素的实现方式是:先对用户输入做关键词识别,再用正则或有限状态机抽取参数。比如把“半径”“直径”“高度”“深度”“间距”“数量”这类词做成字典,然后匹配数字和单位。
这套方案的好处是轻量、容易解释、几乎不用训练,适合输入比较标准化的场景,比如“直径10的孔”“长度50的槽”。坏处也很明显:遇到“在板的左上角挖一个圆孔”这样的表述,正则根本无从下手,因为“左上角”是一个相对方位,需要结合板的尺寸才能算出位置。
我在做模拟项目 X 时,先用正则方案做了个原型,只支持“圆柱”“长方体”“孔”三类特征,准确率大概有八成。但测试集里一旦加入“距离右边10”“居中”这类补充说明,准确率直接掉到四成。这说明没有语义理解能力,系统就非常脆弱。
2.3 路线二:大模型驱动的结构化抽取
现在更被接受的做法,是把自然语言理解交给大模型,让它输出严格的 JSON 或 DSL 指令。大模型负责从输入里提取实体和参数,同时补全被省略的信息。比如用户说“一个直径20、深度10的沉头孔”,模型不仅要识别特征类型是沉头孔,还要知道沉头直径、沉头深度、通孔直径、通孔深度分别是什么,甚至要依据默认的国标或厂标推断缺失值。
我在实际测试中发现,大模型的抽取能力确实比正则强很多,但必须做两件事才能稳定:
第一,输出约束必须非常严格。如果让模型自由发挥,它可能输出互相矛盾的参数,也可能用不存在的字段名。我的做法是在提示词里给出固定 JSON Schema,并且用一次校验函数把关,不符合 schema 的输出全部拒绝重试。
第二,上下文里要带单位体系。模型默认可能把“厚度3”理解成 3 毫米,但在某些行业里厚度 3 意味着 3 英寸。表述单位这件事不写明白,系统很快会在小数点后两位开始翻车。
2.4 路线三:端到端神经网络直接生成模型
第三条路更激进:输入文本直接走神经网络生成中间表征,再通过可微渲染或逆向建模生成 CAD 模型。这类方法在学术圈有不少实验,比如把文本编码成特征向量,然后解码成 B-rep 边界表示的参数序列。
我对端到端方案的评价是:方向很酷,但目前工程化门槛太高。主要原因有三个:数据难以获取,高质量带文本标注的参数化 CAD 模型公开数据集太少;生成结果不可控,即使模型结构准确,也经常出现面与面之间丢失约束;调试成本高,一个看似合理的模型可能无法在真实 CAD 内核里继续编辑。
所以现在我给团队的建议是:短期选路线一,中期选路线二,长期可以持续关注路线三但不要押注。大多数能在半年内产生价值的 text-to-cad 系统,都是大模型加参数化引擎的混合架构。
3. 手把手搭一套最小可用的 text-to-cad 系统
前面铺垫这么多,直接进入实操。这里我不会依赖任何特定商业软件,而是用一套完全虚构的轻量建模环境来演示逻辑。你可以把这套环境理解成“一个能解析参数化指令并生成三维特征的建模内核”,只需要 Python 解释器就能跑通全部逻辑。
3.1 系统整体结构
整个系统分成四层:
| 层级 | 作用 | 对应实现 |
|---|---|---|
| 输入层 | 接收自然语言文本 | 命令行或接口 |
| 解析层 | 把文本转成结构化参数指令 | 大模型调用加 JSON 解析 |
| 规则层 | 校验参数、补全默认值、处理单位 | 规则引擎脚本 |
| 建模层 | 根据指令生成三维特征 | 参数化建模引擎的封装函数 |
其中解析层和规则层是核心。建模层在很多 CAD 内核里已经有现成接口,关键在于把你自己的参数指令翻译成内核能识别的 API 调用。
3.2 定义参数指令的 Schema
大模型输出的中间指令必须足够稳定,我推荐用 JSON Schema 约束。一个圆柱特征的 schema 可以这样定义:
{ "type": "cylinder", "parameters": { "radius": {"type": "number", "required": true}, "height": {"type": "number", "required": true}, "axis": {"enum": ["x", "y", "z"], "default": "z"}, "position": {"type": "array", "items": {"type": "number"}, "length": 3, "default": [0,0,0]} } }这个 schema 看起来简单,但它在实际项目中帮了大忙。因为大模型只要严格遵守这个 schema,后续建出来的模型就肯定不会缺参数。
3.3 解析层:让大模型输出结构化 JSON
解析层的代码逻辑并不复杂,核心是构建一个严格的提示词模板。下面是我调整很多版之后比较稳定的写法:
def parse_natural_language(text): prompt = f""" 你是一个参数化建模指令提取器。 根据用户的自然语言,提取建模指令并输出 JSON。 必须使用以下 JSON Schema: {schema_json} 不允许输出其他文字。 用户输入: {text} """ response = call_llm(prompt) return validate_and_clean(response)你可以看到这里调用了一个call_llm函数,实际工程里你接哪个大模型接口都行。关键是validate_and_clean这步,它必须完成三件事:校验 JSON 格式是否正确、检查必填字段是否存在、对缺失字段填入默认值。
3.4 规则层:单位统一与默认值补全
很多第一次写 text-to-cad 系统的人都会忽略单位问题。用户的表达可能是“长度50”“50mm”“5厘米”“0.05米”,如果不统一,建模层就会失控。
我在规则层里维护了一张单位换算表,把毫米作为内部基准。所有输入参数在进入建模层之前,都被转成以毫米为单位的浮点数。这一步看似基础,但实际测试中单位错误是出现频率最高的 Bug 来源。
默认值补全也要放在这一层。比如用户只说了圆柱半径 10,没有说高度,系统就需要要么询问用户,要么使用默认高度值。我的建议是默认值必须显式标注,比如给圆柱默认高度 20,并在结果里回显“高度未指定,默认使用20毫米”,让用户知道模型被自动补全了信息。
3.5 建模层:把参数指令翻译成特征操作
建模层的代码可以用一种语义化的方式演示,不绑定具体 CAD 内核:
def create_cylinder(radius, height, axis="z", position=(0,0,0)): # 创建草图平面 sketch = new_sketch(plane=axis) # 添加圆形轮廓 circle = sketch.add_circle(center=position[:2], radius=radius) # 拉伸成圆柱体 solid = sketch.extrude(distance=height, direction=axis) return solid这段代码是伪代码,但结构上足够说明问题。你只需要把new_sketch、add_circle、extrude这些函数映射到你实际使用的 CAD 内核 API 上,模型就生成出来了。
我在开发中验证过一个经验:不要试图用文本直接驱动所有高级操作,比如“给这个面加一个复杂的放样特征”。当前大多数系统的稳定区域都集中在基本特征和阵列上,复杂曲面还是留给人工建模更靠谱。
3.6 完整调用链路
把前面四层串起来,一个最简单的调用示例如下:
user_text = "创建一个半径10、高度20的圆柱,底面在原点" params = parse_natural_language(user_text) validated_params = apply_rules_and_defaults(params) model = create_cylinder(**validated_params) export_step_file(model, "output.step")跑了这个流程之后,你会看到终端打印出结构化的参数,以及生成的 STEP 文件路径。拿到 STEP 文件后,任何主流 CAD 软件理论上都能打开,并且模型可以继续编辑。
这一步完成,你就拥有了一个真正的 text-to-cad 最小系统。尽管功能有限,但它已经具备了“自然语言到可编辑三维模型”的完整闭环。
4. 我在实践中踩过的坑与排查技巧
做 text-to-cad 最大的感受是:大部分问题不是模型不够聪明,而是工程链路里某个环节太脆弱。下面这些问题都是我实际遇到并解决过的,整理成速查表供你参考。
| 典型表现 | 真正原因 | 解决办法 |
|---|---|---|
| 明明输入“半径10”,模型却生成了直径20的圆柱 | 提示词没强调半径与直径区别 | 在 Schema 注释里明确写明“半径=直径的一半” |
| 输出 JSON 偶尔带多余说明文字 | 大模型没有严格遵守输出约束 | 增加解析失败重试机制,连续两次失败就召回人工 |
| 相同输入多次生成结果不一致 | 大模型采样温度过高 | 把采样温度调低,甚至设为 0 |
| 生成的模型在 CAD 里不能编辑 | 直接把文本转成了网格体 | 中间必须走参数化特征,而不是三角面片 |
| 单位错了但没报错 | 规则层没有做单位换算 | 所有输入先转毫米后再进入建模层 |
| 阵列数量是 0 导致模型消失 | 默认值补全逻辑有误 | 校验数值范围,0 和负数直接拒绝 |
4.1 提示词模板是性命攸关的事情
很多组队做这个方向的人,最不重视的就是提示词模板。他们喜欢让大模型自由发挥,然后自己写一堆后处理代码补救。我试过这条路,结果越补越乱。
我的做法是,把提示词当成接口文档来设计。开头直接定义角色,中间贴 schema,末尾写清约束,最后只让模型输出纯 JSON。为了更稳,我还会在模板里加上几个示例,比如“输入:长宽高分别为10、20、30的长方体;输出:{...}”。大模型少样本的效果,比你把规则写成长文有用得多。
4.2 参数校验别只检查“有没有”,还要检查“能不能”
刚上线的最小系统只要遇到负数半径、零长度、超大尺寸就崩。后来我加了一个validate_geometry_parameters函数,专门检查物理可行性。
比如半径必须大于 0,高度必须小于某个上限(根据建模环境而定),阵列数量必须是正整数。这些规则看起来简单,但缺了它们,模型库会被脏数据污染,后面再排查非常痛苦。
4.3 文本歧义:宁可直接问,不要瞎猜
系统最怕遇到“在板的中间打一个孔,距离左边远一点”这种描述。“远一点”是模糊量,我一开始选择默认取板的 30% 尺寸,结果用户根本不认可。后来我改成主动反问:“请明确孔到左边线的距离,以及孔的直径”,虽然多了一步交互,但生成结果的准确率大幅上升。
记住一个原则:模型可以把省略的参数补成默认值,但模糊到无法工程化表达的参数,必须原样返还给用户确认。
4.4 批量建模时要给模型加“指纹”
如果你用 text-to-cad 系统批量生成标准件,建议在每个模型的自定义属性里记录生成它的原始文本和模型版本。这样当某个模型出了问题,你可以快速回溯到是哪个文本、哪一版解析逻辑导致的,而不是全靠人工猜。
我在模拟项目 X 里就是这么干的。结果有一次模型批量异常,我用原始文本属性分分钟定位到是“深度”和“厚度”的语义冲突,半小时就修复了。没有这个指纹,恐怕得查一整天。
5. 怎么判断一个 text-to-cad 方案能不能落地
不管是自己写还是采购现成方案,最终都要回答一个问题:这套系统能稳定生产吗?我用三个维度来判断。
5.1 稳定性比花哨更重要
一个能正确处理 100 种复杂句式的系统,如果 10 次有 3 次生成错误模型,我就不敢用。相反,一个只能处理 20 种基础句式但准确率 98% 的系统,反而能立刻投入到标准件库里。做这类工具,稳定性是上线前提。
5.2 可编辑性决定了使用深度
如果生成出来的是“死模型”,那还不如直接要张图片。真正的 text-to-cad 必须让人能在模型树里看到特征、修改尺寸、调整位置。这也是我一直强调参数化特征的原因。
判断方法很简单:拿到生成模型后,尝试修改半径,看关联的拉伸特征会不会自动更新。如果能,说明中间走的是参数化链路;如果只能整体缩放或直接烂掉,那它只是披着 CAD 外皮的图片生成器。
5.3 模型库的成长性
好的 text-to-cad 系统不应该是一个黑盒,而是一个能持续沉淀特征的平台。每次人工修正模型后,系统最好能把修正结果回传,优化后续解析策略。说白了就是要有反馈闭环。我在项目中建立了一个“修正日志”,每次生成的模型被人工改过,就把改动的参数记录下来,定期用这批数据做微调或规则更新,效果提升非常明显。
6. 后续扩展方向与我个人的体会
系统做完基础版本后,可扩展的空间非常大。从我目前尝试过的方向看,至少有三个比较靠谱。
第一个方向是多特征组合。比如用户输入“底板长100宽60高5,四个角各一个半径6的圆角,中心挖一个直径20的通孔”,系统需要把这一连串特征解析成建模序列。一旦做到这一步,text-to-cad 就真正进入了“结构件快速设计”领域。
第二个方向是自动空间布局。比如“把这两个零件装配在一起,间距2”,系统要理解装配约束,这比生成零件本身复杂得多。我目前只在简单轴孔配合上做了实验,距离完全自动化还有很长的路。
第三个方向是参数化族库。把 text-to-cad 的能力封装成标准件入口,让用户用自然语言从库里拉出“铝合金型材 4040 长度500”,直接生成可采购的模型。这个方向离商业价值最近,也是我认为最快能产生回报的落地场景。
最后说说我的个人体会。做了这么多实验后,我最大的感受是 text-to-cad 不是单纯的自然语言处理问题,而是“语言理解”和“几何建模”两个老领域的交叉结合。你不可能靠一个大模型解决所有问题,也不可能靠一堆规则覆盖全部表达。真正能跑起来的方案,往往是让大模型做它擅长的事情——理解意图、抽取参数;再让传统规则引擎做它擅长的事情——校验、补全、建模和约束。两边各让一步,系统的效果就能往前走一大步。
如果你正打算上手这个方向,我建议你先别急着训练或调包,找一个最简单的建模场景,比如圆柱、孔、长方体阵列,把从文本到模型的闭环跑通。再小的闭环,也比挂在嘴上的大规划有用得多。过程中一定会遇到看不懂的参数和奇奇怪怪的语言表达,这些都是良性的,因为每解决一个,你手里的系统就更像一个能交给别人用的正经工具。