不用写代码,网页CAD里说句话就能画图?大模型结合MxCAD的接口优势
MxCAD AI 模块是嵌入网页 CAD 的插件:接收用户自然语言指令,调用大模型生成符合 MxCAD API 规范的 JS 代码,在隔离沙箱中执行,并把结果以图形呈现到图纸。模块本身不含模型、不直接操作图纸,只负责三件事:整理图纸状态、调用模型生成代码、执行并校验结果。
一、MxCAD 接入 AI 模块的优势
传统 CAD 对外提供高层命令(如 drawCircle(圆心, 半径)),命令本身不说明圆心如何确定、半径单位、颜色图层在哪设置,模型只能靠推测补全,出错率高。MxCAD 则把绘图能力拆分为具体的对象和属性:
const center = new McGePoint3d(0, 0, 0);
const circle = new McDbCircle();
circle.center = center;
circle.radius = 100;
circle.trueColor = new McCmColor(255, 0, 0);
entitys.push(circle);
因此 MxCAD 接入 AI 后能做到:
- 意图明确:每行代码对应一个确定的几何动作,模型无需推测整体意图。
- 错误可定位:沙箱执行失败时把具体报错回传模型重新生成。
- 修改可迭代:如“把矩形圆角改成 10”,只需修改已有代码,不必重新理解整张图纸。
- 工程属性不丢失:图层、线型、标注样式全部落在具体字段上,不因多轮对话丢失。
这套做法属于“代码生成”路线(CadQuery / OpenSCAD 一类),缺点是复杂曲面支持较弱、单次失败率较高,优点是可读、可改。MxCAD 的价值在于把失败率控制到可用范围,同时保留可读可改的优势。
工程层面另有三个优点:
1.策略模式统一智能体接口:所有智能体实现同一个 process(task, options),注册在 agentStrategies 表中,新增智能体不需要改动其他代码。
2.LLMClient 作为唯一网络出口:支持全局取消,便于管理和排查。
3.配置与代码分离:供应商、baseURL、模型列表可运行时配置,也可编译进产物。
二、核心架构
2.1 五个阶段、七个步骤

以“画一个矩形,长 100,宽 60,四个角倒圆角,半径 10”为例,从接收指令到出图依次经过五个阶段、七个步骤,每一步只解决一个问题。
阶段一:接收与路由
- 第一步:把用户输入打包成任务对象交给后续环节,界面显示加载中。
- 第二步:判断由谁处理。延续性指令(如“再大一点”)直接交给上一轮的智能体;否则先用关键词表匹配(“画”“创建”“删除”“选中”等),匹配不上的才问模型,省去不必要的网络请求。
阶段二:组装上下文
- 第三步:凑齐模型所需材料——角色与输出格式要求、MxCAD API 文档片段、图纸当前状态(视口范围、选中图形)、前几轮对话。模型对图纸和 MxCAD 的认知全靠这一步提供。
阶段三:模型生成
- 第四步:调用模型,等它返回文字。请求地址和密钥来自配置层,所有请求经同一客户端发出,可中途取消。
- 第五步:剥离 Markdown 标记和多余说明,提取纯代码并补上必要的
import,得到一段可运行的 JavaScript。
阶段四:沙箱验证
- 第六步:在隔离环境中试运行,画出的图形只显示在预览区,不进正式图纸。代码写错、调用不存在的方法、生成过多图形,都在这一步暴露。
阶段五:提交或重试
- 第七步:试运行成功,打开代码编辑器让用户查看代码与预览,决定是否写入图纸;失败则把报错连同原始指令送回模型重新生成,最多重试 3 轮,仍失败则终止并提示。
整个过程中模型只参与第三、四、五步,其余由框架完成。核心思路:不让模型直接操作 CAD,而是让它输出一段可被验证的代码,由框架负责验证与落地。
2.2 五层结构

七个步骤分散在五层结构中,每层只承担一类职责,出问题时可单独排查。
- UI 层:送入需求、展示预览结果;代码编辑器也在此层,让用户写入前能看到 AI 生成的代码。
- 智能体层:调度中心。所有智能体实现统一
process(task, options)并注册到agentStrategies;路由智能体根据指令选择智能体,被选中的负责组装 systemPrompt;新增领域智能体只需实现并注册,不改其他层。 - 核心层:
BaseAgent负责调用流程与重试,LLMClient负责网络请求,沙箱负责执行代码。这是框架主体,也是唯一接触网络、唯一执行外部代码的地方。 - 配置层:存放供应商名称、baseURL、API Key、模型列表,可运行时填写或编译进产物(对应后文两种接入方式)。
- 上下文层:提供图纸状态快照——视口范围、选中实体、对话历史。它决定模型能否“看见”图纸现状;多轮修改能否落在同一对象上,取决于是否把选中实体传进去。
2.3 三个智能体的分工
| 智能体 | 职责 | 典型指令 |
|---|---|---|
IntentRecognitionAgent |
路由调度,不执行具体任务 | 用户无感 |
ModelingAgent |
图形创建与迭代修改 | “画一个长100宽60的矩形,圆角10” |
DefaultAgent |
图纸操作与查询 | “选中所有长度大于100的直线”“把标注图层改成红色” |
分工的意义在于缩小每个智能体的 systemPrompt 范围:ModelingAgent 只讲几何创建,DefaultAgent 只讲属性修改与查询。提示词越窄,模型输出无关内容的概率越低。
同时路由智能体保留“延续会话”判断:用户说“再大一点”时不重新判断意图,直接交给上一轮智能体,保证多轮修改落在同一对象上。
三、如何配置可用的 AI 模型
所有配置最终落到四个参数:供应商、API Key、模型 id、baseURL。入口统一为:CAD 网页 → 聊天胶囊上的齿轮按钮(或执行命令 MxCAD_AIConfig)打开“AI 配置设置”对话框。
3.1 接入自定义部署的 AI 模型
前提条件(部署侧):
模型以 OpenAI 兼容 server 提供服务:llama.cpp(
llama-server)、vLLM、Ollama、LM Studio、SGLang 均可;裸 transformers 脚本需加 FastAPI 或套 LiteLLM 网关;响应必须包含
choices[0].message.content(插件硬编码解析该字段);允许跨域(CORS)——插件在浏览器端直接发请求,llama.cpp 默认已开,vLLM 需加
--allow-origin "*";上下文建议 ≥32K(系统提示词内嵌大段 API 文档,固定请求
max_tokens: 4096)。
方式 A:零代码接入(运行时配置,推荐)
| 参数 | 值 |
|---|---|
| 端点(baseURL 要填到完整路径) | http://xxxxxxxxxxx/v1/chat/completions |
| API Key | xxxxxxxxxxxxxxxx |
| 模型 id | xxxxxxxxxxxxxxx |
| 服务能力 | 上下文 216K(n_ctx 216064),最大输出 40960 token |
第 0 步:接入前用 curl 验证
# 1) 拿真实模型 id(注意:llama.cpp 返回的是 gguf 文件路径,
# 必须以 /v1/models 返回的 id 为准)
curl http://xxxxxxxxxxxx/v1/models
-H "Authorization: Bearer xxxxxxxxxxxx"
# 2) 模拟插件的真实请求,验证协议与 key
curl http://xxxxxxxxxxxx/v1/chat/completions
-H "Content-Type: application/json"
-H "Authorization: Bearer xxxxxxxxxxxxxxxxx"
-d '{"model":"xxxxxxxxxxxxxxxx",
"messages":[{"role":"user","content":"只回复四个字:接入成功"}],
"temperature":0,"max_tokens":64}'
第 1 步:齿轮按钮(或命令 MxCAD_AIConfig)打开“AI 配置设置”对话框。 第 2 步:任选一个供应商(如 OpenRouter),此步只是占位,真实端点由下一步覆盖。 第 3 步:填 API Key,本地服务不校验 key 时任意非空串均可。 第 4 步:填写”自定义 API 地址”——http://xxxxxxxxxxxxxxxx/v1/chat/completions。注意必须写到 chat/completions 完整路径,代码直接 fetch 这个 URL,不会自动拼接。 第 5 步:在下拉框中手动输入模型 id。 第 6 步:点“保存”,配置写入 localStorage(mx_ai_chat_config),所有智能体立即切换,刷新后仍生效。 第 7 步:验证——输入“画一个圆”,确认沙箱出图、代码编辑器收到代码。**
方式 B:代码级内置(做成默认值,构建后开箱即用)
适用场景:交付的 CAD 页面不用进设置界面、默认就走你的模型。修改 MxDrawCloudServer/SRC/sample/app/plugins/pluginAiChatsrc/services/openRouterAPI.ts,重新打包运行。
// ① availableProviders 数组末尾新增供应商
{
id: 'local',
name: '本地/自定义模型',
description: '自托管 OpenAI 兼容服务(llama.cpp/vLLM/Ollama 等)',
icon: '$mdi-home-server',
baseURL: 'http://xxxxxxxxxxxxxxx/v1/chat/completions',
customizable: true
}
// ② fallbackModelsByProvider 新增模型列表(源码里反斜杠写成 \\)
local: [
{ id: 'xxxxxxxxxxxxxxxx(模型id)',
name: 'xxxxxxx',
description: '自托管 llama.cpp 服务,200K 上下文',
provider: 'local', free: true }
]
// ③ modelsByProvider 响应式对象同步加一行
local: [...fallbackModelsByProvider.local]
// ④ defaultConfig 改为默认生效
const defaultConfig: APIConfig = {
provider: 'local',
apiKey: 'Xxxxxxxxxxxxx',
selectedModel: 'xxxxxxxxxxxxxx(模型id)',
baseURL: 'http://xxxxxxxxxxx/v1/chat/completions'
}
3.2 接入内置供应商的 AI 模型
| 参数 | 值 |
|---|---|
| 供应商 | OpenRouter |
| API Key | 用户自填,格式如 sk-or-v1-xxxxxxxx |
| 模型 | deepseek/deepseek-chat-v3-0324:free(免费,代码默认值) |
| baseURL | https://openrouter.ai/api/v1/chat/completions(内置,无需手填) |
操作步骤:
- 齿轮按钮(或命令
MxCAD_AIConfig)打开“AI 配置设置”对话框; - 下拉选择 OpenRouter / OpenAI 之一,自动带出该供应商的默认 baseURL 和第一个预置模型;
- 填 API Key:OpenRouter 为
sk-or-v1-开头的平台 key,OpenAI 为sk-开头的官方 key; - 选模型:OpenRouter 列表为启动时动态拉取的全量模型(带 FREE/PAID 标识,缓存 24 小时),也可手动输入任意模型 id;如需覆盖端点可在“自定义 API 地址”修改(一般不需要);
- 点“保存”,配置持久化到 localStorage;
- 验证:输入“画一个圆”,确认出图与代码编辑器联动。
内置供应商的行为特性:
- OpenRouter 请求会附加
HTTP-Referer、X-Title头和route: "fallback"(启用备用路由); response_format: json_object仅对 openai / iflow 生效,其余场景由parseJSONResponse兜底解析(可剥离 Markdown 代码块包裹);- 所有 LLM 请求支持一键取消:加载状态下悬停聊天按钮,变红即“取消请求”,调用
cancelAllLLMRequests()中止全部在途请求。
四、启动项目并验证效果
4.1 启动项目
- 双击 copy_dist.bat,将 2D 演示应用复制到 dist
- 进入插件目录
cd pluginAiChat npm install npm run dev - 浏览器访问 localhost:3366/plugins/pluginAiChat...
- 执行命令 Mx_showAiFunctionButton,出现聊天胶囊
- 点击齿轮配置模型,输入“画一个圆”
4.2 用自然语言绘制图形
输入:
画一个矩形,长 100,宽 60,四个角倒圆角,半径 10
系统不返回文字说明,而是生成如下代码并在沙箱中执行:
import { MxCpp, McGePoint3d, McDbPolyline, McCmColor } from "mxcad";
function drawRoundedRect() {
const mxcad = MxCpp.getCurrentMxCAD();
const L = 100, W = 60, R = 10;
const bulge = Math.tan(Math.PI / 8); // 90°圆弧的bulge值 ≈ 0.41421356
const pl = new McDbPolyline();
pl.isClosed = true;
pl.trueColor = new McCmColor(0, 128, 255);
pl.constantWidth = 1;
// 逆时针8个顶点,每段直线后跟一个90°圆弧
// 底边
pl.addVertexAt(new McGePoint3d(R, 0, 0));
pl.addVertexAt(new McGePoint3d(L - R, 0, 0), bulge); // 右下角圆弧
// 右边
pl.addVertexAt(new McGePoint3d(L, R, 0));
pl.addVertexAt(new McGePoint3d(L, W - R, 0), bulge); // 右上角圆弧
// 顶边
pl.addVertexAt(new McGePoint3d(L - R, W, 0));
pl.addVertexAt(new McGePoint3d(R, W, 0), bulge); // 左上角圆弧
// 左边
pl.addVertexAt(new McGePoint3d(0, W - R, 0));
pl.addVertexAt(new McGePoint3d(0, R, 0), bulge); // 左下角圆弧
mxcad.drawEntity(pl);
mxcad.zoomAll();
}
drawRoundedRect();
执行成功后图形出现在预览区,用户确认后正式写入图纸。
4.3 用自然语言编辑已有图纸
输入:
选中所有长度大于 10 的直线,把它们改到 WALL 图层,颜色设为红色
系统生成的代码会读取当前图纸实体、逐个判断长度,符合条件者修改 layer 和 trueColor 属性后提交变更,全程无需人工逐个选择对象。
五、总结
MxCAD AI 模块的设计思路:绘图动作转成代码,沙箱执行,结果交给人确认,模型只在中间负责生成文本与自我修正。模型生成、框架执行、人确认,三层分工明确。
建议实施顺序:先接入模型跑通“画一个圆” → 再改提示词适配行业规范 → 然后增加关键词路由提效 → 最后拆领域智能体深入特定场景。每一步都能立即看到效果。
本作品采用《CC 协议》,转载必须注明作者和本文链接
关于 LearnKu
推荐文章: