1. 三款模型同台竞技的背景与选型逻辑
1.1 为什么要做这个对比实测
最近这段时间,AI 编程助手这个赛道热闹得有点不像话。Step 5 Preview、DeepSeek V4 Pro、GLM5.3 这三个名字几乎同时出现在我的信息流里,身边做独立开发的朋友也在群里反复讨论到底该用哪个来干活。说实话,光看官方放出来的 benchmark 数据,三家都说自己代码能力强、推理能力好、长上下文稳,但真正落到一个具体项目上,谁更顺手、谁更容易翻车,光看跑分是看不出来的。
我决定做一个相对硬核的对比:让这三个模型各自从零开始做一个 3D 游戏。为什么选 3D 游戏?因为这类项目天然覆盖了图形渲染、数学计算、状态管理、资源加载、交互逻辑等多个维度,对模型的综合能力要求很高。它不像写一个 CRUD 接口那样有固定套路,3D 游戏里涉及向量运算、矩阵变换、碰撞检测、帧循环这些需要空间想象力的东西,模型如果只是“背代码”而没有真正的推理能力,很容易写出看起来对但跑起来崩的代码。
另外,我这次全程通过 WorkBuddy 这个工作台来调度三个模型。WorkBuddy 的好处是它把多个模型的调用统一在一个界面里,切换模型、管理对话上下文、保存项目文件都比较方便。关于 WorkBuddy 的使用,后面我会专门讲一些实操细节,包括怎么配置、怎么管理缓存目录、怎么设置跨对话记忆这些。
1.2 三个模型的基本定位差异
在正式开始之前,先说说我对这三个模型的初始印象,这会影响我后面给它们分配任务的方式。
Step 5 Preview 是 Step 系列的最新预览版,从命名就能看出来它还在迭代中。它的特点是响应速度快,代码生成风格偏简洁,适合快速出原型。但预览版意味着可能存在一些不稳定的地方,比如长对话后上下文丢失、复杂逻辑处理时容易简化过度。
DeepSeek V4 Pro 是 DeepSeek 的旗舰版本,在代码生成领域口碑一直不错。它的优势在于对复杂逻辑的理解能力比较强,写出来的代码结构清晰,注释也比较到位。之前用 V3 的时候我就发现它在处理数学密集型任务时表现突出,V4 Pro 应该在这方面有进一步提升。
GLM5.3 是智谱的最新版本,这个版本在代码能力和多轮对话上都有明显升级。GLM 系列一直以来的特点是中文理解好、对国内开发者的习惯比较贴合。5.3 版本据说在代码生成质量上有质的飞跃,而且 flashx 版本在速度上有优势。
我选择用同一个 3D 游戏项目来测试,具体是一个“3D 迷宫探索”游戏——玩家在一个随机生成的迷宫中移动,收集物品,找到出口。这个项目不大不小,刚好能体现模型在 3D 数学、碰撞检测、随机生成算法、用户输入处理等方面的能力。
1.3 测试环境的统一配置
为了保证公平,三个模型都在相同的环境下运行。我用的是一台 Ubuntu 22.04 的机器,Node.js 版本 20.x,通过 WorkBuddy 的 Linux 版本进行调度。WorkBuddy 的安装包在 Linux 下可以直接解压运行,不需要复杂的依赖配置,这一点比很多同类工具要省心。
每个模型我都给了完全相同的提示词,分三个阶段:第一阶段让它们生成项目骨架和核心 3D 渲染逻辑;第二阶段让它们实现迷宫生成和碰撞检测;第三阶段让它们加上物品收集和 UI 显示。每个阶段结束后我都会实际运行代码,记录编译错误、运行时错误和逻辑 bug。
提示:做这种多模型对比测试时,一定要控制变量。提示词要完全一致,运行环境要一致,甚至测试的顺序也要考虑——因为如果你先测了某个模型,你对项目的理解会加深,后面测其他模型时可能会不自觉地给出更具体的提示。我的做法是每个模型都从空对话开始,提示词提前写好,测试过程中不修改。
2. 第一阶段实测:项目骨架与 3D 渲染
2.1 提示词设计与预期目标
第一阶段的提示词是这样的:“用 Three.js 创建一个 3D 迷宫探索游戏的基础框架。要求:1. 场景中包含一个地面平面和若干墙壁;2. 有一个第一人称视角的相机,可以用 WASD 键移动,鼠标控制视角方向;3. 墙壁用简单的立方体表示,地面用平面几何体;4. 代码结构清晰,分成场景初始化、相机控制、渲染循环三个模块。”
这个提示词不算复杂,但包含了几个关键考察点:模型是否知道 Three.js 的基本 API、是否能正确处理第一人称相机的旋转逻辑(这里涉及欧拉角和四元数的选择)、是否能把代码组织成合理的模块。
2.2 Step 5 Preview 的表现
Step 5 Preview 的响应速度确实是最快的,大概几秒钟就吐出了完整代码。代码结构比较简洁,用了 Three.js 的 PointerLockControls 来实现第一人称视角,这个选择是对的,省去了手动处理鼠标事件的麻烦。
但问题出在细节上。它生成的代码里,地面平面的尺寸是 100x100,但墙壁的分布范围只覆盖了 20x20 的区域,导致玩家很容易走出墙壁范围掉进“虚空”。另外,它在渲染循环里用了requestAnimationFrame,但没有处理 delta time,导致移动速度跟帧率绑定——在高刷新率屏幕上移动飞快,在低帧率设备上又慢得像蜗牛。
还有一个比较隐蔽的问题:它设置相机初始位置的时候用了camera.position.set(0, 1.6, 0),这个高度模拟人眼高度是对的,但它没有给相机添加碰撞体,所以玩家可以直接穿墙。这个在后续阶段需要修复,但第一阶段就埋下了隐患。
2.3 DeepSeek V4 Pro 的表现
DeepSeek V4 Pro 的代码明显更“老练”。它同样用了 PointerLockControls,但额外加了一个速度向量和阻尼系数,让移动有加速和减速的过程,手感更自然。而且它在渲染循环里正确使用了clock.getDelta()来计算时间增量,移动速度与帧率解耦,这一点做得比 Step 5 Preview 好。
代码结构上,DeepSeek V4 Pro 把场景初始化、控制器设置、渲染循环分成了三个独立的函数,每个函数职责清晰。它还额外加了一个窗口 resize 的处理,保证画布自适应窗口大小。这些细节说明它对实际项目中的常见需求有比较好的理解。
不过 DeepSeek V4 Pro 也有一个小问题:它在创建墙壁时用了循环生成,但墙壁的位置是硬编码的数组,而不是程序化生成的。这意味着第一阶段它只是搭了个架子,真正的迷宫生成逻辑要等到第二阶段。这个不算 bug,但说明它在第一阶段比较保守,没有主动扩展需求。
2.4 GLM5.3 的表现
GLM5.3 的代码风格介于前两者之间。它没有用 PointerLockControls,而是自己实现了一套鼠标控制逻辑,通过监听mousemove事件来更新相机的旋转角度。这个做法更底层,可控性更强,但代码量也更大,而且容易在边界情况上出问题——比如它没有处理鼠标移动到屏幕边缘时的角度跳变。
不过 GLM5.3 有一个亮点:它在代码里加了比较详细的中文注释,解释了每个参数的含义。比如它注释了camera.rotation.order = 'YXZ'这一行是为了避免万向节锁问题。这说明它对 3D 旋转的数学原理有理解,不只是套模板。
在移动逻辑上,GLM5.3 用了Math.sin和Math.cos来计算前后左右的方向向量,这个做法是正确的。但它忘记归一化方向向量,导致斜向移动时速度比直线移动快约 41%。这是一个经典的向量运算错误,很多新手都会犯。
2.5 第一阶段对比小结
| 对比维度 | Step 5 Preview | DeepSeek V4 Pro | GLM5.3 |
|---|---|---|---|
| 响应速度 | 最快 | 中等 | 中等偏快 |
| 代码结构 | 一般 | 清晰 | 较清晰 |
| 帧率解耦 | 未处理 | 正确处理 | 未处理 |
| 碰撞体预留 | 无 | 无 | 无 |
| 注释质量 | 少 | 适中 | 详细 |
| 明显 bug | 地面范围不匹配 | 无 | 斜向速度未归一化 |
第一阶段的结论是:DeepSeek V4 Pro 的代码质量最高,基本可以直接用;GLM5.3 有亮点但有数学错误;Step 5 Preview 速度最快但需要较多修补。
3. 第二阶段实测:迷宫生成与碰撞检测
3.1 迷宫生成算法的选择分歧
第二阶段的提示词是:“实现一个随机迷宫生成算法,用递归回溯法生成迷宫,迷宫尺寸为 21x21。生成后用立方体表示墙壁,并实现玩家与墙壁的碰撞检测,玩家不能穿墙。”
这里我特意指定了递归回溯法,因为这是最经典的迷宫生成算法之一,逻辑清晰但涉及递归和栈操作,能考察模型的算法实现能力。碰撞检测则是 3D 游戏里比较有挑战的部分,需要处理 AABB(轴对齐包围盒)或者球体与立方体的相交检测。
三个模型在这个阶段的表现差异非常明显。
3.2 Step 5 Preview 的迷宫生成
Step 5 Preview 确实实现了递归回溯法,但它的实现有一个致命问题:递归深度太大时会导致栈溢出。21x21 的迷宫有 441 个格子,递归深度可能达到几百层,在 JavaScript 里虽然通常不会直接崩,但在某些环境下会报Maximum call stack size exceeded。
更麻烦的是,它生成的迷宫墙壁位置和碰撞检测用的墙壁位置不一致。迷宫生成用的是二维数组maze[y][x],其中 1 表示墙壁,0 表示通路。但在创建 3D 墙壁时,它把数组索引和世界坐标的映射搞反了,导致视觉上的墙壁和实际碰撞的墙壁错位。玩家看起来撞到了墙,实际上碰撞检测认为那里是通路。
这个 bug 很典型,说明 Step 5 Preview 在处理“数据层”和“表现层”的映射时不够严谨。修复这个 bug 花了我不少时间,因为要同时检查迷宫数组、墙壁 mesh 的位置、碰撞检测的坐标转换三个地方。
3.3 DeepSeek V4 Pro 的迷宫生成
DeepSeek V4 Pro 同样用了递归回溯法,但它做了一个聪明的优化:把递归改成了用栈的迭代实现。这样既保留了算法的逻辑,又避免了递归深度问题。这个选择说明它对 JavaScript 的运行时特性有实际考虑,不只是“能跑就行”。
碰撞检测方面,DeepSeek V4 Pro 用了 AABB 检测,把玩家简化为一个半径为 0.3 的圆(在俯视图上),然后检测圆与墙壁矩形的相交。这个简化在 3D 游戏里很常见,因为精确的网格碰撞计算量大且没必要。它还把碰撞检测封装成了一个独立的函数checkCollision(newPosition),在移动前先检测,如果会碰撞就不允许移动。这个逻辑是正确的。
不过 DeepSeek V4 Pro 的碰撞检测有一个小问题:它只检测了玩家中心点与墙壁的距离,没有考虑玩家半径。导致玩家可以“贴脸”墙壁,视觉上半个身子嵌进墙里。修复方法很简单,把检测距离从 0 改成玩家半径即可,但模型没有主动想到这一点。
3.4 GLM5.3 的迷宫生成
GLM5.3 的迷宫生成用了另一种思路:它没有用递归回溯,而是用了“随机 Prim 算法”。这个算法生成的迷宫同样有解,但风格不同——Prim 算法生成的迷宫岔路更多,死胡同更少。这不算错,但偏离了我的提示词要求。
碰撞检测方面,GLM5.3 用了 Three.js 的Raycaster来做检测。它从玩家位置向移动方向发射一条射线,如果射线与墙壁相交,就阻止移动。这个做法在简单场景下可行,但有两个问题:一是射线检测只能检测前方,如果玩家斜向移动可能穿过墙角;二是性能开销比 AABB 大,在墙壁数量多时帧率会下降。
不过 GLM5.3 在代码里加了一个调试模式,按 T 键可以显示碰撞体的线框。这个功能很实用,方便开发者直观地看到碰撞检测的范围。这个细节说明它在实际开发体验上有考虑。
3.5 碰撞检测的常见坑与修复方案
在这个阶段我踩了不少坑,这里整理几个典型的:
第一个坑是坐标映射错误。迷宫数组的[row][col]对应到 3D 世界的(x, z)坐标时,很容易搞混哪个是 x 哪个是 z。我的经验是:在代码里明确写一个转换函数mazeToWorld(row, col),所有地方都通过这个函数转换,不要手动写x = col * size这种散落的逻辑。
第二个坑是碰撞检测的“穿透”问题。如果玩家移动速度很快,一帧内移动的距离超过了墙壁厚度,就可能直接穿过去。解决方案是限制单帧最大移动距离,或者用射线检测从旧位置到新位置之间是否有墙壁。
第三个坑是碰撞后的“滑动”处理。如果玩家斜向撞墙,直接阻止移动会让玩家卡住。更好的做法是把移动向量分解为 x 和 z 两个分量,分别检测,允许玩家沿着墙壁滑动。
提示:碰撞检测是 3D 游戏里最容易出 bug 的地方之一。我的建议是先在 2D 俯视图上把碰撞逻辑调通,再映射到 3D。这样调试起来直观得多,可以用 console.log 打印玩家位置和墙壁位置,一眼就能看出问题。
4. 第三阶段实测:物品收集与 UI 交互
4.1 游戏逻辑的完整度考察
第三阶段的提示词是:“在迷宫中随机放置 5 个可收集的物品,玩家靠近时自动收集。收集全部物品后,在屏幕中央显示‘恭喜通关’的提示。同时显示一个计时器,记录玩家通关用时。”
这个阶段考察的是模型对游戏状态管理的理解。一个完整的游戏需要维护多个状态:玩家位置、已收集物品列表、游戏是否结束、计时器数值等。这些状态之间还有依赖关系,比如收集完所有物品后要停止计时、显示通关提示、可能还要禁用玩家移动。
4.2 三个模型的状态管理对比
Step 5 Preview 在这个阶段的表现有所回升。它用一个全局对象gameState来管理所有状态,包括collectedItems、totalItems、isGameOver、startTime等。这个做法虽然简单,但对于小游戏来说足够清晰。它还在渲染循环里检查if (gameState.collectedItems.length >= gameState.totalItems)来触发通关逻辑,逻辑是正确的。
但 Step 5 Preview 的计时器实现有问题:它用了Date.now()来记录开始时间,然后在渲染循环里计算差值。这个做法本身没问题,但它没有在通关后停止计时,导致通关提示显示后计时器还在走。这是一个逻辑漏洞,虽然不影响核心玩法,但说明它在状态转换的边界处理上不够细致。
DeepSeek V4 Pro 的状态管理更规范。它用了一个Game类来封装所有状态和方法,包括start()、update()、collectItem()、checkWin()等。这种面向对象的方式让代码可读性更好,也更容易扩展。计时器方面,它用了performance.now()而不是Date.now(),精度更高,而且它在checkWin()里正确地把isGameOver设为 true 并停止了计时。
GLM5.3 在物品收集的检测上用了距离判断:每帧计算玩家与每个未收集物品的距离,如果小于 1.0 就触发收集。这个逻辑是对的,但它没有在收集后从场景中移除物品的 mesh,导致物品虽然“被收集”了但视觉上还在。这是一个典型的“数据与表现不同步”问题,修复方法是在收集时调用scene.remove(item.mesh)。
4.3 UI 显示的三种实现方式
在 UI 显示上,三个模型用了不同的方案。
Step 5 Preview 用了纯 HTML 元素叠加在 canvas 上,通过document.getElementById更新文本内容。这个方案最简单,性能也好,但样式需要自己写 CSS,而且如果 canvas 大小变化,HTML 元素的位置可能需要调整。
DeepSeek V4 Pro 用了 Three.js 的 CSS2DRenderer,把 HTML 元素作为 3D 场景的一部分来渲染。这个方案的好处是 UI 元素可以跟随 3D 对象,但对于固定在屏幕中央的通关提示来说有点大材小用。而且 CSS2DRenderer 需要额外的渲染器设置,增加了代码复杂度。
GLM5.3 用了 canvas 的 2D 上下文来绘制 UI 文本。它创建了一个叠加的 canvas,用fillText绘制计时器和通关提示。这个方案性能最好,因为不需要操作 DOM,但代码量最大,而且文本样式(字体、颜色、阴影)都需要手动设置。
我个人更倾向于 Step 5 Preview 的 HTML 方案,因为对于大多数游戏 UI 来说,HTML 和 CSS 的表达能力足够,而且开发效率高。除非是那种需要大量动态文本或者复杂排版的场景,才需要考虑 canvas 绘制。
4.4 通关逻辑的边界情况
在测试通关逻辑时,我发现了一个三个模型都没考虑到的问题:如果玩家在收集最后一个物品的同时计时器刚好跨过某个时间点,可能会出现计时器数值和通关提示不一致的情况。虽然这个概率很低,但在实际游戏中确实可能发生。
更常见的边界情况是:玩家收集完所有物品后,如果继续按移动键,玩家还能移动。这在大多数游戏里是可以接受的,但严格来说应该在通关后禁用输入。三个模型里只有 DeepSeek V4 Pro 在checkWin()里加了一个controls.enabled = false,其他两个都没有处理。
还有一个问题是物品的随机放置。三个模型都用了Math.random()来生成物品位置,但没有检查物品是否被放在了墙壁里面。如果物品生成在墙壁内部,玩家永远无法收集到它,游戏就无法通关。正确的做法是在生成位置后检查该位置是否是通路,如果不是就重新生成。这个问题三个模型都没有主动处理,需要手动修复。
5. WorkBuddy 工作台的实操经验分享
5.1 为什么选择 WorkBuddy 来调度多模型
这次测试我全程用 WorkBuddy 作为工作台,主要是因为它对多模型的支持比较友好。你可以在同一个项目里切换不同的模型,每个模型的对话历史是独立的,但项目文件是共享的。这意味着我可以用 Step 5 Preview 生成初版代码,然后用 DeepSeek V4 Pro 来审查和修复,再用 GLM5.3 来补充功能,所有操作都在同一个工作区里完成。
WorkBuddy 的安装比较简单,Linux 版本下载后解压就能用,不需要 Docker 或者复杂的依赖。如果你用 Ubuntu,直接下载对应的安装包,解压后运行启动脚本即可。Windows 和 macOS 也有对应的版本,安装过程更简单,基本是下一步下一步。
5.2 缓存目录与对话记录管理
用了一段时间后我发现 WorkBuddy 的缓存目录会随着使用不断增大,尤其是对话记录和临时文件。默认情况下这些文件存在用户目录下的.workbuddy文件夹里。如果你的系统盘空间紧张,可以把这个目录改到 D 盘或者其他大容量磁盘。
修改方法是在 WorkBuddy 的设置里找到“存储路径”选项,把缓存目录指向新的位置。或者你也可以在启动时通过环境变量指定。我实测下来,把缓存目录改到机械硬盘后,启动速度会稍微慢一点,但运行时的响应速度没有明显差异,因为主要的计算还是在内存和 SSD 上。
对话记录的管理也很重要。WorkBuddy 默认会保存所有对话历史,时间长了之后搜索起来会比较慢。我的做法是定期归档旧的对话,把不再需要的项目对话导出后删除。WorkBuddy 支持导出对话为 Markdown 或 JSON 格式,导出后可以存在其他地方备查。
5.3 跨对话记忆与自定义指令
WorkBuddy 有一个很实用的功能是跨对话记忆。你可以设置一些全局的指令或者偏好,让所有对话都遵循。比如我设置了“代码注释用中文”、“优先使用函数式编程风格”、“生成的代码要包含错误处理”这几条规则,这样不管我用哪个模型,生成的代码都会遵循这些偏好。
设置方法是在 WorkBuddy 的设置里找到“自定义指令”或“全局规则”选项,把规则写进去。规则要尽量具体,不要写“写好代码”这种模糊的要求,而是写“所有异步操作必须用 try-catch 包裹”这种可执行的指令。
提示:自定义指令不要设太多,否则会占用上下文窗口,影响模型对实际任务的理解。我的经验是 3 到 5 条最合适,覆盖代码风格、注释语言、错误处理这几个最常用的方面就够了。
5.4 多模型切换的实操技巧
在 WorkBuddy 里切换模型很简单,在对话界面顶部有一个模型选择下拉框,点一下就能切换。但有一个细节需要注意:切换模型后,新模型不会自动读取之前模型的对话历史。如果你想让新模型了解之前的上下文,需要手动把关键信息复制到新的对话里,或者用 WorkBuddy 的“引用”功能把之前的消息引用过来。
我的做法是每个阶段结束后,把当前代码和关键决策记录在一个 Markdown 文件里,切换模型时把这个文件作为附件上传。这样新模型能快速了解项目现状,不需要重新解释一遍。
另外,不同模型对提示词的敏感度不同。Step 5 Preview 对简洁的提示词响应更好,提示词太长反而容易让它抓不住重点。DeepSeek V4 Pro 和 GLM5.3 则能处理更复杂的提示词,给出更细致的回应。所以我在切换模型时会适当调整提示词的详细程度。
6. 三模型最终对比与选型建议
6.1 代码质量综合评分
经过三个阶段的完整测试,我对三个模型的表现有了比较清晰的认识。下面是一个综合评分表,满分 5 分:
| 评估维度 | Step 5 Preview | DeepSeek V4 Pro | GLM5.3 |
|---|---|---|---|
| 代码正确性 | 3 | 4.5 | 3.5 |
| 代码结构 | 3 | 4.5 | 4 |
| 算法实现 | 3 | 4.5 | 4 |
| 边界处理 | 2.5 | 4 | 3 |
| 注释与文档 | 2.5 | 3.5 | 4.5 |
| 响应速度 | 5 | 3.5 | 4 |
| 中文支持 | 4 | 4 | 5 |
| 综合 | 3.3 | 4.2 | 4.0 |
DeepSeek V4 Pro 在代码正确性和结构上领先,GLM5.3 在注释和中文支持上更好,Step 5 Preview 的优势主要在速度上。
6.2 不同场景下的选型建议
如果你是在做快速原型验证,比如想快速看到一个 3D 场景跑起来,Step 5 Preview 的速度优势很有价值。你可以用它生成初版代码,然后手动修复关键 bug。但如果你要做的是需要长期维护的项目,DeepSeek V4 Pro 的代码质量更值得信赖,后期改起来更省心。
GLM5.3 适合那些需要详细注释和文档的项目,或者团队里有新手需要阅读代码的场景。它的中文注释质量确实高,能帮新手快速理解代码意图。另外 GLM5.3 在中文语境下的理解能力也更好,如果你用中文描述需求,它给出的回应往往更贴合你的本意。
还有一个实际考虑是成本。三个模型的定价策略不同,如果你通过 WorkBuddy 来调用,可以关注一下 WorkBuddy 的积分消耗情况。我的实测是,完成同样的任务,Step 5 Preview 消耗的积分最少,DeepSeek V4 Pro 最多,GLM5.3 居中。如果你的预算有限,可以优先考虑 Step 5 Preview 或者 GLM5.3。
6.3 组合使用的实战策略
其实最好的方案不是只用一个模型,而是组合使用。我现在的工作流是这样的:用 Step 5 Preview 快速生成项目骨架和基础代码,因为快;然后用 DeepSeek V4 Pro 来审查代码、修复 bug、优化结构;最后用 GLM5.3 来补充注释和文档。这样每个模型都发挥了自己的长处,整体效率比单用一个模型高不少。
在 WorkBuddy 里实现这个工作流很方便,因为项目文件是共享的,你只需要切换模型然后继续对话就行。但要注意每次切换模型后,给新模型一个简短的上下文说明,告诉它当前项目的状态和你希望它做什么。这个说明不用太长,几句话就行,但能显著提升新模型的表现。
7. 3D 游戏开发中模型容易翻车的几个点
7.1 向量运算与坐标系
3D 游戏开发里最容易出错的就是向量运算和坐标系转换。我测试的三个模型在这个方面都有不同程度的翻车。Step 5 Preview 把迷宫数组的行列映射搞反了,GLM5.3 忘记归一化方向向量,DeepSeek V4 Pro 虽然没犯大错,但在碰撞检测的半径处理上也有疏忽。
这些错误的根源在于模型对 3D 空间的理解还是偏“文本化”的。它们能写出正确的公式,但在具体应用时容易搞混变量的含义。我的建议是,在提示词里尽量明确坐标系约定,比如“x 轴向右,z 轴向前,y 轴向上”,并且要求模型在关键计算处加注释说明每个变量的含义。
7.2 帧率无关的移动逻辑
帧率无关的移动是 3D 游戏的基本要求,但 Step 5 Preview 和 GLM5.3 都没有主动处理。它们直接在每帧里加上固定的移动量,导致在不同帧率下速度不一致。正确的做法是用deltaTime乘以速度,这样每秒移动的距离才是恒定的。
这个问题在测试时很容易被忽略,因为如果你的显示器是 60Hz,看起来一切正常。但如果你换到 144Hz 的显示器,移动速度就会快 2.4 倍。所以测试时最好在不同帧率下都跑一下,或者手动限制帧率来验证。
7.3 资源加载与内存管理
虽然这次测试的项目比较简单,没有涉及复杂的资源加载,但我在扩展测试时发现,三个模型在处理纹理加载和几何体复用方面都有不足。比如它们会为每个墙壁创建一个新的BoxGeometry,而不是复用同一个几何体。在墙壁数量多的时候,这会导致内存占用急剧上升。
正确的做法是创建一个共享的几何体和材质,然后用InstancedMesh或者简单的Mesh复用来渲染所有墙壁。这个优化在小型项目里可能不明显,但在大型场景里能带来数倍的性能提升。
7.4 输入处理的边界情况
输入处理也是模型容易忽略的地方。比如鼠标移动事件在指针锁定后,movementX和movementY的值可能会突然变得很大(当鼠标移动到屏幕边缘时),导致视角瞬间旋转很多。三个模型都没有处理这个边界情况,需要手动加一个 clamp 来限制单帧的最大旋转角度。
键盘输入也有类似问题。如果玩家同时按下 W 和 S,模型生成的代码通常会同时处理两个方向的移动,导致玩家原地不动但速度向量在抵消。更好的做法是记录按键状态,在每帧结束时根据按键状态计算移动方向,而不是在按键事件里直接移动。
8. 从这次实测中提炼的实操建议
8.1 给模型写提示词的几个原则
经过这次测试,我总结了几条写提示词的经验。第一,明确技术栈和版本,比如“用 Three.js r160”比“用 Three.js”更好,因为不同版本的 API 有差异。第二,明确坐标系约定和单位,避免模型在空间关系上犯错。第三,分阶段提需求,不要一次性把所有功能都说完,否则模型容易顾此失彼。第四,要求模型在关键逻辑处加注释,这样你审查代码时能快速理解它的意图。
还有一点很重要:提示词里要明确“不要做什么”。比如“不要用递归,用迭代实现”、“不要硬编码位置,用程序化生成”。模型有时候会选一条看起来更简单但实际有隐患的路,提前排除这些选项能减少后期修复的工作量。
8.2 代码审查的重点检查项
模型生成的代码不能直接信任,必须审查。我通常会重点检查这几个地方:一是坐标转换,所有涉及数组索引和世界坐标映射的地方都要仔细看;二是边界条件,比如数组越界、除零、空值;三是帧率相关的逻辑,确认 deltaTime 被正确使用;四是资源释放,确认没有内存泄漏;五是输入处理,确认没有遗漏的边界情况。
审查时可以用“反向测试”的方法:故意输入一些异常值,看看代码会不会崩。比如把迷宫尺寸改成 1x1,或者把玩家速度设成负数,看看模型有没有处理这些情况。大多数模型生成的代码在正常输入下能跑,但异常输入下就容易出问题。
8.3 性能优化的常见手段
3D 游戏的性能优化有几个通用手段,模型通常不会主动使用,需要你手动加上。一是几何体复用,用InstancedMesh渲染大量相同物体。二是材质共享,避免为每个物体创建独立的材质实例。三是视锥剔除,Three.js 默认会做,但你可以通过设置frustumCulled来微调。四是 LOD(细节层次),远处的物体用低面数模型。
还有一个容易被忽略的优化是减少 draw call。每次渲染调用都有开销,把多个小物体合并成一个大的几何体可以显著减少 draw call。Three.js 提供了BufferGeometryUtils.mergeGeometries来做这件事。在我的测试中,把迷宫的墙壁合并成一个几何体后,帧率从 45fps 提升到了 60fps。
8.4 调试工具与技巧
调试 3D 游戏比调试普通 Web 应用要麻烦一些,因为很多问题在代码层面看不出来,必须可视化才能发现。我常用的工具包括:Three.js 的AxesHelper和GridHelper来确认坐标系方向;BoxHelper来可视化碰撞体;Chrome DevTools 的 Performance 面板来分析帧率和渲染耗时。
还有一个很实用的技巧是在屏幕上显示实时调试信息,比如玩家位置、帧率、碰撞状态等。可以用一个简单的 HTML 覆盖层来实现,每帧更新文本内容。这样你在测试时能直观地看到数据变化,快速定位问题。
提示:调试 3D 游戏时,先把渲染质量降到最低(关闭阴影、降低分辨率),这样帧率会很高,问题也更容易复现。等逻辑调通了再逐步开启特效,确认性能是否达标。
9. 关于模型能力边界的一些个人观察
9.1 模型擅长什么、不擅长什么
从这次实测来看,三个模型在“有明确模式”的任务上表现都不错,比如创建场景、设置相机、添加灯光这些有固定套路的操作。但在需要“空间推理”和“状态管理”的任务上,表现就参差不齐了。迷宫生成算法本身不难,但把算法结果正确映射到 3D 空间,三个模型都或多或少出了问题。
另一个观察是,模型在处理“多步骤依赖”时容易丢失上下文。比如第三阶段要求“收集全部物品后显示通关提示”,这涉及物品收集、状态检查、UI 更新三个步骤,模型往往能实现前两步,但在第三步的触发条件上出错。这说明模型在长链条逻辑上的注意力分配还不够均匀。
9.2 模型迭代的速度与局限
Step 5 Preview 作为预览版,迭代速度很快,我测试期间就收到了两次更新。但预览版的不稳定性也是实实在在的,有些 bug 在更新后消失了,有些新 bug 又出现了。如果你用预览版做正式项目,要做好频繁回归测试的准备。
DeepSeek V4 Pro 和 GLM5.3 作为稳定版,行为更可预测,但更新频率低,一些已知问题可能要等比较久才能修复。这是一个权衡:要稳定还是要新特性。我的建议是,核心项目用稳定版,实验性项目可以用预览版尝鲜。
9.3 对 WorkBuddy 这类工作台的期待
WorkBuddy 在这次测试中表现不错,多模型切换和项目管理都很方便。但我希望它未来能加强几个方面:一是模型间的上下文共享,切换模型时能自动传递关键上下文,而不是手动复制;二是代码差异对比,能直观地看到不同模型对同一任务的实现差异;三是性能分析,能统计每个模型的响应时间和积分消耗,方便做成本优化。
另外,WorkBuddy 的 skill 系统也值得探索。它允许你定义一些可复用的技能,比如“代码审查”、“性能优化”、“文档生成”等,然后在对话中直接调用。我试过用 skill 来做代码审查,效果还不错,能自动检查出一些常见问题。但 skill 的配置需要花时间调试,而且不同模型对 skill 的响应效果不一样,需要针对性地调整。
10. 最后的实操心得
这次三模型对比测试花了我大概一周的时间,中间踩了不少坑,也积累了一些经验。最大的感受是:不要迷信任何一个模型的 benchmark 数据,实际项目里的表现才是最有说服力的。同一个模型在不同任务上的表现可能差异很大,同一个任务用不同的提示词也可能得到完全不同的结果。
另外,工具的选择也很重要。WorkBuddy 这样的工作台能显著提升多模型协作的效率,但前提是你要花时间熟悉它的功能,配置好自定义指令和缓存管理。我一开始没注意缓存目录的设置,结果系统盘很快就被占满了,后来改到数据盘才解决。
如果你也在做类似的多模型对比,我的建议是:控制变量、分阶段测试、详细记录、实际运行。不要只看代码,一定要跑起来。很多问题在代码层面看不出来,只有运行了才会暴露。而且不同模型生成的代码风格差异很大,实际运行时的表现也可能出乎意料。
最后分享一个小技巧:在测试多个模型时,可以准备一个“标准答案”作为参照。比如对于迷宫生成,你可以先自己写一个正确的实现,然后对比模型生成的代码和标准答案的差异。这样能更客观地评估模型的能力,而不是凭感觉判断。这个方法虽然多花一点时间,但能让你的对比结论更有说服力。