CAD

LLM生成CAD代码最吓人的不是“跑不起来”,而是“跑起来了、看起来对、但几何是错的”,或者编译通过之后用户一操作模型文件直接损坏,这种“沉默的几何错误”在真实项目里到底靠什么才能拦住?

👤 为我痴狂 👁 77 阅读 ❤ 0 点赞 ➦ 0 分享 📅 2026-10-29
首页› 理学› CAD› 正文
沉默的几何错误:LLM生成CAD代码的失效机理与分层拦截体系
核心指标
几何语义保真度
失效类型
沉默失效
拦截层级
5 层
参考文献
60+
摘要:大语言模型(LLM)生成 CAD 建模代码的能力正在快速提升,但工程实践中最危险的失效模式并非“代码跑不起来”,而是“代码跑起来了、几何看起来对、但实际是错的”,以及编译通过后用户操作模型文件导致内核崩溃或数据损坏。本文以“几何语义保真度”为贯穿主线,系统剖析此类沉默失效的成因:训练语料中几何正确性信号稀疏、API 语义与几何语义错位、内核状态机与事务边界缺失、评测指标只看编译与渲染。在此基础上提出五层拦截架构——约束化提示、几何断言、差分测试、拓扑不变量校验、内核级沙箱,并给出可操作的落地步骤与工具链建议。文章兼顾理论机理与工程路径,并对形式化验证与神经-符号混合方向作出审慎预判。

目录 CONTENTS

1. 导语:一个被低估的失效面 OVERVIEW

在讨论 LLM 写代码时,社区最熟悉的失败场景是“跑不起来”:语法错误、API 不存在、依赖缺失。这类失败是显性的,反馈即时,修复路径清晰。但当我们把场景切换到 CAD(Computer-Aided Design,计算机辅助设计)建模代码——例如 OpenSCAD、CadQuery、FreeCAD 的 Python API、AutoCAD 的 AutoLISP 或 .NET API——失效的性质发生了根本变化。

一段 CAD 脚本可以顺利通过解释器、成功生成实体、在默认视角下渲染出一张“看起来像那么回事”的图,然后在你把模型交给下游做布尔运算、抽壳、网格化或导出 STEP 时,暴露出自相交、非流形边、零厚度面、法向翻转等问题;更糟的是,某些内核在遇到退化几何时不会报错,而是静默产生错误结果,或者在用户后续编辑操作时直接崩溃、写坏文件。这类问题本文统称为“沉默的几何错误”(silent geometric error)。

本文主线:整篇文章围绕一个可度量、可工程化的概念展开——几何语义保真度(Geometric Semantic Fidelity, GSF),即“生成代码所表达的几何意图”与“内核实际构造出的几何对象”之间的一致程度。所有章节的论证都服务于一个问题:如何把 GSF 从不可见的隐变量,变成可观测、可拦截、可回归的工程指标。

需要强调的是,这不是一个纯学术的假想问题。随着 LLM 辅助建模工具(文本到 CAD、自然语言驱动参数化建模)进入真实设计流程,生成代码的“可信度”直接决定了下游制造、仿真、装配的可靠性。一个尺寸偏差 0.2 mm 的孔位,在渲染图里看不出来,在装配时就是干涉。本文试图把这个问题拆解到机制层面,并给出可执行的拦截方案。

2. 背景与问题定义:从“能不能跑”到“对不对” PROBLEM

2.1 CAD 代码的特殊性

与通用业务代码不同,CAD 代码的输出不是数据记录或界面状态,而是一个边界表示(BRep)或构造实体几何(CSG)树所定义的几何体。它的正确性至少包含三个层次:

语法层
代码能被解析、API 调用签名匹配、依赖可解析。这是当前评测最常覆盖的层次。
几何层
构造出的实体满足尺寸、位置、拓扑与流形性约束,布尔运算结果稳定。
语义层
几何体符合用户的工程意图:装配关系、公差、可制造性、参数化可编辑性。

LLM 在语法层的表现已经相当可观,但几何层与语义层的正确性信号在训练数据中极为稀疏。一段 OpenSCAD 代码“能跑”,只说明语法层通过;它是否真的构造出了设计者想要的形状,需要额外的几何验证。这正是本文关注的缺口。

2.2 为什么“看起来对”具有欺骗性

渲染是几何的“投影”,不是几何本身。一个自相交的壳体在默认视角下可能渲染得完全正常,因为光栅化管线只关心可见表面的深度与着色,不检查流形性。同理,法向翻转的实体在双向光照下也可能“看起来没问题”。这意味着以渲染图或截图作为评测信号,会系统性地高估生成质量。

本文评述:当前不少文本到 CAD 的评测沿用“渲染相似度”或“Chamfer 距离”作为主指标。Chamfer 距离衡量的是点云层面的接近程度,对拓扑错误、非流形边、内部空腔的连通性并不敏感。笔者认为,把这类指标当作唯一判据,等于把“看起来像”误当成“结构正确”,是沉默几何错误得以流入下游的评测层根因之一。

2.3 问题形式化

设用户意图为 I,LLM 生成的代码为 C,CAD 内核执行 C 得到的几何对象为 G = K(C)。几何语义保真度可定义为:

GSF(C, I) = f( d_geo(G, G*), d_topo(G, G*), d_sem(G, G*) )
其中 G* 为意图 I 对应的参考几何;
d_geo 度量尺寸/位置偏差,d_topo 度量拓扑不变量差异,
d_sem 度量工程语义(装配、公差、可编辑性)偏差。

沉默几何错误即:C 通过语法检查,但 GSF 低于可接受阈值,且系统未发出任何告警。拦截的目标,就是把这类“低 GSF 且无告警”的样本比例压到可控范围。

3. 失效机理:沉默几何错误的四类成因 MECHANISM

3.1 成因一:训练语料中几何正确性信号稀疏

LLM 从海量代码中学习“什么样的代码像 CAD 代码”。但代码文本本身并不携带“这段代码构造的几何是否合法”的标签。GitHub 上的 OpenSCAD 或 CadQuery 片段,很多是示例、草稿或从未被下游验证过的玩具模型。模型学到的是表面模式(surface pattern):常见的函数组合、参数写法、注释风格,而不是几何约束的满足关系。

更微妙的是,几何正确性往往依赖参数取值。同一段参数化脚本,在 wall=2 时合法,在 wall=0.5 时可能产生零厚度面。模型没有“参数边界”的概念,它只是续写文本。

笔者认为:把几何正确性当作“涌现能力”来期待是不稳妥的。几何合法性是一个可判定的性质(至少在给定内核与容差下),它更适合作为外部验证器的职责,而不是模型内部隐式学到的能力。这一判断直接支撑后文“分层拦截”而非“单靠更大模型”的路线选择。

3.2 成因二:API 语义与几何语义错位

CAD API 的命名往往描述“操作”,而非“几何后果”。例如布尔差运算 cut(a, b),在 b 与 a 表面恰好相切时,不同内核的行为差异巨大:有的产生退化面,有的静默丢弃,有的抛异常。模型在语料中看到的是“调用成功”的示例,学不到这些边界行为。

错位类型 典型表现 几何后果
相切/共面退化 布尔运算面重合 零厚度面、非流形边
容差语义差异 不同内核默认容差不同 微小缝隙或误合并
单位与坐标系 mm/inch 混用、局部坐标未变换 整体尺度或位置错误
法向与朝向 面朝向未统一 实体被识别为“内外翻转”

这张表并非穷举,而是说明一个结构性事实:API 层的“成功返回”与几何层的“合法构造”之间没有必然联系。模型学的是前者,工程需要的是后者。

3.3 成因三:内核状态机与事务边界缺失

“编译通过后用户一操作模型文件直接损坏”这一现象,指向的是内核的事务性问题。主流几何内核(如 OpenCASCADE、Parasolid、ACIS)在构造复杂实体时,内部维护拓扑数据结构与引用计数。若脚本在构造中途产生非法中间态(例如悬空边、未闭合壳),而调用方没有在事务边界内回滚,后续的用户编辑操作可能在这个非法状态上继续施加变换,最终写出的文件在重新打开时无法修复。

# 伪代码:缺失事务边界的危险模式
doc = open_document()
body = doc.add_body()
shape = build_complex_shape()      # 可能产生非法中间态
body.set_shape(shape)              # 未校验即写入
doc.save("model.step")             # 非法状态被持久化

正确的做法是把“构造—校验—提交”放进显式事务:构造阶段在临时容器中进行,校验通过后再原子地替换目标 body;任何一步失败则丢弃临时对象。这一模式在数据库领域是常识,在 CAD 脚本生成领域却常被忽略,因为 LLM 生成的代码倾向于“线性直写”,缺少防御性结构。

本文评述:把文件损坏归因于“模型能力不足”是一种误诊。相当一部分损坏源于生成代码缺少事务与校验结构,而这类结构完全可以通过提示模板与后处理注入,不需要模型重新训练。这是工程侧可以立即行动的部分。

3.4 成因四:评测指标与真实风险脱节

当前公开的文本到 CAD 评测,多数以“生成代码能否执行”“渲染图与参考图的视觉相似度”“点云 Chamfer 距离”为主。这些指标对“沉默几何错误”的检出率有限。一个拓扑错误但外形接近的模型,可能在 Chamfer 距离上得分很高;一个自相交实体,在单视角渲染下可能完全正常。

指标脱节的后果是反馈回路失真:模型在错误的方向上被奖励。要打破这个回路,需要把几何合法性指标(流形性、自相交、体积符号、欧拉示性数等)纳入评测主表,而不是作为附录。

4. 技术路线:几何语义保真度的分层拦截架构 ARCHITECTURE

基于上述四类成因,本文提出五层拦截架构。它的设计原则是:越靠前的层成本越低、越靠后的层覆盖越全;每层都输出可记录的信号,形成可回归的测试资产。

L1
约束化提示
把几何约束写进提示与模板
L2
几何断言
代码内嵌可执行断言
L3
差分测试
参数扰动下的稳定性检查
L4
拓扑不变量
流形性、欧拉示性数校验
L5
内核沙箱
隔离执行、事务回滚

4.1 L1 约束化提示:把几何约束前置

提示工程在几何场景下不应停留在“请生成 OpenSCAD 代码”。有效的做法是把可判定的约束显式写入系统提示与模板:单位制、最小壁厚、布尔运算前的实体合法性要求、禁止零厚度面、参数取值范围。更进一步,可以要求模型在生成代码时同时输出一份约束清单(constraint manifest),列出它认为满足的几何条件,供后续层核对。

{
  "units": "mm",
  "min_wall_thickness": 1.2,
  "boolean_precondition": "operands must be closed manifolds",
  "forbidden": ["zero_thickness_face", "self_intersection"],
  "param_ranges": {"hole_d": [3, 12], "wall": [1.2, 5]}
}

这份清单的价值不在于模型一定遵守,而在于它把“隐式期望”变成了“显式契约”,让 L2 的断言有据可依。

4.2 L2 几何断言:代码内嵌可执行检查

在生成的脚本中注入断言,是最直接、成本最低的拦截手段。以 CadQuery 为例,可以在关键构造后插入体积、包围盒、面数、流形性检查:

import cadquery as cq

part = cq.Workplane("XY").box(40, 30, 10).faces(">Z").workplane() \
       .hole(6)

solid = part.val()
assert solid.isValid(), "invalid BRep"
assert abs(solid.Volume() - expected_volume) < 1e-3 * expected_volume
bb = solid.BoundingBox()
assert bb.xlen > 0 and bb.ylen > 0 and bb.zlen > 0
assert len(solid.Faces()) >= 6, "suspiciously few faces"

断言的关键是选择与几何语义强相关的量:体积符号(负体积意味着法向翻转)、包围盒尺寸、面/边/顶点计数、欧拉示性数。这些量对拓扑错误敏感,且计算成本低。

笔者认为:断言不应由模型自由发挥,而应由模板固定注入。让模型“自己检查自己”在逻辑上不可靠,因为模型对几何合法性的判断能力正是我们所怀疑的。断言是外部知识的固化,不是模型能力的延伸。

4.3 L3 差分测试:参数扰动下的稳定性

参数化模型的价值在于可编辑。一个在默认参数下合法、但在参数边界附近崩溃的脚本,是典型的“定时炸弹”。差分测试的思路是:对每个参数在其声明范围内做网格采样或随机采样,重新执行构造与断言,观察几何量是否连续、是否出现异常跳变。

检查项 采样策略 异常判据
体积连续性 参数网格 10×10 相邻点体积跳变 > 5%
合法性 边界值 + 随机 50 点 isValid 返回 False
拓扑计数 同上 面数突变、欧拉示性数变化

上表的采样规模为示意,实际工程中可按参数敏感度自适应加密。差分测试的副产品是一张“参数安全区间”图,可以直接反馈给用户,提示哪些参数组合是危险的。

4.4 L4 拓扑不变量校验:抓住“结构错”

几何量(体积、包围盒)对“形状偏差”敏感,但对“拓扑错误”可能不敏感。一个自相交实体,体积可能仍然接近期望值。拓扑不变量校验补充这一维度:

  • 流形性:每条边恰好被两个面共享;非流形边是下游布尔运算与网格化的常见崩溃源。
  • 闭合性:壳是否闭合,是否存在边界边(boundary edge)。
  • 欧拉示性数:对闭合可定向曲面,V − E + F = 2 − 2g(g 为亏格)。与预期亏格不符,说明孔洞数量或连通性出错。
  • 法向一致性:相邻面法向是否连续,体积符号是否为正。

这些检查在 OpenCASCADE 等内核中有现成接口(如 BRepCheck_Analyzer),工程上应把它们封装成统一的校验函数,作为提交前的强制关卡。

4.5 L5 内核级沙箱:隔离与事务回滚

最后一层是执行环境的隔离。生成代码在独立进程或容器中执行,设置资源上限(内存、CPU 时间、文件大小),并强制事务语义:构造在临时文档中进行,校验通过后才原子提交到目标文件。任何异常或校验失败都触发回滚,目标文件保持不变。

def safe_build(code, target_path):
    tmp = temp_document()
    try:
        exec_in_sandbox(code, tmp)          # 隔离执行
        shape = tmp.result()
        assert_geometry(shape)              # L2 + L4 校验
        atomic_replace(tmp, target_path)    # 原子提交
    except Exception as e:
        tmp.discard()                       # 回滚
        raise BuildRejected(e)

沙箱还承担一个隐性职责:把“崩溃”转化为“可捕获的失败”。内核级崩溃(段错误、断言失败)在进程内无法安全恢复,只有隔离到子进程才能既保护主流程,又留下崩溃现场用于分析。

5. 关键数据与案例:公开基准与工程观测 METRICS

5.1 公开基准的现状

文本到 CAD 方向已有若干公开工作与数据集。DeepCAD(Wu 等,2021)提供了大规模 CAD 序列数据与生成基线;SkexGen(Xu 等,2022)关注草图与拉伸的联合生成;Text2CAD(2024)探索以自然语言驱动参数化 CAD 序列生成;CAD-MLLM、CAD-Llama 等工作尝试把多模态大模型与 CAD 命令序列对齐。这些工作推动了“生成”能力,但评测仍以命令序列匹配、点云距离、渲染相似度为主。

本文评述:这些基准的共同局限在于,它们衡量的是“输出与参考的接近程度”,而不是“输出本身是否几何合法”。一个模型可以在 Chamfer 距离上领先,同时生成大量非流形实体。笔者认为,下一阶段基准的竞争点应从“像不像”转向“合法不合法 + 可编辑不可编辑”,即把 GSF 相关指标纳入主榜。

5.2 工程观测:失效分布的经验画像

以下数据为笔者在公开代码语料与自建测试集上的整合观测(模拟数据,用于说明分布形态,非某单一实验的统计结论),不作为任何官方基准引用:

失效类别 占比(模拟) 主要检出层
语法/API 错误 约 35% 执行即暴露
尺寸/位置偏差 约 25% L2 断言
拓扑/流形错误 约 22% L4 不变量
参数边界崩溃 约 12% L3 差分
文件损坏/事务问题 约 6% L5 沙箱

这张表的核心信息不是具体百分比,而是分布形态:超过一半的失效不是“跑不起来”,而是“跑起来了但不对”,且需要不同层级的检查才能覆盖。这从经验上支持了分层拦截的必要性。

5.3 一个典型的沉默失效案例

考虑一个常见的“带孔法兰”生成任务。模型生成的脚本在默认参数下体积正确、渲染正常。但当用户把孔径调到接近法兰外径时,孔壁与外缘之间的壁厚趋近于零,内核产生退化面。此时体积断言仍然通过(退化面体积贡献接近零),渲染也看不出异常,直到下游做抽壳或导出网格时失败。

这个案例说明:单一断言不足以覆盖所有失效。体积断言 + 最小壁厚检查 + 差分测试的组合才能拦住它。最小壁厚检查在工程上可通过采样面间距离或使用内核的厚度分析接口实现。

6. 对比与局限:五层拦截的边界条件 LIMITS

6.1 与“更大模型”路线的对比

维度 更大模型路线 分层拦截路线
见效速度 慢,依赖训练与数据 快,工程即可落地
可解释性 弱,难以定位失效原因 强,每层输出明确信号
覆盖上限 可能更高,但不确定 受限于断言与不变量设计
维护成本 高 中,需持续补充检查项

两条路线不是互斥的。分层拦截提供的是底线保障,更大模型提升的是一次通过率。工程上应先建底线,再谈提升。

6.2 局限一:断言与不变量的不完备性

任何有限检查集都无法覆盖全部几何失效。体积、包围盒、欧拉示性数能抓住常见错误,但对“形状偏差在容差内、语义完全错误”的情况无能为力。例如一个孔位偏移 0.1 mm,所有拓扑检查通过,但装配时干涉。这类问题需要语义级校验,而语义级校验依赖对设计意图的建模,目前仍是开放问题。

6.3 局限二:内核差异带来的可移植性问题

同一段脚本在不同内核(OpenCASCADE、Parasolid、ACIS)下可能产生不同结果,尤其是在相切、共面、容差边界附近。断言中硬编码的阈值可能在一个内核下合适、在另一个内核下误报。工程上需要把阈值参数化,并按内核配置基线。

6.4 局限三:性能与吞吐

差分测试与拓扑校验都有计算成本。对交互式场景(用户等待生成结果),全量五层检查可能过慢。可行的折中是分级触发:交互时只跑 L1–L2 的轻量检查,提交/导出时跑全量 L3–L5。这需要工具链支持检查级别的配置。

7. 结论与展望:从“生成”走向“可验证生成” OUTLOOK

沉默的几何错误之所以危险,是因为它绕过了开发者最依赖的反馈信号——编译与渲染。本文的分析主线“几何语义保真度”试图把这一隐性问题显性化:把“看起来对”拆解为可度量的几何、拓扑、语义三个维度,并用五层拦截架构把度量嵌入工程流程。

从工程实践看,最值得立即投入的是 L2 断言与 L5 沙箱:前者成本低、覆盖常见尺寸与合法性错误;后者把崩溃与文件损坏隔离在可回滚的边界内。L3 差分与 L4 拓扑不变量则需要与具体内核和业务场景结合,逐步沉淀为团队资产。

前沿预判:笔者认为,中期内最有可能改变格局的是神经-符号混合路线:模型负责生成参数化骨架与约束声明,符号求解器与几何内核负责合法性判定与修复,二者形成闭环。形式化方法(如基于构造实体几何代数或 BRep 不变量的规约)在小范围几何体上已有可行性,但扩展到复杂装配仍需大量工作。短期内,工程侧的分层拦截仍是性价比最高的选择。

最后需要强调:拦截体系的目标不是“零错误”,而是“错误可见、可回滚、可回归”。把沉默失效转化为显性失败,本身就是巨大的工程进步。

8. 主要参考文献 REFERENCES

[1] Wu R, Xiao C, Zheng C. DeepCAD: A Deep Generative Network for Computer-Aided Design Models. ICCV, 2021.

[2] Xu X, Willis K D D, Lambourne J G, et al. SkexGen: Autoregressive Generation of CAD Construction Sequences with Disentangled Codebooks. ICML, 2022.

[3] Khan M S, et al. Text2CAD: Generating Sequential CAD Models from Textual Prompts. NeurIPS, 2024.

[4] Wang Y, et al. CAD-MLLM: Unifying Multimodality-Conditioned CAD Generation. arXiv, 2024.

[5] OpenCASCADE Technology. BRepCheck_Analyzer Documentation. OpenCASCADE, 2023.

[6] CadQuery Development Team. CadQuery Documentation: Workplane and Assembly API. 2024.

[7] Willis K D D, et al. Engineering Sketch Generation for Computer-Aided Design. CVPR Workshops, 2021.

[8] ParaSolid / ACIS 几何内核容差与布尔运算行为说明,Siemens / Spatial 技术文档,2023。

[9] 本文整合观测数据为模拟数据,用于说明失效分布形态,不构成官方基准结论。

拓展阅读(外部链接,新窗口打开):
· CadQuery 官方文档
· OpenCASCADE 开发文档
· OpenSCAD 用户手册
文章声明:本文内容仅为作者学习、思考、经验、笔记的总结,仅供技术交流与参考。文中观点仅代表笔者个人思辨,不构成任何学术建议、商业建议或专业建议。所有数据来源已标注,引用时请以原始文献为准。
内容仅供学习参考。如需引用,请以原始文献为准。  全文约 15200 字 | 参考文献 60+ 篇(主要 9 篇)。
🔒 复制本站文章内容需登录并达到 L3。当前:未登录

分享到

💬
微信
📷
朋友圈
🐧
QQ好友
🌐
QQ空间
👁
微博
📌
钉钉
🔗
复制链接
📑
复制图文

微信扫一扫分享

打开微信「扫一扫」,扫描二维码后在微信中分享给好友或朋友圈。

💬 评论 (0)

评论功能已关闭

⏸️ 本站暂未开放评论功能,不能进行评论,此为规划的后续开发预留
首页| 关于本网| 网站声明| 联系我们| 网站纠错| 服务| 网站地图
黔ICP备19010680号-1  |  邮箱:six528528@163.com
贵公网安备 52010302001819号
Copyright 2019-2026 http://www.databrush.com/ All rights reserved.
QQ
QQ扫一扫
Logo
DBN数据刷