你站在一座现代物流园区的中控室里,大屏上实时展示的并不是平面监控地图,而是一整套和真实库区一一对应的 3D 智慧仓储数字孪生场景——AGV 在地面巷道里穿梭,堆垛机正在切换托盘位,货架层格的空闲与占用状态用颜色实时刷新。这种画面现在越来越多出现在物流自动化方案里,但真正动手搭建过的朋友都知道,传统做法里“空间理解”和“场景建模”是最耗人的两个环节。我这一阵在跑的项目里,就是用Antigravity + Blender MCP组合把这两件事一次性串起来的:Antigravity 负责让 AI 具备三维空间认知能力,Blender MCP 负责让 AI 直接操作 Blender 做批量建模。这篇文章就以我最近的智慧仓储数字孪生搭建过程为背景,把这条链路怎么拆、怎么装、怎么跑、怎么避坑讲清楚。适合正在做数字孪生 POC 的开发者、物流自动化行业从业者,以及所有对 AI+3D 工作流感兴趣的朋友,新手也可以顺着步骤复现到能用的程度。既然是上篇,我先把“空间认知引擎 + AI 建模工具”这条主线讲透,动态数据联动和空间推演留到下篇再展开。
1. 链路拆解:Antigravity 和 Blender MCP 在这套方案里到底各干什么
1.1 Antigravity:让大模型从“二维理解”跨进“三维空间认知”
先说说 Antigravity。它不是一个渲染工具,也不是一个普通的三维引擎,而是一套偏“具身智能”的开源工程框架,核心是把大模型往空间理解能力上再推一步。传统大模型在图像上做得非常好,能识别“这是一排货架”“那是一台 AGV”,但你要它回答“这排货架摆在这个位置会不会挡住 AGV 的转弯路径”“如果在这个区域临时堆一批货物,哪些巷道会被压缩”,它就很容易犯糊涂,因为它没有真正建立三维空间心智。
Antigravity 的价值就在这里。它的核心模块里包含了类似 3D Reconciler、Token Learner 这样的空间认知组件,能把多视角图像、深度图、点云等输入统一到一个三维记忆空间里,再基于这个空间预测后续场景状态。你可以把它理解成一种“三维世界模型”:给了环境信息之后,它不仅能告诉你“现在是什么样”,还能推断“接下来最可能变成什么样”。这在智慧仓储场景里非常有用——后面我会单独讲怎么用它做货位预测和 AGV 路径推演。
所以在这套链路里,Antigravity 的角色是“大脑”,负责空间推理、场景解释、布局建议。它不直接生成 Blender 模型,但它输出的空间决策,会变成 Blender MCP 的执行指令。这个分工一定先明确,否则后面很容易把两个工具混为一谈。
1.2 Blender MCP:给 AI 接上一双能直接建模的“手”
MCP 全称是 Model Context Protocol,由 Anthropic 推出的一个开放协议,解决的核心问题只有一个:让 AI 客户端能统一调用外部工具和数据源。类比起来很像 USB-C 接口——以前每接一个新设备就要多一根专用线,现在协议统一了,AI 客户端只要配一次 MCP Server,就可以安全调用 Blender 的能力。
Blender MCP 具体做的工作,是作为 MCP Server 运行在本地或内网,它一边和 AI 客户端通信,一边通过 Blender 的 Python API 调用 Blender 插件来执行建模、修改场景、导出文件等操作。AI 端发起类似“创建一排货架”的 function call,Blender MCP 接收后解析成一组 BPython 指令,实际操控 Blender 在三维视口里一步步建模。
这意味着什么?意味着你不用手动去拖拽每一个立方体,不用一条条写 Blender Python 脚本,甚至不用进 Blender 界面。你用自然语言描述“按 5 列 3 层生成货架,格口宽 1.2 米,留出 2.5 米巷道”,AI 会理解语义并写成对应参数,MCP Server 再把它落地成真实场景。整个链路跑通之后,改仓储布局、批量生成货架、调整 AGV 模型,都只是改自然语言指令的事。
1.3 整体架构:从自然语言到三维可视化的完整通路
把两个工具放到一起来看,整条链路非常清晰:
- 输入层:人类的自然语言指令或仓储问题,比如“在 B 区域增加三排货架”“查看当前货架占用率较高的区域”;
- 决策层:Antigravity 对环境进行空间理解,对布局合理性、遮挡关系、路径规划等问题做推理,输出“应该在哪里放置货架、货架参数是什么、哪些区域需要调整”等决策信息;
- 工具层:Blender MCP 接收决策指令,调用 Blender Python API,完成建模、修改材质、导出 GLB/JSON 等操作;
- 可视化层:Blender 负责离线渲染和复杂场景预览,Web 端则由 Three.js 加载导出模型,做在线交互和实时数据叠加。
我用一张表格把这三个核心角色拆开看:
| 组件 | 核心职责 | 输入 | 输出 |
|---|---|---|---|
| Antigravity | 空间认知、场景推理、状态预测 | 图片/点云/深度图/3D场景数据 | 空间结构化描述、布局决策、预测结果 |
| Blender MCP | 将 AI 指令转成 Blender 操作 | function call 参数 | Blender 场景编辑、模型创建、文件导出 |
| Three.js | 浏览器端渲染与数据联动 | GLB/JSON 模型、实时数据 | 可交互的数字化大屏 |
注意,这里我们没有把大模型本身单独列出来,因为它其实藏在了两层里:Antigravity 内部有大模型作为空间推理引擎,AI 客户端本身也有语言模型负责理解用户语义。你在使用的时候,只需要关心“用户说什么,最后场景变成什么样”,中间的翻译工作由这套链路自动完成。
2. 环境准备与安装:先把三个“轮子”都转起来
2.1 Antigravity 安装与基础验证
我实际操作时的环境是 Ubuntu 22.04 + Python 3.10 + 一张显存 12GB 起的显卡。Antigravity 依赖 PyTorch 生态,所以第一步建议用 conda 建独立环境,避免污染其他项目:
conda create -n antigravity python=3.10 -y conda activate antigravity pip install antigravity-engine如果你是从源码安装,则按官方仓库说明先 git clone 再安装依赖,通常步骤是:
git clone https://github.com/你的仓库地址/antigravity.git cd antigravity pip install -r requirements.txt安装完成后,跑一下版本验证和一个小测试,确保环境没问题:
antigravity --version antigravity run --demo第一次运行会提示登录开发者账号,你按提示完成授权即可。授权之后,Antigravity 会把空间推理能力加载进来,通常几秒到几十秒不等。如果看到 “execution terminated due to error” 或 “更新出错” 这类提示,我在第 4 章专门整理了排查方法,这里先不展开。
2.2 Blender 与 Blender MCP 安装
Blender 我建议直接用 4.x 以上版本,我这边用的是 Blender 4.2 LTS。安装路径不要带中文,尽量简洁,否则后面 MCP Server 读取插件路径容易出问题。
Blender MCP 的安装分两步。第一步是把插件装进 Blender:打开 Blender 后进入 Edit > Preferences > Add-ons,选择 Install from Disk,指向你下载的 blender_mcp 插件压缩包。启用后插件会显示在 Add-ons 列表里,并在 Blender 的侧边栏多出一个 MCP 面板。
第二步是配置 MCP Server。你会看到两个关键信息:一个是本地 Server 监听端口,另一个是 MCP Server 入口文件的路径。把这个入口文件路径记录下来,后面在 MCP 客户端配置里要填。
2.3 在支持 MCP 的客户端里启用连接
我用的是 Claude Desktop 作为演示客户端,其他支持 MCP 的桌面客户端操作类似。先找到客户端的配置文件,比如 Claude Desktop 的claude_desktop_config.json,加入 Blender MCP 配置:
{ "mcpServers": { "blender": { "command": "python", "args": [ "/你的绝对路径/blender-mcp/server.py" ] } } }注意替换成你自己的 Python 绝对路径和 server.py 绝对路径。保存并重启客户端后,在对话里发一条测试指令,比如“请获取当前 Blender 场景的对象数量并返回”。如果配置正确,客户端会调用 Blender MCP 工具,场景里如果有任何物体,你会看到返回的 JSON 信息,同时 Blender 界面会同步刷新。这一步跑通,整个链路的基础就已经就位。
提示:MCP Server 只连接本地或内网里的 Blender,不会也不需要通过外部云端服务转发。配置后如果连接失败,先检查 Blender 插件是否启用、端口是否被防火墙拦截,不要急着怀疑网络环境。
3. 实操流程:从一句中文指令到可运行的仓储场景
3.1 手工搭出基础仓储场景
先别急着让 AI 全自动,我的习惯是自己先手动搭一个基础场景,把坐标原点、单位、命名规则定下来,再让 AI 在上面做增量修改,否则 AI 生成的模型容易出现位置错乱、尺度混乱等问题。
仓储场景一般包含这几类元素:地面、货架、AGV、货物箱、巷道标识线。下面这段 Blender Python 脚本可以快速生成“一个地板 + 一排 5 列 3 层货架”的基础结构:
import bpy # 清空默认场景 bpy.ops.wm.read_factory_settings(use_empty=True) # 地面 bpy.ops.mesh.primitive_plane_add(size=30, location=(0, 0, 0)) floor = bpy.context.object floor.name = "floor" # 货架参数 rows = 5 # 列数 levels = 3 # 层数 bay_width = 1.2 bay_depth = 0.8 bay_height = 1.5 shelf_offset_x = -3.0 for r in range(rows): for l in range(levels): # 立柱简化成小立方体 for dx in (0, bay_depth): bpy.ops.mesh.primitive_cube_add( size=0.1, location=(shelf_offset_x + r * bay_width, dx, l * bay_height) ) # 层板 bpy.ops.mesh.primitive_cube_add( scale=(bay_width * 0.5, bay_depth * 0.5, 0.05), location=(shelf_offset_x + r * bay_width, bay_depth * 0.5, l * bay_height) )跑完这段代码,Blender 里就有了一个最简单的货架骨架。注意我用了bay_width、bay_depth、bay_height这样的参数,目的就是让后续 AI 能针对这些参数做调整。模型不精致没关系,数字孪生第一版本的核心是结构和坐标信息准确。
3.2 让 AI 批量生成货架与轨道:Blender MCP 指令示例
基础场景搭好后,就可以尝试用自然语言让 AI 继续干活了。比如我让 AI 在 B 区域生成 3 排货架,间隔 2.5 米,各 5 列 3 层,并为每个格口放一个半透明的蓝色物流箱。实际对话中我会这样描述:
“在坐标 (10, 2, 0) 处创建一排货架,方向沿 Y 轴正向延伸,5 列 3 层,单格尺寸 1.2m x 0.8m x 1.5m。每个货位上方 0.6m 处放置一个半透明蓝色立方体作为物流箱标记。”
AI 端会把这个语义转成 Blender MCP 的工具调用,比如create_object、modify_object,参数可能长这样:
tool: create_object params: type: cube name: "shelf_A_01" location: [10, 2, 0] scale: [1.2, 0.8, 1.5]Blender MCP 接收到之后,调用 Blender API 生成物体,同时在场景里自动命名shelf_A_01。这种命名规范非常重要,后面数据联动和货位映射全靠它。
“拉框”这一步也值得单独提一下。在 3D 点云或三维场景里,我们经常需要手动拉一个矩形框选中一片区域,标记为某个货位或某个设备范围。Blender 中一般用 Box Select 工具,框选对象后,AI 可以通过 MCP 的get_selected_objects拿到这些对象的名字和包围盒信息。做点云拉框标注时,先导入点云,再用框选范围,接着让 AI 把框内点云聚类成一个个货位区域,输出成 JSON,这为后续仓储管理系统做货位分配打下了基础。
3.3 导出 GLB 与 JSON,让 Three.js 前端直接用
Blender 场景建好之后,下一步是把模型导出给前端。最省心的是 GLB 格式,它自带场景层级、材质和坐标轴信息,Three.js 直接加载即可。在 Blender 里选中所有物体,File > Export > glTF 2.0,导出格式选 GLB,坐标系统默认即可,记得在左侧面板勾选 “Apply Transform”,让模型坐标归一到全局坐标系。
如果是导出结构化 JSON,比如要让前端拿到“每个货架的格口、每个物流箱的坐标”,我建议直接在 Blender 里跑一段脚本,把场景对象序列化成带名称、位置、缩放信息的数组:
import json scene_data = [] for obj in bpy.context.scene.objects: scene_data.append({ "name": obj.name, "type": obj.type, "location": list(obj.location), "rotation": list(obj.rotation_euler), "scale": list(obj.scale), "parent": obj.parent.name if obj.parent else None }) with open("warehouse_scene.json", "w") as f: json.dump(scene_data, f, indent=2)前端加载 GLB 场景只需要十行左右代码:
import * as THREE from 'three'; import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader.js'; import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 0.1, 1000); camera.position.set(20, 18, 16); const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); new OrbitControls(camera, renderer.domElement); const loader = new GLTFLoader(); loader.load('/models/warehouse.glb', (gltf) => { scene.add(gltf.scene); renderer.render(scene, camera); }, undefined, (err) => console.error(err));这样,网页端的数字孪生场景已经可以鼠标拖拽旋转、缩放查看了。如果你用的是 http-server 或 Vite 做静态服务,直接把它跑起来就能看效果。
4. 踩坑实录:Antigravity + Blender MCP 常见问题速查
4.1 错误症状、原因与处理办法对照表
这套链路看着顺畅,实际跑起来坑不少。我把最近一周踩过的和朋友们反馈过的问题整理成速查表,碰到类似情况直接对照处理。
| 症状 | 可能原因 | 处理办法 |
|---|---|---|
| antigravity agent execution terminated due to error | Python 依赖版本冲突,或 torch 与 CUDA 版本不匹配 | 查看完整报错日志末尾,优先检查 torch 版本;建议重建干净 conda 环境重装依赖 |
| antigravity 更新出错 | 项目升级后旧配置或旧依赖残留 | 按官方 changelog 重点看依赖版本变化;删掉缓存重装 |
| antigravity 登录后提示 403 | 授权令牌失效、本地系统时间不对 | 检查系统时间是否准确,重新登录授权 |
| Blender MCP 连接失败 | Blender 插件未启用,或端口被占用 | 重启 Blender,在 MCP 面板查看监听端口,必要时换端口重新启动 |
| 客户端调用工具超时 | 场景物体过多,Blender 主线程被阻塞 | 给 Blender 增加步骤信息输出,先简化场景;大型场景分批建模 |
| 生成的物体位置混乱 | Blender 世界原点和坐标轴方向没约定好 | 建模前去 Dell 好原点,所有 AI 指令说明以世界坐标为准 |
| 模型导出到 Three.js 后比例失真 | Blender 单位设置或 Apply Transform 未生效 | 统一使用米制单位,导出前应用旋转缩放变换 |
4.2 三个容易忽视但能救命的小习惯
第一,永远在让 AI 执行批量操作之前保存一份 .blend 文件。AI 建模虽然方便,但一旦某个参数传错,可能一口气把几十个物体全部改动。我在跑批量建模时习惯先File > Save As保存一个版本,再让 AI 动手,改坏了直接回滚,省掉一大半返工时间。
第二,一定要给 AI 设置可修改范围。比如约定“只允许修改名字前缀为shelf_和agv_的物体”,其他场景元素视为“只读”。这可以用一句 system prompt 或者在 MCP Server 里做对象名过滤实现,否则 AI 在理解偏差时可能把你的地面、灯光甚至相机都给改了。
第三,坐标和单位的统一比造型精细度更重要。数字孪生场景最终要接入真实仓储数据,AGV 位置、货位坐标都要和物理环境一一对应。所以建模时要坚持“1 米 = 1 个 Blender 单位”,并且坐标原点放在仓储区域的固定角点,以后接实时数据时才知道每一个点的位置在哪里。
5. 再往下走:从静态孪生到动态数据的下一步规划
5.1 把实时仓储数据接进来
现在场景还是“静态孪生”,更像一个三维展示模型。要变成真正的智慧仓储数字孪生,必须把实时数据接进来。我这边用了 MQTT 和 WebSocket 两条线:设备状态走 MQTT,位置坐标和任务信息走 WebSocket。
前端收到一条 AGV 位置更新消息后,Three.js 里对应物体的位置也要平滑更新,而不是瞬移。我习惯用一个简单的 lerp 插值来做平滑移动,效果非常自然:
const targetPos = { x: 12.3, y: 6.7, z: 0 }; const agv = scene.getObjectByName('AGV-01'); agv.position.x += (targetPos.x - agv.position.x) * 0.1; agv.position.y += (targetPos.y - agv.position.y) * 0.1;数据格式尽量统一,比如前端接到的 AGV 状态消息是这样的:
{ "agvId": "AGV-01", "x": 12.3, "y": 6.7, "angle": 90, "status": "moving", "zone": "B-03" }货位数据则可以用“坐标 + 状态”表达,把箱子的颜色绑定为状态字段,空闲绿色、占用红色、待检黄色。这样整个仓储大屏就从一个静态模型变成有“生命体征”的系统。
5.2 Antigravity 在做空间推演方面的扩展
动态数据接进来之后,就该让 Antigravity 发挥真正价值了。把过去一周的 AGV 轨迹、货架出入库记录喂给它,它可以做几件很有意思的事:预测下一小时的拥堵区域、判断某个货位组合是否会导致拣货路径绕远、在设备故障前通过异常轨迹提前预警。
这部分的工程化内容比较多,涉及数据清洗、特征拼接、空间对齐、模型微调,我会在下一篇里重点讲讲我自己的做法。这里先给一个方向:Antigravity 输出的不是一张结果图,而是一组“空间状态描述”,你可以把它转成可视化方案,比如在 Three.js 里把预测的高流量区域标成热力图,这比纯文本预警直观得多。
我在实际做这个项目的体会是,没必要一开始就把系统设计得无比复杂。先把 Antigravity 跑通、Blender MCP 能用、Three.js 能加载场景,这就是一个可以演示的完整 POC。后续每加一层数据、每接一个传感器,都是在这个底座上叠加能力。上篇就先分享到这里,下篇我会接着讲动态数据联动、点云拉框标注和空间推演的具体实现,以及更多模型接入方式的实战记录。