今年年初我在忙一个智慧仓储可视化项目,客户绕了很大一圈才说清楚需求:他们要的不是几张效果图,而是一个能跟真实仓库布局严格对应的 3D 数字孪生场景。仓库面积不小,货架、托盘、AGV、月台、消防通道全都要进模型。刚开始我打算按老路子手动在 Blender 里建模,结果光是一个区域的货架就建到怀疑人生。后来我换了个思路,把 Antigravity 和 Blender MCP 接在一起,用自然语言让 AI 智能体直接在 Blender 里批量生成仓储场景,效率完全不一样。
这篇文章是这个系列的上篇,重点讲两件事:一是这套组合到底怎么选型、怎么跑通最小链路;二是怎么把“智慧仓储数字孪生”这个很虚的词,拆成 Blender 里一个个能落地、能验收的建模任务。如果你在做数字孪生、3D 可视化、仓库仿真,或者只是好奇 AI 智能体怎么操作 Blender,这篇应该能给你一套可以直接照搬的打法。
1. 先把牌理清楚:Antigravity、Blender MCP 与“上篇”的边界
1.1 Antigravity 是什么,它解决什么问题
先说我理解的 Antigravity:它是一个面向 AI 智能体运行和编排的云平台。和单次对话不一样,它能让智能体带着目标、带上工具、按步骤执行,并且每一步都能看到返回结果、根据结果调整下一步。这种形态非常适合“建一个仓库模型”这种多步骤任务:先建建筑结构,再排货架,再放托盘,最后做检查。
我最初用它的动机很简单:我不想要一个只能陪我聊天的窗口,我想要一个能替我干活的执行体。Antigravity 的特点是它把思考和执行放在一起。你在控制台新建项目,把目标写清楚,挂上工具,剩下的调用顺序、参数调整、异常处理,智能体会自己决策。比如你说“建一个 5 列 3 层的货架”,它不会停在“好的,我来帮你建”这一步,而是真的去调 Blender 的接口把对象建出来。
不过这里有个容易误解的点:Antigravity 本身不懂 Blender,它懂的是“如何调用工具”。所以真正决定它能干什么的,是你给它挂了哪些工具。这也是为什么 Blender MCP 是整个方案里的关键桥梁。
1.2 Blender MCP:给 AI 装上一双能操作 Blender 的手
MCP 全称是 Model Context Protocol,说人话就是一套统一接口协议。它解决的痛点是:大模型默认只能读写文本,没法直接碰 Blender 这种软件。Blender MCP 做的事情,是在 Blender 里跑一个插件,再启动一个 MCP server,把 bpy 的能力包装成一组可以被智能体调用的工具。
我记得接上去之后看到的工具列表包括:获取当前场景摘要、创建对象、修改对象变换、执行任意 Python 代码等。最后那个“执行 python”其实才是核心,因为 bpy 是 Blender 的完整控制接口,能执行 Python 就约等于能执行 Blender 里任何操作。
打个比方,MCP 像统一充电口,AI 是手机,Blender 是充电器。没有统一协议之前,每个软件都要自己的私有对接方式;有了 MCP,AI 拿同一套协议就能指挥 Blender。你只需要保证两边都支持这个协议,剩下的通信细节协议自己处理。
1.3 为什么这篇只写“上篇”
数字孪生按我的习惯要拆成两个阶段:先有静态骨架,再挂动态数据。静态骨架解决“像不像、全不全、规范不规范”,动态数据解决“活不活、准不准、能不能驱动”。
拿智慧仓储举例,如果模型里的货架编号和真实 WMS 系统的库位编号对不上,那模型再精细也是摆设;反过来,如果数据能驱动模型实时更新状态,哪怕几何体粗糙一点,它也是有价值的数字孪生。上篇先做静态骨架,把环境、工具、建模规范、验收方法讲透,下篇再讲数据接入、动画驱动和导出,避免把太多东西塞进一篇文章,结果哪部分都讲不透。
2. 最小可行链路:从装插件到让智能体建出一个立方体
2.1 环境清单与版本选择
先把环境列出来,我在项目里实际用的搭配是这些:
| 组件 | 版本建议 | 用途 |
|---|---|---|
| Antigravity 控制台 | 官网最新版 | 创建项目、运行智能体 |
| Blender | 4.1 LTS 或 3.6 LTS | 建模载体,提供 bpy 接口 |
| blender-mcp | 最新 release | 提供 Blender 端插件和 MCP server |
| Node.js | 18+ | 运行 MCP server 依赖 |
| Python | 3.10+ | 部分脚本工具依赖 |
版本这里有个容易踩的坑:不要盲目追 Blender 新版。我一开始用 4.3,结果 MCP 插件里几个 bpy 属性接口报错,退回 4.1 后一直很稳定。如果你看到插件作者在 README 里明确写了支持版本,照着写就好,别自作主张。
2.2 安装 Blender MCP 并确认能启动
Blender MCP 一般是两部分:Blender 插件 + MCP server 进程。安装时先在 Blender 偏好设置里安装插件,装完在侧边栏能找到面板,填好端口后点启动。正常的话,Blender 窗口左上角会输出类似 “WebSocket server started” 的日志。
然后启动 MCP server 进程,通常是用命令行跑起来。我建议你先不看 Antigravity,直接手动验证 MCP server 能连上 Blender 插件,因为这里如果出问题,后边智能体那边会显示一堆让人摸不着头脑的错误。检查方法很简单:两个服务都起来后,看插件面板的连接状态是不是变绿或显示 connected。
这里有一个容易忽略的细节:Blender 插件里填的端口和 MCP server 的端口是两个概念。很多默认值看起来都是 9876,但不同版本的插件定义不一样。务必把配置文件里两处端口对齐,否则 Blender 说“服务已启动”,MCP server 那边却连了个寂寞。
2.3 在 Antigravity 项目里挂载 MCP 工具
环境就绪后,到 Antigravity 控制台创建项目,然后在项目工具配置里新增一个 MCP server 配置。填写服务地址时要注意你的运行模式:如果智能体跑在本地开发模式,填本机地址就可以;如果智能体跑在云端,就不能填 localhost,这个坑我第 5 节会详细说。
配置完成后,Antigravity 侧会拉取工具列表。等控制台显示出一串 blender 相关工具名,就说明挂载成功。这一步的核心验证点是:智能体能不能“看见”工具。如果列表为空,先别写任何提示词,回头检查地址、端口和 server 进程。
2.4 跑通最小验证:一个立方体就够
一切准备就绪后,不要一上来就让它建整个仓库,先用最小的任务验证链路。我给智能体的第一句话是:
请在 Blender 里新建一个 2 米乘 2 米乘 2 米的立方体,命名 Warehouse_Block_Test,并归入名为 Test 的集合。
这句话虽然短,但它测试了三件事:智能体能否选中正确的工具、能否理解尺寸参数并传给 Blender、能否把模型生成结果反馈回来。观察 Blender 场景里是否真的出现立方体,再看智能体的返回结果里有没有对象名。
只要这三件事都成立,链路就是通的。后面做整个仓库只是放大工作量,架构上不会再出现新的问题。这个小小的立方体,相当于数字孪生工程的“hello world”。
3. 数字孪生不是沙盘:仓储场景的信息模型与建模规范
3.1 先搭信息骨架,不要先急着建几何体
做数字孪生最忌讳一上来就建一堆好看但不认识的东西。仓库里的每个模型必须对应真实资产,也就是说,每个对象都要有“身份证”:唯一编号、类型、物理尺寸、空间位置。
我习惯把模型分成三层:几何层解决“长得像”,逻辑层解决“能不能查到”,数据层解决“能不能联动”。很多数字孪生项目最后死掉,不是模型不够精细,而是货架编号对不上系统里的库位编号。所以上篇里,我们做静态骨架时就要把逻辑层的东西埋进去,而不是等技术对接时再补。
3.2 智慧仓储的核心建模元素
我把仓储场景里的建模对象整理成四类,这也是我给 Antigravity 写任务时的分类方式:
| 类别 | 常见元素 | 孪生阶段 |
|---|---|---|
| 建筑结构 | 墙体、柱网、地面、消防卷帘、月台门 | 静态阶段 |
| 存储系统 | 货架、托盘、周转箱、立体库堆垛机 | 静态为主,数据下篇 |
| 搬运系统 | AGV、叉车、输送线、机械臂 | 静态建模,动态下篇 |
| 环境与标识 | 安全通道、地标线、充电桩、摄像头 | 静态阶段 |
建设优先级也按这个顺序:建筑结构先打底,存储系统是核心,搬运系统看有没有动画需求,环境标识最后做。别让智能体一次性建完所有东西,按区域、分批次生成,验收一块再建下一块。
3.3 坐标、单位与命名纪律
Blender 默认单位是米,但绝大多数仓库 CAD 图给的是毫米。我统一的处理方式是:全场景按米建模,所有 CAD 坐标在进 Blender 之前除以 1000。
坐标系原点也是个容易出问题的点。我习惯把原点放在仓库西南角地面,X 轴向东,Y 轴向北,Z 轴向上,所有对象位置都基于这个原点计算。别小看这一步,后期如果要对接 IoT 定位数据,坐标系不一致就是灾难现场。
命名规范我直接贴我项目里正在用的:集合按功能划分,例如 Storage、Equipment、Building、Environment;对象名格式是“类型_区域_行_列_层”。比如货架叫 Shelf_A01_02_03_L2,意思就是 A01 区域第 2 排第 3 列第 2 层;托盘叫 Pallet_A01_02_03_L2。这样光看对象名就能知道它在仓库里哪个位置,排查问题时候效率高很多。
3.4 给智能体写一份“施工规范”
让 AI 批量干活不失控的关键,是把规则前置。我会把施工规范写成一个固定文本,每次都给智能体带上,而不是指望它临场发挥。我的规范大概长这样:
- 全场景默认单位是米,尺寸一律用米;
- 所有新建对象必须归入对应集合,不允许散落在根目录;
- 托盘统一尺寸:长 1.2 米、宽 1 米、含货物高 1.5 米;
- 主通道宽度不小于 2.8 米;
- 对象命名必须符合命名规范;
- 禁止合并对象、禁止清理掉自定义属性;
- 每个库位对象必须添加自定义属性:shelf_id、grid_x、grid_y、level。
这些规则看起来死板,但它们是智能体批量建模时的锚点。比如你让它建 45 个库位,如果没有规范,它可能把托盘尺寸建得一个样一个样;有了规范,每个步骤都会朝规则上靠。后面做数据驱动时,这些自定义属性就是现成的接口。
4. 实战第一个任务:让 Antigravity 在 Blender 里生成托盘库
4.1 把客户需求拆成可执行参数
客户说“先做一个托盘库”,这句话是不能直接丢给智能体的。我得先拆成参数。当时我定的目标是:3 排货架、每排 5 列、3 层,总共 45 个库位,每个库位放一个标准托盘。参数如下:
- 货架排数:3
- 每排列数:5
- 层数:3
- 排距:4 米
- 列距:3 米
- 层高:1.8 米
- 托盘尺寸:1.2 x 1.0 x 1.5 米(含货物)
这个拆解过程其实就是把业务语言翻译成建模语言。客户不在意你用的是 EMPTY 还是 Mesh,但你在意,因为后面要挂属性、要导出、要做碰撞检查。参数越明确,智能体发挥空间越小,结果越稳定。
4.2 我实际用的提示词模板
下面这个模板我每次做仓储建模都会改改参数直接用,你拿去改成自己的场景就行:
你是仓储数字孪生建模助手。请严格按以下规范在 Blender 中生成一个托盘库: 1. 创建集合 Storage/PalletRack_A,所有对象放入该集合。 2. 使用 bpy 脚本循环生成 3 排货架,每排 5 列、3 层。 3. 每列宽度 3 米,每层层高 1.8 米,排距 4 米。 4. 货架立柱采用 0.1 米 x 0.1 米的方柱,横梁高度按层高设置。 5. 每个库位中央放置一个托盘,托盘尺寸 1.2m x 1.0m x 1.5m。 6. 每个库位对象添加自定义属性 shelf_id、grid_x、grid_y、level,命名按“类型_区域_行_列_层”规则。 7. 完成后执行检查脚本,统计对象数量、缺失属性和坐标范围,并以 JSON 格式输出结果。这里最关键的是第 2 条:明确要求它使用 bpy 脚本循环生成。因为 45 个库位如果让智能体一个个调用“创建对象”工具,至少几十次工具往返,又慢又容易中断;而写一次脚本循环,一次工具调用就完成。
4.3 工具背后发生了什么
Antigravity 拿到这个提示词后,通常会先调用场景摘要工具看看 Blender 里现在有什么。如果场景是空的,它就会进入批量生成分支,也就是写一段 Python 代码交给 execute_blender_code 执行。
脚本内部逻辑大致是:先检查旧集合、清空冲突对象,再创建集合,然后三层嵌套 for 循环遍历排、列、层,计算每个实例的世界坐标,用 bpy 的 primitive 创建长方体作为货架和托盘,最后给每个库位设置自定义属性。这一步我们看不到实时画面,但可以从返回结果里看到创建成功信息和对象数量。
我自己在实际跑的时候,会盯着 Blender 的实时视口看生成过程。看到一个个货架像“长”出来一样出现,那种体验确实和手动建模完全不一样。
4.4 验收清单:别信智能体的嘴,要看数据
任务执行完不代表结束,我有一套验收清单:
- 对象总数是否符合 45 库位 + 货架构件;
- 集合层级是否正确;
- 每个库位对象是否都有 shelf_id 属性;
- 坐标范围是否和预设区域一致;
- 是否有对象重叠或悬空。
我会让智能体再执行一次检查脚本,输出结构化 JSON,比如这样:
import bpy import json result = { "db_object_count": len(bpy.data.objects), "missing_shelf_id": [], "min_corner": None, "max_corner": None, } for obj in bpy.data.objects: if "Pallet" in obj.name and obj.get("shelf_id") is None: result["missing_shelf_id"].append(obj.name) print(json.dumps(result, ensure_ascii=False))如果检查发现问题,直接把结果丢回给智能体,告诉它“检查发现缺失属性、位置偏移,请修复并复检”。它能读懂错误信息、修正脚本、重新执行。这就是数字孪生建模比传统手动建模爽的地方:不是智能体一次生成完美,而是它能在你给的反馈环里自己修正。
5. 我从报错里摸出的坑:终止执行、403 与 MCP 本地连接
5.1 先给一个态度:别一出错就怪平台
我看搜索热词里很多人问 antigravity agent execution terminated due to error、antigravity 403、eligibility check failed,我也都碰到过。但我的经验是,九成问题出在工具返回格式、网络配置和权限检查上,真正平台崩溃的次数反而很少。所以遇到报错,我建议按“工具侧 → 配置侧 → 平台侧”的顺序排查,别一开始就陷入“是不是平台抽风”的焦虑。
5.2 agent execution terminated due to error 的真实触发点
这个报错的核心意思是:执行链在某一步断裂了。最常见的情况是 execute_blender_code 抛了异常,把一长串 Python traceback 原样返回给智能体。模型看到又臭又长的报错,解析不了,任务就被判定为终止。
我的解决方式是强制结构化错误处理。所有交给 Blender 执行的代码,一律用 try/except 包住,返回统一 JSON 结构:success、data、error。同时限制单次脚本输出长度,尽量控制在几百字符内;如果任务太重,就拆成多批,每批最多 50 个对象,跑完一批再跑下一批。这样智能体每次拿到的都是干净、可理解的结果,中断概率大幅下降。
另一个触发点是 Blender 卡死。一次生成 200 个对象的时候,如果实时视口刷新压力太大,WebSocket 会断掉,智能体等不到返回,自然报执行终止。这种情况不是 MCP 的锅,而是任务设计问题:把大任务拆小,或者关掉 Blender 实时视口刷新。
5.3 Antigravity 403 和 eligibility check failed 怎么判断
403 和 eligibility check failed 我遇到的场景主要是三类:账号登录态失效、项目或工具权限没配置完整、访问链路不稳定。
处理顺序建议是:先看控制台账号状态,有没有重新登录提示;再看项目绑定的工具列表,是否有工具处于不可用状态;最后才考虑链路问题。有一点很重要,别在这个报错上疯狂快速重试,那只会更容易触发风控策略。等几分钟,做一次干净的检查,比连点十次有用得多。
5.4 MCP 本地连接的最大架构坑
如果你把 Antigravity 智能体跑在云端,而 MCP server 跑在自己电脑上,工具地址填 localhost:9876 是一定连不上的。因为对于云端智能体来说,localhost 指向它自己那台机器,而不是你的电脑。我有一阵子一直在这个问题上打转,最后才把架构理顺。
可行做法有三种:
- 把智能体切换成本地运行模式,让 Agent 进程和 Blender MCP 在同一台机器上跑,地址填 localhost 就成立;
- 把 MCP server 部署到一台云主机上,服务绑定到 0.0.0.0,Blender 客户端也从同一个网络访问它;
- 让 MCP server 和 Agent 跑在同一个内网网段内,互相能通就行。
这里还要顺带检查端口占用:MCP server 和 Blender 插件端口看似都是 9876,但实际是两个独立服务。用 ss 或 netstat 看端口监听状态,能省很多时间。
5.5 让工作流稳定的三条纪律
我把踩坑经历总结成三条纪律,写在这里当备忘:
- 规范前置:建模规范写进提示词上下文,不让 AI 临场自由发挥;
- 小步验收:每批只生成 20 到 50 个对象,跑完立刻检查,有问题尽早暴露;
- 异常结构化:所有工具脚本都返回结构化 JSON,错误信息可读可重试。
只要守住这三条,你碰到的报错至少减少一半。剩下的就是网络和权限这类环境问题,按上面说的顺序排查即可。
6. 上篇收尾:自定义属性才是下篇数据驱动的接口
6.1 现在埋下的字段,是后面的“数据插座”
做静态模型时,有人会觉得给每个库位加 shelf_id、grid_x、grid_y 这些自定义属性是多余动作。但在我看来,这就是下篇数据驱动的接口。
举个例子:库位对象一旦带上 shelf_id,后续接 WMS 库存表,某个库位有没有货、库存状态如何、是不是缺货,都能直接按 shelf_id 更新材质颜色或文字标签。如果现在不埋这些字段,后面返工的代价远大于现在多写几行脚本的代价。所以建模阶段的命名规范和自定义属性,本质上是在给整个数字孪生项目铺电路。
6.2 下篇要让智能体做三件事
下篇我会让 Antigravity 干三件事:读取外部数据源、通过 MCP 工具更新 Blender 对象属性、再根据属性变化驱动动画或材质状态。
比如库存低于安全线时,托盘颜色从绿色变成橙色;有出库任务时,对应的 AGV 模型沿路径移动。到这个阶段,数字孪生才真正“活”起来,不再是好看的静态沙盘。
6.3 还有个不能拖到后面的事:导出与 LOD
最后提一个很多人会忽略的点:数字孪生最终要给前端、给大屏、给浏览器,不能只活在 Blender 里。导出 glTF 或 USD 时,如果集合层级乱、命名不规范,前端工程师加载模型后根本没法做场景管理。
所以每次让智能体建模时,我都会强调集合归类和命名规范。这看起来是建模的事,其实是在给未来的导出和 Web 渲染铺路。LOD 细节下篇再展开,但方向可以先想清楚:远端模型低精度,靠近后高精度,这套逻辑和生成规范同样重要。
如果让我给上篇画一个句点,我会说:Antigravity 加 Blender MCP 的价值,不只是把手动建模那几个小时省掉,而是把数字孪生从“一次性建模”变成“可持续维护、可自动更新”的工作流。下篇我们直接接数据,回头见。