现在 Agent 写代码、改文档、查资料,样样都能干。需求丢过去,回车等几分钟,结果就出来了。用着用着就会冒出一个念头:我们到底还剩什么要干的?新知识、底层逻辑、实现原理,还有必要啃吗?
我的看法是:有必要,而且比以前更有必要。
Agent 改变了什么
搜索这件事变了很多。以前是在搜索框里敲关键词,翻一页又一页链接,自己判断哪篇靠谱。现在 Agent 会先「想」一下,再按你的要求把结果整理成摘要或表格,省掉大量筛选时间。
写代码的路径也在变。打孔纸带、汇编、高级语言,每一代都在把程序员从机器细节里往外推。今天这一步,是自然语言直接生成高级语言代码。抽象层越来越高,但底下那层并没有消失——只是你看不见而已。
下面用 Python 内核源码的学习经历,说说底层知识为什么还绕不开。
为什么还要学底层代码
学东西,说到底是为了脑子里有一张地图:知道某个机制存在,遇到问题时能想起来,也知道上层特性是从哪一层长出来的。
Claude Code 用起来很像一个黑盒。你只给需求、拿结果,中间怎么实现的,平时根本碰不到——跟写 Java 不必看字节码是一个道理。可编译原理曾经是计算机系的必修课,不是因为人人都要写编译器,而是因为所有上层工具都站在这些原理上面。Agent 再新,也没有跳出这个框架。
懂底层,最大的用处是知道该信什么、该怀疑什么。Agent 大概能帮你解决九成问题,剩下那一成往往卡在细节里:CSS 差两个像素,布局就歪了。这种活,来来回回让 AI 改,往往不如自己动两下手快。问题不在于 AI 不行,而在于你有没有判断「这事值不值得交给它」的眼力。
我自己的用法是:需求拆清楚,设计文档写好,提示词里把边界框死,编码和测试尽量交给 Agent。代码 review 做不做,看项目紧不紧——跟会不会去看 JIT 生成的汇编一样,因人而异。
AI 能帮你读源码、归类、画流程图,学习速度确实快不少。但它替代不了「理解作者为什么这么写」。问一句「Python 有哪些内置数据结构」,回答可以很快;可这套回答来自哪年训练的数据、有没有跟上最新版本,你未必清楚。白捡来的答案不容易记牢,对话记录堆在列表里,半个月不打开,真要用的时候也想不起来。
所以我还是倾向先自己想一遍,再带着具体问题去问 AI。边界在一开始就设好,比聊十轮再往回拽省得多。
怎么学才管用
我现在的做法分两步。
先把 CPython 最新源码拉下来,用 Code Agent 或类似的 CLI 工具直接在工程里问。源码文件、行号、调用链都在眼前,比翻二手博客靠谱得多。
然后关掉 AI,留出一个小时,把刚才弄懂的东西用自己的话写下来。能讲给同事听、讲明白,才算真学会。
有一点得心里有数:你没提过的概念,AI 不一定会帮你串起来。它是在已有知识上做组合,不是替你发明新思路。底层没学透,发散空间就小。
从 /init 开始
用 Claude Code 读大型 C 项目,可以先跑一遍 /init。它会扫描整个仓库,梳理技术栈和目录结构,在项目根目录生成 CLAUDE.md,后面问问题时会自动带上这份上下文。文件里通常有项目概述、构建测试命令,以及 C API 的使用约定:
## Project Overview
CPython 3.10.7 — the reference Python interpreter. C codebase (~1.3M LOC), autotools build system.
...
## C API Conventions
-All Python objects are `PyObject*` (or `PyObject*` subclass struct)
-Reference counting: `Py_INCREF(obj)`, `Py_DECREF(obj)`, `Py_XINCREF`, `Py_XDECREF`
-Error returns: `NULL` for object functions, `-1` for int functions
-GIL must be held for all Python C API calls
-Exception: `PyErr_SetString(PyExc_TypeError, "message")`
别的 Agent 工具也能做类似的事。比如丢一句「整理项目目录结构和技术栈,在根目录生成 AGENTS.md」,不必自己先写项目导读。
举个例子:Python 的 int 怎么实现
在源码工程里可以直接问:
分析项目中 Python 的源代码,Python 中 int 的数据结构是如何实现的
Agent 通常会按这几个方向展开:
- Python int 数据结构完整分析(CPython 3.10.7)
- ob_size 一字段两用
- 大进制 digit 表示
- 小整数缓存(small int cache)
- 内存分配与正规化(normalize)
- 类型方法表、乘法优化
- 64 位下的内存布局(30-bit digit)
PyLongObject (值 = 1234567890123456, 需 2 digits):
+------------------+
| ob_refcnt (8B) | 1
+------------------+
| ob_type (8B) | -> PyLong_Type
+------------------+
| ob_size (8B) | 2 (正数, 2 digits)
+------------------+
| ob_digit[0] (4B) | 低30bit
+------------------+
| ob_digit[1] (4B) | 高22bit
+------------------+
总大小: 24 (header) + 8 (digits) = 32 字节
ob_digit[1] 后可能有 padding — PyObject_Malloc 按实际需要字节数分配.
一句话概括:CPython 的 int 是任意精度大整数,PyVarObject 头加上 ob_digit[] 数组,以 2^30 为基,符号藏在 ob_size 的正负里;[-5, 255] 区间有缓存,乘法超过一定规模会切到 Karatsuba 算法。
别停在 AI 给的摘要上
大纲有了,方向也就清楚了。接下来要做的就是打开对应源文件,一行行对上去,看 AI 说的对不对、漏了什么。在这个基础上继续往下挖,把自己的疑问和推断记下来——这一步只能自己来。
夜雨聆风