Writing Code Is Easy. Reading It Isn't.
Drawing on years of contract work, the author argues that the real cost of software lives in reading, not writing: every codebase demands a mental model, built by tracing function definitions, return types, database paths, caches, error handling, and call sites. Understanding one getUserPreferences-like function often means opening five other files. Because LLMs can now emit code faster than anyone can consume it, they enlarge the reading burden; the lawyer who filed fictitious ChatGPT-sourced cases failed not at generating but at verifying through reading. The practical conclusion is to point AI at comprehension—explaining existing code, uncovering side effects, compressing context—rather than at producing bigger diffs. Team throughput should be measured by how quickly members construct accurate mental models, not by lines generated. A grounded opinion piece for engineers who want AI assistance without mistaking output volume for velocity.
Writing code is easy. Once you have a solution in mind, and have mastered the syntax of your favorite programming language, writing code is easy. Having an LLM write entire functions for you? Even easier. But the hard part isn’t the writing. It’s the reading. It’s the time it takes to load the mental model of the system into your head. That’s where all the cost really is.
A mental model is the thing you build when you read code. It’s your internal map of how the system works, where the tricky parts are, what depends on what. Without it, you’re just staring at lines of text.
写代码是容易的。一旦你心里有了方案,又掌握了自己常用语言的语法,写代码就很容易。让 LLM 帮你写整段整段的函数?那就更容易了。可难的不是写,而是读——是把整个系统的心智模型装进脑子里所花的时间。所有成本其实都花在这里。
心智模型是你在读代码时搭建起来的东西:它是你脑中的一张系统地图,记录系统如何运转、难点藏在哪里、什么依赖什么。没有它,你盯着的不过是一行行文字。
When I worked as a contractor, most of my jobs started the same way. I’d get a task to fix a bug or add a new feature in an application I’d never seen before. My mental model was clean and empty at first. To start filling it, I’d check the homepage to see what it looked like. I’d look at the page source: is this React? jQuery? A third-party plugin? I’d scan the codebase to see if the carousel they are requesting on the front page was used elsewhere. I’d check their build process, their testing setup, the tools they leaned on. Every little detail I discovered got appended to the model in my head.
It was like moving into a new city. You start at the foot of your apartment, wander a few streets, notice which roads lead to the freeway, where the grocery store is, and slowly you start to orient yourself. That’s what reading code feels like: you’re building a mental map so you don’t get lost every time you move around.
当年做合同工时,我的大部分项目都以同样的方式开场:接到一个任务,去修某个我从未见过的应用里的 bug,或者加个新功能。起初,我的心智模型干净而空白。为了开始填充它,我会先打开首页看看它长什么样;再看一下页面源码:这是 React?jQuery?还是某个第三方插件?我会翻一遍代码库,确认他们要在首页放的轮播图是不是在别处已经用过;还会看构建流程、测试配置,以及他们依赖的工具。每发现一个细节,就往脑中的模型上添一笔。
这就像搬进一座新城市。你从公寓楼下出发,在几条街里走走转转,留意哪条路上高速、超市在哪儿,慢慢地就有了方向感。读代码也是这种感觉:你在构建一张心理地图,免得每次移动都迷路。
Say you need to understand a simple function like getUserPreferences(userId). To build your mental model, you need to trace:
Where is this function defined?
What does it return? Is it a Promise? What's the shape of the data?
Does it hit a database directly or go through an API?
Are there caching layers involved?
What happens if the user doesn't exist?
Who else calls this function and in what contexts?
Are there side effects?
Understanding that one function means jumping between database schemas, API definitions, error handling middleware, and multiple call sites. Only after building this web of relationships do you have enough context to safely modify anything.
比方说,你要理解 getUserPreferences(userId) 这样一个简单的函数。为了搭建心智模型,你需要一路追查:
这个函数定义在哪里?
它返回什么?返回的是 Promise 吗?数据的结构长什么样?
它是直接访问数据库,还是走 API?
中间有没有缓存层?
用户不存在时会怎样?
还有谁会调用这个函数?在什么场景下调用?
它有没有副作用?
理解这一个函数,就是要你往返于数据库表结构、API 定义、错误处理中间件和多个调用点之间。只有把这层关系网建起来,你才有足够上下文去安全地修改任何东西。
And it’s slow. Reading code is harder than writing it. Much harder. Writing code is forward motion: you’re laying down fresh pavement. Reading code means retracing someone else’s steps, which usually means jumping between files, chasing function calls, inferring side effects, and deciphering intentions that aren’t written down. Understanding one function often means looking at five other files. Only after all that do you have enough of a map to even begin.
It’s the same reason debugging is harder than coding. On Stack Overflow, one of the most common comments you’ll see under a bad question is: “Can you show us what you did?” Without seeing the steps, no one can load the right model in their head to help. It’s also why the XY problem keeps coming up. People ask about a symptom without giving the context that would let others reconstruct the whole picture.
而且这很慢。读代码比写代码更难,难得多。写代码是向前推进:你在铺一条崭新的路。读代码则是重走别人的脚印,通常意味着在文件之间跳来跳去、追着函数调用跑、推断各种副作用、揣摩那些没有被写下来的意图。要理解一个函数,往往得翻另外五个文件。只有绕完这一大圈,你才勉强有了一张可以开始行动的地图。
调试比写码更难的,也正是同一个原因。在 Stack Overflow 上,糟糕问题下面最常见的评论之一就是:“能给我们看看你做了什么吗?”看不到操作步骤,任何人都没法在脑中装入正确的模型来帮忙。这也是 XY 问题反复出现的原因:人们只描述症状,却不给出能让别人还原全貌的上下文。
I'm still fascinated by the lawyer who used ChatGPT in court. He filed a brief that cited six cases which turned out not to exist. Everyone asked: why didn’t he read them? The answer is the same: it takes time and effort to build the model. He would have had to chase down each case, read them, and slot them into a broader understanding of legal precedent. Reading is the hard part. Generating is easy.
那位在法庭上使用 ChatGPT 的律师,至今仍让我着迷。他提交的诉讼文书引用了六个判例,结果这些判例根本不存在。所有人都在问:他为什么不去读一读?答案还是同一个:构建模型需要时间和精力。他必须先逐一追查这些案例、通读它们,再把它们放进对法律先例的更整体理解中。读才是难的那部分,生成很容易。
Reading isn't just about going through the code and examining it line by line. It's also about going through the documentation, code reviews, and peer programming. In fact, these are solutions for accelerating the process of building our mental model. But with that in mind, you still have to, well, read and understand. You'll notice that programmers often want to rewrite things from scratch, because "the old code sucks". What sucks is taking the time to read and understand it.
阅读并不只是通读代码、逐行审视。它也包括阅读文档、代码评审和结对编程。事实上,这些都是为了加速我们构建心智模型而存在的方案。但即便如此,你终究还是得——嗯——去读、去理解。你会注意到,程序员经常想把东西推倒重写,因为“旧代码太烂了”。真正让人难受的,其实正是花时间去读它、理解它。
And this is what makes LLMs both powerful and dangerous in programming. Whether the AI generates perfect code or complete hallucinations, you still have to read it. You still have to trace through what it’s supposed to do, how it interacts with the rest of the system, and what the side effects are. The longer the generated code, the longer it takes to build your mental model. And only once you’ve done that can you spot the issues, the places where the generated code doesn’t quite fit, or quietly breaks something else.
When an LLM can produce an infinite amount of code or text, it tempts us to skip the reading. But you can’t skip the model. You wouldn’t want to load someone else’s saved game and be dropped in the middle of a boss fight. That’s what it feels like to inherit or generate code you don’t understand.
这正是 LLM 在编程中既强大又危险的原因。不管 AI 生成的是完美代码,还是彻头彻尾的幻觉,你都得读一遍。你仍要弄清它本意要做什么、它与系统其他部分如何交互、副作用在哪里。生成的代码越长,搭建心智模型需要的时间就越长。只有完成这一步,你才能发现那些问题:哪段生成代码与整体不契合,又在悄悄破坏什么。
当 LLM 能无限量地产出代码或文本时,它会诱使我们跳过阅读。但心智模型这关绕不过去。你不会想读别人存好的游戏进度,然后直接被丢进一场 Boss 战。接手或生成一段你不理解的代码,感觉正是如此。
This is why the real bottleneck in software development isn’t writing, it’s understanding.
For now, we don't have the LLM equivalent for understanding. Something that could instantly transfer a complete mental model from the system to your head. Until we do, the bottleneck hasn't moved. We've solved the "typing speed" problem. We can generate more code than we could ever hope to read. But until we solve the "understanding" problem, the cost of software development remains the same: the time it takes for someone to make sense of it all.
这就是为什么软件开发的真正瓶颈不是写,而是理解。
目前,我们还没有与 LLM 对应的“理解机器”——一种能把完整心智模型瞬间从系统传进你脑中的东西。在它出现之前,瓶颈没有移动。我们已经解决了“打字速度”问题,现在能生成的代码,比我们能读完的还要多得多。但在“理解”问题解决之前,软件开发的成本依然如故:仍然取决于某个人把这一切弄明白需要花多长时间。
This has real implications for how we use AI tools. Instead of asking AI to generate large blocks of code, we might be better off asking it to help us understand existing code. Instead of measuring productivity by lines of code written, we should measure it by how quickly teams can build accurate mental models of their systems.
The future of programming might not be about generating more code faster. It might be about generating understanding faster. And that's a much harder problem to solve.
这对我们如何使用 AI 工具有实实在在的启示:与其让 AI 生成大段代码,不如请它帮我们理解现有代码;与其用“写了多少行代码”衡量生产力,不如看团队能以多快速度建立起关于系统的准确心智模型。
编程的未来也许不在于更快地生成更多代码,而在于更快地生成理解。而那是更难解的题。