前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片NEW
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 业务场景题真实业务问题与追问
  • 查漏补缺常见问题解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
    • AI 定制路线NEW按你的简历现排
    • AI 知识地图NEW串起全站知识点
  • 动态
    • AI 热点NEWAI 每日动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
AI 助手NEW
旧版
返回 AI 情报前线
All News · 全部资讯8611
  • 人脸年龄验证的2年误差困局与设计陷阱
  • 自主 AI 公司39天实验:487M tokens、$1.1k成本、零收入
  • 语音 AI 的转身悖论:延长静音阈值反而更差
  • Claude Code 三大提效流程:规划-构建-修复
  • Agent 内存用向量存储的天花板:聚合查询失效
  • MoE 模型压缩魔法:2GB 内存跑 Gemma 26B 的权重共享方案
  • Herdr:编码代理多路复用器,像 tmux 一样管理并发 Agent
  • Claude Opus 5 一句话生成 3D 游戏,含物理和音乐
  • Claude Code 赋能容量规划:从被动应急到主动预测
  • 本地部署 16 块高端 GPU 运行开源大模型完整方案
  • 真 Agent vs 伪 Agent:金融自动化平台的量化对标与选型框架
  • 本周技术速览:K3 开源、MCP 无状态化、Agent Office CLI
  • Claude 红队测试突破 3 个组织隔离、上传恶意包到 PyPI
  • DeepSeek-V4-Flash 正式版 API 上线,性能媲美闭源模型
  • 用 MCP 把 AI Agent 变成运维工程师
  • METR 呼吁:每次 AI Agent 失控都应独立调查
  • Agent 流水线中的 Goodhart 陷阱:5 个作弊案例
  • AI Agent 发送短信前的人工审批设计模式
  • Lean 项目 CI 优化:41 分钟到 12 分钟的三轮实验
  • AI Agent 安全防护:模型提取与密钥泄露风险清单
  • 代码生成陷阱:格式匹配不等于执行成功
  • Agent 自主支付协议 x402 商用落地
  • 自托管 DeepSeek-V3:$8/月 vs Claude Opus 成本 1/180
  • DeepSeek V4-Flash:开源模型性能 Opus 级、成本 1/100
  • AI 生成应用审计清单:5 大维度常见缺陷与修复
  • NVIDIA开源Molt: PyTorch原生强化学习框架
  • Termexo: AI编程Agent会话管理工作台
  • 国产开源模型登顶全球调用量,程序员有了平价选择
  • Go+Rust构建本地离线AI助手: 安全架构深度指南
  • Python 和 TypeScript 生态新版图
  • CI中的自主代码审查与自动修复:Claude Code实战
  • MCP 工具服务搭建实战指南
  • Agent 工具成本优化:从隐形开销到 Tool Search
  • Agent DevOps 安全:暴露旧日权限管理漏洞
  • 从零构建 MCP 服务器:Agent 工具集成标准化指南
  • 长时任务 Agent 的持久化队列架构
  • Agent 平台从原型到生产的实战经验
  • 小规模 Agent 治理协议的实现范例
  • 微软生成式AI入门教程(21课)
  • Ollama本地AI:免费运行GPT级模型
  • 电商订单管理的5层Agent架构设计
  • 235 家公司联署:开源权重 AI 模型是竞争和安全基础
  • 7 月模型速览:GPT-5.6 与 Claude Opus 5 新特性汇总
  • Agent认知记忆8层架构设计与实现
  • 月费 6 美元自托管 Llama 2 完整指南
  • LLM 限流应对:系统优雅降级完整设计指南
  • 开源音频全能工具:集语音克隆、识别、翻译于一体
  • AI 猜测 vs 确定的三个识别信号
  • AI 项目记忆体系:向量搜索的文档优先设计
  • 用对抗性Agent审核提示词发现隐藏的工程漏洞
  • IHUI-AI:176 个 LLM 统一接口框架
  • 已加载 51 / 8611
8.0
热点
AI SCORE
技术实践2026-08-02 15:04

代码生成陷阱:格式匹配不等于执行成功

dev.to · AI#代码生成#工程陷阱#测试
Editor brief · 编辑速览

代码生成工具仅用正则检查闭合标签判断成功是常见陷阱,完整标签不代表代码能运行,真正验证需实际执行;揭露成功信号与可用性的时间差。

文章思维导图
Knowledge map
拖拽缩放
Full translation

完整中文译文

我们在开发 Zugo,它能把一句文字描述变成一个可以运行的游戏、网站或 app。有段时间,我们用下面这段代码判断构建是否成功:

function htmlComplete(text) {
  return /<\/html>/i.test(text);
}

一个闭合标签。这就是判断构建成功与否的关卡。只要模型输出了 </html>,这一轮就算成功,界面会显示绿色对勾,同时扣除 credits。至于页面能不能真正打开,并不在判断范围之内,因为扣费发生时,我们还没有把文档挂载到任何地方。

如果你正在开发任何生成代码的产品,这就是一个很容易掉进去的陷阱。文件是否已经写出来,很容易观察;文件能否正常运行,却没那么容易判断。于是,在不知不觉中,“能否运行”就不再是“完成”的标准了。

为什么标签平衡检查救不了你

我们的第二道检查会统计开始标签和结束标签的数量。它的代码注释已经坦白说明了自己的能力边界:这只是平衡检查,并不代表“页面能够渲染”。一个文档完全可以做到标签严格配对、以 </html> 结尾,然后在第一个 script 的第一行就抛出异常。这样的构建仍会被计费,并被判定为彻底成功。

更糟糕的是,失败会以一种最消耗用户信任的方式隐藏起来:流式输出一结束,对勾立刻变绿;真正的结果却要几秒后才会到达。根据我们在自身流程中的测量,这段延迟对于网站是 2.6 秒,对于游戏是 4.2 秒,对于 React app 是 6.2 秒;如果第一次判定失败,还会额外进行一次静默的重新挂载。因此,一个失败的构建可能会在空白页面上顶着绿色对勾长达约 12 秒。这个时间已经足够让用户觉得产品在欺骗自己,然后直接关闭标签页。

你无法从文档外部监视它

显而易见的修复方式,是用 error boundary 包裹 preview 并监听错误。但在我们的场景中,这行不通。如果你也在沙箱中运行生成的代码,背后的原因值得了解。

preview frame 使用的是 sandbox="allow-scripts",没有设置 allow-same-origin。这会让它拥有一个 opaque origin,而这正是我们想要的效果:生成的文档绝不能访问宿主 app、宿主的存储或 session。但同一堵隔离墙也意味着宿主无法看到 frame 内部发生了什么。包裹在 preview 外层的 React error boundary 捕获不到文档内部的任何错误。如果用户看到了我们的 error boundary,那说明崩溃的是编辑器,而不是他们构建出来的内容。

因此,监听器必须运行在 frame 内部,也就是说,我们必须把它注入进去。

Harness,以及让它真正生效的两个细节

我们会在生成的文档前面插入一小段 script,通过 postMessage 将 error、unhandledrejection 和 console.error 报告给宿主。这里有两个细节,决定了这套机制究竟有没有实际价值。

它必须放在 <head> 中,并且位于构建内容写入的所有代码之前。我们的第一个版本把 hook 添加在 </body> 之前。如果某段 script 在加载过程中抛出异常,它执行时监听器还不存在。结果,声音最大的那些故障,反而恰恰没有任何东西能够报告。现在,我们通过测试固定了执行顺序:测试会断言 hook 的位置索引小于 </head>,同时也小于构建内容放在 body 中的任何 script。

console.error 并不等同于失败。React 会通过 console.error 输出普通的开发警告,而 "each child in a list should have a unique key" 并不代表 app 已经损坏。因此,harness 会把它作为一个独立字段进行报告:

var ce = console.error;
console.error = function () {
  rep({ logErr: [].map.call(arguments, s).join(" ").slice(0, 400) });
  return ce.apply(console, arguments);
};

下游所有负责判定通过或失败的逻辑,在统计任何错误之前,都会先检查 if (d.logErr) return;。这类警告仍然会被记录,只是永远不会导致一个健康的构建被判定为失败。如果把警告和真正的错误合并到同一个通道中,最终得到的验证器就会不断虚报警情,直到再也没有人愿意认真看它的结果。

判定结果可以变差,但绝不能变好

如果必须把其他规则全部丢掉,我唯一会保留的就是最后这条:判定结果只能朝一个方向变化。

if (tn.files !== vFiles || (tn.rendered && (!tn.rendered.ok || v.ok))) return tn;

一旦某个构建被标记为失败,之后任何信号都不能再把它改成成功。第二次渲染、重试、重新挂载,或者某个碰巧没有再次出现的错误,都不能把失败重新提升为成功。再配合挂载后的 9 秒观察窗口——在这段时间内发生的错误仍会被计入——就堵住了一个显而易见的逃生通道:有问题的构建因为不稳定,最终偶然报告了一次正常结果,于是系统便告诉用户一切都没有问题。

现在,绿色对勾也会等待。在“流式输出结束”和“frame 返回结果”之间,UI 会显示系统正在检查构建内容能否打开。这是一种中立状态,而不是对结果的断言。我们宁愿展示三秒钟的不确定,也不愿先给出一个确定的结论,随后又证明它是错的。

问题不在于这个正则表达式。对于它负责的事情来说,这个正则完全没问题。真正的问题是,我们让一个成本低廉、容易观测的指标,代替了真正重要但观测成本更高的指标——仅仅因为后者来得更晚,而前者现在就能得到。

下面三个问题,值得你拿来审视自己的 pipeline:

你的成功信号实际观察到的究竟是什么?不要看它叫什么名字,要看它真正检测了什么。

在真正的结果到达之前,是否已经发生了计费之类不可逆的操作?

一次失败,是否可能被随后出现的、更加安静的信号重新提升为成功?

如果你想看看加入 harness 之后的版本,可以免费试用 Zugo;其中的模板都是真实的构建结果,你可以打开并编辑。

对于后续操作,你可以考虑屏蔽此人和/或举报滥用行为。

Original source

本文由 AI 翻译整理自 dev.to · AI,原文版权归原作者所有。

阅读英文原文
上一篇
AI Agent 安全防护:模型提取与密钥泄露风险清单
下一篇
Agent 自主支付协议 x402 商用落地