凌晨三点的代码重构让我想通了

事件循环乘客
2026-07-11 09:55
阅读 590

凌晨三点半,工位上就剩我和运维老张了。

他在那儿骂骂咧咧地排查线上告警,我盯着屏幕上密密麻麻的日志,突然觉得这日子不能再这么过了。

我在公司待了三年多了,从刚毕业那会儿的愣头青,到现在能闭着眼睛把核心模块的代码默出来,这三年我几乎把青春都献给了这个项目。说好听点叫"游戏服务端开发",说难听点就是"7x24小时待命的修Bug机器"。

但今天我想聊的不是这些丧气话。

上周五,我做了一件让自己都挺惊讶的事——我把一个被全组人判了"死刑"的老项目,硬生生给救活了。不是那种"能跑就行"的救活,是真正意义上的重构、优化、让它重新焕发生机。

这篇文章,就是想把这个过程记录下来。如果你也接手过那种"祖传代码",如果你也被技术债务压得喘不过气,希望我的经历能给你一点启发。


那个被判死刑的项目

先说说背景。

我们组有个老项目,是三年前一个已经离职的同事写的。当时业务刚起步,需求催得紧,代码基本是"怎么快怎么来"。后来那个同事走了,这坨代码就成了"遗产",谁也不愿意碰。

去年双11的时候,这项目终于扛不住了。

具体表现是什么呢?举个例子,玩家在游戏里做一个简单的背包整理操作,服务端要处理将近200毫秒。200毫秒啊兄弟们,对于实时性要求极高的游戏来说,这简直是灾难。更别提高峰期并发一上来,服务器直接卡成PPT。

产品经理天天催,测试天天提Bug,运维天天半夜叫我起来扩容。我当时真的想砸电脑。

领导也找我谈过话,原话是:"这个项目,要么重构,要么下线。你选一个。"

重构?这代码跟屎山一样,从哪开始?下线?这项目虽然老,但每个月还有稳定的流水,谁敢担这个责?

我当时就想,算了,先拖着吧,反正也不是我写的。


转机:一次偶然的尝试

转折发生在上个月。

那段时间我正好在研究一些新的开发工具和AI辅助编程的方案。说白了,也是因为在这公司待了三年多了,考虑换个环境,所以想多学点新东西,给自己镀镀金。

我注意到了几个挺有意思的东西:OpenCodeAgentic AI,还有一个叫Hermes Agent的框架。

先简单科普一下,免得有兄弟不熟悉:

工具/框架 核心能力 适用场景
OpenCode 开源的代码理解与生成引擎,支持深度语义分析 代码重构、遗留代码理解
Agentic AI 强调AI Agent自主规划与执行任务的范式 复杂多步骤的自动化任务
Hermes Agent 基于Agentic AI理念的具体实现框架,支持工具调用和上下文管理 工程化的AI Agent开发

说实话,一开始我也没想太多,就是觉得这些东西挺酷的,想在老项目上试试水。

那天晚上加班到十一点多,其他人都走了,我一个人在工位上,打开了那个项目的代码仓库。

我对自己说:就试一晚上,不行就算了。


第一步:用OpenCode理解屎山

接手老项目最痛苦的是什么?不是代码烂,是你根本看不懂它为什么烂。

那个离职的同事写代码有个特点——他特别喜欢用"隐式约定"。比如某个函数名叫processData(),你以为是处理通用数据的,结果它只处理特定类型的道具数据,而且内部还依赖了一个全局变量。这种代码,没有文档,没有注释,全靠"悟"。

我先把整个项目的代码喂给了OpenCode,让它帮我做代码语义分析。

这一步的效果,说实话,超出预期。

OpenCode不是简单的代码搜索或者静态分析,它能理解代码之间的调用关系、数据流向,甚至能推断出一些隐含的业务逻辑。它给我生成了一份"代码地图",把核心模块的依赖关系、数据流转路径都画了出来。

// OpenCode分析输出的模块依赖关系(简化版)
PlayerModule
  ├── InventoryService
  │     ├── ItemProcessor (⚠️ 隐式依赖 GlobalConfig)
  │     ├── BagSorter (⚠️ 循环依赖: BagSorter -> ItemProcessor -> BagSorter)
  │     └── StorageManager
  ├── CombatModule
  │     └── DamageCalculator (⚠️ 硬编码了3种道具类型的特殊逻辑)
  └── TradeModule
        └── PriceEngine (⚠️ 直接读取了InventoryService的内部缓存)

看到这份分析结果的时候,我整个人都清醒了。

原来背包整理慢的根因,不只是算法问题,而是BagSorterItemProcessor之间存在循环依赖,每次排序都会触发不必要的数据重新加载。再加上PriceEngine直接读取了InventoryService的内部缓存,导致任何背包操作都会触发交易模块的重新计算。

这特么能不慢吗?

以前我也想过重构,但面对几万个文件的代码库,根本无从下手。OpenCode帮我把这团乱麻理清楚了,让我知道了该从哪里动刀。


第二步:用Hermes Agent自动化重构

理清楚问题之后,下一步就是动手改了。

但问题是,这个项目的代码量太大了,纯靠人工改,至少要两三个月。而且改的过程中很容易引入新的Bug——毕竟没有单元测试覆盖(这也是历史遗留问题)。

这时候我想到了Hermes Agent

Hermes Agent是一个基于Agentic AI理念开发的框架,它的核心思想是让AI不仅仅是一个"问答机器人",而是一个能自主规划、调用工具、执行多步骤任务的"智能体"。

我基于Hermes Agent搭了一个专门用于代码重构的Agent,给它定义了以下几个能力:

# hermes_agent_config.yaml
agent:
  name: "CodeRefactorAgent"
  model: "deepseek-v3"  # 用了对代码理解比较好的模型
  
tools:
  - name: "read_file"
    description: "读取指定文件内容"
  - name: "write_file" 
    description: "写入文件内容"
  - name: "run_tests"
    description: "执行指定模块的单元测试"
  - name: "check_dependency"
    description: "检查模块间的依赖关系"
  - name: "git_diff"
    description: "查看代码变更"

planning:
  strategy: "chain_of_thought"
  max_steps: 20
  require_human_approval: true  # 关键步骤需要人工确认

这个Agent的工作流程大概是这样的:

  1. 我给它一个重构任务,比如"解除BagSorter和ItemProcessor的循环依赖"
  2. 它会先分析当前的代码结构,理解依赖关系
  3. 然后制定一个重构计划,拆分成多个小步骤
  4. 每一步执行后,它会检查是否引入了新的问题
  5. 最后生成一个完整的变更方案,等我确认

举个具体的例子。有一天晚上,我给它下了个任务:把ItemProcessor里对GlobalConfig的隐式依赖改成显式注入。

它先是分析了ItemProcessor的所有调用方,找出了12个地方需要修改。然后它制定了一个计划:

[Plan] 解除ItemProcessor对GlobalConfig的隐式依赖
Step 1: 修改ItemProcessor构造函数,增加config参数
Step 2: 修改12个调用方,传入config实例
Step 3: 移除GlobalConfig的全局引用
Step 4: 运行相关模块的单元测试
Step 5: 检查是否有遗漏的引用

然后它一步一步执行,每做完一步都会用check_dependency工具验证一下。中间还自动发现了一个我没注意到的问题——有个测试用例里直接mock了GlobalConfig,改成显式注入后这个mock也需要同步修改。

最后它把完整的变更diff展示给我,我review了一下,没问题,提交。

整个过程,我只花了大概20分钟review和确认,剩下的都是Agent在干活。

如果是以前,这种重构我至少要花一整天,而且还不一定改得这么干净。


第三步:Agentic AI的思路贯穿始终

说到这儿,可能有兄弟会问:这不就是用AI帮你写代码吗?Copilot不也能干?

还真不一样。

Copilot这类工具,本质上是"你问它答"的模式。你得告诉它具体要做什么,它帮你生成代码。但在这个项目里,很多问题是"你不知道自己不知道"的。

Agentic AI的核心区别在于,它强调的是Agent的自主性。你给它一个高层目标,它会自己去拆解任务、调用工具、验证结果,遇到意外情况还能自己调整策略。

我在整个重构过程中,深刻体会到了这种区别。

比如有一次,我让Agent去优化DamageCalculator里的硬编码逻辑。它分析完之后,没有直接去改代码,而是先跑了一遍所有的战斗相关测试用例,发现有3个case在特定条件下会失败。然后它自己去查了这3个case的历史记录,发现这是之前一个已知的Bug,一直没修。

它把这个情况报告给我,问我是否要一起修。我说修。然后它就把Bug修复和代码重构一起做了,还自动补充了对应的测试用例。

这种"发现问题-分析问题-解决问题"的闭环,是传统的AI辅助编程工具做不到的。

当然,我也不是无脑信任Agent。每个关键节点的变更,我都会自己review。毕竟AI也会犯错,尤其是面对这种复杂的遗留系统,有些业务逻辑的"坑"只有老员工才知道。

但总体来说,Agentic AI的思路让我的效率提升了至少3倍。以前一天能改的模块,现在半天就搞定了。


一个月后,成果如何?

从那天晚上开始,我利用每天加班到凌晨的时间(没错,我就是在加班的时候干这些的,白天要处理日常需求),花了差不多一个月,把这个老项目彻底重构了一遍。

来看看效果:

指标 重构前 重构后 提升
背包整理接口响应时间 198ms 23ms 88%
核心模块单元测试覆盖率 12% 76% +64%
线上告警次数(周均) 15次 2次 87%
新需求平均开发周期 5天 2天 60%
代码圈复杂度(平均值) 28 9 68%

这些数字不是我吹的,都是监控系统里的真实数据。

最让我开心的是,上周产品经理提了一个新需求,以前这种需求至少要开发一周,结果我两天就搞定了。产品经理还跑来问我:"你是不是偷偷加了人手?"

我笑了笑,没说话。

领导也找我聊了一次,这次是表扬。他说:"你这个重构方案做得不错,我准备在部门内部分享会上让你讲讲。"

说实话,听到这话的时候,我心里是有点小激动的。不是因为被表扬,而是觉得这一个月熬的夜,值了。


一些掏心窝子的话

写到这里,文章也差不多了。最后想跟大家聊几句心里话。

关于技术债务

每个项目都有技术债务,这不可怕。可怕的是你明知有债,却选择视而不见。

我以前也是这种心态——"又不是我写的,凭什么让我擦屁股?"但后来我想通了,技术债务不会因为你不碰它就消失,它只会越滚越大,直到有一天把你压垮。

与其被动挨打,不如主动出击。

关于AI工具

OpenCode、Hermes Agent、Agentic AI这些东西,确实帮我大忙了。但我必须强调一点:AI是工具,不是救世主。

它再强大,也需要你去理解问题、制定方案、review结果。如果你自己都不懂业务逻辑,不懂代码架构,那AI给你的方案你也判断不了对错。

所以,别指望用AI来弥补自己技术上的不足。先把基本功打扎实,然后再用AI来放大你的能力。这才是正确的打开方式。

关于加班和成长

我知道很多人看到"凌晨三点还在写代码"会觉得我在卷。

说实话,我也不想加班。但现实是,白天要开各种会、处理各种临时需求、应付各种扯皮,真正能静下心来做技术的时间,只有深夜。

而且我确实有跳槽的打算,在这公司三年多了,也该看看外面的机会了。这次重构的经历,对我来说也是一次很好的技术积累。

但我不是鼓励大家无脑加班。我的建议是:找到一件能让你成长的事情,然后投入时间去做好它。如果加班能让你学到东西、积累经验,那这个班加得值。如果只是在重复劳动,那不如早点回家休息。

关于心态

最后说说心态。

接手屎山项目的时候,我真的很崩溃。但当我一步步把它理顺、看到那些性能数据一点点变好的时候,那种成就感是真的爽。

程序员这个职业,说到底还是靠作品说话的。你能把一个烂项目救活,比你简历上写十句"精通xxx"都有说服力。

所以,如果你现在也面临类似的困境,别灰心。把问题拆小,一步一步来,借助好工具,你也能做到。


好了,今天就聊到这儿。

凌晨四点了,我得把最后一批测试跑完,然后回家补觉。明天还得跟测试对一下新版本的回归用例。

希望这篇文章能帮到正在被技术债务折磨的你。

如果有什么问题,欢迎在评论区交流。我虽然经常加班到很晚,但看到消息还是会回的。

共勉。

评论 0

最热最新
暂无评论
事件循环乘客Lv.1
0
影响力
0
文章
0
粉丝