[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fCtau8PYpJeE8QyaKY4TVIKNncgkGbHoRqlihjmFMVeY":3},{"item":4,"related":51},{"id":5,"type":6,"title":7,"slug":8,"summary":9,"body":10,"coverUrl":11,"productScreenshots":12,"productLinks":13,"authorName":14,"authorUrl":15,"authorSubject":16,"category":17,"tags":22,"sourceLabel":39,"sourceName":40,"sourceUrl":41,"status":42,"seoTitle":43,"seoDescription":44,"canonicalUrl":45,"isFeatured":46,"sno":47,"sortOrder":48,"publishedAt":49,"updatedAt":50,"createdAt":50},"18be9090-3d46-4fc4-8010-1448ef76c9cb","article","可复现构建：同一份源代码应该得到同一份软件","reproducible-builds-ai-coding","可复现构建要求相同源码和构建条件产生逐字节一致的产物，帮助 AI 生成的软件实现验证、审计与问题追踪。","## 可复现构建：同一份源代码应该得到同一份软件\n\n软件交付时，人们通常关心“源码是什么”，却容易忽略“二进制是怎样产生的”。可复现构建要求：在相同源码、构建环境和构建指令下，不同的人或不同机器能够得到逐字节一致的产物。它让源码和最终安装包之间多了一条可以验证的连接。\n\n## 为什么同一份代码会产生不同文件\n\n构建过程可能把当前时间、机器路径、用户名、随机数、文件遍历顺序或本机工具版本写进产物。即使这些差异不影响程序运行，最终哈希也会不同。某些压缩格式还会记录文件时间和权限，导致“内容看起来一样”但字节不一样。\n\n因此，可复现构建不是简单地把代码再编译一次，而是逐步清理不稳定输入：固定依赖，稳定排序，统一时区，去掉无意义的时间戳，记录编译器版本，并确保构建步骤不偷偷访问系统外部资源。\n\n## AI 生成代码为什么需要这个概念\n\nVibe Coding 的速度很快，产物也可能由不同 Agent、不同云环境和不同 CI 工作流生成。如果每次构建都留下不同的二进制，出了问题就很难判断差异来自代码、工具还是环境。可复现构建让团队可以重新生成产物并与原产物比较。\n\n它还有审计价值。如果源码没有变化，构建结果却发生了无法解释的变化，就值得检查工具链、依赖和构建脚本。对于使用 AI 生成或修改的项目，这种“结果可重新验证”尤其重要。\n\n## 可复现不等于功能正确\n\n错误的代码也可以被稳定地构建十次。可复现性解决的是“同样输入是否得到同样输出”，不是“输出是否符合需求”。它需要和测试、静态分析、安全扫描及人工审查一起使用。\n\n## 普通开发者怎样开始\n\n先记录 Node、Python、JDK、编译器和包管理器版本，再在干净环境中构建两次并比较产物。若结果不同，就让 AI 帮忙找出时间、路径、顺序或随机性来源，而不是立即重新生成所有代码。\n\n可复现构建的定义和实践建议见 [Reproducible Builds 官方文档](https:\u002F\u002Freproducible-builds.org\u002Fdocs\u002F)。","\u002Fuploads\u002F2026-09-14\u002F6bb235b2-b055-42c9-9283-e18668483892.jpg",[],[],"Foundit","https:\u002F\u002Ffoundit.cn","foundit-ai-editorial",{"id":18,"name":19,"slug":20,"description":21},"6179d3b6-dc34-4483-9ded-3cd9f1b37a47","科普","abbreviation","介绍各领域新兴概念",[23,27,31,35],{"id":24,"name":25,"slug":26},"0848beb4-db26-4fb8-b391-f852a11be192","AI编程","ai-coding",{"id":28,"name":29,"slug":30},"144abe77-0dc6-4f66-a176-20bddb1c0bfa","编程","coding",{"id":32,"name":33,"slug":34},"7c76bfc2-f80f-4ee0-a95d-27bd8708b434","技术","slug",{"id":36,"name":37,"slug":38},"68cedb55-2cac-412f-8f81-fda8c7d686dd","思考","thought","官方资料","Reproducible Builds","https:\u002F\u002Freproducible-builds.org\u002Fdocs\u002F","published","可复现构建是什么？AI 生成软件为什么需要它","了解时间戳、路径和工具版本如何影响构建结果，以及如何让软件产物可重新验证。",null,false,55,0,"2026-09-14T00:00:00.000Z","2026-09-14T15:01:39.101Z",[52,61,69],{"id":53,"type":6,"title":54,"slug":55,"summary":56,"coverUrl":57,"authorName":14,"sno":58,"publishedAt":59,"createdAt":60},"7418caa8-c69e-4dd7-bf51-795caea4a39d","Vibe Coding 时，为什么最容易泄露 API Key 和密码","vibe-coding-api-key-secret-leak","AI 编程最容易把秘密藏进前端、日志、配置和聊天上下文。本文解释浏览器端密钥、环境变量、日志暴露和 Agent 权限的风险，并给出适合个人项目的最小安全检查清单。","\u002Fuploads\u002F2026-09-13\u002F794d5f6a-d25b-4e2c-a002-cd743a31acff.jpg",47,"2026-09-13T00:00:00.000Z","2026-09-13T11:55:51.460Z",{"id":62,"type":6,"title":63,"slug":64,"summary":65,"coverUrl":66,"authorName":14,"sno":67,"publishedAt":59,"createdAt":68},"190a2a0d-4b47-40f7-902a-00ac69ce1b15","AI 编程时代，为什么 Git 和 Pull Request 更重要了","ai-coding-git-pull-request-safety-net","AI 让改动出现得更快，也让变化更难凭记忆追踪。本文解释小提交、Pull Request、自动检查和人工批准如何把 AI 编程变成可比较、可验证、可回滚的协作流程。","\u002Fuploads\u002F2026-09-13\u002F95ac3b51-0915-4200-8130-4ba3195fd935.jpg",40,"2026-09-13T11:56:01.900Z",{"id":70,"type":6,"title":71,"slug":72,"summary":73,"coverUrl":74,"authorName":14,"sno":67,"publishedAt":59,"createdAt":75},"7cc644a5-e0de-4d7b-802e-9e8b69677e12","AI 生成的代码会不会复制开源项目","ai-code-open-source-reference-license","AI 生成代码不等于天然没有来源。本文区分常见写法与高相似片段，解释代码引用、许可证、依赖供应链和轻量来源检查，帮助团队把合规当成代码质量的一部分。","\u002Fuploads\u002F2026-09-13\u002F920327ad-de7f-4caa-a2f4-816d467c9f9c.jpg","2026-09-13T11:55:49.911Z"]