自然语言驱动的高精度 3D CAD 模型生成引擎
通过自然语言描述,自动生成可用于工程制造的精确 3D CAD 模型。基于 LLM + CadQuery 技术栈,支持多轮对话迭代优化,输出工业级 STEP/STL 格式。
- 自然语言建模 — 用文字描述零件,自动生成参数化 CAD 模型
- 工程级精度 — 尺寸约束提取 + 拓扑校验 + 语义验证三层保障
- 多轮迭代 — 对话式修改:"把孔径改成 8mm"、"加一个倒角"
- 多格式输出 — STEP(精确 B-Rep)、STL(网格)、PNG 预览图
- 多模型后端 — 通过 LiteLLM 统一支持 Claude、GPT-4、DeepSeek、Ollama 等
- 用户认证 — 邀请码注册制,JWT 认证,管理员可管理用户和邀请码
- 数据持久化 — Session、聊天记录、API 设置与账号绑定,SQLite 持久化,重启不丢失
┌─────────────────────────────────────────────────────────┐
│ 用户交互层 │
│ Web UI (React + Three.js) / CLI / REST API / WebSocket │
└──────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ Prompt 解析引擎 │
│ 意图识别 · 参数提取 · 约束规范化 │
└──────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ LLM 编排层 │
│ 多模型适配 · Prompt 模板 · 上下文管理 │
└──────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ CadQuery 代码生成与执行 │
│ 代码生成 · 沙箱执行 · 错误恢复 │
└──────────────────────┬──────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ 精度验证引擎 │
│ 尺寸校验 · 拓扑检查 · 语义匹配 │
└──────────┬───────────────────────────────┬──────────────┘
│ 通过 │ 不通过
▼ ▼
┌────────────────────┐ ┌─────────────────────┐
│ 输出渲染 │ │ 反馈修正循环 │
│ STEP/STL/预览图 │ │ 错误信息→LLM重新生成 │
└────────────────────┘ └─────────────────────┘
| 模块 | 职责 | 目录 |
|---|---|---|
frontend |
Web UI — 3D 预览、多轮对话、版本管理、校验报告 | frontend/ |
prompt_parser |
意图识别、参数提取、约束规范化 | cad2ai/parser/ |
llm_backend |
LiteLLM 多模型适配、Prompt 模板管理、流式输出 | cad2ai/llm/ |
code_engine |
CadQuery 代码生成、沙箱执行、错误恢复 | cad2ai/engine/ |
validator |
尺寸/拓扑/语义三层校验 | cad2ai/validator/ |
session |
多轮对话状态、模型版本管理 | cad2ai/session/ |
renderer |
STEP/STL 导出、PNG 预览渲染 | cad2ai/renderer/ |
db |
SQLite 数据库层(用户、会话、消息、设置持久化) | cad2ai/db.py |
auth |
JWT 认证、密码哈希、FastAPI 依赖 | cad2ai/auth.py |
将自然语言转化为结构化建模意图:
# 输入: "做一个 50x30x10mm 的铝合金底板,四角有 M4 螺丝孔,孔距边缘 5mm"
# 输出:
{
"type": "create",
"base_shape": "box",
"dimensions": {"length": 50, "width": 30, "height": 10},
"material": {"name": "aluminum"},
"features": [
{
"type": "hole_pattern",
"pattern": "corners",
"hole_spec": {"standard": "M4", "diameter": 4.0, "through": true},
"edge_offset": 5.0
}
],
"constraints": [
{"description": "Overall length", "parameter": "length", "expected_value": 50.0, "tolerance": 0.01}
],
"unit": "mm"
}关键设计:
- 分离 理解 和 生成 — 先用 LLM 提取结构化意图(
PromptExtractor),再用意图驱动代码生成(CodeGenerator) - 支持增量修改 — "把高度改成 15mm" 通过
Intent.merge()字段级 patch,不重建整个意图 - 约束规范化 — 统一单位(默认 mm)、标准件规格(M4 → Ø4.0, 通孔 Ø4.5)
通过 LiteLLM 统一所有 LLM 后端接口:
class LLMBackend(Protocol):
async def generate(self, messages: list[LLMMessage], config: GenerateConfig) -> str: ...
async def generate_stream(self, messages: list[LLMMessage], config: GenerateConfig) -> AsyncIterator[str]: ...
# 支持的后端(全部基于 LiteLLM)
backends = {
"claude": ClaudeBackend, # Anthropic Claude
"openai": OpenAIBackend, # GPT-4 系列
"deepseek": DeepSeekBackend, # DeepSeek Coder
"ollama": OllamaBackend, # 本地模型
}Prompt 策略:
- System Prompt 注入 CadQuery API 参考和建模规范
- Few-shot 示例库按零件类型索引(板件、支架、空心圆柱、齿轮毛坯、壳体盒)
- 错误修复 Prompt 包含上次代码 + 报错信息 + 错误类型专属修复指导
class SandboxExecutor:
def execute(self, code: str) -> ExecutionResult:
"""在受限沙箱中执行 CadQuery 代码"""
# 1. AST 静态分析:禁止 import os/sys/subprocess 等
# 2. 受限 __builtins__(仅保留安全函数)
# 3. 白名单 __import__(仅 cadquery/math)
# 4. SIGALRM 超时控制(默认 30s)
# 5. 捕获 result 变量或错误
...沙箱安全:
- 白名单导入:仅允许
cadquery,math - AST 静态分析:拦截危险 import、
eval/exec/__import__调用、dunder 属性访问 - 受限内建函数:移除
open,exec,eval,__import__,breakpoint等 - 超时控制:默认 30s
错误恢复:
- 语法错误 → 直接反馈 LLM 修复
- 运行时错误 → 附加堆栈信息和错误类型专属修复指导
- 最多自动重试 3 次(可配置)
三层校验流水线,每层独立、可配置(none / basic / standard / strict):
原始 Prompt ──┐
├──→ [ 尺寸校验 ] ──→ [ 拓扑校验 ] ──→ [ 语义校验 ] ──→ 通过
生成的模型 ───┘ │ │ │
× × ×
尺寸偏差报告 拓扑缺陷报告 语义偏差报告
从 Intent 提取尺寸约束,与实际模型的包围盒/特征尺寸对比:
class DimensionValidator:
def __init__(self, tolerance: float = 0.01): # mm
...
def validate(self, shape, constraints: list[DimConstraint]) -> ValidationResult:
# 包围盒尺寸检查(length/width/height/thickness/diameter)
# 返回 ValidationResult 含每项 check 的 pass/fail 状态
...确保模型是有效的实体:
- BRepCheck 实体有效性
- 实体封闭性(watertight / 正体积)
- 无退化面(零面积面)
- 无退化边(零长度边)
用 LLM 对比原始描述和生成结果:
- 特征完整性 — 要求的孔/槽/倒角是否都存在
- 关系正确性 — "居中"、"对称"、"等间距" 等约束是否满足
- 常识检查 — 壁厚是否合理、结构是否可制造
class Session:
id: str
history: list[Message] # 对话历史
intent_stack: list[Intent] # 意图演化链
model_versions: list[ModelSnap] # 模型版本快照
current_code: str # 当前 CadQuery 代码
def rollback(self, version: int) -> ModelSnap:
"""回退到指定版本"""
...- 每次成功生成后保存模型快照(
ModelSnap),支持回退 - 意图合并策略:通过
Intent.merge()做字段级 patch,保留未修改部分 - 对话上下文窗口:最近 N 轮(默认 20)+ 当前完整意图 + 当前代码
| 格式 | 用途 | 实现 |
|---|---|---|
| STEP (.step) | 精确几何交换,用于 CAM/CAE | Exporter.export_step() |
| STL (.stl) | 网格预览、3D 打印 | Exporter.export_stl() |
| PNG (.png) | 快速预览 | VTK 离屏渲染(SVG fallback) |
端到端精度保障的核心流程:
1. 约束提取 Prompt → 结构化约束列表(尺寸、位置、关系)
↓
2. 约束注入 将约束以注释/断言形式嵌入生成的代码
↓
3. 执行期校验 CadQuery 代码中内嵌 assert 语句
↓
4. 后置几何校验 对生成的 BREP 做独立的几何测量
↓
5. 语义回检 LLM 对比 Prompt 和模型特征列表
↓
6. 反馈循环 任何一层失败 → 生成修复 Prompt → 重新生成
设计原则:
- 不信任 LLM 的一次性输出,通过多层独立校验建立信心
- 每层校验产出结构化报告(
ValidationReport),可用于自动修复和人工审查 - 校验严格度可配置:
none/basic(仅尺寸)/standard(尺寸+拓扑)/strict(全部)
| 类别 | 技术 | 说明 |
|---|---|---|
| CAD 内核 | CadQuery + OCP | Python 参数化 CAD,基于 OpenCascade |
| LLM 集成 | LiteLLM | 统一多模型接口(Claude/OpenAI/DeepSeek/Ollama) |
| 沙箱执行 | AST 静态分析 + 受限 exec | 白名单 import + 受限 builtins + 超时控制 |
| 几何校验 | OCP 原生 API | BRepCheck, BRepGProp |
| 3D 渲染 | VTK(可选) | 离屏 PNG 渲染,SVG fallback |
| API 框架 | FastAPI | 异步 HTTP + WebSocket |
| 认证 | python-jose + passlib | JWT 令牌 + bcrypt 密码哈希 |
| 数据库 | aiosqlite | 异步 SQLite(用户/会话/消息/设置持久化) |
| 前端框架 | React 18 + TypeScript + Vite | SPA 前端应用 |
| 3D 预览 | Three.js + @react-three/fiber | 浏览器内 STL 实时渲染 |
| 状态管理 | Zustand | 轻量级 React 状态管理 |
| UI 样式 | Tailwind CSS | 暗色主题 CAD 工具风格 |
| 代码高亮 | CodeMirror 6 | Python 语法高亮只读查看器 |
| 任务队列 | Celery + Redis(可选) | 长时间生成任务异步化 |
| CLI | Typer + Rich | 交互式对话 + 单次生成 |
| 配置管理 | Pydantic Settings | 环境变量 + .env 文件 |
cad2ai/
├── cad2ai/
│ ├── __init__.py # CAD2AI 主类 + CADSession + GenerateResult
│ ├── __main__.py # python -m cad2ai 入口
│ ├── app.py # FastAPI REST API + WebSocket(纯 API,无页面)
│ ├── auth.py # JWT 认证、密码哈希、FastAPI 依赖
│ ├── cli.py # Typer CLI(generate / chat 命令)
│ ├── config.py # Pydantic Settings 配置管理
│ ├── db.py # SQLite 数据库层(aiosqlite)
│ ├── tasks.py # Celery 异步任务定义
│ ├── worker.py # Celery Worker 配置
│ ├── parser/
│ │ ├── intent.py # Intent / Feature / DimConstraint 数据模型
│ │ └── extractor.py # PromptExtractor — LLM 意图提取
│ ├── llm/
│ │ ├── backend.py # LiteLLM 统一后端(Claude/OpenAI/DeepSeek/Ollama)
│ │ ├── prompts.py # Prompt 模板(System/Intent/CodeGen/Recovery/Semantic)
│ │ └── examples/ # Few-shot 示例库(板件/支架/圆柱/齿轮/壳体)
│ ├── engine/
│ │ ├── generator.py # CodeGenerator — Intent → CadQuery 代码
│ │ ├── sandbox.py # SandboxExecutor — 安全执行生成代码
│ │ └── recovery.py # ErrorRecovery — 错误分类 + LLM 自动修复
│ ├── validator/
│ │ ├── dimension.py # DimensionValidator — 包围盒/特征尺寸校验
│ │ ├── topology.py # TopologyValidator — 封闭性/退化面/退化边
│ │ └── semantic.py # SemanticValidator — LLM 语义回检
│ ├── session/
│ │ ├── manager.py # Session — 多轮对话 + 版本回退
│ │ └── snapshot.py # ModelSnap / Message 数据结构
│ └── renderer/
│ ├── exporter.py # Exporter — STEP/STL 导出
│ └── preview.py # PreviewRenderer — VTK PNG 渲染
├── frontend/ # React + Three.js Web UI
│ ├── src/
│ │ ├── api/
│ │ │ ├── types.ts # TypeScript 接口(镜像后端 Pydantic 模型)
│ │ │ ├── client.ts # REST API fetch 封装
│ │ │ └── websocket.ts # WebSocket 连接管理(自动重连)
│ ├── stores/
│ │ │ ├── auth-store.ts # 认证状态(token/user/login/register/logout)
│ │ │ ├── session-store.ts # 会话列表 + 消息历史(服务端持久化)
│ │ │ ├── model-store.ts # 代码/校验/文件/版本/生成状态
│ │ │ └── ui-store.ts # 面板开关/设置/Toast 通知
│ │ ├── hooks/
│ │ │ └── use-websocket.ts # WebSocket 消息处理 hook
│ │ ├── components/
│ │ │ ├── layout/ # AppShell / LeftSidebar / BottomDrawer / StatusBar / Toast
│ │ │ ├── viewer/ # R3F 3D 查看器 + STL 加载 + 导出叠加层
│ │ │ ├── chat/ # 聊天面板 + 消息 + 输入框 + 生成状态指示器
│ │ │ ├── auth/ # 登录页 / 注册页
│ │ │ ├── admin/ # 管理员面板(用户管理 + 邀请码管理)
│ │ │ ├── sessions/ # 会话列表(创建/切换/删除)
│ │ │ ├── versions/ # 版本历史(查看/回退)
│ │ │ ├── code/ # CodeMirror Python 只读代码查看器
│ │ │ ├── validation/ # 校验报告面板(尺寸/拓扑/语义)
│ │ │ └── settings/ # 设置对话框 + 导出按钮
│ │ ├── App.tsx
│ │ ├── main.tsx
│ │ └── index.css # Tailwind CSS 暗色主题
│ ├── vite.config.ts # Vite 配置 + 开发代理
│ ├── package.json
│ └── tsconfig.json
├── tests/
│ ├── test_parser.py # 意图数据模型测试
│ ├── test_engine.py # 沙箱执行测试
│ ├── test_validator.py # 校验层测试
│ └── fixtures/
├── examples/
│ ├── simple_box.py # 单次生成示例
│ ├── bracket.py # 多轮迭代示例
│ └── gear.py # 齿轮毛坯示例
├── pyproject.toml
├── Dockerfile
├── .env.example
└── README.md
CadQuery 依赖 OCP(OpenCascade),需要通过 conda 安装:
# 创建 conda 环境(需要 Python 3.11)
conda create -n cad2ai python=3.11
conda activate cad2ai
# 安装 CadQuery
conda install -c conda-forge cadquery
# 安装项目及开发依赖
pip install -e ".[dev]"
# 配置 LLM API Key(二选一)
# 方式一:编辑 .env 文件
cp .env.example .env
# 编辑 .env,填入你的 API Key
# 方式二:启动 Web UI 后在设置对话框中直接填写from cad2ai import CAD2AI
cad = CAD2AI(llm_backend="claude")
# 单次生成
result = cad.generate("一个 100x60x3mm 的钢板,中间有一个 Ø20 的通孔")
result.export_step("plate.step")
result.export_stl("plate.stl")
result.preview("plate.png")
# 多轮迭代
session = cad.session()
session.send("做一个 L 型支架,长臂 80mm,短臂 40mm,厚度 5mm")
session.send("在长臂末端加两个 M6 安装孔,间距 30mm")
session.send("所有边加 1mm 倒角")
session.export_step("bracket.step")# 单次生成
python -m cad2ai "做一个100x60x3mm的钢板"
# 指定后端和输出
python -m cad2ai generate "齿轮毛坯,外径60mm" --backend openai --png
# 交互式多轮对话
python -m cad2ai chat
# 对话中可用命令:
# /export <name> — 导出当前模型
# /rollback <n> — 回退到版本 n
# /code — 查看当前代码
# /quit — 退出uvicorn cad2ai.app:app --reload
# 纯 API 服务,无页面,访问 http://localhost:8000/docs 查看接口文档cd frontend
npm install
npm run dev
# 一条命令同时启动后端 API + 前端开发服务器(热更新)
# 访问 http://localhost:5173首次使用:
- 打开页面后看到登录界面,点击 "Register" 注册
- 第一个注册的用户自动成为管理员,无需邀请码
- 进入主界面后,管理员可在左下角点击管理面板生成邀请码
- 后续用户需要使用邀请码才能注册
- Session、聊天记录、API 设置均绑定账号,重启后端后数据不丢失
生产预览:
cd frontend
npm run build
npm run preview
# 访问 http://localhost:4173Web UI 功能:
+------------------+-------------------------------+--------------------+
| Left Sidebar | Center: 3D Viewer | Right: Chat |
| (280px) | (flex-1) | (380px) |
| | | |
| [Sessions tab] | Three.js STL 渲染 | [消息列表] |
| [Versions tab] | + 网格 + OrbitControls | [生成状态指示器] |
| | + 导出/视角按钮 | [输入框] |
+------------------+-------------------------------+--------------------+
| Bottom Drawer (可折叠, 250px) |
| [Code tab — CodeMirror Python] [Validation tab — 三层校验报告] |
+-----------------------------------------------------------------------+
| Status Bar: session ID · version · backend |
+-----------------------------------------------------------------------+
- 3D 实时预览 — STL 自动加载,OrbitControls 旋转/缩放,三点照明
- 多轮对话 — WebSocket 流式更新,实时显示 parsing → generating → validating 进度
- 会话管理 — 创建/切换/删除会话
- 版本回退 — 查看历史版本,一键回退
- 代码查看 — CodeMirror Python 语法高亮
- 校验报告 — 尺寸/拓扑/语义三层 pass/fail 状态
- STEP/STL 导出 — 一键下载
- 主题切换 — 亮色/暗色/跟随系统三种模式,设置对话框中切换,选择持久化到 localStorage,页面加载无闪烁
- 设置 — LLM 后端 → Base URL → API Key → 校验级别 → 模型名称手动填写,按配置流程排列,设置与账号绑定持久化到服务端
- 用户认证 — 邀请码注册制,JWT 认证,登录后才能使用
- 管理面板 — 管理员可管理用户(启用/禁用、授予/撤销管理员)和邀请码(生成/删除/复制)
- 数据持久化 — Session、聊天记录、API 设置存储在 SQLite,与用户账号绑定,后端重启不丢失
- 错误提示 — 全局 Toast 通知系统,API 错误等操作状态实时反馈
# 认证(无需 token)
POST /api/v1/auth/register # 注册(第一个用户无需邀请码,自动成为管理员)
POST /api/v1/auth/login # 登录,返回 JWT token
GET /api/v1/auth/me # 获取当前用户信息
# 管理(需要 admin 权限)
POST /api/v1/admin/invite-codes # 生成邀请码
GET /api/v1/admin/invite-codes # 列出所有邀请码
DELETE /api/v1/admin/invite-codes/{code} # 删除未使用的邀请码
GET /api/v1/admin/users # 列出所有用户
PUT /api/v1/admin/users/{id} # 切换用户 admin/disabled 状态
# 以下所有端点均需要 Bearer token 认证
POST /api/v1/generate # 单次生成
GET /api/v1/sessions # 获取当前用户的 session 列表
POST /api/v1/sessions # 创建会话
GET /api/v1/sessions/{id} # 获取会话信息
DELETE /api/v1/sessions/{id} # 删除会话及其消息
GET /api/v1/sessions/{id}/messages # 获取会话消息历史
POST /api/v1/sessions/{id}/messages # 发送消息(多轮)
GET /api/v1/sessions/{id}/model # 获取当前模型
POST /api/v1/sessions/{id}/rollback # 回退版本
GET /api/v1/sessions/{id}/export # 导出文件
GET /api/v1/files/{filename} # 下载生成的文件
GET /api/v1/settings # 获取用户设置(API Key 脱敏)
PUT /api/v1/settings # 更新用户设置
WS /api/v1/sessions/{id}/stream?token=xxx # WebSocket 流式输出(token 通过 query param 传递)
# 登录获取 token
curl -X POST http://localhost:8000/api/v1/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "password123"}'
# 响应: {"token": "eyJ...", "user": {"id": "...", "username": "admin", "is_admin": true}}
# 单次生成(需要 Bearer token)
curl -X POST http://localhost:8000/api/v1/generate \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJ..." \
-d '{
"prompt": "一个 50x30x10mm 的底板,四角 M4 螺丝孔",
"output_formats": ["step", "stl"],
"validation_level": "strict"
}'
# 响应
{
"id": "gen_abc12345",
"status": "success",
"code": "import cadquery as cq\n...",
"validation": {
"passed": true,
"dimension": {"passed": true, "checks": 3, "passed_count": 3, "details": [...]},
"topology": {"passed": true, "checks": 4, "passed_count": 4, "details": [...]},
"semantic": {"passed": true, "checks": 1, "passed_count": 1, "details": [...]}
},
"files": {
"step": "/api/v1/files/gen_abc12345.step",
"stl": "/api/v1/files/gen_abc12345.stl"
}
}WS /api/v1/sessions/{id}/stream?token=eyJ...
# 客户端发送
{"type": "message", "content": "加一个倒角"}
# 服务端推送
{"type": "status", "stage": "parsing"}
{"type": "status", "stage": "generating"}
{"type": "status", "stage": "validating"}
{"type": "result", "status": "success", "version": 2, "code": "...", "validation": {...}, "files": {...}}
通过环境变量或 .env 文件配置,所有变量前缀为 CAD2AI_(API Key 除外)。API Key 和 LLM 设置也可通过 Web UI 的设置对话框配置,设置与账号绑定持久化到服务端:
| 变量 | 默认值 | 说明 |
|---|---|---|
ANTHROPIC_API_KEY |
— | Anthropic API Key |
OPENAI_API_KEY |
— | OpenAI API Key |
DEEPSEEK_API_KEY |
— | DeepSeek API Key |
OLLAMA_API_BASE |
http://localhost:11434 |
Ollama 服务地址 |
CUSTOM_OPENAI_API_KEY |
— | 自定义 OpenAI 兼容服务 API Key |
CUSTOM_OPENAI_API_BASE |
— | 自定义 OpenAI 兼容服务地址(如 OpenRouter) |
CAD2AI_LLM_BACKEND |
claude |
默认后端:claude/openai/deepseek/ollama/custom_openai |
CAD2AI_LLM_MODEL |
自动 | 模型覆盖(如 gpt-4o) |
CAD2AI_VALIDATION_LEVEL |
standard |
校验级别:none/basic/standard/strict |
CAD2AI_DIMENSION_TOLERANCE |
0.01 |
尺寸校验容差(mm) |
CAD2AI_SANDBOX_TIMEOUT |
30 |
沙箱执行超时(秒) |
CAD2AI_MAX_RETRIES |
3 |
生成失败最大重试次数 |
CAD2AI_JWT_SECRET |
随机生成 | JWT 签名密钥(未设置则每次启动随机生成,重启后 token 失效) |
CAD2AI_DB_PATH |
./cad2ai.db |
SQLite 数据库文件路径 |
- CadQuery 代码生成 + 沙箱执行
- 单次 Prompt → STEP/STL 输出
- 基础尺寸校验
- CLI 工具
- 多轮对话状态管理
- 模型版本快照与回退
- REST API + WebSocket
- 拓扑校验
- 语义校验(LLM 回检)
- Few-shot 示例库
- 自动错误修复循环
- 校验报告可视化
- 多模型后端适配(LiteLLM)
- 任务队列(Celery + Redis)
- 用户管理 + 会话持久化
- Web UI(React + Three.js 3D 预览 + 对话界面 + 版本管理)
- 装配体生成(多零件 + 约束)
- 参数化模板库
- DFM(可制造性)分析
- 与 FreeCAD / Fusion 360 集成
MIT