AI驱动三维建模:Codex与SketchUp集成环境搭建与MCP插件开发指南
在实际三维建模和自动化设计流程中将AI代码生成能力与成熟的建模软件如SketchUp深度集成正成为提升设计效率的关键路径。Codex作为强大的AI代码生成模型与SketchUp的结合需要通过一个稳定、高效的桥梁——MCPModel Control Protocol插件来实现。然而从零开始搭建这套环境常常会遇到软件版本冲突、依赖缺失、配置项理解不清等问题导致“第一步”就卡住。本文旨在为开发者、设计师或技术爱好者提供一个清晰、可复现的指南完成从软件下载、环境变量设置到插件初步验证的全过程。我们将聚焦于Windows系统下的典型配置但核心思路同样适用于macOS。学完本课后你将拥有一个可运行的Codex与SketchUp通信基础环境为后续的实时建模、脚本控制等高级功能开发打下坚实基础。1. 理解核心组件Codex、SketchUp与MCP插件在开始安装之前必须厘清三个核心组件各自扮演的角色以及它们之间的协作关系。混淆概念会导致后续配置方向性错误。1.1 CodexAI代码生成引擎Codex是OpenAI基于GPT-3微调而成的代码生成模型。它能够理解自然语言描述并生成多种编程语言的代码片段。在本系列课的语境中Codex并非一个需要本地安装的桌面软件而是一个通过API调用的云端服务或本地部署的类似模型服务。我们的目标是构建一个能够向Codex发送指令如“在SketchUp中创建一个长宽高为2米的立方体”并接收其生成的对应脚本代码如Ruby脚本的客户端。关键点访问方式通常通过HTTP API调用。你需要一个有效的API密钥如果使用OpenAI官方服务或一个本地部署的模型服务端点URL。输出Codex生成的是代码文本例如用于控制SketchUp的Ruby脚本而不是直接的操作指令或三维数据。1.2 SketchUp三维建模平台SketchUp是一款广泛使用的3D建模软件以其易用性和强大的Ruby API著称。用户或插件可以通过编写Ruby脚本以编程方式创建和修改模型中的几何体、组件、材质等。关键点扩展能力SketchUp支持通过Ruby脚本.rb文件或编译后的插件.rbz文件进行功能扩展。通信需求要让AI生成的代码在SketchUp中生效必须建立一条从外部环境如我们的插件服务到SketchUp内部Ruby解释器的通信通道。1.3 MCP插件协议与桥梁MCPModel Control Protocol是本系列课程的核心概念。它不是一个现成的、有唯一官方实现的软件而是一个协议规范或通信约定的抽象概念。其核心思想是定义一套标准化的消息格式使得外部服务如Codex客户端能够与SketchUp这样的建模软件进行双向通信。一个典型的“MCP插件”实现可能包含以下部分SketchUp端插件一个Ruby脚本在SketchUp内部运行负责监听外部请求例如通过本地网络端口、文件监视或进程间通信接收代码并传递给SketchUp的Ruby环境执行然后将执行结果返回。外部服务端/客户端一个独立进程可能用Node.js、Python等编写负责与Codex API交互并将格式化后的指令通过MCP协议发送给SketchUp端插件。为什么需要MCP没有它Codex生成的代码只是一段文本无法自动在SketchUp中运行。MCP协议定义了“如何发送代码”、“如何触发执行”、“如何返回成功或错误信息”从而实现了自动化闭环。2. 基础环境准备安装运行时与工具假设我们的MCP插件外部服务部分使用Node.js编写因为它非常适合构建轻量级的网络服务和处理JSON数据MCP消息很可能采用JSON格式。SketchUp端则使用其原生支持的Ruby。2.1 安装Node.js与npmNode.js是运行JavaScript服务端的环境npm是其包管理器。访问官网前往Node.js官方网站nodejs.org下载LTS长期支持版安装程序。LTS版本更稳定适合生产开发环境。运行安装运行下载的.msi安装包。安装过程中请务必勾选“Automatically install the necessary tools...”或类似选项该选项通常会自动安装构建工具并确保安装路径不含中文和空格。验证安装打开命令提示符CMD或PowerShell执行以下命令node --version npm --version如果正确显示版本号如v18.x.x和9.x.x则安装成功。2.2 安装SketchUp并启用Ruby控制台下载与安装从SketchUp官网下载适合你用途的版本免费版或Pro版。完成常规安装。启用Ruby控制台启动SketchUp进入菜单窗口 (Window) - Ruby控制台 (Ruby Console)。这将打开一个可以输入并立即执行Ruby脚本的命令行窗口。这是测试SketchUp API和插件通信的关键工具。了解插件目录SketchUp插件通常存放在特定目录。你可以通过在Ruby控制台中输入以下命令来找到它puts Sketchup.plugins_directory记下这个路径后续我们的MCP插件Ruby脚本需要放置于此或子目录下。2.3 可选准备Codex API访问凭证如果你计划使用OpenAI的Codex API请注意其可用性可能已发生变化或已被更先进的模型如GPT-4 Turbo with vision替代你需要访问OpenAI平台platform.openai.com。注册账号并创建API密钥。妥善保管该密钥如sk-...后续需要在你的服务端代码中配置。重要提示由于网络访问限制确保你的开发环境能够稳定访问相关API服务。本文不涉及任何网络访问工具的配置。3. 构建一个最小化的MCP插件原型我们将创建一个最简单的“概念验证”MCP插件。它不包含完整的协议但演示了核心通信流程外部服务发送Ruby代码 - SketchUp接收并执行 - 返回结果。3.1 项目结构与初始化创建一个项目文件夹例如sketchup-mcp-bridge。mkdir sketchup-mcp-bridge cd sketchup-mcp-bridge初始化Node.js项目并安装必要的依赖。我们将使用express创建一个简单的Web服务器作为外部服务端使用axios来调用AI API模拟Codex。npm init -y npm install express axios3.2 编写SketchUp端Ruby插件监听器在项目文件夹中创建mcp_listener.rb文件。这个文件最终需要被复制到SketchUp的插件目录。# mcp_listener.rb require sketchup require webrick module MCPBridge class Listener def initialize(port8080) port port server nil end def start # 防止重复启动 stop if server server WEBrick::HTTPServer.new(:Port port) # 定义一个处理POST请求的servlet server.mount_proc /execute do |req, res| res[Content-Type] application/json begin # 解析请求体中的JSON期望格式{code: ruby code here} data JSON.parse(req.body) ruby_code data[code] if ruby_code.nil? || ruby_code.empty? res.body { status: error, message: No code provided }.to_json res.status 400 next end # 关键步骤在SketchUp的上下文中执行接收到的Ruby代码 execution_result nil error nil begin # eval 会在此插件的上下文中执行代码要访问Sketchup模块需确保在其上下文中 execution_result eval(ruby_code) rescue Exception e error e end if error res.body { status: error, message: error.message, backtrace: error.backtrace }.to_json res.status 500 else res.body { status: success, result: execution_result.to_s }.to_json end rescue JSON::ParserError res.body { status: error, message: Invalid JSON }.to_json res.status 400 end end # 在后台线程中启动服务器避免阻塞SketchUp主线程 Thread.new { server.start } puts MCP Listener started on port #{port} UI.messagebox(MCP Listener started on port #{port}) if defined?(UI) end def stop server.shutdown if server server nil puts MCP Listener stopped end end end # 自动启动监听器开发时方便生产环境可能需要菜单控制 listener MCPBridge::Listener.new(8080) listener.start代码解释该插件使用Ruby标准库webrick创建了一个微型的HTTP服务器监听8080端口。它暴露了一个/execute的POST接口。当收到请求时它会解析JSON请求体提取code字段。使用eval方法在SketchUp的Ruby环境中执行这段代码。将执行结果或错误信息包装成JSON返回。警告在生产环境中直接eval来自网络的代码是极度危险的此处仅用于原型演示。真实场景需要严格的代码沙箱、身份验证和指令白名单。3.3 编写Node.js外部服务端在项目根目录创建server.js文件。// server.js const express require(express); const axios require(axios); // 用于模拟调用Codex API const app express(); const port 3000; app.use(express.json()); // 解析JSON请求体 // 模拟的AI服务函数实际应替换为真实的Codex API调用 async function callMockAIService(prompt) { // 这里模拟一个简单的响应。真实情况下你需要 // 1. 设置OpenAI API密钥环境变量中 // 2. 使用axios向 https://api.openai.com/v1/completions 发送请求 // 3. 选择正确的模型如code-davinci-002如果仍可用 // 4. 解析返回的代码片段 console.log(Received prompt: ${prompt}); // 模拟根据提示生成SketchUp Ruby代码 if (prompt.includes(立方体) || prompt.includes(cube)) { return ents Sketchup.active_model.entities cube ents.add_group face cube.entities.add_face([0,0,0], [2.m,0,0], [2.m,2.m,0], [0,2.m,0]) face.pushpull(2.m) puts \创建了一个2米边长的立方体\; } else if (prompt.includes(圆柱) || prompt.includes(cylinder)) { return ents Sketchup.active_model.entities circle ents.add_circle([0,0,0], [0,0,1], 1.m) face ents.add_face(circle) face.pushpull(2.m) puts \创建了一个半径1米、高2米的圆柱\; } else { return # 未能识别的指令: ${prompt} puts \请提供更明确的建模指令例如‘创建一个立方体’。\; } } // 核心端点接收自然语言指令调用AI发送代码到SketchUp执行 app.post(/generate-and-execute, async (req, res) { const { prompt } req.body; if (!prompt) { return res.status(400).json({ error: Prompt is required }); } try { // 步骤1: 调用模拟的AI服务生成Ruby代码 const generatedCode await callMockAIService(prompt); console.log(Generated Ruby Code:\n, generatedCode); // 步骤2: 将生成的代码通过MCP协议发送给SketchUp插件 const sketchupResponse await axios.post(http://localhost:8080/execute, { code: generatedCode }, { timeout: 10000 // 10秒超时 }); // 步骤3: 将SketchUp的执行结果返回给客户端 res.json({ ai_generated_code: generatedCode, sketchup_execution_result: sketchupResponse.data }); } catch (error) { console.error(Error in pipeline:, error.message); let statusCode 500; let message Internal server error; if (error.code ECONNREFUSED) { statusCode 503; message 无法连接到SketchUp MCP插件。请确保SketchUp已启动且插件正在运行。; } else if (error.response) { // SketchUp插件返回的错误 statusCode error.response.status; message SketchUp插件执行错误: ${JSON.stringify(error.response.data)}; } else if (error.request) { statusCode 504; message 请求SketchUp插件超时。; } res.status(statusCode).json({ error: message, details: error.message }); } }); app.listen(port, () { console.log(MCP Bridge server listening on http://localhost:${port}); console.log(POST your prompt to http://localhost:${port}/generate-and-execute); });代码解释服务运行在3000端口提供/generate-and-executePOST接口。callMockAIService函数模拟了Codex API的调用。在实际应用中你需要替换为真实的API调用并妥善管理API密钥建议使用环境变量。收到指令后服务先“生成”Ruby代码然后通过HTTP请求将其发送到运行在SketchUp内部的插件localhost:8080/execute。最后它将AI生成的代码和SketchUp的执行结果一并返回给调用者。包含了基本的错误处理如连接失败、超时等。4. 运行验证与测试现在让我们启动整个系统验证MCP通道是否畅通。4.1 启动SketchUp并加载插件将编写好的mcp_listener.rb文件复制到SketchUp的插件目录路径可通过之前提到的Sketchup.plugins_directory命令获取。重启SketchUp或通过Ruby控制台执行load ‘你的插件路径/mcp_listener.rb’来热加载。观察Ruby控制台输出应该看到“MCP Listener started on port 8080”的消息。同时可能会弹出一个提示框。4.2 启动Node.js服务端在项目目录sketchup-mcp-bridge下打开终端运行node server.js终端应显示服务已在http://localhost:3000启动。4.3 发送测试请求使用任何你熟悉的API测试工具如cURL、Postman或VS Code的REST Client扩展。使用cURL测试curl -X POST http://localhost:3000/generate-and-execute \ -H Content-Type: application/json \ -d {\prompt\: \在原点创建一个边长为2米的立方体\}预期成功响应{ ai_generated_code: ents Sketchup.active_model.entities\ncube ents.add_group\nface cube.entities.add_face([0,0,0], [2.m,0,0], [2.m,2.m,0], [0,2.m,0])\nface.pushpull(2.m)\nputs \创建了一个2米边长的立方体\, sketchup_execution_result: { status: success, result: 创建了一个2米边长的立方体 } }同时你应该能在SketchUp的模型空间中看到一个新创建的立方体并且在Ruby控制台中看到输出的文字。4.4 验证关键检查点SketchUp插件状态Ruby控制台无报错且显示监听启动成功。Node服务状态终端无报错能正常打印接收到的prompt和生成的代码。网络连通性API测试工具能收到来自localhost:3000的完整JSON响应。建模结果SketchUp中确实生成了对应的几何体。错误流尝试发送一个空prompt或无法识别的指令观察错误信息是否按预期返回。5. 常见问题排查第一课典型问题在环境配置和初次运行阶段你很可能遇到以下问题。5.1 SketchUp插件未加载问题现象可能原因检查与解决Ruby控制台没有“MCP Listener started”输出1. 插件文件未放在正确目录。2. 文件有语法错误。3. SketchUp未重启。1. 再次确认Sketchup.plugins_directory路径并将.rb文件放入。2. 在Ruby控制台手动输入load ‘完整文件路径.rb’根据错误信息修正语法。3. 确保重启SketchUp。提示“无法加载文件因为找不到webrick”Ruby环境缺失标准库webrick。SketchUp内置的Ruby通常包含webrick。如果缺失可能是SketchUp版本问题。尝试在插件开头添加require ‘webrick’如果失败考虑使用其他HTTP服务器库如sinatra但这需要额外安装gem复杂度增加。5.2 Node.js服务启动失败或请求报错问题现象可能原因检查与解决Error: listen EADDRINUSE: address already in use :::30003000端口被其他程序占用。1. 修改server.js中的port变量为其他值如3001。2. 或在终端查找占用端口的进程并关闭netstat -ano | findstr :3000然后taskkill /PID 进程号 /F。Error: Cannot find module ‘express’依赖未安装。在项目目录下确保已运行npm install。检查package.json和node_modules文件夹是否存在。请求返回“无法连接到SketchUp MCP插件”1. SketchUp插件未运行。2. 防火墙阻止了端口通信。3.server.js中连接的端口(8080)与插件监听端口不一致。1. 确认SketchUp插件已成功启动看Ruby控制台。2. 暂时关闭防火墙测试或添加入站规则。3. 检查mcp_listener.rb中的port和server.js中axios.post的URL端口是否一致。5.3 代码执行失败或无效果问题现象可能原因检查与解决SketchUp执行结果返回“success”但模型无变化生成的Ruby代码逻辑有误或操作未在活动模型上执行。1. 检查Node服务端日志查看AI生成的原始Ruby代码是什么。2. 将该代码直接复制到SketchUp的Ruby控制台中执行看是否有错误或效果。3. 确保代码中引用了Sketchup.active_model.entities来获取当前模型的实体集合。返回“error”消息为安全限制相关SketchUp的安全设置阻止了某些操作。SketchUp对一些潜在危险操作如文件IO、网络访问有沙箱限制。原型阶段在受信任环境开发。复杂的插件可能需要用户手动批准。6. 环境配置清单与生产考量完成第一课你的基础环境应满足以下清单[ ] Node.js (LTS版本) 及 npm 已安装并可通过命令行访问。[ ] SketchUp 已安装Ruby控制台可正常打开。[ ] 项目目录已初始化package.json和node_modules存在。[ ]mcp_listener.rb文件已放入SketchUp插件目录且SketchUp启动时无加载错误。[ ] Node.js服务端 (server.js) 能正常启动监听指定端口。[ ] 能通过API测试工具成功触发一次“自然语言 - AI生成代码 - SketchUp执行 - 返回结果”的完整流程。从原型到生产环境的考量安全性直接eval网络代码是灾难性的。生产环境必须实现身份验证/授权服务端和插件间使用密钥签名。指令白名单只允许执行预先审核过安全性的、有限的API命令集而非任意Ruby代码。沙箱环境考虑在隔离的、权限受限的上下文中执行代码。通信协议本课使用简单的HTTPJSON。正式的MCP协议可能会定义更丰富的消息类型如初始化、工具调用、流式响应等。错误处理与重试需要更健壮的网络错误处理、超时重试和事务回滚机制。性能与并发WEBrick是单线程的并发能力弱。生产环境需换用并发性能更好的服务器如Puma并考虑连接池、队列等。配置外置服务器端口、API密钥、SketchUp连接地址等应通过环境变量或配置文件管理而非硬编码。日志与监控需要完整的请求日志、错误日志和性能指标便于排查问题。第一课的目标是打通最关键的技术链路理解数据是如何在“自然语言 - AI服务 - 桥接服务 - 建模软件”这个链条中流动的。有了这个可运行的基础框架后续课程才能在此基础上深入探讨更复杂的MCP协议设计、更安全的代码执行策略、更丰富的SketchUp API应用以及如何集成真正的Codex或类似大模型API。