而非脚本能力
ABSTRACT 摘要与问题起点
一组小规模但信息量很高的实测数据值得工程界认真对待:在 FreeCAD 环境下,让通用大模型把 2D 工程图纸转成 3D 实体,最简提示词方案在 9 个零件上做对了 5 个(55.6%),结构化提示词方案做到 6 个(66.7%),而三个复杂零件全部失败。这个结果的解释空间很大,但最容易被误读的一种解释是"模型不够强、脚本写得不够好"。恰恰相反:当失败集中在复杂零件上、而简单零件在两种提示词下都能稳定通过时,瓶颈已经不在代码生成环节,而在"把一张 2D 图纸读懂成正确的 3D 特征结构"这一前置认知环节。
本文以这组实测为锚点,提出一条贯穿全文的分析主线:AI 读图的能力缺口可以分解为三层语义——符号语义层(图元与标注代表什么)、拓扑约束层(图元之间构成什么几何关系)、工程意图层(设计者为什么这样画)。三层缺口的性质不同,可用的补全手段也不同:第一层可靠视觉-语言对齐与标准符号库缓解,第二层必须引入几何约束求解与可验证的中间表示,第三层则超出当前通用模型的能力边界,需要"人在环"或领域知识注入。全文围绕这条主线展开:先定义问题与评测口径,再逐层拆解机制与失败模式,然后给出可操作的工程路径与评测方法,最后对前沿方向做审慎预判。
提示词工程带来的增益约为 11 个百分点(55.6%→66.7%),属于"边际改善";而复杂零件的通过率从简单零件的水平直接跌到 0,属于"能力断层"。边际改善靠提示词,能力断层只能靠表示与验证机制。这一判断构成本文后续所有方法建议的逻辑基础。
CONTENTS 目录
OVERVIEW 一、背景与问题定义:为什么"2D 转 3D"是一个读图问题
1.1 工程语境中的 2D 图纸并非"图片"
在机械设计与制造语境中,2D 工程图是一种受标准约束的、承载制造信息的符号系统。它至少同时编码了四类信息:几何形状(轮廓线、中心线、隐藏线)、尺寸与公差(线性尺寸、直径、半径、形位公差框格)、工艺信息(表面粗糙度、热处理、材料)、以及装配关系(配合代号、基准体系)。国际标准化组织与各国标准体系(ISO 128 系列、ASME Y14.5、GB/T 4457 系列)对这些符号的绘制规则有明确规定。换言之,图纸不是"看起来像什么",而是"按规则应该被读成什么"。
这一点决定了 2D 转 3D 任务的性质:它不是图像到图像的翻译,也不是图像到网格的重建,而是从一套符号约定中恢复出一个满足约束的三维特征历史。恢复结果不仅要"形似",还要在参数上可编辑、在拓扑上合法、在工程上可制造。本文评述:把该任务类比为"OCR + 拉伸"是常见但危险的简化,它解释了简单零件为何容易通过,却完全无法解释复杂零件为何系统性失败。
1.2 从"生成脚本"到"理解图纸"的重心转移
FreeCAD 的 Python 接口(Part、Sketcher、PartDesign 等模块)使得"用自然语言驱动建模"在技术上可行:模型输出一段脚本,脚本调用 Part.makeBox、Part.makeCylinder 或 Sketcher 的约束草图 API 完成建模。这条链路上,脚本生成本身是相对成熟的能力:语法正确、API 调用正确、布尔运算顺序合理,这些在近年代码生成评测中已有较好表现。真正的风险在于:如果输入给脚本的"特征结构"本身就是错的,那么脚本写得越流畅,错误被固化得越彻底。
实测中"结构化提示词只提升约 11 个百分点"这一现象,恰好印证了重心位置:结构化提示词改善的是脚本组织与步骤分解,它能让模型少犯低级错误,但无法让模型"看懂"它本来就没看懂的视图关系。因此,把资源继续投入到提示词模板的精细化上,边际收益会迅速衰减。
1.3 问题形式化
可以把任务形式化为一个映射问题。设图纸为 D(包含若干视图 Vi、标注集合 A、标题栏信息 T),目标是得到一个特征序列 F = (f1, f2, …, fn),使得由 F 构造的实体 S 满足:
约束满足: ∀ c ∈ C(D) : c(S) = True
投影一致: Proj_i(S) ≈ V_i (对每个视图 i)
参数可溯: ∀ a ∈ A : ∃ 参数 p ∈ S, p 由 a 决定
可制造性: S 满足最小壁厚、拔模、刀具可达等工艺约束
这四个条件中,前两个是"看起来对",后两个是"工程上对"。当前多数演示性方案只验证前两个,甚至只验证第一个,这正是通过率虚高的来源之一。笔者认为,任何声称解决该任务的系统,都应至少报告"投影一致"与"参数可溯"两项指标,否则结论不可比。
METRICS 二、评测口径:9 个零件、两种提示词与"通过"的判定标准
2.1 数据规模与解读边界
9 个零件、两种提示词策略,这是一个典型的"小样本探针"设计。它的价值不在于统计显著性,而在于失败模式的定性信息:哪些零件稳定通过、哪些零件在两种策略下都失败、失败发生在哪一步。需要明确的是,样本量过小意味着 55.6% 与 66.7% 之间的差异不能直接做显著性推断(在 n=9 时,单个零件的翻转就带来约 11 个百分点的变化),因此本文不把它当作"提示词有效性的统计证据",而当作"能力边界的定位线索"。
注:上表为基于实测结论(5/9、6/9、复杂件 0/3)的整合归纳,类别划分与失败环节为笔者依据公开的 2D 转 3D 研究文献与工程经验所做的归类,非原始实验逐件记录,引用时请以原始实测数据为准。
2.2 "通过"的判定标准为何关键
如果"通过"仅指"脚本无报错、生成了某个实体",那么通过率会显著虚高。更严格的判定应分层:
本文评述:55.6% 与 66.7% 这两个数字,若按 L1 判定会显得偏低,若按 L3/L4 判定则可能偏高。因此讨论"AI 读图还差几层"之前,必须先锁定判定层级。笔者建议工程实践统一采用 L2 作为主指标、L3 作为辅助指标,L4 作为长期目标,这样不同方案之间才具备可比性。
FRAMEWORK 三、分析主线:AI 读图的三层语义缺口
本文的核心主张是:把"AI 读图"当成一个整体能力来评估,会掩盖不同性质的问题。更有效的做法是把它分解为三层语义,每层有独立的输入、输出、失败模式与补全手段。这三层不是并列的模块,而是层层依赖的语义栈:下层错误会向上传播,且上层无法通过自身努力修复下层错误。
┌─────────────────────────────────────────────┐
│ L3 工程意图层 为什么这样画 / 可制造性 │ ← 当前通用模型基本缺位
├─────────────────────────────────────────────┤
│ L2 拓扑约束层 图元之间是什么几何关系 │ ← 需约束求解 + 可验证表示
├─────────────────────────────────────────────┤
│ L1 符号语义层 图元与标注分别代表什么 │ ← 视觉-语言对齐可部分缓解
└─────────────────────────────────────────────┘
失败传播方向:L1 → L2 → L3(单向)
简单零件之所以能通过,是因为它们在 L1 上几乎无歧义、在 L2 上约束稀疏、在 L3 上意图单一;复杂零件之所以集体失败,是因为三层同时承压,且 L1 的微小误读会在 L2 被放大成拓扑错误,最终在 L3 表现为"形状对但工程上不成立"。因此,"还差几层"的答案是:不是差一层,而是三层都差,但差的性质不同——L1 差在覆盖度,L2 差在机制,L3 差在范式。
LAYER 1 四、第一层:符号语义——图元、标注与标准体系
4.1 符号语义的构成
符号语义层要回答的是"这个像素块代表什么"。它至少包含四类子问题:线型识别(粗实线、细实线、虚线、点划线、双点划线分别对应可见轮廓、尺寸线、隐藏轮廓、中心线、假想投影)、标注解析(尺寸数字、公差框格、基准符号、表面粗糙度符号)、视图类型识别(主视图、俯视图、剖视图、断面图、局部放大图)、以及标题栏与技术要求文本的抽取。这四类子问题在计算机视觉上都有相对成熟的技术路线,但组合起来仍存在长尾。
值得强调的是,线型不是装饰,而是语义标签。一条虚线被误读为实线,意味着一个内部孔洞被读成了外部轮廓,后续所有特征都会错位。这类错误在简单零件上不常出现(因为线型少、对比强),但在复杂零件上极为常见(因为线型密集、遮挡严重)。
4.2 为什么 L1 是"覆盖度"问题而非"能力"问题
通用视觉-语言模型在自然图像上的识别能力已经很强,但工程图纸属于分布外输入:黑白高对比、线条极细、文本极小且旋转、符号高度标准化。近年出现了一批面向工程图纸的数据集与基准,例如用于符号与文本检测的工程图数据集、面向 CAD 图纸理解的问答基准、以及面向矢量化与图元提取的研究工作。这些工作共同表明:在受控条件下,L1 的多数子任务可以达到较高准确率,但一旦进入真实扫描件、低分辨率截图、手绘草图,准确率会明显下降。
本文评述:L1 的问题本质是覆盖度——标准符号库庞大,长尾符号(特殊形位公差、非标准工艺标注、企业自定义符号)难以穷举。这意味着 L1 不可能靠"更大的通用模型"一劳永逸解决,而更适合用"通用模型 + 标准符号库检索 + 规则校验"的组合来提升召回。这也是后文 DSIL 中间层要把符号解析结果显式结构化的原因。
4.3 一个可操作的 L1 增强步骤
- 预处理标准化:对输入图纸做二值化、去噪、倾斜校正、分辨率归一(建议长边 ≥ 2000 px),并对细线做形态学膨胀以提升可检测性。这一步对扫描件尤其关键。
- 图元与文本分离:先用轻量检测模型分离"线稿层"与"文本层",文本层单独走 OCR(含旋转文本),避免 OCR 与线检测相互干扰。
- 符号库检索对齐:将检测到的符号候选与标准符号库(可自建 SVG/矢量模板库)做模板匹配或嵌入检索,输出"符号类别 + 置信度"。
- 规则校验:用标准规则做一致性检查,例如"直径标注必须伴随 φ 符号"、"剖视图必须有剖切符号与投射方向"。
拓展阅读:FreeCAD 官方的 Sketcher 约束文档与 Part 模块 API 文档是理解"读图结果如何落到建模"的第一手材料,建议对照阅读 FreeCAD Sketcher Workbench 与 FreeCAD Part module;工程图标准方面可参考 ISO 128 系列 的公开介绍页。
LAYER 2 五、第二层:拓扑约束——从"看见线"到"知道关系"
5.1 拓扑约束的定义与重要性
拓扑约束层要回答的是"这些图元之间构成什么几何关系"。一条轮廓线与另一条轮廓线是平行、垂直、相切还是共线?两个圆是同心的、等径的还是阵列的?一个孔的轴线是否与某个基准面垂直?这些关系在图纸上往往不显式写出,而是通过几何布局、尺寸链与制图惯例隐含表达。人类工程师读图时,会不自觉地完成这种关系推断;而模型若只做"图元分类 + 位置回归",就会丢失这层信息。
拓扑约束是欠定问题:同一组视图可能对应多个满足投影的实体,只有引入约束(平行、垂直、对称、共面、同心)才能把解空间收缩到唯一或少数几个。约束越稀疏,模型越容易"猜错";约束越密集,越需要求解器而非生成器。这正是复杂零件失败的机制根源:约束密度随零件复杂度上升,而当前方案缺乏约束求解环节。
5.2 从"生成"到"求解"的范式差异
当前主流做法是"生成式":让模型直接输出特征序列或脚本。生成式在约束稀疏时表现良好,但在约束密集时会退化为"模式匹配"——模型见过类似形状就照搬,没见过就编造。另一种做法是"求解式":先把图纸解析为一组几何约束(点、线、圆、距离、角度、相切、同心),再用约束求解器(如 FreeCAD Sketcher 内置的求解器、或独立的几何约束求解库)求出满足约束的草图,最后做拉伸/旋转/放样得到实体。
本文评述:求解式并非万能——它要求先把图纸"翻译"成约束集,而这个翻译本身仍是语义理解问题。但求解式的关键优势在于可验证:约束冲突会显式报错,而不是悄悄生成一个错误实体。对于工程应用,"知道自己错了"比"看起来对了"更有价值。因此笔者主张:L2 应以求解式为主干、生成式为补充,而不是反过来。
5.3 视图对应:L2 中最容易被低估的难点
多视图之间的"对应关系"(同一几何要素在不同视图中的投影)是 L2 的核心难点之一。工程制图用"长对正、高平齐、宽相等"的投影规律约束视图间关系,但模型需要先建立"这个视图中的这条线对应那个视图中的那个点/线"的映射。这个映射在简单零件上几乎唯一,在复杂零件上却可能多解——尤其是当存在对称结构、隐藏特征或多个相似孔位时。
一个可操作的缓解手段是投影一致性回验:让模型先给出一个候选实体,再把实体重新投影到各视图,与原始图纸做像素级或矢量级比对,差异大的区域作为"待澄清区域"反馈给模型或人工。这个闭环不需要模型一次做对,但需要模型能"检查自己"。近年一些面向 CAD 反演与程序化建模的研究,正是沿着"生成—投影—比对—修正"的闭环思路推进的。
LAYER 3 六、第三层:工程意图——设计者为什么这样画
6.1 工程意图的构成
工程意图层要回答的是"设计者为什么这样画"。它包含但不限于:这个尺寸为什么标在这里而不是那里(设计基准与工艺基准的差异)、这个公差为什么是 H7 而不是 H8(配合性质)、这个圆角为什么是 R2 而不是 R1(刀具半径与应力集中)、这个特征为什么用剖视表达(内部结构的重要性)。这些信息一部分写在技术要求里,更多部分不在图纸上,而在设计者的头脑与企业的设计规范里。
这意味着 L3 在信息论意义上就是欠定的:仅凭图纸,某些意图不可唯一恢复。本文评述:任何声称"完全自动读图"的方案,若不能说明它如何处理这种欠定性,就应当被审慎对待。合理的做法不是假装欠定不存在,而是把欠定部分显式标记为"待确认",交由人工或企业知识库补全。
6.2 为什么 L3 是"范式"问题
L1 和 L2 的缺口,原则上可以通过更好的模型、更好的表示、更好的求解器来缩小;L3 的缺口则涉及评估范式:我们究竟期望 AI 输出什么?如果期望它输出"一个正确的实体",那么 L3 的错误会被 L2 的投影一致性掩盖(形状对但意图错);如果期望它输出"一个带置信度与待确认项的特征树",那么 L3 的欠定性就能被显式管理。后者才是工程上可落地的目标。
把目标从"全自动 2D→3D"改为"人机协同的图纸理解":AI 负责 L1 的批量解析与 L2 的约束求解,把 L3 的欠定项以结构化问题形式呈现给工程师确认。这样做的直接好处是:通过率不再是二值的,而是"自动完成度 + 待确认项数量",更贴近工程实际。
FAILURE 七、失败模式解剖:复杂零件为什么集体归零
7.1 三类典型失败链
把复杂零件的失败归因为"模型不够强"过于笼统。更有解释力的是识别失败链的类型。基于三层语义框架,可以归纳出三类典型链条:
7.2 为什么提示词无法修复这些链条
结构化提示词的作用是改善输出组织:让模型分步骤、分模块地写脚本,减少遗漏与语法错误。但链条 A、B、C 的错误发生在输入理解阶段,输出组织得再好,也只是把错误组织得更整齐。这解释了实测中"结构化提示词只提升约 11 个百分点"的现象:它修复了部分组织性错误,但没有触及理解性错误。
本文评述:这个现象在软件工程中并不陌生——更好的代码规范能减少 bug,但不能替代需求分析。2D 转 3D 的"需求分析"就是读图,而当前多数方案把这一环节压缩成了一次前向推理,缺少显式的中间表示与校验。
SOLUTION 八、工程路径:图纸语义中间层(DSIL)的设计与落地
8.1 DSIL 的定位
基于三层语义缺口,笔者提出一个工程化的中间表示:图纸语义中间层(Drawing Semantic Intermediate Layer,DSIL)。它不是一个新的模型,而是一个显式的、可校验的数据结构,位于"图纸解析"与"脚本生成"之间。其核心思想是:把模型从"一次前向推理直接产出脚本"改为"分阶段产出可校验的中间产物",每一阶段都可独立验证、独立纠错。
图纸 D
│
├─[阶段1] 图元与文本解析 ──→ DSIL.L1 { 线型, 标注, 视图类型, 文本 }
│ │ 校验:符号库匹配、规则一致性
├─[阶段2] 约束抽取 ──→ DSIL.L2 { 几何约束集, 视图对应表 }
│ │ 校验:约束求解、投影回验
├─[阶段3] 意图标注 ──→ DSIL.L3 { 基准, 公差语义, 待确认项 }
│ │ 校验:企业规范库、人工确认
└─[阶段4] 特征树生成 ──→ FreeCAD 脚本 / 特征树
│ 校验:L2 投影一致 + L3 参数可溯
8.2 DSIL 的数据结构设计
DSIL 应至少包含四个子结构,且每个字段都带来源与置信度,便于追溯。下面给出一个简化示例(JSON 风格),重点在于"每个断言都有出处"这一设计原则:
{
"L1_symbols": [
{"id":"e17","type":"line","style":"dashed","bbox":[120,340,420,340],
"semantic":"hidden_contour","conf":0.91,"src":"detector_v2"},
{"id":"a03","type":"dimension","value":25.0,"unit":"mm",
"symbol":"phi","attached_to":"e21","conf":0.88,"src":"ocr+rule"}
],
"L2_constraints": [
{"kind":"concentric","a":"c01","b":"c02","conf":0.86},
{"kind":"perpendicular","a":"e17","b":"e30","conf":0.79},
{"kind":"view_correspondence","front":"e17","top":"p08","conf":0.72}
],
"L3_intent": [
{"kind":"datum","ref":"A","faces":["f02"],"conf":0.81},
{"kind":"fit","code":"H7","hole":"c01","conf":0.65,
"note":"需人工确认配合性质"}
],
"unresolved": [
{"item":"c02 的深度","reason":"剖视图局部放大区分辨率不足",
"action":"请求更高分辨率或人工补录"}
]
}
本文评述:DSIL 的价值不在于结构本身多精巧,而在于它把"模型的不确定性"变成了"可查询的数据"。当 unresolved 非空时,系统不应强行生成,而应暂停并请求澄清。这一条规则就能显著降低"静默错误"的比例。
8.3 与 FreeCAD 的对接方式
DSIL 到 FreeCAD 的对接有两条路径。其一是脚本路径:由 DSIL 生成 Python 脚本,调用 Part/Sketcher API。其二是特征树路径:直接构造 FreeCAD 文档对象模型(Document Object Model),逐个添加 Sketch、Pad、Pocket、Fillet 等特征。后者更利于参数可溯(L3),因为每个特征都保留了参数引用;前者更灵活但容易丢失参数关联。笔者建议:以特征树路径为主,脚本路径作为兜底。
拓展资源:FreeCAD 的脚本化建模可参考官方 Python scripting tutorial;约束求解器的原理可参考 Sketcher solver 文档;几何约束求解的经典开源实现可参考 SolveSpace 项目。
PLAYBOOK 九、可操作步骤:一套可复现的评测与改进流程
9.1 评测集构建
- 分层抽样:按复杂度分三档(简单/中等/复杂),每档不少于 10 件,避免 n=9 的统计脆弱性。复杂度可按视图数、标注数、特征数、约束密度四个维度打分。
- 来源多样:混合公开数据集、企业脱敏图纸、教科书例题。公开数据可参考面向工程图理解与 CAD 反演的基准(如 CAD 图纸问答、工程符号检测数据集),企业数据需做脱敏与授权。
- 标注真值:每件零件提供"参考实体 + 特征树 + 关键尺寸表"三件套,便于 L2/L3 判定。
- 预处理记录:记录分辨率、二值化阈值、去噪参数、OCR 引擎版本,确保可复现。
9.2 分阶段改进流程
9.3 一个最小可行的投影回验脚本思路
投影回验是 L2 闭环的关键。其基本思路是:把候选实体按标准视图方向做正投影,得到边线图,再与原始视图做矢量或像素比对。下面给出伪代码,重点在流程而非具体 API:
def verify(solid, views, tol=2.0):
scores = {}
for name, view_img in views.items():
proj = project_orthographic(solid, direction=name) # 正投影
edges = extract_edges(proj) # 提取边线
score = match_score(edges, view_img, tol) # 矢量/像素比对
scores[name] = score
# 差异区域作为反馈
diff_regions = locate_mismatch(scores, views)
return scores, diff_regions
本文评述:回验的难点不在投影本身,而在视图方向与图纸视图的对应——主视图、俯视图、左视图的方向约定必须与图纸一致,否则比对无意义。建议在 DSIL 中显式记录"视图类型 → 投影方向"的映射表,作为回验的前置条件。

