
1. 从一句话到三维模型text-to-cad 到底在解决什么问题第一次听到 “text-to-cad” 这个词我脑子里蹦出来的画面是对着电脑敲一句“给我画一个 80 毫米见方的法兰盘中心开 30 毫米通孔四角各一个 M6 螺栓孔”然后屏幕上就自动生成一个可以导出 STEP 的实体模型。这个画面在几年前还属于科幻范畴但最近一两年随着大语言模型和 agent 架构的成熟它已经变成了一个可以动手复现的工程项目。所谓 text-to-cad本质上是把自然语言描述转换成 CAD 可识别的几何建模指令最终产出 STEP、URDF 这类标准格式文件的一套系统。它要解决的核心痛点很直接传统 CAD 建模需要人熟悉软件操作、坐标系、约束逻辑学习曲线陡峭而大量重复性、参数化的建模需求其实可以用语言描述清楚没必要每次都手动点草图、拉伸、倒角。这套东西适合谁我觉得有三类人值得关注。第一类是机械、机器人领域的工程师尤其是做 URDF 导入 Coppeliasim 这类仿真工作的经常需要快速生成一批结构相似的零件模型手工建模效率太低。第二类是做 agent 开发的开发者text-to-cad 本身就是一个非常典型的 agent 应用场景涉及工具调用、代码生成、结果校验的完整闭环拿来练手 agent 架构再合适不过。第三类是对 AI 辅助设计感兴趣的爱好者哪怕你只是想知道“AI 画图”在工程领域到底能做到什么程度这个项目也能给你一个清醒的认知。需要提前说明的是text-to-cad 目前并不是要取代 CAD 工程师它更像是一个“建模加速器”把语言层面的意图快速转成可编辑的几何草稿后续的精修、装配、工程图还是得靠人。我在实际折腾这套流程的过程中最大的感受是难点根本不在“生成代码”这一步大语言模型写 OpenSCAD 或者 CadQuery 脚本已经相当熟练了真正的坑在于如何保证生成的几何是有效的、尺寸是合理的、导出格式是下游软件能吃的。这也是为什么 text-to-cad 必须和 agent 架构绑在一起讲——单纯的文本生成模型给不了你可靠的结果只有加上工具调用、执行反馈、错误重试的 agent 循环才能把“一句话”稳定地变成“一个能用的 STEP 文件”。2. 整体架构设计为什么 text-to-cad 必须是一个 agent 而不是一个模型2.1 从“文本到代码”到“文本到几何”的关键跨越很多人对 text-to-cad 的第一反应是这不就是让 GPT 写一段 CAD 脚本吗这话对了一半。文本到代码确实是核心环节但代码到几何之间还隔着一道鸿沟。大语言模型生成的建模脚本语法可能没问题但几何逻辑经常出岔子——比如布尔运算的顺序搞反了导致实体被减没了或者圆角半径大于了相邻边的长度导致建模失败又或者坐标系定义混乱导致零件朝向不对。这些问题在纯文本层面是看不出来的必须真正执行一遍才能暴露。所以 text-to-cad 的系统设计里执行环节是不可省略的。一个完整的流程应该是用户输入自然语言描述agent 解析意图并选择合适的建模后端生成对应的建模脚本调用本地或云端的 CAD 内核执行脚本捕获执行结果和错误信息如果失败则根据错误反馈让模型修正脚本并重试成功后导出 STEP 或 URDF 文件最后可选地渲染一张预览图给用户确认。这个循环就是典型的 agent 执行闭环和那些只会聊天的模型有本质区别。2.2 建模后端选型OpenSCAD、CadQuery 还是直接调 CAD 内核选哪个建模后端直接决定了整个项目的技术栈和最终能导出的格式。我对比过几种主流方案各有取舍。OpenSCAD 是最容易上手的它的脚本语言接近声明式大语言模型对它的掌握程度也最高生成成功率相对可观。缺点是 OpenSCAD 的几何内核能力有限复杂曲面和高级倒角支持得不好而且它原生导出的是 STL 和 CSG要转 STEP 需要额外的转换步骤转换过程中还可能丢失拓扑信息。如果你的目标只是快速验证概念、生成用于 3D 打印的网格模型OpenSCAD 够用。CadQuery 是基于 OpenCASCADE 的 Python 建模库这个就专业多了。OpenCASCADE 是工业级的几何内核CadQuery 能直接导出 STEP几何精度和拓扑完整性都有保障。CadQuery 的 API 是链式调用风格写起来比较符合编程直觉大语言模型生成 CadQuery 代码的质量也在逐步提升。缺点是 CadQuery 的安装依赖稍微麻烦一点而且模型对 CadQuery 某些高级 API 的掌握不如 OpenSCAD 那么熟练复杂模型需要多轮修正。我个人的建议是如果下游需要 STEP 或者要做 URDF 导入仿真优先选 CadQuery一步到位省得后面转换折腾。还有一种思路是直接调用商业 CAD 的 API比如通过脚本驱动本地安装的 CAD 软件建模。这种方案生成的模型质量最高因为用的就是原生内核但依赖具体软件的授权和接口开放程度部署起来重不太适合做轻量化的 agent 项目。对于 text-to-cad 这种偏实验性质的项目我倾向于用 CadQuery 作为主力后端OpenSCAD 作为备选两者结合覆盖大部分场景。2.3 agent 架构的核心组件拆解一个能跑的 text-to-cad agent至少需要这几个组件。意图解析模块负责把用户的自然语言拆解成结构化的建模需求比如识别出零件类型、关键尺寸、特征列表。这个环节可以用大语言模型加结构化输出约束来实现让模型输出 JSON 格式的需求描述而不是直接写代码。代码生成模块根据结构化需求生成建模脚本这里要给模型提供清晰的 API 文档和几个示例few-shot 的效果比零样本好很多。执行沙箱负责安全地运行生成的脚本因为模型可能生成死循环或者资源消耗巨大的代码必须限制执行时间和内存。错误处理模块捕获执行异常把错误信息翻译成模型能理解的反馈驱动重试。导出模块负责把成功的模型转成目标格式STEP 用 CadQuery 原生导出即可URDF 则需要额外处理关节和链接的层级关系。这套架构里我觉得最容易被低估的是错误处理模块。很多人做 demo 的时候只跑成功案例一旦模型生成的代码报错就卡住了。实际上让 agent 能够读懂错误、自我修正才是从玩具到工具的关键一步。我在实践中的做法是把常见的几何错误分类比如“布尔运算结果为空”“圆角失败”“尺寸超出边界”等针对每类错误给模型一个简短的修正提示这样重试的成功率会明显提高。3. 核心细节解析自然语言到建模脚本的转换要点3.1 需求结构化把模糊描述变成确定参数用户说“画一个支架”这句话对人来说都需要追问对 agent 来说更是无法直接执行。所以第一步必须做需求结构化把自然语言里的关键信息抽取成明确的参数。我通常会让模型输出一个包含零件类型、整体尺寸、特征列表、约束条件的 JSON。比如“一个 100x60x8 毫米的底板四角各一个直径 6 毫米的孔孔中心距边缘 10 毫米”结构化成底板尺寸、孔数量、孔径、边距这几个字段。这里有个经验不要让模型自由发挥补全缺失参数而是明确标注哪些参数是用户给定的哪些是模型假设的。假设的参数要在最终输出里提示用户确认避免模型自作主张导致尺寸错误。我在早期版本里吃过亏用户说“画个法兰”模型自动补了一堆尺寸结果生成的模型和用户预期完全不符返工成本很高。后来改成缺失参数必须显式标注并给出默认值建议用户确认后再生成体验好很多。3.2 建模脚本生成的提示词设计提示词的质量直接决定生成脚本的可用率。我的提示词模板大概包含这几块角色设定让模型扮演熟悉 CadQuery 的工程师API 参考列出常用的建模函数和参数说明输出格式约束要求只输出可执行的 Python 代码不加解释示例演示给两到三个从简单到复杂的完整案例最后是本次的具体需求。这个结构看起来简单但每一块的细节都很讲究。API 参考部分不能只列函数名要给出参数类型和返回值说明最好附上一行调用示例。比如box(length, width, height)要说明三个参数都是浮点数单位是毫米返回一个 Workplane 对象。示例部分我建议覆盖“纯拉伸”“带孔”“带圆角”“布尔运算”这几种典型场景让模型有参照。输出格式约束里一定要强调不要用show_object之类的预览函数因为我们要的是可导出的实体不是可视化对象。这些细节看起来琐碎但每一条都能减少一类失败。3.3 执行沙箱的安全与资源控制生成的脚本必须放在受控环境里执行这一点不能省。我见过模型生成过带while True的代码也见过递归调用把自己跑爆的。沙箱的基本要求是限制执行时间比如 30 秒超时限制内存使用比如 2GB 上限禁止网络访问和文件系统写入只允许在指定目录导出结果。Python 里可以用subprocess加超时参数来实现更严格的话用容器隔离。资源控制之外还要考虑几何有效性检查。脚本执行成功不代表模型有效可能生成了一个空实体或者自相交的曲面。CadQuery 提供了一些校验方法比如检查实体的体积是否大于零检查导出的 STEP 文件大小是否合理。我一般会在导出前加一道校验体积为零或者文件异常小的情况直接判定失败触发重试。这道校验帮我拦下了不少“看起来成功实际是空壳”的案例。4. 实操过程从零搭建一个可用的 text-to-cad 流程4.1 环境准备与依赖安装先说明一下CAD 软件的安装和激活不在本文讨论范围我们走的是纯代码路线不依赖任何商业 CAD 软件的本地安装。核心依赖是 Python 环境加 CadQuery。我建议用 conda 创建独立环境因为 CadQuery 依赖的 OpenCASCADE 库通过 conda 安装最省心。创建环境后安装 cadquery 包再装一个用于调用大语言模型的 SDK以及用于结构化输出的辅助库。安装完成后做个简单验证写一段三行的 CadQuery 脚本生成一个立方体并导出 STEP能跑通说明环境没问题。这一步看似简单但 OpenCASCADE 的依赖链比较长不同操作系统上可能遇到库版本冲突提前验证能省去后面排查的麻烦。如果导出 STEP 时报错大概率是 OpenCASCADE 相关依赖没装全重新用 conda 安装 cadquery 通常能解决。4.2 需求解析模块的实现需求解析模块的输入是用户的一句话输出是结构化 JSON。我用的是大语言模型的函数调用能力定义一个parse_requirement函数参数包括零件类型、尺寸字典、特征列表。提示词里给出几个解析示例让模型学会把“边长 50 的立方体上面挖一个直径 20 深 10 的圆孔”解析成{type: cube, size: {edge: 50}, features: [{type: hole, diameter: 20, depth: 10, position: top_center}]}这样的结构。这里的关键是特征描述要足够通用能覆盖孔、槽、圆角、倒角、阵列这些常见操作。我设计特征结构的时候参考了 CAD 软件里特征树的组织方式每个特征有类型、参数、作用面或作用边。位置描述用相对坐标或者命名面比如“顶面中心”“底面四角”避免让模型直接算绝对坐标减少出错概率。实测下来这种半结构化的描述比让模型直接输出坐标数值要稳定得多。4.3 代码生成与执行闭环代码生成模块拿到结构化需求后拼装提示词调用模型生成 CadQuery 脚本。脚本写到一个临时文件里然后交给沙箱执行。执行结果分三种情况成功且几何有效进入导出环节执行报错把错误信息回传给模型要求修正执行成功但几何无效同样回传校验失败信息要求修正。重试次数我设的是 3 次超过就返回失败并附上最后一次的错误信息让用户决定是调整描述还是手动介入。这个闭环里有个细节值得说错误信息的翻译。Python 的报错堆栈对模型来说信息量太大直接丢回去效果不好。我会提取关键错误行和错误类型用自然语言描述成“布尔减运算失败可能是因为减去的实体与目标实体没有交集”这样的提示模型理解起来更准。这个翻译层是提升重试成功率的关键虽然写起来有点繁琐但值得投入。4.4 导出 STEP 与 URDF 的处理差异STEP 导出相对直接CadQuery 的exporters.export方法指定格式即可。需要注意的是单位CadQuery 默认单位是毫米导出 STEP 时保持一致避免下游软件读取时出现尺寸缩放问题。另外导出前建议做一次几何清理比如合并共面、移除微小边这样导出的 STEP 在别的软件里打开时拓扑更干净。URDF 导出就复杂一些因为 URDF 描述的是带关节的机器人模型不是单个零件。如果用户的需求是生成一个多连杆机构agent 需要把每个连杆分别建模然后按照关节关系组装成 URDF。这里涉及坐标系变换和关节轴定义模型容易搞错。我的做法是让 agent 先生成各个零件的 STEP再单独生成一个描述关节关系的配置文件最后用一个脚本把两者合并成 URDF。这样分工明确每步的出错概率都降低。导入 Coppeliasim 之前建议先用 URDF 校验工具检查一遍确认链接和关节的层级没有循环引用。5. 常见问题与排查技巧实录5.1 生成脚本执行失败的典型原因实际操作中脚本执行失败的原因集中在几类。最常见的是 API 用法错误模型把 CadQuery 的方法名记混了或者参数顺序搞反了。这类问题通过完善提示词里的 API 参考能大幅减少。第二类是几何逻辑错误比如在不存在的位置打孔或者圆角半径过大。这类问题需要执行后才能发现靠错误反馈重试解决。第三类是数值问题比如尺寸算出来是负数或者零导致建模失败。这类问题可以在需求解析阶段加一道数值合理性校验提前拦截。我整理了一个常见错误对照表方便快速定位。错误现象可能原因排查方向执行超时脚本含死循环或复杂布尔运算检查循环逻辑简化运算实体体积为零布尔运算顺序错误或参数无效检查减运算的实体是否有交集圆角失败半径大于相邻边长度减小半径或调整边选择导出 STEP 报错几何拓扑不完整执行几何清理后再导出URDF 导入仿真失败关节轴或坐标系定义错误校验 URDF 结构检查关节轴5.2 几何有效性校验的实操心得几何有效性校验这一步我踩过不少坑。最开始只检查脚本有没有报错结果导出的 STEP 在 CAD 软件里打开是一片空白因为生成的是空实体。后来加了体积检查又发现有些实体体积正常但存在自相交下游做仿真时会出问题。现在的做法是三重校验体积大于零、包围盒尺寸与需求匹配、导出文件能被重新读取。第三重校验最严格用 CadQuery 重新导入导出的 STEP能成功读取且体积一致才算通过。这套校验会增加一些执行时间但相比把有问题的模型交给下游导致的返工这点开销完全值得。尤其是做批量生成的时候自动校验能拦住大部分低级错误人工只需要处理校验不通过的少数案例。5.3 提升生成成功率的几个实用技巧第一个技巧是给模型提供“零件模板库”。与其让模型从零生成不如预置一批常见零件板、轴、法兰、支架的参数化模板模型只需要填充参数和添加特征。这样生成成功率能提升一大截因为模板本身是验证过的模型只需要做参数替换和特征叠加。第二个技巧是分步生成复杂零件拆成几个简单特征依次生成每步验证通过再进入下一步避免一次性生成一大段代码出错后难以定位。第三个技巧是保留历史成功案例把每次成功生成的脚本和对应的需求描述存起来下次遇到相似需求时作为 few-shot 示例喂给模型效果比通用示例好得多。提示不要追求一次生成完美模型把目标定为“生成一个可编辑的草稿”后续人工精修。这个心态调整后对生成质量的容忍度会合理很多整体效率反而更高。5.4 与下游工具链的衔接注意事项text-to-cad 生成的模型最终要进入下游工具链衔接环节有几个坑。导出 STEP 时注意版本不同 CAD 软件对 STEP 版本的支持不一样AP214 兼容性最好。如果下游是仿真软件注意模型的坐标系朝向最好在生成时就统一成 Z 轴向上。URDF 导入 Coppeliasim 时注意关节的初始位置和限位设置这些在 URDF 里定义不清楚的话仿真时会出各种奇怪现象。我的建议是在 text-to-cad 的输出里附一份元数据文件记录模型的单位、坐标系约定、关节参数下游导入时有个参照减少沟通成本。6. 这套流程的边界与我的实际体会折腾 text-to-cad 这段时间我对它的能力边界有了比较清醒的认识。它擅长的是参数化、规则明确的零件比如板类、轴类、简单支架这些用语言描述清楚后生成的成功率很高。它不擅长的是自由曲面、复杂装配、需要工程判断的结构这些还是得靠人。所以我的定位很明确text-to-cad 是建模流程的前段加速器把重复性的、描述清晰的建模需求自动化让人把精力放在真正需要创造力和工程经验的地方。另外一点体会是agent 架构的可靠性比模型能力更重要。同样的模型加上执行反馈和重试循环后端到端的成功率能翻好几倍。所以如果你打算做类似的项目别在模型选型上纠结太久把精力花在错误处理、校验、重试这些工程环节上回报更明显。最后分享一个小技巧把每次失败的案例和修正过程记录下来定期整理成新的提示词示例系统的成功率会随着使用逐步提升这个正反馈循环是这套方案最让人舒服的地方。