30 天提交 51.8 万行,生产环境只留下 23.5 万行
上周我做了一件平时几乎不会做的事:数了数自己的提交。不是数我记得写过的那些,而是数仓库里真实记录下来的那些。自建 Gitea 上 5 个生产仓库、三十天、一个人:865 次 Commit、新增 518,233 行、删除 130,892 行。
然后我数了数活下来的部分。对主生产项目的最新版本跑一次干净扫描,有效代码总量是 234,976 行;同一时间窗口里净增 58,240 行的视频转码器,今天整个仓库只有 43,050 行。
那 28 万行进哪儿去了?没有丢。它们被写出来、跑过测试、被判为不对,然后删掉——或者被一个更小、做同一件事的东西替换掉。我想把这条循环记下来,因为它这一年对我工作方式的影响,比任何一次模型升级都大。
一开始我不信的这几个数字
以下是 2026 年 9 月 17 日至 10 月 17 日,名下 5 个活跃仓库的精确 Git 统计:
| 仓库名称 | 30 天 Commit | 累计新增 (+Add) | 累计删除 (-Del) | 净变动 (Net) | 当前存量有效代码/文本 | 核心技术栈 |
|---|---|---|---|---|---|---|
| numerology-report | 432 | +331,672 | -98,937 | +232,735 | 234,976 | PHP, Markdown, JSON |
| hevc-transcode | 187 | +58,240 | -15,508 | +42,732 | 43,050 | Python, HTML, Shell |
| dsm-resource-management | 132 | +58,234 | -14,076 | +44,158 | 368,793 | Python, TypeScript, Astro |
| hoelee-blog | 88 | +23,603 | -709 | +22,894 | 55,933 | Astro, TypeScript, Markdown |
| hoelee-agent-dist | 26 | +46,484 | -1,662 | +44,822 | (Dist) | Python, Shell, Markdown |
| 合计 | 865 | +518,233 | -130,892 | +387,341 | — | — |
其中两行你可以自己复算,这就是完整的量法:
git -C numerology-report log --since=2026-09-17 --until=2026-10-17 \
--numstat --pretty=format: | awk '{add+=$1; del+=$2} END {print add, del}'
在人类团队里,这样的更替量通常意味着出事了:需求在代码底下不停移动、有人偷偷在重写、架构反复塌陷。这几种情况我一条都不占——这 5 个仓库都是我每天在跑、离不开的东西,每一次提交都发生在能读到 diff 的会话里。
生成成本变低之后,这种更替量就是重构的样子:Agent 起草一段改动,我跑闸门,闸门不同意,这段就被丢掉或者改小重写。凡是闸门写对的那几天,代码总量往下掉得比功能上来的速度还快。
Agent 实际接手的是什么
大多数人第一次让 AI 写代码,是在一个浏览器标签页里:把函数粘进对话框,再把答案拷回编辑器。这条路的瓶颈是剪贴板,而且模型离真正重要的两样东西都很远——仓库自己的约定,以及运行它刚写出来的东西的能力。
所以我的是跑在终端里、跑在这台机器上的,手里有真工具:
- 文件与语法工具:直接读已有模块,用模糊匹配打补丁而不是整文件覆盖,保存前先过语法与 AST 校验。
- 测试与执行器:PHPUnit 单元测试、pytest 套件、无头 Chrome 探针,在前台跑起来并把输出读回来。
- 版本控制上下文:读
git diff、显式暂存指定路径、翻一个文件的历史看上一个决定为什么这么做。
这套组合很快,比我亲手打第一版快一个数量级;但它本身也是让代码库腐烂得更快的方法——这一半通常没人提醒。
臃肿是从哪里长出来的
不受约束的模型天生爱写代码。给它一个细小的边界情况,它的第一反应是新建一个私有辅助类、把一个已有工具函数复制一份改个参数,或者给一个库套上三层抽象——那三层只有在这段 diff 里才讲得通。放它自己跑一周,就是几千行语气笃定、看起来合理、其实没必要的代码。
我这么讲是因为我自己的历史里就有那一周。每天读这些 diff,最后落成两条规矩:
- 新建一个类,要跟一个我本来就有的标准库调用竞争位置。
- 生成出来的东西默认有罪,直到某个确定性检查说它没问题。模型说「看起来对」不算证据,红的测试才算。
真正把代码删掉的是三道闸门
在最近一次主生产系统的 V2 架构重构中,三十天里删掉了 98,000 多行。这些几乎不是我坐下来专门去删的,而是三道闸门不断把回来的东西打回,最后留下的就是更小的版本:
1. 用确定性脚手架,而不是问「这段看着对不对」
让模型审查自己写的代码,多数时候产出的是自信,不是正确。有用的做法是把它接到一个没法被说服成绿灯的东西上:
- PHP 应用里,所有公开路由参数必须带显式默认值,由专用的反射探针(
ControllerAutoRouteSafetyTest.php)守着——这个测试存在,是因为一条裸路由在生产上真的 500 过。 - 报告生成管线里,无头 PDF 解析器先数一遍渲染出的汉字数量,数不对就不许构建通过;这样字体或排版改动如果悄悄漏字,就是构建失败,而不是发出一份坏 PDF。
- 转码队列里,台账比的是精确字节数而不是 MB 估算,因为圆整过的数字把一次体积回退藏了好几个星期。
闸门红了,Agent 要么改到过,要么把这段撤掉。没有任何东西能豁免。
2. 把剪枝当成日常动作,而不是一次大扫除
每次会话都会分出一段时间专门删东西:这个 200 行的辅助类,能不能换成一行已有的原生调用?这个新的映射层,是不是在重复 app/Libraries/ 里放了一年的某个函数?上面那 13 万行删除不是重写的副产品,而是活过头了的脚手架、只有一个调用方的迁移层,以及换了名字出现两遍的同一段逻辑。
3. 确定性的活留给确定性代码
我在 AI 项目里反复看到的坑,是让模型去做它根本不该碰的计算。如果一条 Shell 管道、一个 SQL 约束、一个幂等脚本或者一个 Cron 任务就能给出答案,那 LLM 就不该出现在那里。
模型擅长起草初始实现、生成三语词库、摸清三方 API 的脾气;但状态流转、钱、队列调度,我不会交给它——一个确定性问题上概率性的答案,是一颗带延时引信的 bug。
我的工作方式变了什么
我职业生涯的大部分时间里,物理瓶颈是打字速度和记语法。产出就是指标,一个高效的一周看起来就是新建了很多文件。
现在语法是免费的。我可以一边读上一次改动的 diff,一边让 Agent 起草一份带单元测试的 500 行迁移。于是瓶颈转移到了模型替我看不了的三件事上:
- 边界设计:模块从哪里分开,哪些状态允许跨过去。
- 验证体系:那个能抓住类型检查看不见的语义漂移的脚手架。
- 剪枝的决断力:愿不愿意删掉那 28 万行探索性、冗余、已死掉的代码,只把 23.5 万行送进生产。
所以我现在不再把提交曲线当生产率图表看。一个月新增 50 万行,只能说明工具在转;真正说明这一个月值不值的是那删掉的 13 万行、底下的重构,和一套仍然全绿的测试。
需要一套能长期不倒的系统?
我运营 Hoelee Enterprise,为马来西亚中小企业做网站设计与系统开发。上面这套 Agent 工作流、测试脚手架和自托管基础设施,就是我给客户交付并长期维护系统时用的同一套东西。
如果你需要全栈系统研发、业务流程自动化,或者能扛住自己维护周期的自建基础设施:
- WhatsApp: +60 12-797 2969
- Email: [email protected]
- 官网: hoelee.com