ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

GLM-5.3 Flash实测:4个前端任务一次跑通,仅花4分钱

GLM-5.3 Flash实测:4个前端任务一次跑通,仅花4分钱 从上周开始我一直在用 GLM-5.3 Flash 处理真实前端需求而不是像很多人那样只拿面试题或算法题喂给模型。我挑了 4 个平时工作中经常遇到的开发任务从零开始写提示词全程记录它给的代码能不能直接跑、改了几次才通过、最后花了多少钱。结果确实有点出乎意料4 个任务全部一次跑通账单显示总共只花了 4 分钱。这篇文章就把这 4 个任务的完整过程、提示词思路、踩坑记录、以及账单明细一起整理出来给想在实际项目里用 AI 写前端代码的朋友做一个参考。先说我的测试环境Node.js 20.11.0纯前端项目没有框架依赖用的都是浏览器原生 API 加少量 npm 包代码运行在 Chrome 121 下。GLM-5.3 Flash 通过官方 API 调用temperature 设为 0.3max_tokens 设为 4096其他参数保持默认。我没有给它喂任何项目上下文文件全靠提示词里的描述让模型理解需求这样能更真实地反映它在“冷启动”状态下写代码的水平。1. 测试目标与任务选题思路1.1 为什么选 GLM-5.3 Flash 做前端实测选择测试 GLM-5.3 Flash 不是因为它是最强的模型而是因为它在官方介绍中被定位为“轻量级、低延迟、高性价比”的版本在日常开发这种高频调用场景里比大尺寸模型更实用。实际用下来它在响应速度上确实有优势单次请求基本在 1 到 3 秒内返回结果写一个完整组件的代码通常只需要一次请求最长的一次也没超过 8 秒。我更在意的指标是“一次通过率”因为在实际开发中模型生成代码后要反复追问修正这个来回沟通的时间成本远高于 API 费用本身。如果你让模型写 100 行代码API 返回只要 2 秒但你为了让它改对却要来回问 5 次、每次重新生成 200 行那实际效率反而比手写更差。所以这轮测试的核心目的很明确验证 GLM-5.3 Flash 在真实前端任务中能不能用最少的请求次数给出可直接运行的代码。1.2 四个测试任务的选型逻辑我挑选任务时给自己定了三条标准必须是平时工作里真的会写的功能不能是玩具级 Demo要覆盖不同的前端技术方向不能全部都是 DOM 操作任务难度要有梯度从简单到复杂都要有这样才能看出模型的真实能力边界。最终定下的四个任务分别是任务一实现一个带防抖功能的搜索框要求支持键盘操作、请求竞态处理、结果列表渲染总代码量约 120 行。任务二写一个基于 Canvas 的图片压缩工具页面要求支持拖拽上传、压缩比例预览、压缩前后大小对比约 180 行。任务三实现一个拖拽排序的列表组件要求支持触摸屏操作、动画过渡、排序状态保存到 localStorage约 220 行。任务四写一个 WebSocket 消息推送的实时数据看板要求自动重连、消息队列缓冲、连接状态展示约 260 行。这四个任务分别对应了前端开发中最常见的高频场景表单交互、文件处理、复杂 UI 交互、实时通信。每个任务都不是单纯的“写个函数”而是需要综合运用 DOM 操作、事件机制、异步处理、状态管理等多种能力比网上常见的“用 JavaScript 写一个九九乘法表”要贴近实际工作得多。2. 四个真实任务的实测过程与代码分析2.1 任务一带防抖的搜索框一次跑通的关键在哪第一个任务我做的是搜索框这个功能看起来简单但里面埋了好几个容易出错的点。我给 GLM-5.3 Flash 的提示词是这样的请帮我实现一个搜索框组件功能要求用户输入时不做请求停止输入 500 毫秒后才发送请求请求结果按顺序返回如果先发的请求后返回后发的请求先返回不能覆盖前面的结果支持键盘上下键选择搜索结果回车确认点击外部区域关闭结果列表。给 HTML、CSS、JavaScript不要用第三方库。模型返回的 HTML 结构是常规的 input 加 ul 列表JavaScript 部分用了一个自执行函数封装状态整体组织得比较规整。真正让我意外的是它处理竞态的方式let requestId 0; async function fetchResults(keyword) { const currentRequest requestId; const response await fetch(/api/search?q${encodeURIComponent(keyword)}); const data await response.json(); if (currentRequest requestId) { renderResults(data); } }这个实现用的是“请求 ID 比对法”在每次发起新请求时递增 requestId响应回来后检查当前 requestId 是否等于发起请求时的值不相等就说明有更新的请求已经发出去了直接丢弃这次结果。这个方案不是最优的严格来说还可以用 AbortController 取消旧请求但逻辑完全正确能避免竞态问题。防抖函数它也写对了用的是闭包加 setTimeout 的标准写法function debounce(fn, delay) { let timer null; return function (...args) { if (timer) clearTimeout(timer); timer setTimeout(() { fn.apply(this, args); }, delay); }; }这里有个细节值得注意它用了fn.apply(this, args)而不是简单的fn(...args)这样能保留函数调用时的 this 指向虽然在这个场景里没有用到 this但说明模型对防抖函数的边界情况理解是对的。键盘操作部分它用的是 keydown 事件监听 ArrowDown、ArrowUp、Enter 和 Escape 四个键并且在列表为空时不会报错。点击外部区域关闭列表用了 document 级别的 click 事件监听通过e.target.closest(.search-container)判断点击是否在组件内部。整体代码可以直接运行没有语法错误没有未定义的变量。实际运行中我注意到一个小问题它在处理 Escape 键时同时执行了清空输入框和隐藏列表两个操作但列表隐藏后搜索结果没有被销毁这意味着你再次聚焦输入框时旧结果会重新出现。不过这不影响首次运行的正确性只能算是一个交互细节上的小瑕疵。这个任务 GLM-5.3 Flash 用了约 1.8 秒返回结果总共生成了 130 行代码一次通过。2.2 任务二Canvas 图片压缩工具文件 API 用的很熟第二个任务我让它写一个图片压缩工具这个功能涉及 FileReader、Canvas、Blob、URL.createObjectURL 等多个浏览器 API属于对 API 熟悉度要求比较高的任务。我的提示词是写一个纯前端的图片压缩工具页面用户可以选择图片文件或将图片拖拽到页面上然后显示压缩前大小、压缩后大小、压缩比例用户可以通过滑块调整压缩质量点击下载按钮可以下载压缩后的图片。要求显示图片预览支持 PNG 和 JPEG 格式。不需要后端所有操作在浏览器本地完成可以用 Canvas API。模型给出的 JavaScript 代码核心思路是用 FileReader 读取文件为 DataURL然后创建 Image 对象加载在 onload 回调里绘制到 Canvas 上最后用 canvas.toBlob() 输出压缩后的图片。整体流程是正确的代码写得很正统文件读取、图片加载、Canvas 绘制三个步骤衔接正常。有一个值得表扬的地方是它做了 MIME 类型映射而不是像很多 AI 生成代码那样直接写死输出格式function getCompressedType(fileType) { if (fileType image/png) return image/png; if (fileType image/jpeg) return image/jpeg; return image/jpeg; }这个处理的用意是保证输出的图片格式和原图一致避免用户上传 PNG 图片后下载下来变成 JPG 导致透明背景变黑的尴尬情况。模型能想到这一点说明它对图片处理的实际场景有一定理解而不是只会套 API。拖拽上传部分它用了 dragover 和 drop 两个事件dragover 里调用了e.preventDefault()来阻止浏览器默认行为drop 里通过e.dataTransfer.files[0]获取文件。这两个事件的处理细节都正确没有漏掉 preventDefault这是一些新手常犯的错误。压缩后大小对比的实现方式是用 URL.createObjectURL 创建临时 URL 给 img 标签预览同时用(file.size / 1024).toFixed(1)计算 KB 数并显示。整个过程没有内存泄漏隐患因为它在每次新文件选择时会清理之前的 object URL。运行过程中我发现了一个小 bug当用户上传非常大的图片比如手机拍的 4000x3000 像素照片时Canvas 绘制的画布尺寸是原图尺寸这会占用大量内存而且压缩后的文件大小可能不会明显减小。这不是代码逻辑错误而是没有做尺寸限制导致的体验问题。但从“能运行”的标准来看任务二是完全达标的。这个任务 GLM-5.3 Flash 用时约 2.4 秒返回生成了 185 行代码一次通过。2.3 任务三拖拽排序列表触摸事件处理超出预期第三个任务我刻意提高了难度让它实现一个支持触摸屏的拖拽排序列表。这个功能在桌面端用 HTML5 拖放 API 能轻松实现但触摸屏不支持 drag 事件需要用 touchstart/touchmove/touchend 模拟而且还要处理动画过渡和状态持久化。我的提示词实现一个可拖拽排序的列表组件支持鼠标拖拽和触摸屏拖拽拖拽时有平滑的动画过渡效果排序结果实时保存到 localStorage刷新页面后保持排序位置。列表数据用数组存储每一项包含 id、title 和 color 三个字段。请给出完整可运行的代码。GLM-5.3 Flash 用了指针事件 Pointer Events 来统一处理鼠标和触摸操作这是比我预期更现代的实现方式。它先通过e.pointerType判断操作类型但核心逻辑对鼠标和触摸是一致的用 pointerdown/pointermove/pointerup 替代了 touch 系列事件省去了大量兼容代码。看到这个方案时我特意查了一下Pointer Events 在 Chrome 和 Safari 13 都已经完整支持所以这个选择是合理的。拖拽的实现逻辑是pointerdown 时记录拖拽元素的初始位置和鼠标位置pointermove 时计算位移并给元素设置 transform: translateY()同时判断是否应该与其他元素交换位置。这个方案比“拖到哪个位置就把 DOM 元素插到哪”的方式更平滑因为 DOM 结构不变只是视觉上在移动性能更好。排序交换的判断逻辑它用了简单的“中心点交叉检测”当拖拽元素的中线越过相邻元素的中线时触发数组位置交换。这个实现比网上很多用 offsetTop 边界检测的实现更好因为中心点检测的结果更稳定不会出现快速拖动时跳位的情况。localStorage 保存部分它用一个saveOrder()函数统一处理每次排序完成后把数组的 id 顺序用 JSON.stringify 存到 localStorage页面加载时在初始化阶段读取并重新排序。这里有个细节如果 localStorage 为 null 或解析失败它用 try-catch 捕获异常并回退到默认顺序这个容错处理很到位。动画过渡部分它用了两个策略初始渲染后给所有列表项添加transition: transform 0.2s ease拖拽中的元素则去掉 transition 以获得即时跟随效果。这两个策略的结合保证了“非拖拽元素平滑移动”同时也保证“拖拽元素不卡顿”是前端动画细节里比较高级的处理方式。运行结果功能完整性上没有任何问题拖拽排序、动画、持久化都正常工作。唯一的小缺点是触摸拖拽时没有设置touch-action: none在触摸屏上拖拽可能会触发页面滚动导致体验不完美。但这个问题的出现与否取决于运行设备不影响功能正确性。这个任务 GLM-5.3 Flash 用时约 3.2 秒返回生成了 226 行代码一次通过。2.4 任务四WebSocket 实时数据看板重连逻辑做得到位最后一个任务我直接挑战了一个偏复杂的场景WebSocket 实时数据看板。这个功能除了基础的 WebSocket 通信外还涉及断线自动重连、消息队列缓冲、状态展示等机制对前端工程师来说都属于进阶内容。我的提示词是请用纯 JavaScript 写一个实时数据看板页面通过 WebSocket 连接 wss://demo.example.com/ws 接收消息。要求连接断开后自动重连重连间隔从 1 秒开始每次失败后翻倍最大间隔 30 秒连接过程中收到的消息需要缓存重连成功后补发页面需要展示当前的连接状态连接中、已连接、重连中、已关闭收到消息时用列表展示最新 20 条数据。HTML、CSS、JavaScript 都要不要用框架。这个任务的难点不在 WebSocket 本身的用法而在重连策略和消息缓存的设计。GLM-5.3 Flash 给出的实现里有一个重连管理器使用了指数退避算法代码是这样的let reconnectAttempt 0; const maxReconnectDelay 30000; const baseReconnectDelay 1000; let reconnectTimer null; function scheduleReconnect() { if (reconnectTimer) return; const delay Math.min(baseReconnectDelay * Math.pow(2, reconnectAttempt), maxReconnectDelay); reconnectTimer setTimeout(() { connectWebSocket(); reconnectTimer null; }, delay); reconnectAttempt; }这个指数退避实现是标准做法初始 1 秒第一次重连失败后 2 秒第二次 4 秒以此类推到 30 秒封顶。它用reconnectTimer防止重复调度这是很多 AI 代码会忽略的地方如果没有这个判断回调函数可能被触发多次导致多个 WebSocket 连接同时建立。消息缓存部分是它用一个数组存储断线期间收到的消息重连成功后将缓存的消息追加到列表中let pendingMessages []; function handleMessage(event) { const data JSON.parse(event.data); if (ws.readyState WebSocket.OPEN) { appendToDashboard(data); } else { pendingMessages.push(data); } }这个逻辑有一个逻辑上的小问题当 WebSocket 断开时onmessage 事件根本不会被触发所以 pendingMessages 这个数组实际上只会在“连接尚未建立但代码已经注册了 handler”这样的极端情况下接收到消息。也就是说这个缓存机制在标准场景下永远不会生效。不过它也不会造成任何错误只是代码里有一段功能没有实际用上。重连成功后的清理逻辑倒是做得很好onopen 里它会重置 reconnectAttempt 为 0这样下次断线重连时退避计时会重新从 1 秒开始不会出现多次断线之间间隔越来越长的问题。这个细节说明模型理解了指数退避重连的设计意图而不只是背代码模板。状态展示部分它维护了一个updateStatus(text, color)函数在 onopen、onclose、onerror 等不同阶段调用页面顶部有一个带状态圆点的信息栏连接中显示黄色圆点已连接显示绿色重连中显示橙色已关闭显示灰色。这个视觉反馈的逻辑完整状态切换边界没有漏。这个任务 GLM-5.3 Flash 用时约 4.1 秒返回生成了 255 行代码一次通过。代码里 WebSocket 地址是假的 wss://demo.example.com/ws我实际运行时把它替换成本地服务地址其余代码没做任何修改运行正常。3. 账单 4 分钱的成本拆解与对比3.1 GLM-5.3 Flash 的 token 消耗细账账单 4 分钱对应的是四个任务加起来的全部 API 调用成本。我在测试前特意开通了用量统计功能每次请求都记录了输入 token 数、输出 token 数和计费金额。因为四个任务都是一次跑通没有额外的追问修正请求所以实际费用比预想中低很多。具体账单如下任务输入 token输出 token总 token费用搜索框4861,4321,918约 0.008 元图片压缩5121,9862,498约 0.010 元拖拽排序5942,2732,867约 0.012 元数据看板6312,6423,273约 0.013 元合计2,2238,33310,556约 0.043 元四舍五入后的实际扣费是 4 分钱。从 token 消耗来看四个任务的输出 token 加起来大约 8,300 个平均每个任务输出 2,000 个 token 左右。这说明我的四个任务难度都不算极端每个任务的代码量大约在 120 到 260 行之间属于标准的前端小功能。按这个比例换算如果一天写 20 个类似的小功能消耗大约 5 万 token费用也就是两毛钱左右几乎可以忽略不计。对个人开发者来说这个成本基本谈不上“预算”但对需要控制成本的中大型团队来说把这种高频调用场景从大尺寸模型切换到轻量模型确实能省下不少费用。3.2 和传统开发方式相比省了什么做一个简单的对比。传统方式下如果我自己从零手写这四个任务从需求分析到编码再到调试保守估计需要 2 到 3 个小时。如果碰到不太熟悉的 API比如任务二的 Canvas 压缩查找文档和试错的时间还会更长。用 AI 辅助写代码最直观的提升就是时间成本被压缩到原来的十分之一左右。但我想强调一点AI 写代码省掉的是“把思路变成代码”的过程而不是“理解需求、设计交互、测试验证”的过程。比如任务三的拖拽排序如果我完全不懂 Pointer Events即便模型给的代码是能运行的我也没有能力判断它是不是最优方案更没有能力在它出问题时去修。所以我建议把 AI 当作“高效的编码助手”而不是“替代思考的工具”它帮你省的时间应该用来做更重要的架构设计和代码审查。如果是和传统用大模型 API 开发的方式对比GLM-5.3 Flash 的成本优势主要体现在响应速度和价格上。我不会在评测里给出所谓性价比排行因为不同产品的价格体系经常变化我只说一点在同样能完成任务的前提下优先选更快的模型因为前端开发的瓶颈通常是“等待响应”而不是“代码生成”速度快的模型能让你保持连贯的开发状态。3.3 为什么成本能压到这么低GLM-5.3 Flash 能把四个任务的总成本压到 4 分钱和它采用的 MoE 稀疏激活架构有很大关系。这个架构的意思是模型内部被拆分成多个专家模块每次生成 token 时只激活其中一小部分专家参与计算而不是像传统密集模型那样所有参数都参与推理。参数量虽然是几十亿甚至上百亿级别的但单次推理的实际计算量只有几分之一。另一个原因是任务本身只涉及前端代码生成不需要大量的上下文内容。模型在生成代码时只需要理解提示词描述的需求然后输出一条代码路径不需要像处理长文档那样在多个段落之间做决策。这也解释了为什么在比较复杂的算法推理任务上Flash 版本的效果可能不如大尺寸版本因为它本身定位就是高频、轻量、短文本场景。成本计算上实际情况是按 token 数计费。前端代码生成场景下输入 token 主要是提示词和一些必要的说明几百 token 就够了输出 token 取决于代码量。如果按每百万 token 的单价来估算生成大约 8,000 个输出 token 的成本在几分钱量级确实是低成本。4. 实际操作中的问题与排查建议4.1 遇到过的连接超时与重试策略虽然我这次四个任务都一次跑通了但在之前的日常使用中GLM-5.3 Flash 也遇到过几次连接超时的问题。最常见的情况是网络不稳定时请求直接报 ECONNRESET 错误服务端返回 503 或 429 状态码。这不是模型本身能力问题而是任何云端 API 都会遇到的基础设施风险所以我提前写了一个带重试的调用封装。我的重试策略是失败后等待 1 秒重试连续重试最多 3 次间隔指数递增1 秒、2 秒、4 秒。超过 3 次后直接放弃并提示用户“AI 服务暂时不可用”。注意这里的退避间隔上限要比重连策略大一些因为 API 调用失败通常意味着服务端负载较高过快重试可能加重负载。async function callGLM(prompt, maxRetries 3) { for (let attempt 0; attempt maxRetries; attempt) { try { const response await fetch(/api/glm, { method: POST, headers: { Content-Type: application/json }, body: JSON.stringify({ prompt }) }); if (!response.ok) throw new Error(HTTP ${response.status}); return await response.json(); } catch (err) { if (attempt maxRetries - 1) throw err; await new Promise(resolve setTimeout(resolve, Math.pow(2, attempt) * 1000)); } } }调用时把提示词和参数包装成一个 JSON 结构如果一次调用失败整个请求重来不保留中间状态这个设计在幂等场景下是安全的前端代码生成正是这种场景。不过要注意这个重试逻辑不适用于非幂等操作比如从模型输出中直接写入数据库的任务如果第一次调用的响应丢失但服务端已经处理重试可能导致重复写入。4.2 代码“看上去能用但细节不完整”的翻车案例我想诚实地说一下 GLM-5.3 Flash 之前翻车的一个案例这样你对它的能力边界会有更清楚的认识。有一次我让它写一个图片懒加载组件要求是图片进入视口时才开始加载加载时显示占位符加载失败时显示错误提示。模型给出的代码用了 IntersectionObserver这个 API 选得没错但它把rootMargin和threshold两个参数都设置了不合理的值rootMargin: 100px 0px导致图片提前 100 像素就开始加载而threshold: 0.5又要求图片元素至少有 50% 进入视口才触发。两个参数叠加的效果是页面快速滚动时图片加载时机完全不符合预期。这类问题的根源不是模型不懂 API而是它缺乏在真实浏览器环境下测试代码的机会。它能理解 API 的签名和大致用法但无法验证“与另一个参数组合起来是否合理”。所以我的建议是凡是涉及多个参数联动的代码一定要在浏览器里实测一遍特别是性能相关的配置。4.3 自查清单用 GLM-5.3 Flash 写前端代码的常见问题排查根据我这段时间的使用体验整理了十个常见问题的快速排查方案分享给你参考问题可能原因解决方法运行时报错xxx is not defined模型漏写了导入语句或变量声明检查代码末尾是否缺少依赖或让模型补全完整代码而不是片段中文显示为乱码HTML 文件缺charsetutf-8在head中补上meta charsetUTF-8CSS 样式不生效选择器与 HTML 结构不匹配检查类名和 ID 是否与 HTML 一致Canvas 绘制不出来获取 Canvas 上下文时 typo确认是getContext(2d)而不是getContent(2d)拖拽没有动画transition 属性缺失或值错误检查是否设置了 transition: transformWebSocket 无法连接协议不匹配或 URL 错误确认是ws://还是wss://检查端口是否对外开放异步请求竞态没有竞态保护用 requestId 或 AbortController 处理localStorage 不生效存储格式不是字符串使用JSON.stringify()和JSON.parse()包装键盘事件失效监听对象不是 document确保focus在输入框上事件绑定在 document 上图片跨域画布污染Canvas 引入了跨域图片给图片设置crossOriginanonymous且服务端允许 CORS这个检查表是基于 GLM-5.3 Flash 输出的常见问题整理的你在调试过程中如果遇到其他错误也可以按照“运行时错误 - 变量作用域 - API 参数 - 浏览器兼容性”的顺序去排查这基本可以覆盖大多数前端代码踩坑点。4.4 实测经验四个任务各自的注意要点四个任务都跑通之后我又做了一轮检查逐个任务验证了边界情况。搜索框组件里我清空了搜索词点击回车结果列表会显示“暂无搜索结果”这个提示逻辑是正确的。但有个交互细节值得改进当用户连续快速输入时防抖函数能正常合并请求不过请求返回后搜索结果列表会短暂闪烁原因是每次请求结束后都会重新渲染列表包括数据完全相同的情况。你可以用JSON.stringify(prevData) JSON.stringify(newData)做一层浅比较避免不必要的 DOM 更新。图片压缩工具在 Windows 的 Chrome 上测试了拖拽功能从桌面拖入图片没有问题。但在 Safari 上发现一个问题拖拽图片后页面会直接打开图片文件而不是触发 drop 事件这是因为 Safari 默认对图片文件的拖拽行为处理不同最简单的方法是在 dragover 里调用e.preventDefault()并且在 document 级别绑定 drop 事件阻止默认行为。拖拽排序列表在移动端用 Chrome 的设备模拟器测试通过但换成真实手机访问时排序时会偶尔出现页面抖动的现象根本原因是触摸拖拽时没有禁用浏览器的默认触摸行为。你可以在监听 touchmove 时调用e.preventDefault()或者给列表容器设置touch-action: none的 CSS 属性两种方式都能解决。WebSocket 数据看板在本地测试时模拟了服务端断连观察到了重连日志退避间隔确实是 1 秒、2 秒、4 秒这样递增的。唯一让我觉得可以改进的是它没有处理页面切换 tab 时的 WebSocket 连接状态当页面在后台超过 30 秒时浏览器可能自动断开 WebSocket恢复前台时页面不会主动检测连接状态要等下一次重连触发时才恢复正常。如果你做实时性要求高的功能建议加一个 visibilitychange 事件监听在页面恢复可见时主动检查 WebSocket 状态并触发重连。5. 关于 GLM-5.3 Flash 在真实前端开发的定位思考说实话这次测试之前我对轻量模型写前端代码的印象停留在“写个简单函数还行组件级别容易翻车”的程度GLM-5.3 Flash 的表现刷新了我的预期。四个中等复杂度的真实前端任务全部一次跑通没有出现语法错误和明显的逻辑硬伤。它不是完美无缺有三个地方我做了手动调整搜索框的空结果状态、图片压缩的尺寸限制、触摸拖拽的 touch-action 设置。但拿“作为开发初稿”的标准来看这个通过率已经相当可用。从工作流的角度看GLM-5.3 Flash 更适合的角色是“第一版代码生成器”和“技术方案咨询”它写的代码不一定是最优的但只要需求描述足够清楚它给出的初版代码大概率能运行然后由工程师在此基础上做优化、补边界、加注释。这个工作流能省掉从零搭建基础框架的时间把注意力集中在更重要的架构设计和交互体验上。最后分享一个我的小习惯每次让 AI 写代码前我会像给新同事交代任务一样写清楚“需求背景、功能列表、技术约束、预期效果”四个部分。比如你写“实现一个拖拽排序列表”它给你的可能只是一个能用的 Demo但你加上“支持触摸屏、有动画、状态保存到 localStorage、不要用第三方库”这些条件后它输出的就会是一个更接近生产环境的实现。提示词质量直接决定输出质量这个规则在 GLM-5.3 Flash 上体现得特别明显。
返回列表