上周有个做智慧物流的朋友找到我说他们想给新建的仓储中心做一个三维数字孪生演示系统用来给客户展示货架利用率、AGV 路径和拣货动线。搁在以前这种需求意味着至少两到三周的建模周期先在 Blender 里手工搭货架再导进前端引擎做数据绑定还得单独写一套代码去对接传感器。但这次我换了一条路——让 Antigravity 这个 AI Agent 直接接管 Blender通过 MCP 协议把建模、改场景、绑数据全部变成可对话、可执行的任务。整体跑下来从环境搭建到做出一个能响应实时数据的仓库基础场景我只花了一个周末。这篇文章是系列第一篇标题带了个上字是因为我准备分两篇把整套方案写透。这篇聚焦在把仓库长出来这个阶段环境怎么搭、MCP 怎么配、AI 怎么用代码生成货架和路径、以及数据如何驱动模型动起来。第二篇再聊浏览器端呈现和实时数据接入。适合对数字孪生、AI 编程 Agent、Blender 自动化建模这些方向感兴趣的工程师和产品同学。有基础的可以直接跳到第 3 节看建模实操纯小白建议从头到尾过一遍我会把每个环节的原理和操作理由都说清楚。1. 为什么是这组组合数字孪生开发的老路与新路1.1 传统链路到底痛在哪先说清楚背景。我做数字孪生相关的项目有三四年了最常见的需求其实就是这几类把现实中的场地、设备、管线在三维里复原再把业务数据库位占用、设备状态、人员位置映射到模型上。听起来不复杂但真正动手过的人都知道光复原现实这一关就能拖垮整个项目。早期我接仓库类项目时流程大概是这样的先找客户要 CAD 图纸对着图纸在 Blender 里手工起模型。一个标准货架区有几百根立柱横梁手工搭建大概需要两三天整个仓库区分为存储区、分拣区、充电区、月台加起来十几个区域建模阶段就得一两周。模型建完还不是终点后面要导成 glTF 或 FBX 给前端用前端团队再写代码绑定数据。每个环节都有格式转换、材质丢失、坐标轴不一致的幺蛾子。更难受的是改需求。客户一开始说货架间距 3.2 米等你搭完他改口说 3.5 米手工场景里这意味着你几乎要重来一半。这种项目做多了以后我最大的感受是数字孪生项目在技术上并不神秘瓶颈全在把现实翻译成三维场景这件事太依赖纯手工了。1.2 Antigravity 在这里不是帮你写代码的工具很多人一听到 AI Agent第一反应是它帮我写点 Python 脚本。确实Antigravity 能写代码但它真正有价值的地方在于它是一个端到端的执行器你描述目标它自己规划步骤自己检查当前环境的状态自己运行命令遇到错误自己修改方案重试。我把它理解成一个愿意坐在你工位旁边、听你指挥并且真的动手干活的实习生。在数字孪生这个场景里这意味着我不需要先把 Blender 的操作流程翻译成精确的代码指令而是可以直接说帮我在场景里建 20 排双深货架每排 8 组高度 5 层层间距 0.4 米它会自己去调用 Blender 的 Python API 实现然后把结果同步回对话里。这种交互方式和传统手写脚本、调试、再手写的区别我用一个实际对比来说明。手写脚本适合固定流程但数字孪生项目的特点是场景需求一直在变——今天客户说货架间距从 3.2 改成 3.5明天说要在月台加两个装卸位。用 Agent 对话式改场景比改代码再跑一遍整体循环快得多。而且 Antigravity 在执行过程中会把每一步操作记录在日志里这相当于自动生成了项目的操作文档后期复盘非常有用。1.3 MCP 协议解决了什么问题MCPModel Context Protocol模型上下文协议是这套方案里的关键基础设施。如果给不了解的朋友一个定位可以把它理解成AI 工具界的 USB-C 接口——它定义了一套统一的规范让 AI 模型能发现外部工具、调用外部工具、接收外部工具返回的结果。在没有 MCP 之前想让 AI 操作 Blender要么用底层自动化去模拟鼠标键盘脆弱得不堪一击Blender 界面稍微变一下脚本就废要么针对特定 AI 写定制插件换一个模型就要重写一遍。MCP 把这个事标准化了Blender 这边启动一个 MCP Server把 Blender 的能力创建物体、修改属性、查询场景信息等暴露成一组工具Antigravity 这类 Agent 作为 MCP Client通过标准协议发现这些工具并调用。Blender 不用关心对面是谁Agent 也不用关心 Blender 的内部实现。打个比方MCP Server 相当于给 Blender 装了一个同声传译器把 Blender 的语音bpy API翻译成 Agent 能理解的标准工具调用。Agent 说我要一个立方体Server 就翻译成一次 bpy 操作指令Agent 说把场景里所有叫 rack 的物体列出来Server 就查完场景把清单返回给 Agent。这种解耦让整个链路变得非常干净。2. 环境搭建实录从零跑通 Antigravity 与 Blender 的对话2.1 版本选型与安装顺序这个组合涉及的软件有三层Blender 本体、Blender 的 MCP 插件Addon、MCP Server以及 Antigravity 客户端的 MCP 配置。每一层都有自己的版本和兼容性问题。先说 Blender 版本。我建议直接用 4.0 或更高版本插件生态和 Python API 的稳定性明显比 3.x 好。我之前在 3.6 上试过一部分 MCP 插件的属性读写接口有兼容问题升到 4.1 后基本没再碰到。MCP 协议本身迭代很快选插件时尽量挑更新活跃的版本并关注它声明支持的 MCP SDK 版本。安装顺序有个小讲究先把 Blender 装好确认能正常启动然后装 Blender 的 MCP 插件一般是 Edit - Preferences - Add-ons 里安装接着在 Blender 里启用插件它会在本地开一个 WebSocket 服务典型端口是 9876最后才去 Antigravity 的 MCP 配置入口把 MCP Server 的启动命令填上。这个顺序别反过来因为 Agent 连接 MCP Server 时Server 会反过来探测 Blender 的 WebSocket 端口如果 Blender 还没就绪第一次握手就会失败。这里插一个我踩过的版本坑有段时间 Blender 更新到 4.2 之后我之前装的 MCP 插件在启动时报错提示插件模块找不到。排查下来是插件用到的某个 Python 库在 Blender 自带的环境里没有需要在 Blender 的 Python 环境里手动补装。这就是antigravity 更新出错这类问题的高频来源——不是 Agent 的问题而是底层工具链脱节。2.2 MCP Server 配置的关键字段在 Antigravity 里配置 MCP Server入口通常在设置的 MCP 管理页面。配置本质上是填一个 JSON核心是告诉 Agent 客户端这个 Server 叫什么、怎么启动、连到哪。我这里用一个典型的配置结构说明字段含义{ mcpServers: { blender: { command: python, args: [-m, blender_mcp, --port, 9876], env: { BLENDER_MCP_HOST: 127.0.0.1 } } } }这里 command 和 args 取决于你用的具体 Blender MCP 实现有的是提供 Python 包有的直接提供一个可执行文件按自己装的版本改就行。env 里通常要指明 MCP Server 需要读取的环境变量比如连接的 WebSocket 主机和端口。有一点很关键MCP Server 是 Agent 在任务启动时拉起来的子进程它必须能够独立找到 Blender 插件开的那个 WebSocket 服务否则工具调用全都会失败。推荐的做法是先不管 Antigravity直接在终端手动运行一次 MCP Server 启动命令确认进程能稳定运行、端口能被访问然后再去 Antigravity 里配置。这一步能拦截掉八成Agent 莫名其妙连不上 Blender的问题。另外把 MCP Server 的日志输出重定向到文件也是一个好习惯后面排查问题会省很多事。2.3 连接验证让 AI 真的碰到 Blender配置好以后怎么确认链路通了我的做法是直接在 Antigravity 里发一个最简单的最小任务创建一个默认立方体把它移动到坐标 (2, 3, 0)然后把当前场景里的物体列表告诉我。如果 Agent 能返回场景信息并且立方体真的出现在 Blender 视口里说明整条链路是通的。我一般会紧接着发第二个任务做反向验证删掉刚才创建的立方体。 这能确认工具调用不是只读的写入操作也正常。这里提一个实际观察到的问题Antigravity 偶尔会在执行中报 agent execution terminated due to error。我在日志里看到过好几种原因最常见的是 MCP Server 没有正常启动Agent 在等待工具返回时超时另外就是权限问题导致子进程被系统杀掉。解决思路是分两步第一步先确认本地手动启动 MCP Server 是正常的第二步把任务规模缩小让 Agent 每次都只调一两个工具别让它在一次任务里做十件事。提示整条链路里最容易出问题的不是 Agent而是 MCP Server 的生命周期。Agent 启动任务时会拉起 MCP Server任务结束有时会留下进程、有时会杀掉。复用连接时如果发现连不上先看本地端口有没有进程在监听。3. 让 AI 用代码搭仓库程序化建模实操3.1 单位与坐标系先立规矩再动手这一节开始正式建模。Blender 的默认单位是米这对仓储场景非常友好——货架间距、巷道宽度这些尺寸本来就是按米算的1:1 建模可以避免后面的比例换算。但坐标系要提前立好规矩。Blender 是 Z 轴向上的右手坐标系这点和前端常用的 Three.js 不一样Three.js 是 Y 轴向上。如果我们最终要把场景导入浏览器展示就得在 Blender 里就约定好哪个方向是北哪个方向是巷道纵轴。我的习惯是仓库的纵向巷道走向沿 Y 轴横向排架方向沿 X 轴高度沿 Z 轴。所有物体按这个约定放置导出到前端做轴变换时只需要做一次全局旋转避免每个模型都要单独校正方向。3.2 货架、托盘、AGV 路径的生成逻辑建模这一步正是发挥 Agent 优势的地方。传统做法是我自己写一个生成货架的脚本反复调参现在只需要给 Agent 描述清楚参数让它生成脚本并执行。我让 Antigravity 生成的货架脚本大致是这样简化版本import bpy from mathutils import Vector def create_shelf_beam(start, end, height, radius0.03): 在 start 和 end 之间生成一根横梁 delta end - start length delta.length direction delta.normalized() bpy.ops.mesh.primitive_cylinder_add(radiusradius, depthlength, location(0, 0, height)) obj bpy.context.active_object # 让圆柱体对齐到 start - end 的方向 obj.rotation_euler direction.to_track_quat(Z, X).to_euler() obj.location (start end) / 2.0 return obj def create_shelf_unit(origin, width1.2, depth0.8, height2.4, levels4): 生成一个双立柱多层的货架单元 objects [] # 四根立柱 corners [ origin, origin Vector((width, 0, 0)), origin Vector((0, depth, 0)), origin Vector((width, depth, 0)), ] for c in corners: bpy.ops.mesh.primitive_cube_add(size0.06, location(c.x, c.y, height / 2)) obj bpy.context.active_object obj.scale.z height / 0.06 objects.append(obj) # 每层两根横梁沿巷道方向 for level in range(levels 1): h level * (height / levels) for d in (0, depth): obj create_shelf_beam(origin Vector((0, d, 0)), origin Vector((width, d, 0)), h) objects.append(obj) return objects这中间有很多细节值得注意立柱用 cube 拉伸还是 cylinder取决于你要不要圆角横梁用 cylinder 做方向对齐时to_track_quat 这个 API 用不好很容易转出莫名其妙的欧拉角让 Agent 在每次生成后截图检查是最快的验证方式层板往往用一个薄 cube 盖在横梁之间不在这个简化示例里。批量排列就相对简单了一层双重循环def layout_shelves(rows, cols_per_row, spacing_x, spacing_y, origin): for row in range(rows): for col in range(cols_per_row): pos origin Vector((row * spacing_x, col * spacing_y, 0)) create_shelf_unit(pos)AGV 路径我一般生成一条 Nurbs 曲线把路径点列表交给 Agent让它转换成曲线控制点。这样后面做运动动画时可以直接通过曲线位置插值拿到任意时刻的坐标不用自己维护点阵。3.3 从布局表到三维场景的信物流转真正做项目的时候客户给的不是20 排 8 组这种诗意描述而是一张 Excel 布局表。这时候要让 Agent 直接读表格文件每一行对应一组货架、一个托盘位或一台设备然后批量生成。我在实际项目里一般这么约定字段type,id,x,y,z,width,depth,height,levels,rotation rack,A-01,0,0,0,1.2,0.8,2.4,4,0 rack,A-02,1.2,0,0,1.2,0.8,2.4,4,0 pallet,P-001,2.8,1.2,0,1.0,1.0,0.15,1,0 agv_charger,C-01,10,8,0,1.5,0.8,0.6,1,90Agent 的任务就是读这个 CSV按 type 映射到对应的生成函数循环创建并把物体的 name 属性设置成 id比如 A-01、P-001。这一步的核心价值在于后面无论数据接口传过来的库位号是A-01-03还是P-001前端都能通过 id 和模型一一对应。三维场景本质上只是业务数据的另一个视图脱离 id 谈建模纯属白干。注意物体命名千万不要用默认的 Cube.001 这种。数字孪生的核心是一一对应如果模型和现实之间没有稳定的标识符后面接数据的时候你会抓狂的。4. 从静态模型到数字孪生数据驱动与状态同步4.1 数据层设计先造模拟数据建模只是第一步数字孪生的灵魂是数据能驱动模型。所以第二个阶段是给场景接数据。我在这个演示项目里分了三个层次数据源层可以是真实的 WMS 接口、MQTT 消息、WebSocket 推送也可以是模拟脚本按固定频率生成假库存数据数据管道层收到数据后做清洗、格式化为统一的 JSON 载荷场景绑定层把 JSON 载荷映射为 Blender 物体的属性变更对于演示系统我强烈建议先用模拟数据。原因很简单真实系统权限多、字段乱调试时你根本分不清是数据问题还是模型问题。模拟数据可以制造一切你想要的边界情况——空库位、满库位、设备告警、AGV 卡住——提前把可视化效果调好等接真实数据时只需要换数据源层的东西。一个典型的载荷长这样{ ts: 1710000000000, type: inventory_update, items: [ {location: A-01-03, status: occupied, sku: SP-1001, weight: 12.5}, {location: A-01-04, status: free, sku: null, weight: 0}, {location: B-02-01, status: alarm, sku: SP-2002, weight: 8.2} ] }4.2 Blender 侧的状态同步机制要让物体响应数据有几种方案我分别试过说下区别。第一种是逐帧轮询用 bpy.app.handlers.frame_change_post 每帧触发一次回调在回调里读取最新数据比如从本地文件、socket 或队列然后修改物体属性。这种方式开发最快适合演示场景缺点是帧率越高开销越大每帧做文件 IO 不划算所以我会主动跳帧比如每 30 帧才检查一次时间戳。第二种是模态操作符modal operatorBlender 的模态机制会持续占用主线程做循环适合做平滑动画但会阻塞用户操作需要小心设计。实际上我建议普通场景别用仓储库位状态是离散的不值得为它牺牲界面的响应性。第三种是用修改器与驱动Drivers适合连续数值变化比如机械臂的关节角度、传送带的速度。仓储场景里库位状态是布尔型的用驱动属于杀鸡用牛刀。我最后选的方案是模拟数据脚本每 2 秒往本地一个 JSON 文件写入一次状态Blender 侧注册一个 frame_change_post 处理器每 60 帧读一次文件并更新材质颜色。货架上每组托盘位对应一个空物体库位被占用就把对应的托盘物体显示出来并调成暖色空库位隐藏托盘告警库位改成红色并且让材质做脉动闪烁。逻辑先写成脚本反复测试稳定后再让 Antigravity 补边界情况整个过程可控很多。4.3 可视化增强热力、轨迹与标注考虑到给客户演示是刚需我在场景里叠加了几个可视化要素。第一个是热力层。把每个库位的占用率映射到平面的彩色小方块上通过调整自发光强度表现热力高低。简单做法是给每个库位单独建一个小平面直接改材质的基础色不需要额外烘焙光照演示完全够用。第二个是 AGV 轨迹线。AGV 移动路径在建模阶段生成以后用一个半透明管状曲线表示计划路径再用一个移动的立方体表示 AGV 当前位置位置数据由模拟数据脚本计算并写入Blender 侧每帧读取后移动立方体。这样一眼就能看出车在哪个位置、接下来往哪走。第三个是标注文字。Blender 里可以用 Text 物体做标注我给每个分区加了一个分区号文本让 Agent 根据布局表自动摆放。客户常常对平面图都要看半天加了三维标注之后讲解成本低了很多。这三样叠加起来演示效果已经能让业务方直观理解整个仓库的运转逻辑了。5. 踩坑记录从跑通到跑稳5.1 MCP 连接不稳定日志、超时与重连这个坑我印象最深。项目做到一半Antigravity 突然失去对 Blender 的控制发任何指令都是超时。我一开始以为是 Agent 的问题后来排查发现Blender 插件还活着但 MCP Server 进程已经挂了而 Agent 并不知道只管在那等着。我的排查链路大致是这样查看 Antigravity 任务日志确认报错发生在 MCP 工具调用步骤本地终端测试 WebSocket 端口确认 Blender 插件侧正常检查 MCP Server 进程是否存在发现已经退出查看 MCP Server 的退出日志确认是连接超时被父进程清理解决方案是在 MCP Server 启动参数里调大超时时间并且在 Antigravity 的提示词里写清楚如果调用 Blender 工具失败先检查进程是否存活并尝试重启。同时把 MCP Server 日志输出到文件出问题时先看文件再改代码别像无头苍蝇一样盲试。5.2 模型比例错乱单位与缩放修正有一版场景做出来前端同事说货架看起来只有人小腿那么高。查了一圈是 Blender 场景单位设置的问题。Blender 的 Unit Scale 如果被设成 0.01你写 1.2 米实际上建模出来的是 1.2 厘米这类问题不仔细看数值根本发现不了。检查方法选中一个已知尺寸的物体打开右侧 Sidebar 的 Item 面板看尺寸数值再和设计尺寸比对。修正方法是把场景单位统一为 MetersUnit Scale 设为 1.0。另外导入 glTF/OBJ 时如果源文件来自其他建模软件可能会带上英寸转换因子导入面板的缩放参数也要检查一遍。这个坑在混合使用多个软件的项目里特别常见。5.3 Agent 执行中断与长任务的拆解agent execution terminated due to error 这句话我见过不下五次。多数原因有三个任务描述太长Agent 的上下文窗口接近上限规划能力明显下降单个任务要求做的事太多超出了单次执行的时间预算Agent 试图做高开销操作比如生成大量模型触发了超时。我的处理方式是拆单一个大需求拆成三到五个小任务每个小任务明确输入输出。比如搭建整个仓库拆成生成货架并命名、生成 AGV 路径线、放置设备模型并摆放标注三个任务每跑完一个就检查一次。这样既能降低执行中断的概率出问题也好定位是哪一步坏了。还有一次碰上 eligibility check failed 之类的启动期报错查下来是本地依赖环境检查没过把组件重装后就好了——这类问题通常和 MCP Server 启动有关和建模逻辑无关先检查环境再怀疑任务本身。5.4 Blender 导出 JSON 与前端衔接数字孪生项目最终大概率要在浏览器里展示Blender 侧要输出两样东西几何数据glTF 或 FBX和场景结构数据JSON。有人问过我Blender 如何导出 JSON其实核心不是导出这个动作而是如何组织你想导出哪些信息。我的做法是写一个导出脚本遍历场景里的空物体和关键模型把层级关系、位置、尺寸、id 字段提取出来写成 JSONimport json import bpy result {objects: []} for obj in bpy.context.scene.objects: if obj.type EMPTY: result[objects].append({ id: obj.name, type: obj.get(warehouse_type, unknown), pos: list(obj.location), rot: list(obj.rotation_euler), scale: list(obj.scale) }) with open(//warehouse_layout.json, w) as f: json.dump(result, f, indent2, ensure_asciiFalse)这里的 warehouse_type 是一个自定义属性在建模阶段就由 Agent 写入。前端读这个 JSON 就能知道场景里有个空物体叫 A-01它代表一个货架组坐标在 (0,0,0)再结合数据接口就能做完整绑定。导出 glTF 时记得在导出面板开启Apply Modifiers和Export Object Name这样前端拿到的节点名和 JSON 里的 id 就能对上。6. 下一篇预告与这套方法的可迁移性这一篇讲的其实是把仓库长出来的部分——数字孪生的地理基础和静态骨架。下一篇我会重点写两件事一件是浏览器端 Three.js 的呈现怎么把 Blender 导出的 glTF 和 JSON 组合成一个可交互的网页场景另一件是实时接上真实的 MQTT 数据流之后如何在 Blender 和前端之间做低延迟的状态同步以及在数据吞吐变高时会不会卡、怎么优化。另外我打算把这套组合的通用经验沉淀一下。不光是 Blender很多本地软件设计工具、编辑器、甚至一些工业仿真软件目前都有 MCP 生态了玩法基本都是同一个套路软件装一个插件、本地开一个端口Agent 通过 MCP 连进来。这个方法论是可以复用的。如果你已经在用别的 Agent 工具配置 MCP 的路径大同小异我在这篇里写的排查思路也同样适用。最后说一句真心话数字孪生这个方向过去最大的门槛不在算法而在把现实世界翻译成三维场景的过程太手工化。AI Agent 加 MCP 这套东西真正改变的是让这个翻译过程从手工绘图加手工绑定变成自然语言描述加自动执行。虽然目前可靠程度还没到能完全无监督跑完整个项目但对于我来说它已经把一周的工作量压到了半天。就冲这一点我觉得值得每个做数字孪生相关方向的人认真试一次。
阅读完成 · 觉得有帮助?