惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
V
Vulnerabilities – Threatpost
GbyAI
GbyAI
P
Proofpoint News Feed
L
LINUX DO - 热门话题
P
Palo Alto Networks Blog
A
About on SuperTechFans
T
Tenable Blog
M
MIT News - Artificial intelligence
IT之家
IT之家
I
Intezer
D
DataBreaches.Net
爱范儿
爱范儿
T
Threatpost
C
CERT Recently Published Vulnerability Notes
云风的 BLOG
云风的 BLOG
博客园 - 三生石上(FineUI控件)
WordPress大学
WordPress大学
K
Kaspersky official blog
大猫的无限游戏
大猫的无限游戏
A
Arctic Wolf
Y
Y Combinator Blog
Cyberwarzone
Cyberwarzone
酷 壳 – CoolShell
酷 壳 – CoolShell
D
Darknet – Hacking Tools, Hacker News & Cyber Security
H
Help Net Security
Microsoft Security Blog
Microsoft Security Blog
Spread Privacy
Spread Privacy
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
AWS News Blog
AWS News Blog
博客园 - 聂微东
C
Check Point Blog
S
Securelist
有赞技术团队
有赞技术团队
雷峰网
雷峰网
aimingoo的专栏
aimingoo的专栏
Last Week in AI
Last Week in AI
Stack Overflow Blog
Stack Overflow Blog
MongoDB | Blog
MongoDB | Blog
D
Docker
G
GRAHAM CLULEY
T
The Exploit Database - CXSecurity.com
C
Cybersecurity and Infrastructure Security Agency CISA
T
Tailwind CSS Blog
L
Lohrmann on Cybersecurity
G
Google Developers Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
L
LangChain Blog

祝融说。

共识并不平均,但是基本上均衡。 权力是共识切片的曲率。 存在不是「是什么」,而是一系列极小的,从分歧到共识再到分歧的,连续的构建过程。 分歧实际上是对共识往哪个方向延伸的拉力。 分歧是尚未落实的实在,是可能性基底中尚未被锁定的在共识中相互牵引的可用余量。 权力从来不是中立的,它是带有倾向性的「牵扯力」。 过程即完备,容错即自由。 第10章 逆向投喂:用真实数据让AI做出精准诊断 第11章 测试电网:用刚性指标代替肉眼审查 第13章 防退化契约:确保每一次修改都是在进步 第14章 全生命周期演练:从零开始用“有效约束”交付一个项目 第15章 随身工具包:即查即用的约束指令库 第1章 这不是结对编程,这是“人机共生” 第2章 你必须警惕的三个陷阱 第3章 把话说死:用 Markdown 建立 AI 的“单源真相” 第4章 负空间设计:先规定“不准做什么”,再让它写代码 第5章 模块化解耦:让AI每次只面对一个小问题 第6章 上下文断头台:善用 `/clear` 斩断错误蔓延 第7章 剥夺执行权:强制 AI 像资深工程师一样“慢思考” 第8章 角色锁定:用一句话给AI戴上“思考帽” 第9章 遥测驱动:帮AI长出“千里眼”和“顺风耳” 结语:成为系统牧马人,而不是代码搬运工 第八章 金融与科技的“禁手”:现代战争的底层收敛 第二章 认知锚点:心理战中的“强制步” 第九章 历史的单行道:那些被剥夺国运的时刻 第六章 消费主义的迷宫:在货架上剥夺选择 第七章 战略逼压:没有硝烟的“切香肠战术” 第三章 构造绝杀:逻辑闭环的艺术 第十二章 绝对零度下的生机:成为“不可测”的人 第十一章 掀翻棋盘:非对称竞争与正交化打击 第十章 识破隐形控制:第一时间嗅到危险 第四章 标准的暴政:打造“不得不”的生态 第五章 锁死阀门:关系链与供应链的囚笼 第一章 降熵法则:时空维度的隐蔽控制 结语:愿你在这个被设定的世界里,永远握有掀桌的权力。 引言:自由意志的幻觉 项羽 当前的AI工程化本质上是受限于上下文长度而采用的「以提示词约束去置换确定性」的一种妥协。 即时反应是一种不假思索,它是观念通过最简单、轻易、高效的路径寻求表达。 青衫 第九章:估值的坐标:建立“内在记分牌” 第六章:资产重估的艺术:从“硬实在”到“认知折价” 第七章:预期差交易:坍缩“概率波” 第十一章:内在博弈:克服‘评估异化’ 第十章:交易的算法:逆人性的“人之道” 第五章:空间套利:高能耗产业的跨境建构 结语:构建你的“财富多重宇宙” Code-Coder 第八章:效率革命:细分赛道的“降本增效” 第二章:评估权的博弈:商业模式的权力差序 第三章:去伪存真:穿透“符号泡沫” 第四章:能源共识:黑金的物理法则 第一章:宏观观察者:借势“国家共识” 前言:从“市场囚徒”到“清醒的观察者” Code-Ledge-X Code-Lint-X
第12章 定期“垃圾回收”:别让系统背负AI制造的债务
祝融 · 2026-05-16 · via 祝融说。

在第11章,我们为项目建立了一道坚固的“测试电网”。这道电网,能极大地保证我们代码库的“正确性”。只要电网不断电,我们就能确保系统的核心行为,不会在AI的修改下发生偏离。

然而,“正确”的代码,并不等同于“健康”的代码。

一个软件系统,就像一个生命有机体。除了需要有强健的骨骼(架构)和可靠的行为(测试)之外,它还需要一个高效的“新陈代谢”系统。一个健康的有机体,会不断地将老旧、无用、甚至有害的细胞,清除出体外,为新的、有活力的细胞,腾出空间和资源。

如果一个有机体,只进不出,不断地累积代谢废物,那么即使它眼下还能正常活动,也终将因为内部的“拥堵”和“中毒”,而变得臃肿、迟缓,最终走向衰败。

在AI编程时代,我们享受了前所未有的“创造”速度,代码的“生长”速度被极大地加快了。但与此同时,如果我们没有一个与之匹配的、同样高效的“清理”机制,那么代码库中“代谢废物”——即技术债务——的累积速度,也将是史无前例的。

本章,我们将学习如何成为一名软件世界的“清道夫”和“园艺师”。我们要建立一套定期的“垃圾回收”机制,主动地、系统性地去识别和清除那些由AI(以及我们自己)在快速迭代中,不经意间制造出来的“代码垃圾”。我们的目标,是让我们的系统,在一次次的版本迭代中,不仅功能越来越强大,代码本身也越来越纯粹、精炼,最终实现一种令人向往的“逆生长”状态。

12.1 为什么 AI 写的代码里“死代码”特别多?

在与AI协作一段时间后,你会敏锐地发现一个现象:AI生成的代码里,似乎特别容易出现“死代码”——那些被定义了,但从未被任何地方调用过的函数、变量、类或导入。

此外,AI也特别喜欢留下一些逻辑上看似合理,但实际上在当前业务流程中,永远不会被执行到的“冗余逻辑分支”。

这种现象,并非偶然,它源于AI的两个核心天性:“概率联想”和“缺乏全局意识”。

天性一:基于“模式补全”的概率联想

AI写代码,并不像人类那样,是基于一个清晰的、从A到B的“意图驱动”逻辑。它的核心,是一种“模式补全”的机制。

当你让AI写一个处理用户上传图片的函数时,它的神经网络会被“图片上传”这个关键词激活。然后,它会从它的训练数据中,调取所有与“图片上传”这个模式相关的、最常见的代码片段。

  • 它知道,处理图片上传,通常需要处理“文件类型验证”。于是,它可能会写一个isValidFileType()的辅助函数。
  • 它知道,通常需要处理“文件大小限制”。于是,它可能会写一个isWithinSizeLimit()的辅助函数。
  • 它甚至知道,一个“健壮的”图片上传功能,可能还需要处理“图片压缩”、“生成缩略图”、“添加水印”等。于是,它可能会“贴心”地为你,把compressImage()createThumbnail()addWatermark()这些函数,也都一并生成出来。

现在,问题来了:在你的具体业务需求里,你可能只需要“文件类型验证”和“大小限制”。你根本不需要压缩、缩略图和水印功能。

但AI并不知道这一点。它只是在“概率”的驱动下,为你补全了一个它认为“最完整”、“最常见”的“图片上传处理”代码模式。于是,compressImage()createThumbnail()addWatermark()这三个函数,就成了“死代码”。它们被定义了,语法完全正确,甚至可能还有对应的单元测试,但它们从未在你的业务主流程中,被调用过一次。

天性二:受限于“上下文窗口”的局部视野

我们在第五章讲过,AI的“认知”是受限于其“上下文窗口”的。即使有超长的上下文,它对代码的理解,依然是“扁平化”的,缺乏人类那种对项目整体架构的、层次化的“心智模型”。

这种“局部视野”,导致AI在进行修改时,特别容易制造出“孤儿代码”。

【一个典型的场景】

  1. 初始状态:项目里有一个V1_ReportGenerator.js模块,它被DashboardPage.jsAdminPanel.js两个地方调用。
  2. 你的指令:“我们现在要升级报表系统。请创建一个V2_ReportGenerator.js,并让DashboardPage.js改用这个新模块。”
  3. AI的操作:AI完美地执行了你的指令。它创建了V2_ReportGenerator.js,并修改了DashboardPage.jsimport语句,使其指向了新模块。
  4. 产生的问题:AI的“上下文”里,只有DashboardPage.js。它不知道,在项目的另一个遥远的角落,还有一个AdminPanel.js,仍然在引用那个旧的V1_ReportGenerator.js
  5. 后续演化:过了一段时间,你又让AI去重构AdminPanel.js。在这次重构中,AI发现AdminPanel.js里生成报表的功能,和DashboardPage.js里的很像,于是它(正确地)决定,也让AdminPanel.js改用V2_ReportGenerator.js
  6. “死代码”诞生:在这一刻,V1_ReportGenerator.js这个模块,已经不再被项目里的任何一个地方所引用了。它变成了一个彻头彻尾的“孤岛”。但没有任何人(包括AI)会意识到这一点。这个包含了数百行旧逻辑的文件,将像一个“幽灵”一样,永远地留存在你的代码库中,占用空间,并在未来的开发者阅读代码时,制造巨大的困惑。

AI制造的“技术债务”的特点

由AI制造的“死代码”和“冗余逻辑”,通常具有以下几个特点:

  • 语法上是正确的:它们能通过所有的Linter检查和编译器检查。
  • 逻辑上是合理的:单看代码本身,它们似乎都在做一些有意义的事情。
  • 功能上是孤立的:它们的问题,不在于代码“写错了”,而在于代码“没人用”。

这种类型的技术债务,极其隐蔽,难以通过常规的Code Review和自动化测试被发现。测试只能保证“被调用的代码”是正确的,但它无法告诉你“哪些代码从未被调用”。

因此,我们必须建立一套专门的、定期的“垃圾回收”机制,来主动地、系统性地清扫这些由AI高速创造力所伴生的“代谢废物”。

12.2 建立定期扫描与清理机制:冗余逻辑、无效 fallback、过期注释

对抗“代码熵增”,不能靠一时的心血来潮。它必须被流程化、制度化,成为你和你的团队,开发周期中一个不可或缺的“仪式”。

这个“仪式”,可以设定在每个“迭代”开始前,或者每个“主要版本”发布后。它的目标,不是去开发新功能,而是专门停下来,对现有的代码库,进行一次彻底的“大扫除”。

这个大扫除,主要聚焦于三类“垃圾”。

第一类垃圾:结构性冗余

这类垃圾,指的是那些在代码结构上存在的、完全无用的部分。清理它们,需要借助静态代码分析工具。

死代码

  • 识别工具:
  • JavaScript/TypeScript: 可以使用ts-pruneESLintno-unused-vars规则(但后者功能较弱)。Webpack的Tree Shaking在构建时能移除死代码,但我们希望在“编码时”就发现它们。
  • Python: vulture是一个专门用于发现死代码的优秀工具。
  • Go: go vet自带了一些检查,社区也有deadcode等工具。
  • IDE的辅助:现代IDE(如VS Code, GoLand)通常能通过颜色(如灰色显示)来提示未被使用的导入和变量,这是一个重要的信号。
  • 清理流程:
  1. 在CI流水线中,增加一个专门的“Dead Code Scan”步骤。
  2. 运行ts-prunevulture等工具,并将它们的输出,作为构建产物。
  3. 初期:可以只将结果作为“警告”输出,由团队成员定期审查并手动清理。
  4. 成熟期:可以将其设置为“门禁”。一旦发现新的死代码被引入,CI构建直接失败。

冗余依赖

  • 识别工具:
  • JavaScript/TypeScript: depcheck是一个必不可少的工具。它会扫描你的代码,然后告诉你package.json里的哪些依赖,从未在代码中被importrequire过。
  • 清理流程:
  1. 定期(比如,每月一次)在项目根目录运行npx depcheck
  2. 审查depcheck的报告,对于确认不再需要的依赖,果断地从package.json中移除,并重新运行npm installyarn install
  3. 这不仅能减小node_modules的体积,还能降低项目的安全风险(更少的依赖=更小的攻击面)。

第二类垃圾:逻辑性冗余(Logical Redundancy)

这类垃圾,无法被工具100%自动发现,它需要结合工具和人类的“领域知识”进行判断。

永不触及的逻辑分支

  • 现象:代码里有一个if (condition)块,但由于系统其他部分的演进,这个condition在逻辑上,已经永远不可能为true了。
  • 识别方法:
  1. 代码覆盖率报告是你的“X光片”。在你的覆盖率报告中,仔细寻找那些分支覆盖率不是100%的代码行。
  2. 如果某个if语句的分支,在经过了你全面的自动化测试之后,依然显示为“未覆盖”,这本身就是一个强烈的“危险信号”。
  3. 人工介入:你需要和AI一起,审查这个“未覆盖”的分支。向AI提问:“根据我们现有的业务逻辑,是否存在任何一个真实的场景,能够让这个if条件成立?如果不存在,请解释为什么,并帮我安全地移除这个分支和它内部的代码。”
  • AI非常擅长这种“逻辑推理”。它可能会告诉你:“这个分支是为了处理一种叫做'LEGACY_USER'的用户类型。但在三个月前,我们已经完成了数据迁移,系统中已不再存在这种用户类型。因此,这个分支是安全的死代码。”

无效的降级逻辑

  • 现象:我们在10.2节中讨论过,为了系统的健壮性,我们可能会加入一些“降级逻辑”。但随着时间的推移,那个导致降级的“根本原因”,可能已经被修复了。
  • 识别方法:
  1. 日志监控是你的“听诊器”。定期(比如,每周)在你的日志监控系统里,专门搜索那些与“降级”相关的WARN日志事件(比如,event: "FALLBACK_TO_GENERIC_RECOMMENDATIONS")。
  2. 如果一条降级日志,在过去的一个月里,一次都没有出现过,这同样是一个强烈的信号。
  3. 人工介入:和AI一起审查这段降级逻辑。向AI提问:“我们观察到,这条降级逻辑在生产环境中,似乎从未被触发过。请分析其触发条件[... a ...],并判断在当前系统架构下,这个条件是否还可能发生。如果不可能,请帮我移除这段降级代码,并将原来的try-catch块,简化为直接调用。”

第三类垃圾:认知性冗余

这类垃圾,不影响程序的运行,但会极大地增加人类(和AI)理解代码的“认知成本”。

过期的注释

  • 现象:AI在重构代码时,很可能会改变函数的逻辑,但却“忘记”更新描述这个旧逻辑的注释。
  • 识别方法:这是最难自动化的。它依赖于严格的Code Review习惯。
  • 清理流程:
  1. 在团队的Code Review检查清单中,明确加入一条:“检查所有被修改代码块周围的注释,确认它们与新代码的逻辑保持一致。”
  2. 鼓励一种“反注释”的文化:最好的代码,是自解释的。与其写一段复杂的注释去解释一段复杂的代码,不如让AI帮你把那段复杂的代码,重构成简单、清晰、不需要注释就能看懂的代码。

废弃的“功能开关”

  • 现象:为了能安全地发布新功能,我们经常使用“功能开关”。但当一个功能被100%全量发布、并稳定运行一段时间后,这个功能开关本身,以及它所包裹的那些if/else逻辑,就变成了技术债务。
  • 识别方法:
  • 维护一个集中的“功能开关注册表”(可以在一个文档里,或专门的配置中心里)。
  • 为每个功能开关,设定一个“生命周期”,比如,“上线后一个月,必须被清理”。
  • 清理流程:
  1. 定期审查这个注册表。
  2. 对于那些已经“功成身退”的开关,创建一个专门的“技术债务清理”任务。
  3. 这个任务,非常适合交给AI来完成:“功能开关'ENABLE_NEW_FEATURE_X'现在已经100%开启,并且是永久性的。请扫描整个代码库,移除所有与这个开关相关的if/else判断,并只保留if分支内的逻辑。”

通过建立这样一套覆盖了“结构”、“逻辑”和“认知”三个维度的定期清理机制,你就拥有了一个强大的“代码新陈代谢”系统。这个系统,将确保你的项目,不会在AI的“催化”下,过早地衰老和僵化。

12.3 让系统在一次次迭代中实现“逆生长”

“逆生长”,听起来是一个违反自然规律的、充满诗意的理想。但在软件的世界里,它并非不可能。

一个常规的软件项目,其生命周期曲线,通常是这样的:

  • 初期:代码量少,结构清晰,开发速度极快。
  • 中期:代码量和复杂度急剧增加。为了兼容旧逻辑和添加新功能,代码中充满了补丁和妥协。开发速度开始显著下降,修复一个Bug可能要比开发一个新功能花的时间还长。
  • 末期:系统变成一个“巨石泥潭”。没有人能完全理解它的所有细节。任何微小的改动,都可能引发雪崩式的连锁反应。最终,团队被迫做出痛苦的决定:推倒重来。

这个过程,就是软件的“熵增定律”的体现。

而我们建立的“定期垃圾回收”机制,其终极目标,就是要对抗熵增。它与我们日常的“功能开发”工作,共同构成了项目演进的“阴”和“阳”两面:

  • 功能开发(阳):为系统增加新的功能和复杂性。这是“生长”的过程。
  • 垃圾回收(阴):从系统中移除无用的、冗余的复杂性。这是“修剪”和“净化”的过程。

当“生长”和“修剪”达到一种动态平衡时,奇迹就会发生。

每一次迭代,我们都:

  1. 增加了新的、有价值的业务代码。
  2. 移除了等量(甚至更多)的、无价值的旧代码、死代码、冗余逻辑。

结果就是,项目的总代码行数(LOC, Lines of Code)可能增长缓慢,甚至在某些迭代中是下降的!但系统的业务价值,却在持续、稳健地提升。

系统的“复杂度”被控制在了一个相对平稳的水平,而不是无限地指数增长。代码库,像一个被精心照料的盆景,而不是一个肆意疯长的热带雨林。它在不断地新陈代陈,变得越来越“精炼”,越来越“纯粹”。

这就是“逆生长”。

AI在这个过程中的角色: AI,既是那个可能加速“熵增”的“催化剂”,也是我们执行“熵减”的、最强大的“手术刀”。

  • 在“阳”面,我们利用AI,快速地实现新功能。
  • 在“阴”面,我们利用AI,高效地识别和重构代码,清理我们为它设定的“清理清单”上的每一项。

一个成熟的AI协作团队,其迭代节奏,不应该是“开发-开发-开发”,而应该是“清理-开发-清理-开发”。将“垃圾回收”制度化,把它放在和“功能开发”同等重要的战略位置上,是确保你的项目能够穿越时间周期,实现长期价值和可持续发展的唯一道路。

【清理清单】每次迭代前必查的10个冗余点

请将这份清单,作为你每个迭代周期“大扫除”仪式的行动指南。你可以把它做成一个模板,在每次迭代规划会议上,逐项检查。

分类#检查点如何检查(工具/方法)AI协作指令
结构性1未使用的导出 (Dead Exports)ts-prune"Run ts-prune and help me analyze its report. For each reported unused export, confirm if it's safe to remove."
2未使用的依赖 (Unused Dependencies)depcheck"Run depcheck and remove all identified unused dependencies from package.json."
3空文件/空目录 (Empty Files/Dirs)find . -type f -empty"Find and list all empty files or directories in the src folder for deletion."
逻辑性4无法触及的分支 (Unreachable Branches)审查代码覆盖率报告中的非100%分支"This if branch is never covered by our tests. Analyze the condition and confirm if it's unreachable in our current logic. If so, refactor the code to remove it."
5永不触发的降级 (Obsolete Fallbacks)搜索生产环境日志,寻找长期未出现的降级事件"This fallback logic hasn't been triggered for a month. Is its triggering condition still possible? If not, please simplify the try-catch block."
6重复/相似的逻辑 (Duplicate Logic)jscpdpmd (CPD) 等代码重复检测工具"Our CPD tool found these two functions are 90% similar. Please refactor them by extracting the common logic into a shared utility function."
认知性7过期的注释 (Outdated Comments)人工审查"The logic of this function has changed. Please review and update its docstring/comment to accurately reflect the new behavior."
8废弃的功能开关 (Stale Feature Flags)审查功能开关注册表"The feature flag '...' is now obsolete. Please scan the codebase and remove all related logic, keeping only the 'enabled' path."
9模糊/待办的注释 (Vague/TODO Comments)搜索代码库中的 // TODO:, // FIXME:, // HACK:"List all TODO comments in the codebase. Let's review them one by one. Can we resolve this one now? If so, implement the required change."
10被注释掉的代码 (Commented-out Code)使用正则表达式搜索被注释掉的大块代码"This block of code has been commented out for a long time. It should have been managed by Git. Please remove it. If we need it, we can find it in the Git history."

将这份清单,融入你的团队文化。让“保持代码的清洁”,和“交付新功能”一样,成为一种能带来荣誉感和满足感的、值得骄傲的工程实践。

当你做到这一点时,你就真正地、完全地驾驭了AI。你不仅利用了它的“光”——那无与伦比的创造速度;也控制了它的“影”——那同样惊人的、制造混乱的潜力。你成为了一个真正意义上的、面向未来的“软件大师”。