最近模型更新真是下饺子一样频繁,Step 5 Preview、DeepSeek V4 Pro、GLM5.3 接连放出来,社区里各种跑分帖子满天飞。但说实话,跑分单测和我日常写代码是两码事,我更关心的是:把同一个活真的扔给它们,谁能一遍干明白,谁会在半路撂挑子。所以我挑了一个特别能折磨模型的题目——直接用自然语言让三个模型各自从零生成一个 3D 小游戏。
为什么选 3D 游戏当试金石,后面会细说。先说结论:这三个模型放在同一个题目下,交出来的代码风格、完成度、踩坑方式完全不一样,非常有意思。这篇文章会把我的实测过程、提示词设计、对比结果,以及中间遇到的各种环境问题(包括 GLM5.3 本地部署时 vLLM 镜像版本怎么选)全部摊开来讲,想拿 AI 写游戏或者做模型横评的朋友可以直接抄作业。
1. 为什么偏偏拿“3D 游戏”来测代码能力
1.1 3D 游戏是综合工程能力的“压力测试”
很多模型评测喜欢用 LeetCode 题库或者 SQL 生成,但我个人觉得这些东西偏“套路记忆”,模型只要见得多就能答得好。3D 游戏完全是另一个量级的需求,它不是单个函数,而是一个完整的小型软件工程。以我这次的“3D 迷宫跑酷”题目来说,里面要同时处理场景搭建、光照、相机跟随、玩家输入、碰撞检测、计时器 UI、胜利判定这几个子系统,任何一个环节掉链子,游戏就跑不起来。
更关键的是,3D 游戏涉及的知识点非常凌乱,比如 Three.js 的坐标系是 Y 轴朝上的,而 Canvas 2D 是 Y 轴朝下的;相机的投影矩阵决定了透视效果;AABB 碰撞盒的坐标必须跟着物体世界坐标实时更新。这些细节如果模型“知其然不知其所以然”,写出来的代码大概率是能看不能用。让三个模型在同一个提示词下各自实现一遍,就等于用一把尺子量它们的综合代码能力,而不是单维度看谁背的题多。
1.2 三个参赛选手的“人设”差异
先说 Step 5 Preview。这个预览版模型最近讨论度很高,主打方向就是代码生成和“低返工率”,社区里有人测试过复杂前端项目的一遍通过率,数据相当能打。但预览版的问题在于稳定性未知,同一个提示词多跑几次可能给出风格差异很大的结果。我在实测前就做好了两手准备:一次生成如果跑不起来,我会记录它需要多少次人工干预,而不是直接判它出局。
DeepSeek V4 Pro 走的是深度推理路线,数学和逻辑推理是它的强项。这类模型写代码有一个特点:喜欢在关键算法上掉书袋,比如碰撞检测会给你写一个完整的分离轴定理(SAT),哪怕题目只是两个 AABB 盒子碰撞。优点是逻辑严密、边界条件处理得好,缺点是有时候为了“显得聪明”而过度设计,增加了代码复杂度。
GLM5.3 是智谱 AI 的新版本,这次更新除了基础对话能力,代码能力也做了大幅增强。而且它家生态有个特点,很多人拿它做本地部署,热搜里的“glm5.3 flashx”和“glm5.3 使用 vllm 哪个版本的镜像”就能说明问题。所以在实测生成代码之余,我还额外做了一轮本地部署环境测试,这部分会单独开一节详细讲。
2. 测试方案设计:同一道题、同一个提示词,杜绝鸡同鸭讲
2.1 固定提示词模板
模型对提示词的敏感度超乎很多人想象。同一个模型,你把“写一个迷宫游戏”改成“请用 Three.js 写一个带有碰撞检测和计时器的 3D 迷宫跑酷游戏”,生成结果可能天差地别。为了让三个模型处在同一起跑线上,我用了一份完全相同的提示词,一个字都不改:
请用 Three.js 开发一个 3D 迷宫跑酷小游戏。要求: 1. 迷宫由绿色墙体组成,地面为浅灰色,场景有环境光和方向光; 2. 玩家用方向键或 WASD 控制一个红色小球从起点移动到终点; 3. 碰到墙壁时球不能穿墙,需要停在墙前; 4. 页面上显示实时计时器,到达终点后停止计时并弹出胜利提示; 5. 代码必须完整,包含 HTML、CSS、JavaScript,可直接保存为 HTML 文件在浏览器打开运行。这里解释一下为什么我特意要求“可直接保存为 HTML 文件”。很多模型默认会假设你在某个已经配置好的前端工程环境里,于是只输出一个组件文件或者一段函数,这对实际体验来说等于没写。强制要求单 HTML 文件,能逼着模型把所有依赖(通常是通过 CDN 引入 Three.js)、所有样式、所有脚本都塞进一个文件里,这非常考验模型的工程直觉。
2.2 评分标准:不只看“能不能跑”
我把评分拆成五个维度,每个维度按 0 到 10 打分,最后看总分。这样比单纯说“某某跑出来了”更客观。
| 维度 | 考察点 |
|---|---|
| 一次跑通率 | 粘贴到浏览器后能否直接运行,还是需要人工修代码 |
| 功能完整度 | 移动、碰撞、计时、胜利判定这些需求是否全部覆盖 |
| 代码质量 | 结构是否清晰、注释是否合理、有没有明显冗余或死代码 |
| 边界处理 | 玩家卡进死角、快速按键导致穿透、窗口缩放等场景 |
| 可维护性 | 变量命名、函数拆分、后续想加功能是否容易 |
之所以把“边界处理”单独列出来,是因为我见过太多模型生成的游戏,正常玩没问题,但如果你按住两个方向键不放,小球就斜着穿墙而过了。这类问题在评分里非常拉差距。
3. 实测过程:三个模型轮番上阵的完整记录
3.1 Step 5 Preview:初稿就让我意外
先说 Step 5 Preview 的表现。它生成的代码结构让我第一反应是“这是照着教科书写的”,HTML 结构里包含了<style>块、Three.js 场景初始化、然后是游戏循环。迷宫数据直接用二维数组表示,1 代表墙体,0 代表通路,这个做法很标准,后续如果要改迷宫布局,只需要改那个二维数组,不需要动逻辑代码。
它的碰撞检测用的是一套比较均衡的方案:每一帧根据当前按键方向,先计算目标位置,再检测目标位置所在的格子是否为墙体,如果是墙体就取消这次移动。这个方案的好处是天然防穿墙,因为移动是一次性提交的,不会出现每帧逐步移动时“钻”进墙体交叉位置的漏洞。坏处是移动速度必须和帧率解耦,它用了deltaTime来控制,这一点做得相当专业。
第一次运行,直接双击 HTML 文件,浏览器里就出现了迷宫场景,红球能走,能撞墙,计时器正常走到终点,弹窗“You Win”。我复制粘贴运行的过程没有动一行代码。唯一的小瑕疵是初始相机角度稍微有点歪,迷宫终点在视觉上被墙挡了一部分,需要玩家先把镜头转过去才发现路。不过这不算功能缺陷,只能叫“审美问题”。我给 Step 5 Preview 的初稿评分是:功能完整度 10 分,一次跑通率 10 分,代码质量 9 分。
3.2 DeepSeek V4 Pro:聪明反被聪明误
DeepSeek V4 Pro 交出来的答案风格完全不同。它没有用 Three.js,而是直接用原生 WebGL 加自己封装的一小段数学库实现了整个场景。看到这段代码的时候我第一反应是“这模型是不是在炫技”,因为使用原生 WebGL 意味着要手动处理顶点缓冲、矩阵变换、着色器编译,代码量直接翻倍。
但静下心来看,它的逻辑是有道理的:它认为 30 个格子的迷宫用 Three.js 有点“杀鸡用牛刀”,而且引入外部依赖会加载慢。于是它自己写了一个极简的渲染管线,用正交投影配合二维数组迷宫,把小球的移动映射到画布上,实现了一个伪 3D 的轴测图效果。
说实话,这段代码的数学功底非常强。矩阵乘法、旋转、投影全都封装得干净利落,注释也写得很详细,甚至解释了为什么正交投影更适合这个场景——因为玩家不需要看到远处的透视变化,保持迷宫格子等距看起来更直观。但问题也很明显:它没有做相机跟随,也没有明确的“胜利判定”函数,游戏运行到终点后,计时器没有停止,玩家会陷入“不知道该干嘛”的状态。我后来把终点区域画了一个高亮色块,但胜利弹窗逻辑还是得手动补。这意味着 DeepSeek V4 Pro 在“一次跑通”和“功能完整度”上都要扣分。
还有一个让人哭笑不得的细节:由于它用的是自绘正交投影,小球在视觉上是一个扁平的圆形贴图,而不是三维球体。虽然它自己在注释里写了“这是为了风格统一”,但我个人认为这更像是一个为了降低实现难度而做出来的让步。这给了我一个很重要的经验:如果你要求模型严格使用某个框架,而模型决定绕开框架,一定要在提示词里写明“禁止更换技术栈”,否则你会得到一份看似聪明但偏离需求的答案。
3.3 GLM5.3:完成度高,但依赖项“过新”
GLM5.3 的表现在三者里属于“中庸偏上”。它老老实实用了 Three.js,也实现了 AABB 碰撞检测和终点判定。和 Step 5 Preview 的做法不同,它不是通过迷宫二维数组来判断碰撞,而是给每个墙体创建了一个BoxGeometry网格对象,然后在游戏循环里检测小球和所有墙体网格的包围盒是否相交。这个方案更接近真实游戏开发,因为墙体是可交互的对象实体,后续如果想加“可破坏墙体”之类的功能,扩展起来会容易很多。
它的代码有一个硬伤:用的是 Three.js 最新版 r170+ 的 API,比如outputColorSpace、SRGBColorSpace、ACESFilmicToneMapping这些较新的属性。问题在于,我本地测试时用的 CDN 地址指向的是 r128 的稳定版,新代码直接在旧版本上跑,控制台报了一堆“无法设置未定义属性”的错。我把 CDN 链接换成官方最新版之后,一切正常。这个问题的本质不是模型笨,而是模型知识库里包含了较新版 API 的文档,但它没法知道你本地环境用的到底是哪个版本。这个坑在真实开发中太常见了,尤其是光看官方示例代码、懒得锁版本号的队伍,很容易中招。
4. 关键细节拆解:同样是“能跑”,差在哪
4.1 移动速度和帧率:代表选手的分水岭
大部分 AI 生成的游戏代码有一个通病,就是更新位置直接写死一个speed = 0.1,然后在每一帧里执行player.position.x += speed。这样看起来没问题,但在高刷新率显示器(比如 144Hz)上,游戏速度会比 60Hz 显示器快 2.4 倍;在帧率波动时,角色会出现忽快忽慢的现象。
三个模型里只有 Step 5 Preview 和 DeepSeek V4 Pro 用了基于时间的移动方式,Step 5 Preview 用的是deltaTime乘以统一速度,DeepSeek V4 Pro 用的是固定时间步长加插值。GLM5.3 这轮反而用的是最朴素的每帧固定增量,原因可能是它把精力放在碰撞检测的整体架构上了,忽略了运动学细节。这其实反映了不同模型的“视野宽度”:专注某个模块的模型往往会忽略跨模块的联动问题。
针对这个问题,我给出一段直接可用的标准写法,不管哪个模型生成代码,你都可以把移动逻辑替换成下面这样:
const speed = 5; // 单位:米/秒 let delta; clock.getDelta(); // 每帧调用前先重置 delta = clock.getDelta(); const moveX = (keys.right ? 1 : 0) - (keys.left ? 1 : 0); const moveZ = (keys.down ? 1 : 0) - (keys.up ? 1 : 0); const normalized = new THREE.Vector2(moveX, moveZ).normalize(); player.position.x += normalized.x * speed * delta; player.position.z += normalized.y * speed * delta;这里关键点是先归一化移动向量再乘以速度,很多模型生成代码时会漏掉这一步,导致按斜方向键时角色移动速度变快,因为vector(1,1)的长度是约 1.414,等于斜着走会比直线快 41%。
4.2 碰撞检测的两种流派:查格子 vs 碰包围盒
这个题目里,碰撞检测的实现路径最能区分模型的真实水平。Step 5 Preview 用的是“格子预判法”,先算出下一个位置在迷宫二维数组里的行列坐标,如果是墙就不让走。这个方案性能极好,迷宫只有 30x30 的格子,连循环都不用,一次下标索引就拿到碰撞结论,而且几乎不可能出现穿透。
GLM5.3 用的是“包围盒相交法”,每一帧遍历所有墙体网格,逐个调用Box3.isIntersectingBox3。代码看起来更“面向对象”,墙是实体,球是实体,两者碰了就是撞了。但缺点也很明显:如果迷宫墙体数量上百个,每帧都要做上百次包围盒相交计算,对性能不友好。在小场景里这没有体感差异,但一旦把迷宫扩大到 100x100,帧率立刻会掉下来。
如果你想在实测中快速验证一个模型是否真的理解碰撞检测原理,我建议直接问它“如果我连续快速按方向键,会不会穿过墙”,然后看它的答案。只会抄 API 的模型通常答不上来,而真正理解碰撞检测的模型会告诉你:帧率足够低时,单帧位移超过墙的厚度,就可能发生“隧穿”,需要用更小步长或连续碰撞检测。
4.3 计时器和胜负判定:最容易被忽略的“游戏规则”
三个模型在计时器上的表现也很有意思。Step 5 Preview 用Date.now()差来计算耗时,GLM5.3 用performance.now(),DeepSeek V4 Pro 这个环节则直接翻车。计时器的本质不复杂,但需要手动处理“开始时间”和“结束时间”的语义:游戏加载后就开始计时,还是玩家首次按键才开始计时?到达终点后,时间必须冻结,不能让定时器一直累积。
我接到的三个模型生成结果里,只有 GLM5.3 做对了“到达终点后冻结计时”这个逻辑,其他两个模型都会在胜利弹窗出现后继续跳动。这个问题在测试时很隐蔽,因为弹窗一出来你多半会立刻关闭,根本注意到底下的计时器还在走。我建议大家在验收这类需求时,专门写一条测试用例:胜利弹窗出现后,等三秒再关闭,看计时器数字是否还在变。这种边界行为最能体现模型的细心程度。
5. 部署配套:GLM5.3 本地跑起来时遇到的 vLLM 镜像版本问题
5.1 为什么有人要把 GLM5.3 部署到本地
我这次除了用官方 API 测 GLM5.3,还顺手做了一轮本地部署测试。原因纯粹是客观场景需要:这种大模型在代码生成场景下,往往会涉及大量业务代码,把数据放到本地推理环境更可控,也能规避远端服务的排队等待。本地部署也有利于私有化调优,这点对很多团队来说是刚需。
本地部署 GLM5.3 时,大家普遍会用到 vLLM 这个推理加速框架。它的核心优势是用 PagedAttention 技术把显存利用率提上去,推理速度和吞吐量都比原生 PyTorch 实现快好几倍。但 vLLM 的版本与模型支持矩阵是个“玄学地带”:版本太旧不认新的模型结构,版本太新又可能引入不兼容的依赖。
5.2 “glm5.3 用哪个版本的 vLLM 镜像”避坑实录
我在实测时踩过一个具体的坑:直接用pip install vllm装了当时的最新稳定版,然后加载 GLM5.3 权重,结果启动时报了类似 “Unsupported model architecture” 的错误。后来查了模型卡文档才知道,GLM5.3 的多模态部分走的是新的模型结构,必须要 vLLM 的较新版本才内置了对这个架构的支持。
那些在网上搜“glm5.3 使用 vllm 哪个版本的镜像”的人,大概率也撞到了同一个问题。我的实测结论是:建议使用 vLLM 官方镜像vllm/vllm-openai的最新标签,或者在 tag 列表里选择当前已适配 GLM5.3 的稳定版本。由于 GLM5.3 更新较快,如果启动时报模型结构不识别,优先换更新版本的 vLLM 镜像,而不是去改模型加载代码。从社区反馈来看,较新的 vLLM 版本内置支持度已经比较完善,用旧版镜像容易在加载时被各种莫名其妙的算子报错卡住。
这里具体分享一个可操作的验证流程。先把镜像拉下来,用docker run启动一个带 8000 端口映射的反向代理服务,然后调用/v1/models接口看模型是否被正确加载。如果响应里正常返回模型名,说明镜像版本和模型结构匹配;如果接口直接超时或返回 500,优先查容器日志里的 “Unsupported” 字样,确认是哪一层不支持,再去换镜像版本。
另外补充一个重要细节:无论用哪种镜像,显存至少准备一个大于模型权重总大小的量。GLM5.3 这种大模型,fp16 权重加载后还要留出 KV Cache 的空间,显存不够最常见的表现不是加载报错,而是推理过程中 OOM,让你误以为是代码问题。
5.3 部署和代码生成之间的“同源坑”
最后说一个有意思的联想:我遇到的 GLM5.3 代码生成中“用了新 API,旧环境跑不动”的问题,和本地部署中“模型结构太新,旧 vLLM 不支持”的问题,本质上是一个东西——模型的知识快照永远领先于你本地的环境快照。模型训练时看到的是最新的库和最新的 AI 框架结构,但你本地环境可能还停留在半年前。
所以我现在做任何模型生成任务,都会在提示词末尾加一句环境约束,比如:“项目使用 three@0.128.0,不要使用 r150 之后的新特性”或者“部署环境使用 vllm 0.7.x 分支”。这个习惯帮我省掉了大量由于版本差异导致的纠错时间,强烈推荐你们也养成。
6. 横评结果汇总与避坑清单
6.1 最终评分表
| 评分维度 | Step 5 Preview | DeepSeek V4 Pro | GLM5.3 |
|---|---|---|---|
| 一次跑通率 | 10 | 7 | 8 |
| 功能完整度 | 10 | 6 | 9 |
| 代码质量 | 9 | 10 | 8 |
| 边界处理 | 9 | 8 | 7 |
| 可维护性 | 8 | 6 | 9 |
| 总分 | 46 | 37 | 41 |
补充一点:这个总分是综合“游戏本身”和“修复成本”后的结果。DeepSeek V4 Pro 的数学功底确实强,原生 WebGL 的代码质量甚至比另外两个模型调用的 Three.js 更高,但对普通用户来说,“粘贴即运行”才是王道,所以我给它的功能完整分压得很低。
6.2 三个模型分别适合干什么
Step 5 Preview 适合快速出原型,尤其是那些“今天就要看到东西”的紧急需求。它生成的代码结构清晰,加点注释就能交给别人维护,基本就是把需求翻译成代码的“稳定翻译官”。
DeepSeek V4 Pro 适合做算法验证和性能敏感场景。它倾向于用更底层的办法解决问题,如果项目本身对依赖体积、运行性能有高要求,给它多点时间,它能给你一份很有研究价值的实现。
GLM5.3 更适合具体业务工程的续写和调试。它在“理解现有代码结构”和“按模块扩展”上表现更自然。不过使用它生成的代码之前,一定要先确认运行环境的版本依赖,避免新旧 API 冲突。
6.3 通用避坑经验清单
生成前把技术栈写死在提示词里,例如“只能用 Three.js”,否则模型会自作主张换原生 WebGL,然后从零手写渲染管线。这个分岔一旦发生,纠错成本很高。
所有 AI 生成的代码,全部用 CDN 锁版本的方式引入依赖,不要用“latest”这种链接。Three.js 的改动不算小,r128 和 r170 之间光是颜色管理就完全不同,经常出现“示例能跑、自己一粘就黑屏”的情况。
验证碰撞检测多做一组“快速键连打”测试,按住方向键同时快速切换另一个方向,很多穿墙 bug 在慢速移动时根本暴露不了。
计时器功能验收时,等弹窗出现后再盯三秒。如果数字还在动,说明胜利后没有清理定时器,这是 AI 模型的高频失误点。
本地部署模型时,镜像版本选新不选旧。启动失败先查日志里是否出现 “Unsupported model architecture”,不要一上来就怀疑显存不够。
这次测试跑下来,我最大的感受是:模型之间的能力差距,已经不只是“会不会写代码”的差距,而是“能不能替你把事情考虑全”的差距。单个模型的强项和短板都很鲜明,与其争论谁更强,不如把它们的风格特质摸清楚,按需取用。像 Step 5 Preview 这种适合流程图式开发,DeepSeek V4 Pro 适合攻坚算法,GLM5.3 适合在既有工程里做长线迭代。最后再分享一个小技巧:每次生成前,把你对运行环境的要求用一两句话写在提示词末尾,哪怕只是“用 three@0.128.0,不要新特性”这一句,都能显著降低返工概率。实测下来,这个习惯比换一个更强的模型还管用。