
一、痛点:机械设计为什么难被 LLM 接管
做硬件、做机器人的同学大概都有过这种体验:脑子里一个工装方案已经想清楚了,但要落地,得打开 SolidWorks / Fusion 360,鼠标点几百下——画草图、拉伸、打孔、倒角、阵列、装配……一套下来半天没了。改个尺寸?重新点一遍。
这种GUI 驱动、操作密集的工作流,LLM 根本插不上手。它能写代码,但点不了鼠标。
所以问题变成了:有没有一种方式,让机械建模本身变成"写代码"? 只要建模是代码,LLM 就有了着力的支点。
答案是 CadQuery——一个纯 Python 的脚本化 CAD 库。
二、为什么选 CadQuery
CadQuery 不是又一个画图玩具,它的定位很明确:用 Python 代码做参数化实体建模,底层是工业级内核 OpenCASCADE(OCP)。
和同类方案比:
- vs FreeCAD:FreeCAD 是 GUI 应用,CadQuery 是纯代码库,天然适合 LLM 生成。
- vs OpenSCAD:OpenSCAD 用自己的 DSL,靠 CSG 布尔拼凑;CadQuery 用 Python,能用循环/函数/数学库,表达能力高一个量级,且底层是 B-Rep 实体(精度远高于多边形网格)。
- vs 直接调 OpenCASCADE:OCP 原生 API 极其繁琐,CadQuery 在上面封了一层 fluent API(
Workplane().box().cut()),可读性接近自然描述。
最关键的是产出:CadQuery 能直接导出 STEP(工程级,可进任何 CAD/CMC)和 STL(打印用)。这意味着 LLM 生成的代码,端到端能落地到一个真实的、可制造的结果——不是停在屏幕上的渲染图。
我们这边的版本是 CadQuery 2.7,跑在独立 venv 里。
三、核心思路:把 LLM 变成"机械建模工程师"
很多人用 LLM 做技术活失败,不是因为模型不行,而是没给它一份像样的"岗位说明书"。
做机械建模尤其如此——LLM 默认会写出"能跑但不可打印"的东西:零厚度面、自交、悬垂 80°、薄壁 0.5mm、孔没留公差……每一个都是打印翻车现场。
所以这个项目的核心不是调 prompt 技巧,而是写两份严格的工程规范文件,把一个资深机械工程师脑子里的"纪律"固化下来:
CLAUDE.md—— 给 Claude Code 的岗位说明AGENTS.md—— 给 Codex 的岗位说明(OpenAI 的 agent 用 AGENTS.md 约定)
两份文件都把 LLM 的角色定义为同一句话:精通 CadQuery 的机械建模工程师,产出可直接运行、可 3D 打印、参数可调的模型脚本。

规范里钉死的几条硬约束(节选):
- 目标打印机 Bambu Lab P1S,可用体积 250×250×250mm——任何单件包围盒三方向都必须 ≤250mm,超出必须主动拆件;
- 参数化纪律:所有尺寸在文件顶部定义为大写参数变量 + 中文注释,几何代码里禁止魔法数字;
- 可打印性:水密实体、布尔运算后
.val().isValid()自检、薄壁 ≥2mm、孔位预留 0.2~0.4mm 公差、悬垂 >45° 必须标注"需要支撑"; - CadQuery 编码习惯:显式基准面、选择器要注释(
.faces(">Z") # 选择顶面)、布尔运算前对齐坐标系; - 每个项目强制三件套:源码
.py+preview.py(双模式预览)+README.md,外加stl/、step/产物目录; - 文首信息块:每个
.py顶部必须有项目名/开发者/版本/时间/说明。
这不是"建议",是"必须"。LLM 一旦接受这套规范,它的产出就从"看起来像 CAD 的代码"变成了"真的能上打印机的工程件"。
四、工具链搭建
一份干净的 venv 是基础:
python3 -m venv .venv
.venv/bin/pip install --upgrade pip wheel setuptools
.venv/bin/pip install cadquery # 核心建模 + STL/STEP 导出 + 自带 VTK 预览器
.venv/bin/pip install cq-editor # GUI 预览器(PyQt5)
验证安装:
.venv/bin/python -c "import cadquery as cq; print(cq.__version__)"
# 2.7
之后所有运行/导出都走这个 venv 的解释器,不用系统 python3,避免环境污染。
五、实战案例:食材体积扫描的烤箱工装
需求很具体:验证一个**"深度相机 + 转台"**的食材体积估计方案,需要一个小型扫描腔体工装——前开放矩形腔体,底部带 NEMA17 步进电机驱动的转台,顶部后角装倾斜俯视的深度相机,顶部前方装环形光源。
腔体内部默认 200×200×220mm,总装高度逼近 250mm 上限,必须拆件打印。

参数化:改一个数,整件联动
源码顶部把所有尺寸定义清楚(节选):
# --- 腔体 ---
CHAMBER_W = 200 # 腔体内部宽度 (X)
CHAMBER_D = 200 # 腔体内部深度 (Y)
CHAMBER_H = 220 # 腔体内部高度 (Z)
WALL_T = 3 # 壁厚
# --- 转台 ---
TURNTABLE_DIA = 100 # 转台盘直径
SHAFT_DIA = 8 # 转台中心轴孔直径(配电机轴)
MOTOR_MOUNT_W = 42 # NEMA17 电机安装方孔边长
# --- 相机支架 ---
CAM_TILT_DEG = 45 # 相机俯视倾角(相对水平)
CAM_LENS_HOLE_DIA = 15 # 镜头避让开孔直径
派生尺寸由参数计算,不写死:
OUT_W = CHAMBER_W + 2 * WALL_T # 外形宽 = 206
# 相机楔形支架高度,由倾角三角推出,保证光学轴 = CAM_TILT_DEG
WEDGE_H = FLANGE_D * math.tan(math.radians(90 - CAM_TILT_DEG))
想把腔体加大、相机倾角改成 40°?动两个数,所有部件重新生成。这是 GUI 建模给不了的迭代速度。
部件函数:每个零件一个 make_xxx()
每个独立部件封装成函数,返回 cq.Workplane 对象。以底座为例(节选,已去掉部分细节):
def make_base():
"""底座+转台座:含墙板榫卯槽、电机方孔、4 螺丝孔、中心轴孔、转台凸台。
打印朝向:底面朝下。"""
b = cq.Workplane("XY").box(OUT_W, OUT_D, BASE_THICK,
centered=(True, True, False))
# 前/后墙板榫卯槽(顶面下切)
for sy in (1, -1):
groove = (cq.Workplane("XY")
.box(OUT_W, GW, GROOVE_D, centered=(True, True, False))
.translate((0, sy * (CHAMBER_D/2 + GW/2), BASE_THICK - GROOVE_D)))
b = b.cut(groove)
# 电机安装方孔(贯穿)
b = b.cut(cq.Workplane("XY").box(MOTOR_MOUNT_W, MOTOR_MOUNT_W, BASE_THICK+4)
.translate((0, 0, -2)))
# 中心轴孔 + 转台凸台 ...
return b
看到没?这段代码读起来几乎就是一句自然语言:"取一块板,在顶面四边切出墙板槽,中间开个电机方孔,再立个转台凸台。" 这正是 CadQuery 配合 LLM 的杀手锏——代码即设计意图,可读、可改、可 diff。
运行、导出、验证
一条命令导出全部 STL/STEP:
.venv/bin/python 2026-07-01-体积扫描烤箱工装/oven_tooling.py
交付前必须过两道自检——包围盒 ≤ 250mm + 水密性 isValid:
.venv/bin/python -c "import cadquery as cq; \
r=cq.importers.importStep('2026-07-01-体积扫描烤箱工装/step/base.step'); \
bb=r.val().BoundingBox(); \
print('bbox', round(bb.xlen,1), round(bb.ylen,1), round(bb.zlen,1), \
'valid', r.val().isValid())"
# bbox 206.0 206.0 16.0 valid True
最终产出的部件包围盒(证明全部 ≤ 250mm):
| 部件 | X×Y×Z (mm) |
|---|---|
| base 底座 | 206 × 206 × 16 |
| wall 墙板 | 206 × 3 × 226 |
| top 顶板 | 206 × 206 × 6 |
| camera_bracket 相机支架 | 52 × 45 × 45 |
| turntable 转台盘 | 100 × 100 × 5 |
最大单件 226mm < 250mm ✓,全部 isValid=True ✓。这套件可以直接切片上机。
双模式预览:同一份 preview.py 兼容两种看法
这里有个很实用的工程技巧:一个 preview.py 同时兼容命令行预览和 GUI 预览,靠环境探测自动分支,用户不用改代码:
from cadquery.vis import show
# 探测是否在 CQ-editor 中运行(它会向命名空间注入 show_object)
try:
show_object # noqa
_IN_CQ_EDITOR = True
except NameError:
_IN_CQ_EDITOR = False
if _IN_CQ_EDITOR: # 方式2:CQ-editor,各部件命名显示
for name, obj, color in DISPLAY:
show_object(obj, name=name, options={"color": color, "alpha": 0.9})
else: # 方式1:命令行,弹 VTK 窗口
show(*[o for _, o, _ in DISPLAY])
两种用法:
# 方式1:命令行直接弹 VTK 窗口(先导出总装 preview STEP)
.venv/bin/python 2026-07-01-体积扫描烤箱工装/preview.py
.venv/bin/python 2026-07-01-体积扫描烤箱工装/preview.py --png out.png # 无桌面离屏出图
# 方式2:CQ-editor 打开,右侧 Objects 面板逐件显隐/改色
.venv/bin/CQ-editor 2026-07-01-体积扫描烤箱工装/preview.py
这种“一份脚本双模式”的设计,是规范里强制要求的——交付物不能只给个 .py 让人自己琢磨怎么看。
📸 【实拍截图位置 · Claude Code】 下图是 Claude Code(国产 GLM 模型代理)实际生成的 3D 模型渲染——烤箱扫描工装总装预览,来自
2026-07-01-体积扫描烤箱工装/preview.py的运行结果。

六、双 Agent 同题对照:这条路可复现
这个项目最有意思的地方,是用 Claude Code 和 Codex 两个不同的 agent,独立做同一个题:
- Claude Code 产出 →
2026-07-01-体积扫描烤箱工装/(oven_tooling.py,7 个部件函数,榫卯 + M3 螺纹杆组装) - Codex 产出 →
CX-2026-07-01-烤箱扫描工装/(oven_scan_fixture.py,9 个部件,榫槽 + M3 通孔,版本 v1.1)
📸 【实拍截图位置 · Codex】 下图是 Codex(GPT-4)实际生成的 3D 模型项目截图——同一个烤箱扫描工装需求的另一套实现,来自
CX-2026-07-01-烤箱扫描工装/。

两套方案细节不同(拆件粒度、连接方式各有取舍),但都满足同一份规范:参数化、可打印、双模式预览、包围盒全部 ≤250mm、isValid=True、都带完整 README。

这说明了一件重要的事:让 LLM 做参数化机械建模,不是某个模型的偶然 lucky shot,而是一套可复现的方法论。 只要规范写到位,不同 agent、不同模型都能稳定产出合格的工程件。这才是"能用"和"玩具"的分水岭。
当然,两个 agent 的产出也有差异——这正是双跑的价值:同题双答,工程师做选型/合并,比单跑一次盲信结果靠谱得多。
七、踩出来的几条经验

跑通这个项目,有几点值得记下来:
规范比模型更重要。同一份 CLAUDE.md/AGENTS.md,换了 agent 也能跑通;反过来,没有规范约束的强模型,照样写出不可打印的废件。纪律 > 模型能力。
可打印性约束必须显式写进规范。水密、薄壁、公差、悬垂——这些是机械工程师的肌肉记忆,但 LLM 没有。你得替它写进"岗位说明书",否则它根本意识不到 0.5mm 薄壁打印不出来。
isValid()是底线。布尔运算(union/cut)很容易产生非流形、零厚度面。每件导出后必须过.val().isValid(),不过就返工。这是自动验证闭环的关键一环。参数化让 LLM 的迭代优势真正发挥。GUI 建模改尺寸成本极高,LLM 改一个参数重跑一次,几秒钟。参数化 + 代码 + LLM,三者叠加才叫降维打击。
交付物要"自解释"。源码 + preview.py + README 三件套,让任何接手的人(或下一个 agent)能立刻运行、预览、验证。这是把一次性脚本变成可持续工程资产的前提。
文首信息块不是形式主义。项目名/版本/时间/说明,让每件产出可追溯、可版本管理。机械设计终于能像软件一样 git diff 了。
八、观点:机械设计正在被"代码化"
做完这个案例,我对一个趋势更确信了:机械设计正在从"操作密集的手艺"变成"代码驱动的工程"。
这件事的连锁反应很深远:
- 可版本化:实体模型能进 Git,每一次修改有 diff、有 commit、有 blame。传统 CAD 文件几乎做不到。
- 可自动化:参数一改,整件重生;CI 里跑
isValid和包围盒检查,把"能不能打印"变成自动化测试。 - 可被 LLM 接管:当代码是建模的唯一入口,LLM 就成了最自然的"建模工"——它读规范、写代码、跑验证、改参数,闭环。
但这不意味着机械工程师要失业。恰恰相反——当"怎么画"被代码和 LLM 接管,工程师的价值上移到了"画什么、为什么这么约束、怎么验收"。
- 需求拆解(这个工装要解决什么扫描问题、转台要多大、相机俯角几度);
- 约束定义(打印机体积、壁厚、公差、配合方式);
- 结果验收(包围盒、水密、装配干涉、实际打印)。
这些是 LLM 替不了的判断力。和之前聊量化部署、MLOps 选型一样——AI 接管执行层,工程师退到决策层。 工具变了,工程师的护城河没变:对问题的理解、对边界的把握、对结果的负责。
九、结语
这个项目验证了一件具体的事:今天,你完全可以把"我需要一个工装件"这句话,丢给一个被工程规范约束好的 LLM,几分钟后拿到一份参数化、可打印、带预览和文档的完整工程包。
而且不止一个 agent 能做到——Claude Code 行,Codex 也行。方法可复现。
机械设计的代码化不是未来时,是现在进行时。对做硬件、机器人、嵌入式工装的同学来说,早点把你的建模纪律写成规范、交给 LLM,比纠结"哪个 CAD 软件更好用"值得得多。
下次你需要打个工装件,试试先写代码。

参考链接: [1] CadQuery 官方文档(Python 脚本化 CAD) https://cadquery.readthedocs.io/
[2] CadQuery 源码仓库(GitHub) https://github.com/CadQuery/cadquery
[3] CQ-editor GUI 预览器(GitHub) https://github.com/CadQuery/CQ-editor
[4] OpenCASCADE / OCP 内核官网 https://dev.opencascade.org/
[5] Claude Code 官方介绍 https://www.anthropic.com/claude-code
[6] OpenAI Codex 介绍 https://openai.com/index/openai-codex/
[7] Bambu Lab P1S 3D 打印机 https://bambulab.com/