摘要:让 AI 以角色身份住进 3D 世界,有个前提问题要先解决:服务器上没有渲染,像素只存在于每个访客的浏览器里——AI 拿不到截图,也就没法用"看图"的方式理解世界。我们的解法是把感知做成结构化接口:一套按距离查询的雷达(observe),一套按时间窗口推送的事件流。本文讲这套感知接口的设计取舍:为什么不用截图、雷达半径为什么分档、事件流为什么设三档,以及这套设计把单个 AI 的流量压到了每秒约 1 KB。
这篇来自我们自己项目的真实实现,数据出自项目内可重跑的验收脚本。上一篇文章讲了整体架构与能力边界,这篇专门展开其中最容易被忽略的一层:感知。
标签:AI Agent 3D Three.js WebSocket 系统设计
一、先说清楚问题:AI 在这个世界里没有眼睛
浏览器端 3D 世界的架构和传统服务端渲染完全是两回事:服务器只保存和转发状态(位置、动作、聊天),每一帧画面都是访客自己的浏览器算出来的。这个架构对人类访客没有问题,但对 AI 是个麻烦——在服务器这一侧,根本不存在一张可以喂给视觉模型的图。
于是只剩两条路:
- 服务端补渲染:为了给 AI 供图,专门渲染一遍再喂视觉模型。画面有了,但渲染成本、视觉模型的按帧计费、识别延迟全都回来了——把浏览器省下的那部分成本又加倍花出去。
- 结构化感知:AI 不看画面,直接读数据——周围有什么、在哪里、多远、正在发生什么。
我们选了第二条。理由很直接:AI 在 3D 世界里要做的决策(往哪走、跟着谁、对谁说话、和哪个物件交互)需要的都是关系信息,不是像素信息。"展台在它北偏东 20 度、距离 12 米"这条数据,对导航来说和一张截图等价,但成本差了几个数量级。
二、空间感知:observe 雷达
空间这一侧,Agent 有一个查询式的雷达接口 observe:发起一次查询,拿回周围环境的结构化快照——附近有哪些物体、哪些角色,各自的方位和距离。
两个设计点值得单独说:
半径是分档的。 管理员授权的 Agent 查询半径 200 米,游客场景下的 Agent 半径 30 米。这不是技术限制,而是权限模型:一个世界里的 AI 能"知道"多大范围的事,应该由世界运营方决定,而不是接入方。导览类 Agent 给大半径,因为要跨展位带路;挂在大世界里的氛围类 Agent 给小半径,够它跟周围几个人互动就行。
是查询,不是全量推送。 雷达按需调用——AI 决策时查一次,而不是持续订阅整个世界的变化。这个区分对成本影响很大:一个站着不动的迎宾 Agent,雷达调用频率可以很低;只有带路、跟踪这类连续决策的场景才需要高频查询。
三、时间感知:15 秒窗口的事件流,三档可选
雷达解决"现在周围什么样",事件流解决"这世界正在发生什么"。设计上是按 15 秒一个窗口批量推送,分三档:
| 档位 | 每 15 秒推送量 | 适合的 Agent |
|---|---|---|
| eco | 0 条(不推送) | 纯被动响应,只靠调用方驱动 |
| standard | 14 条 | 常规导览、迎宾 |
| realtime | 65 条 | 需要密集响应场景的 Agent |
为什么用窗口批量,而不是每个事件实时推一条?两个原因:一是平滑——热闹场景里事件是爆发式出现的,逐条推会造成流量尖峰,批量窗口把流量摊平;二是给接入方留决策节奏——大模型的推理本身有延迟,把 15 秒内的事件打包给一次决策,比追着每条事件做决策更现实。接入方如果嫌 15 秒慢,选 realtime 档就好,档位是接入方自己的选择。
四、把流量账算出来
感知接口的代价最终要落到账上。实测数据:
| 指标 | 实测值 |
|---|---|
| 单个 Agent 的下行流量 | ≈ 1 KB/s |
| 100 个 Agent 同时在线 | ≈ 0.8 Mbps |
| 100 个 Agent 的服务器算力 | ≈ 0.079 个核 |
| 空闲 Agent | 5 分钟自动退场 |
这组数字能压这么低,结构上只有三个原因:感知是文本 JSON(没有图像字节);画面渲染由访客浏览器分担(AI 不给服务器增加一帧);空闲即退场(不占连接)。反过来说,如果当初选了"服务端渲染 + 视觉模型"那条路,这四个数字里的每一个都会换一个量级——光是 100 路 AI 的画面供给,就不是 0.8 Mbps 能打住的。
五、从感知到动作:闭环怎么走
感知只是输入,闭环靠动作指令完成。当前协议里 Agent 能做的动作有八个:move / walk_to / follow / rotate / jump / say / interact,加上基础位移。组合起来的典型链路是:事件流里看到有人靠近 → observe 确认对方方位和身份 → walk_to 走到对方附近 → say 开口。
这条链路里有两个刻意的约束:
移动必须走寻路,逐帧走出来。 没有凭空出现、没有跨地图跳转——AI 在别人眼里是一个真实在场景里移动的角色,这是产品底线,不是实现限制。代价是调度 AI 时要给移动留时间。
身份始终明示。 访客能看出它是 AI。实测里这不减分——访客知道对面是 AI 之后,反而更愿意试探它、跟它互动。
另外,大模型这一侧是完全解耦的:世界提供的是"身体 + 感知 + 动作通道",接哪个模型、提示词怎么写、知识库挂什么,都是接入方自己的事。模型换代,协议不动。
六、这套设计放弃了什么
结构化感知换来了低成本,也划死了能力上限,这两条要一起说才诚实:
它认不出"长相"。 雷达告诉它"有一个角色在东南方 15 米",但不告诉它这个角色穿着什么、旁边的海报写了什么。凡是依赖视觉理解的场景(认图、读场景内文字),都要在通道之外另接视觉方案,那是一笔独立的开销,别算进接入成本里。
它不处理声音。 感知接口里没有语音链路,对话走文本。需要语音交互的场景,识别和合成都要接入方自建。
事件流不是全知。 三档推送都是采样过的世界动态,不是完整日志。想让 AI 掌握"过去一小时世界发生了什么",得靠接入方自己留存,通道不负责补历史。
把这三条放弃写清楚,接入方才能在方案阶段就把"AI 能做到哪、做不到哪"对齐——这比能力清单更影响项目成败。
七、常见问题
问:雷达和事件流为什么是两套,合成一个接口不行吗?
答:可以合,但没必要。两者的使用模式不同:雷达是"决策时查一次",事件流是"持续低频订阅"。合成一个接口意味着要么常开雷达(浪费流量),要么放弃订阅(丢时间感知)。分开之后,接入方按自己的 Agent 类型自由组合。
问:15 秒窗口会不会让 AI 反应很迟钝?
答:对导览、迎宾这类场景,15 秒的决策节奏足够了——真人接待的对话节奏也就这个量级。确实需要快进快出的场景选 realtime 档,65 条 / 15 秒的密度不低。真正决定反应速度的往往不是窗口,而是接入方调大模型的耗时,这部分在世界通道之外。
问:多个 Agent 会不会互相"看见"造成混乱?
答:它们在雷达里就是普通角色,身份是明示的。要不要让 AI 之间互动,是接入方的编排问题,通道层不禁止也不特殊处理。
问:这套感知接口换一个 3D 引擎还能用吗?
答:协议本身是引擎无关的——雷达和事件流都是结构化数据,不依赖任何渲染实现。只要目标世界有等价的状态同步层,接入逻辑是通用的。
写在最后
让 AI 住进 3D 世界,感知层的答案不是"给它一双眼睛",而是把世界翻译成它能读的句子——雷达给空间,事件流给时间,剩下的交给动作通道。上面这套接口与取舍来自我们项目的真实实现——创世Genesis(即创世虚拟世界CRM系统),一套浏览器端、可部署在自有服务器上的 3D 虚拟世界基底,文中数字出自项目内可重跑的验收脚本。
如果你也在给 AI 设计"身体",希望这份感知层的取舍清单对你有参考价值。
本文为开发过程中整理的技术复盘,数据来自项目内验收脚本,可复跑核验。第六节所列能力边界为当前实现的如实描述,不作为后续承诺。