← 全部文章

AI 越来越会写代码,我们为什么仍然需要理解代码?

了解使用 AI 构建 FiboCode 如何改变我对代码、架构与信任的看法,以及人在软件持续演进中为何仍必须承担理解代码的责任。

我用 AI 做了一个帮助人理解代码的产品。

但很有意思的是,随着这个产品越来越复杂,我自己反而开始看不懂它了。

FiboCode 是在 2025 年 7 月左右开始做的。那时候 Vibe Coding 很火,大家都在讨论怎么用 AI 帮助人写代码、降低开发成本。我当时很自然地想到了一件事:

既然 AI 可以帮助人写代码,那它能不能也帮助人理解代码?

写代码的成本正在不断下降,但理解一个陌生项目,依然是一件很痛苦的事情。尤其是面对一个已经存在了很多年的代码仓库,里面有复杂的目录结构、模块依赖、历史设计和各种约定,往往光是弄清楚“应该从哪里开始看”,就要花很长时间。

FiboCode 最初就是从这个很简单的想法开始的:利用 AI 分析代码,生成对应的文档和关系图,再让代码、文档和图之间可以相互跳转。

那时候它还只是一个代码分析工具。

后来为了方便围绕代码提问,我给它加了一个简单的 Agent。为了让代码阅读体验更好,我又接入了 Monaco Editor。编辑器都有了,那代码跳转、符号引用和语言诊断也应该有,于是又支持了 LSP。

支持了阅读,自然又会想到编辑。

等到它可以修改代码以后,我又开始考虑,怎么让 Agent 真正理解一个项目,而不只是根据当前打开的几个文件做判断。于是慢慢加入了 MCP 和 Skills,希望把项目里的设计规范、架构背景和历史信息也提供给 AI。

后来我发现,很多开发者其实已经习惯了 Claude、Codex 这类 Agent CLI。他们未必需要再使用一个新的内置 Agent,更需要的可能是一个适合审阅 Agent 工作结果的界面。

所以 FiboCode 又支持了终端,并且专门针对 Agent CLI 的输出做了一些优化,让终端里的文件引用、代码修改和执行过程,可以和代码、文档以及关系图联动起来。

就这样,它从一个简单的代码分析模块,一点一点长成了一个越来越复杂的系统。

我开始忘记自己写过的项目

AI 编程确实很方便。

虽然早期模型的能力还没有现在这么强,但每次 AI 生成完代码,我都会认真 Review 很多遍。我会去看模块是怎么拆分的,数据是怎么流动的,为什么要使用这样的架构。

开发过程中,项目经历过很多次重构。有些重构的范围很大,但因为我对当时的设计细节比较熟悉,最终都没有把项目改崩。

后来模型越来越强,生成代码的速度也越来越快,项目的代码量开始迅速增长。

我渐渐发现,即使是一两周前刚刚 Review 过的代码,我也已经记不起当时的设计细节了。

一开始我其实有点恐惧。

这个项目是我自己做的,里面的每一个功能也都是我提出来的,但我却不再能够记住每一个模块为什么这样设计、每一段逻辑是怎么运行的。

后来我慢慢想明白,这可能是一件必须接受的事情。

它已经不再是最开始的那个小项目了。对于一个足够复杂的系统,人本来就不可能记住所有代码的实现细节。真正重要的,也许不是把每一行代码都记在脑子里,而是知道系统最核心的部分在哪里,模块之间如何协作,哪些地方可以放心交给 AI,哪些地方必须认真理解。

我需要学会取舍。

从纷繁的代码里找到关键路径,建立对整个系统的大致印象,然后给 AI 更准确的要求和约束。

从这个角度看,FiboCode 其实也在反过来帮助我开发 FiboCode。

我用 AI 开发这个产品,产品变得越来越好用,又能帮助我更快地理解和迭代它。这个正反馈的过程确实很让人亢奋,也是我能够坚持做这么久的重要原因。

但兴奋之外,我也经常会想一个问题:

在这个开发过程中,我还剩下什么?

当我把越来越多的认知交给 AI

在很长一段时间里,我逐渐养成了一种习惯。

有什么需求,先交给 AI。

遇到问题,先让 AI 排查。

它给出修改方案以后,我负责验证。验证失败了,就把结果继续发给它,让它再次分析和修复。

有时一整天过去,我都在反复向 AI 描述需求、解释 Bug 的现状,再把测试结果反馈给它。

看起来,AI 完成了几乎所有复杂的脑力活动,而我负责的事情,只剩下定义需求和返回结果。

那段时间,我确实有过一种很强烈的感觉:

我似乎没有什么存在的价值了。

但继续做下去以后,我又发现,好像也并不是这样。

和 AI 一起开发的过程中,我接触到了很多过去不会主动去学习的技术,也看到了大量不同的实现方式。我开始有意识地先看设计和架构,再去看具体实现。

有些任务,我可以很快判断出修改范围比较小,交给 AI 直接完成就可以。

但有些任务涉及多个模块,或者会影响项目最核心的结构,我会立刻意识到这件事没有那么简单。AI 可能只看到了当前的需求,却没有意识到某个历史设计的原因,也不一定知道这次修改会间接影响到哪些地方。

还有一些代码,即使 AI 可以写出来,我也必须做到接近百分之百的理解。因为一旦这里出现问题,后果可能很难控制。

我不再执着于理解每一个实现细节,却开始对系统的边界、依赖、风险和变化更加敏感。

或许人的工作并没有消失,只是在发生变化。

以前,我们通过亲自实现一段代码来理解系统。

以后,我们可能会减少对重复实现的投入,把更多注意力放在架构、流程、约束、验证和长期演进上。

AI 能写出来,不代表我们一定敢于相信

我并不确定,未来 AI 是否真的能够完全取代人类专家,完成所有编程工作。

这当然是一个技术问题,但我觉得,它同样也是一个信任问题。

即使 AI 有一天可以独立生成一个非常复杂的系统,也不代表我们愿意毫无保留地相信它。

当系统出现异常时,我们能不能知道为什么?

能不能定位错误?

能不能验证修复?

能不能让其他人接管?

如果它造成了严重后果,谁应该负责?

这些问题,不是单纯把模型准确率从 99% 提高到 99.9% 就能够彻底解决的。

对于一些低风险、容易替换的应用,我们当然可以提高对黑箱的容忍度。只要功能可用,开发速度足够快,也许并不需要关心所有实现细节。

但对于操作系统、数据库这类基础软件,或者金融、电力等会对社会产生重要影响的系统,我们很难真正接受一个完全无法理解、无法审计、无法接管的黑箱。

这些系统仍然需要人去维护。

人不一定要亲手写下其中的每一行代码,但必须有人知道它大致如何运行,关键风险在哪里,出现问题时应该从哪里开始调查。

因此我越来越相信,代码理解不会因为 AI 编程的出现而消失。

它只会变成另一种形式。

过去,我们为了编写代码,所以需要理解代码。

未来,我们可能是为了验证、维护、接管和继续演进 AI 构建的系统,所以必须理解代码。

那些消失的初级任务

代码理解还有另一层意义。

AI 的出现正在压缩一部分以重复实现和基础任务为主的初级岗位。即使岗位没有直接消失,很多过去交给新人完成的工作,也正在优先被 AI 自动化。

这件事情对新人并不友好。

传统的工程师成长路径,通常是从一些简单任务开始。修复一个 Bug,阅读一小段代码,完成一个小功能,再慢慢参与更复杂的模块和系统设计。

新人就是在这些看起来并不重要的任务里,一点点建立对真实项目的认识。

但现在,这些基础任务可能直接被 AI 完成。

那么,当原本用于训练新人的入口变少以后,未来的高级工程师又要从哪里成长出来?

这也是我做 FiboCode 的另一个初衷。

我自己也是一个职场新人。第一次面对复杂的存量代码时,我常常会感到手足无措。

文件很多,目录很多,服务之间互相调用,各种类型、接口和配置散落在不同的位置。你知道答案一定藏在代码里,但你不知道该从哪里看起,也不知道哪些内容重要,哪些只是实现细节。

很多时候,真正困难的并不是看不懂某一行代码,而是没有一张完整的地图。

我一直希望能有一个工具,可以先帮我分析整个项目的结构,告诉我核心模块在哪里、代码之间如何关联、一次改动可能影响哪些地方。

这样新人就不必完全依赖别人手把手带领,也不用在陌生代码仓库里反复摸索。

它不能替代成长过程,但可以降低进入复杂系统的门槛。

在原本的成长道路逐渐被 AI 截断以后,我希望 FiboCode 能够重新连接一条路。

不一定是一条可以跳过所有基础的捷径,更像是一张地图、一套导航,以及一条让新人能够更快建立系统认知的通道。

代码只记录了现在

在开发过程中,我还发现了一个问题。

直接把任务交给 AI,让它自己探索代码仓库,有时会出现考虑不周的情况。

AI 可以看见当前的代码,却不一定知道某个模块为什么要这样设计。它也可能不知道,这段代码和另外一些看起来毫不相关的文件,实际上存在间接联系。

代码通常只能告诉我们一个系统现在是什么样子,却很难说明它为什么会变成这样。

我最初想过把这些内容全部写进代码注释里。

但后来觉得不太合适。

大量设计背景、历史原因和变更解释会让代码文件变得越来越膨胀,也可能给 AI 引入很多与当前任务无关的上下文。注释适合解释局部逻辑,却很难承载一个项目完整的演进过程。

因此,我又设计了一系列 Fibo Skills。

它们用于记录项目中的规范、设计、实现过程和 Diff 解释,让一次次代码变更留下更加完整的痕迹。

我希望未来的 AI 在修改代码时,看到的不仅是项目现在的状态,也能理解它过去发生过什么,以及某些设计为什么被保留下来。

当一个项目的演进历史变得有迹可循,AI 对它的理解也会更加完整。

这也是 FiboCode 后来逐渐形成的一个方向:

它最初是为了帮助人理解代码而设计的,后来也开始帮助 AI 更好地理解代码。

FiboCode 是怎么长出来的

回过头看,FiboCode 并不是一开始就被设计成今天这个样子。

它从一个简单的代码分析模块开始,后来有了文档和关系图,有了 Agent、编辑器和语言服务,又逐渐支持代码编辑、终端、MCP 和 Skills。

我希望它能给 Agent CLI 带来类似 Cursor 的代码审阅体验,也希望把代码分析产生的文档和关系信息,真正变成 AI 可以使用的上下文。

它一路从一个简单模块演变成了复杂系统,这种不断生长的过程,暗暗契合了斐波那契数列的增长方式。

这也是 FiboCode 这个名字,以及那只蜗牛形象的由来。

蜗牛壳里藏着黄金螺旋的数学之美。

它前进得不算快,但一直在向前生长。

FiboCode 并不是想让人重新手写每一行代码,也不是想把 AI 拒之门外。

恰恰相反,它是在接受 AI 会编写越来越多代码的前提下,希望帮助人仍然能够理解、验证、维护和接管自己的系统。

在这个所有人都在追求生成速度的时代,我仍然希望我们能够偶尔慢下来。

去理解代码为什么如此运行,理解一个系统为什么会变成今天的样子。

也重新找回当初编程的乐趣。