[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$f8EYMr2ET-hlV840TCexGWltECUYU8z1DHeXecksZwLk":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},"1fc136a1-6613-413d-aabd-3d8a3cd03a98","article","Semantic Diff：代码改了多少行，不等于逻辑改了多少","semantic-diff-ai-code-review","语义差异比较从函数、类和表达式层面理解代码变化，帮助人和 AI 区分真正的逻辑修改与格式噪声。","## Semantic Diff：代码改了多少行，不等于逻辑改了多少\n\n传统 diff 通常逐行比较文本。空格、换行、格式化和代码移动，都可能制造大量红色和绿色区域。Semantic Diff，语义差异比较，则尝试先理解代码结构，再比较函数、类、变量和表达式发生了什么变化。\n\n## 文本差异为什么会误导人\n\n把一个函数从文件顶部移到文件底部，逐行 diff 可能显示整段代码被删除又新增。统一格式化也可能让整份文件看起来都变了。审查者必须在大量噪声中寻找真正的逻辑变化，AI 代码生成速度越快，这种审查压力越大。\n\n语义 diff 会把“移动”“重命名”“新增参数”“条件改变”和“实现替换”区分开。它不一定能理解业务含义，但至少能把结构上的变化表达得更接近程序员真正关心的问题。\n\n## 它为什么适合 AI 编程\n\nAI 常常会重新排版、调整导入顺序、拆分函数或重写一段实现。把普通文本 diff 直接塞给另一个模型，会浪费上下文在格式变化和重复代码上。结构化 diff 可以帮助审查 Agent 聚焦真正改变的实体。\n\n对人类审查者来说，语义 diff 也提供了更好的提问入口：这个函数的输入输出是否改变？某个权限判断是否被移动？是否新增了一个外部调用？这种问题比“请检查这 500 行红绿文本”更具体。\n\n## 语义 diff 也有边界\n\n不同语言需要不同解析和匹配规则；宏、动态代码和生成文件可能难以准确比较。更重要的是，结构相同不代表行为相同，结构差异也不一定代表业务变化。最终审查仍需结合测试、调用关系和需求。\n\n## 一个实用工作流\n\n先用普通 diff 确认修改范围没有超出任务，再用结构化视角查看函数和接口变化，最后运行测试与静态检查。让 AI 总结“新增、删除、移动、重命名和行为变化”五类信息，可以明显降低审查遗漏。\n\n语义差异工具的基本思路可参考 [SemanticDiff 官方说明](https:\u002F\u002Fsemanticdiff.com\u002Fdocs\u002Fwhat-is-semanticdiff\u002F)。","\u002Fuploads\u002F2026-09-14\u002Fd36cee9f-244c-4c84-9a73-d762934411a2.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},"a202d639-99a6-488a-a712-4d4c6ffd7e15","开发","dev",{"id":36,"name":37,"slug":38},"63b56667-dcdb-4b8b-bcbe-c405143a7ec2","测评","test","官方资料","SemanticDiff","https:\u002F\u002Fsemanticdiff.com\u002Fdocs\u002Fwhat-is-semanticdiff\u002F","published","Semantic Diff 是什么？为什么 AI 代码审查不能只看行数","从代码移动、重命名和格式化出发，理解语义 Diff 如何减少 AI 代码审查中的噪声。",null,false,51,0,"2026-09-14T00:00:00.000Z","2026-09-14T15:01:49.500Z",[52,60,69],{"id":53,"type":6,"title":54,"slug":55,"summary":56,"coverUrl":57,"authorName":14,"sno":58,"publishedAt":49,"createdAt":59},"ebf1c66c-307a-4aa4-9927-e89b4b103cff","Consumer-driven Contract：前端真正依赖的是什么","consumer-driven-contracts-ai-coding","消费者驱动契约把前端真实使用的请求与响应变成可执行约束，减少 AI 同时修改前后端时的接口错位。","\u002Fuploads\u002F2026-09-14\u002F9fcb3348-6f56-4bc2-b10d-64b07ee28aa8.jpg",60,"2026-09-14T15:01:48.695Z",{"id":61,"type":6,"title":62,"slug":63,"summary":64,"coverUrl":65,"authorName":14,"sno":66,"publishedAt":67,"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-13T00:00:00.000Z","2026-09-13T11:56:01.900Z",{"id":70,"type":6,"title":71,"slug":72,"summary":73,"coverUrl":74,"authorName":14,"sno":75,"publishedAt":49,"createdAt":76},"54d83c94-d588-400d-9d13-42daa20331e2","CAS：文件的身份可以由内容决定","content-addressable-storage-ai-coding","内容寻址存储 CAS 用内容摘要识别文件和构建产物，解释 AI 编程工具、容器和缓存为什么能复用结果。","\u002Fuploads\u002F2026-09-14\u002F3fab23b3-8bcd-4a3b-bf5a-2ab895ce3a10.jpg",41,"2026-09-14T15:01:41.114Z"]