🔶 此处有凶险:当 Agent 接管编码工作,开发者究竟还需要懂什么?
英文标题:🔶 Here be monsters: What do you still need to know when agents do the work?
随着 AI Agent 深入软件开发,代码产出速度已远超人类逐行理解的能力,传统依靠“纯手写代码”建立系统认知与培养新人的模式正面临失效。行业目前在“放任不管的乐观派”与“坚持逐行审查的怀疑派”两极之间摇摆,但对初级开发者而言,旧有的成长路径在经济上已不再可行。作者指出,未来软件掌控力(Ownership)的关键不再是亲自手写每一行代码,而是掌握三大支柱:扎实的基础原理(识别系统隐性异常)、跨领域的认知广度(构建全局架构图谱)以及即时深潜能力(在未知领域快速下潜排障)。
68.3 KB
67.1 KB
224.1 KB
73.1 KB
76.5 KB
80.9 KB
90.9 KB
中文
CI 挂了。这很出乎意料。我已经将自己的 Agent 工作流调校到了极为稳定的程度,如果哪个 Agent 提交了包含失败测试的分支,我都会感到惊讶。难道是 CI 偶尔抽风,或是环境问题?等等,居然是 SonarQube 在报 App.tsx 的错误?难道是我们从 npm 引入了什么可疑的新依赖?并不是。SonarQube 标记这个文件存在圈复杂度(cyclomatic complexity)过高的问题。我已经好久没见过这个报错了。
确实。App.tsx 总共大约只有 30 行代码,但其中有 15 行实际上是 Codex 决定整行写完一个完整组件的产物。这本身倒也没什么大不了,用 prettier 格式化一下就行了。但这并不能解释为什么圈复杂度会超标。每一个组件都相当复杂,包含了大量的展示逻辑和业务逻辑。如果是以前的我,肯定会小心翼翼地对其进行重构,确保代码具备可读性。然而,Codex 根本不在乎整整个组件全挤在一行里;更重要的是,它完全不介意这种复杂度。在经历数个特性的迭代过程中,它一直非常愉快且稳定地在这个文件上进行修改。
CI 工具标记出了一个问题,可能是对的,也可能是误报。但这是一个真实的生产系统,所以我必须深入探查。格式化文件后,我仔细检查了这些组件和逻辑。Codex 是否在边缘情况覆盖上超出了普通开发者的常规做法,甚至有些过度设计?是的,但代码全都完全正确。我挑不出任何毛病,所有的复杂度都是受业务需求驱动的。于是我让 Codex 去让 SonarQube 满意,它通过重构将代码拆分成了 10 个文件。CI 通过了;特性顺利发布。尽管这次小插曲很快就解决了,但你完全可以想象情况本来可能会变得多么糟糕。毕竟,这些代码我在此之前一眼都没看过。
这正是我们行业所迈向的未来:对一个软件系统的掌控权(Ownership),将越来越少地依赖于是否曾亲手编写过它(或类似的系统);相反,最重要的能力将转变为:掌握恰到好处的知识以辨别何时出现异常,并在需要时有能力且有意愿尽可能深地潜入其中探明究竟。
深潜机器人与金块
想象你正身处一艘船上(你可以自由挑选喜欢的船型),你的工作是从海底打捞微小的金块。直到最近,如果你想捞一袋金子,你必须亲自跳进水里,游到底部,四处搜寻,然后装满你的袋子。如果你身处清澈的浅海,这轻而易举,但你可以想象,随着深度增加,这会迅速演变成多么艰难的任务。因此,随着浅水金矿逐渐枯竭,你和同行工程师们制造了各种各样的机械和工具,以便从更深、更危险的海域中开采黄金。在大多数时候这行之有效,你和团队精心组装、维护并轮换设备,不断潜入海底采矿点维持其运转。你偶尔也会听闻某些采矿设施倒塌的消息,有时是因为海底巨大的水压,有时是因为意外事故或操作员的技术失误。挑战在于,这是一个地质活动极度活跃的世界,海床瞬息万变,旧矿枯竭的同时新矿在不同海域冒头。
但好消息来了!过去几年里,人们研发出了越来越复杂的深潜机器人(divebots),它们可以自主下潜并独立搭建采矿作业系统。你只需告诉它们在哪里建造,它们就会潜入水下,只在需要同步进展和递送金块时浮出水面。一切看起来棒极了,你现在可以坐在船上放松,任由机器人在水下忙碌,你唯一需要操心的只是船里还能装下多少黄金。这就是乐观派阵营。
直到……
“等你的机器人下潜太深迷路了你就知道了。”“哈哈,你的机器人带上来的东西看着像金子,实际上只是闪闪发光的章鱼便便。”随着机器人的泛滥,你看到的翻车事故越来越多。机器人在深海迷失,忘记了自己原本要建什么;机器人建造出了极其复杂、怪异的东西,连它们自己都难以维护,最终只能被下一代机器人全盘丢弃。所有的水下采矿设施从原本精心设计、工程严谨的大教堂,变成了杂乱无章的迷宫庄园,到处是暗道和潜伏的恐惧。你离实际作业越脱节,发生的崩塌事故就越具毁灭性。这就是怀疑派阵营。
此处有未知凶险(Here Be Monsters)
软件工程行业(我猜不久后许多其他行业也是如此)正在经历上述场景的现实版本。你可能已经清楚自己更偏向怀疑派还是乐观派,即使你目前还不确定该站队哪一方。
传统观念认为,要开发和维护一个具有相当规模的系统,你必须对其拥有正确的心智模型。我想几乎没人会反对这一点。在过去的软件工程中,你是通过直接与代码打交道来建立这种心智模型的。数年乃至数十年的编码与阅读经验,赋予了你理解所负责系统所需的知识与工具。每一次线上事故、每一个深夜调试、每一次成功上线,所有这些经历汇聚成了你掌控系统所需的宏观视野。在本文语境下,掌控权(ownership)意味着当系统崩溃时,被电话叫醒解决问题的那个人是你。
Agent(深潜机器人)彻底颠覆了这一切。Agent 产出代码的速度远远超过任何人的吸收能力;在过去,你可以假定复杂系统的代码至少曾经过人类之手,但现在这一假设已不复存在。如今,有经验的老手可以通过管理一支 Agent 舰队,以空前的规模创造软件。这些操盘手通晓技艺,利用自身丰富的经验来管理并架构过去需要整个团队才能构建的大型系统。但这暴露出了我们行业面临的最大挑战:我们该如何培养下一代工程师?
在极端情况下,乐观派和怀疑派对这个问题的答案天差地别。一方面,有知名人士声称,维持对这些系统的控制的唯一途径是阅读机器人生成的每一行代码;必须能够手写这些代码;必须能够解释每段代码的作用及其在应用程序上下文中的契合方式。而在另一个阵营中,同样权威的声音则表示甚至连代码都不需要看一眼;把精力放在构想“建造什么”上,忘掉“如何构建”,模型自会搞定。我认为这两种观点都不正确。
事实在于,今天资深工程师的成长路径——即通过亲手编写代码、经历漫长的调试、直面生产事故等——对于今天的初级工程师来说已经不再现实。明确地说,这在经济上不可行,意味着企业极不可能愿意资助初级开发者数年时间让他们“学着手写代码”,这纯属一厢情愿。经常被提及的替代建议还包括“确保你理解 Agent 写的每一行”、“与资深工程师结对”或“执行极其严格的代码审查”。再次强调,除了极少数团队,这在整个行业看来同样是不切实际的幻想。如果你认为全行业都会采纳这些做法,那我只能祝你好运了。
为了探寻一条切实可行的能力进阶之路,我们必须审视掌控一个非平凡软件系统的真正含义。想想典型的架构师、技术负责人或 CTO 是如何运作的,很明显,为了取得成功,他们的脑海中必须有一套系统模型——一张海域航海图。真正的核心问题是:需要达到多细的粒度?想象一个拥有数百万行代码的遗留系统,多年来由无数人编写和扩充,CTO 本人甚至可能也写过一部分。现在假设发生了生产事故,你作为一个倒霉的 SRE,在凌晨两点一边收到跨时区同事愤怒的催促短信,一边试图排查故障。此时你需要一张怎样的系统图谱?你需要的是一张宏观的、远距离的全局地图,你需要掌握恰到好处的知识,以便知道该从哪里下潜、哪里潜伏着凶险怪物;你需要能够跳进任何未知的代码库中,弄清正在发生什么,发布热修复补丁,并在故障复盘报告中清晰复盘整个过程。
请注意,这并不等同于对整个系统的细枝末节了如指掌。我们能够管理复杂系统的唯一方式就是构建抽象层。每一层抽象都让我们能更进一步,但无论你手握怎样的地图,都必须牢记:底层全都是层层叠叠的抽象,没有人能够真正参透所有的层级。“我写了模块 X 并且对它了如指掌”与“我掌握了系统抽象的合适模型,能够在任何模块出故障时深入其中将其修复”之间存在着巨大的鸿沟。手写代码赋予了我们前者,但作为一个系统的负责人,那个在紧急时刻被呼叫的人,真正需要的是后者。
那么,这幅全局图景该如何构建?如果一个人从未亲手打捞过金块,又怎能指望他潜入未知的深海,去收拾深潜机器人留下的烂摊子呢?
基础原理、认知广度与即时深潜能力
在复杂系统中,最隐蔽、最致命的故障往往是“静默失败”。这种情况下系统大体上还在工作,但某些地方就是感觉不对劲。也许是响应突然变慢,也许是错误率小幅上升,又或者大多数时候运转完美,但每到第 19 次尝试就会失败。这还没到在凌晨两点触发报警的程度,但足以让你察觉到异样。作为系统的拥有者,你必须理解系统的故障模式(failure modes)。作为一个行业,我们拥有向大家传授如何检测和推演这些故障的工具:基础原理(fundamentals)。好消息是,几十年来我们一直在向计算机专业的学生传授这些知识:数据结构与算法、计算机网络、并发编程、分布式系统等。这也不一定非要来自科班教育,这些都是你可以自主阅读和学习的主题。
举个简单的例子(资深工程师请见谅):假设你派遣深潜机器人执行任务。在浅水区,你让它下潜 2 米去捞取金块,它用时 4 秒顺利返回,一切正常;接着你让它下潜 4 米,这次却花了 16 秒,这很奇怪;下一次任务下潜 16 米,结果耗时 256 秒。你肯定明白我想说什么了,显然有地方出了问题。在计算机科学中,这被称为二次方复杂度(quadratic complexity),而识别它的最佳途径,就是理解理论并知道这类事物的存在。
这就引出了掌控力的第二大支柱:认知广度(breadth)。我有幸共事过的大多数优秀工程师和技术管理者,几乎都能就任何技术或非技术话题展开深入探讨。他们可能在某些特定领域是专家,但最令人叹服的,是他们能够从不同学科中提取看似毫不相干的概念并融会贯通,运用这些知识去解决现实问题。这就是那张宏观的高空海域图,它能告诉你哪些海域潜藏着更高的危险。认知的广度赋予了你指出“我们该从这里下潜”的能力。需要澄清的是,我所指的并非在你能想象到的每个领域都达到专家级别,而是拥有足够的认知,以便在出现异常时知道该去查阅什么。它们就是指引你探索深海的浮标。
曾有人问我:“我们该如何传授广度?开一门包罗万象的通识课吗?”我当时没有很好的答案。但在深入思考后,我认为这并不是可以通过课堂传授的东西,世界上没有《万物通识 101》这样的课程。我们最多能做的,就是鼓励大家去阅读、探索并保持好奇心。尽可能多地汲取信息,记住那些离奇的突发事故和“大事不妙”的惊险时刻,反思它们与你的工作有何关联。随着经验的累积,有意识地将日常见闻与工作连接起来。我已经记不清有多少次,多年前在某个偶然项目中掌握的冷门知识,会在关键时刻挺身而出化解危机。这种经验与广度会不断复利累积,但前提是你必须持续维护它。
掌控力的最后一个支柱,被我称为即时深潜能力(just-in-time depth)。这是一种愿意且能够扎进任何问题并彻底将其查明的能力。即使你身处未知的陌生海域;即使你必须钻进防鲨笼与鲨鱼同游片刻;即使你不得不召集团队,启动专业的重型潜水艇,潜过巨型乌贼盘踞的深渊去弄清系统究竟出了什么问题。这是一种为了达成目标而愿意学习任何所需知识的意愿;同时也是一种知晓何时下潜已超出自身能力范围、需要寻求帮助的谦逊。并非每一次下潜都能单打独斗,也不是每一次下潜都值得去做。
几个月前,在构建我的 Agent 编排器时,我遇到了 Agent 及其子 Agent 的稳定性与生命周期 Bug。我清楚我想让它们做什么,但负责构建系统的机器人做得很仓促粗糙,所有潜在的 Bug 集中爆发。当我坐在屏幕前,看着我的 Agent 在一小时内第 N 次崩溃,且在多次尝试让机器人修复自身 Bug 均告失败后,我想起多年前读过的一本关于 Kubernetes 的书(没错,我就是个技术呆子),脑海中突然浮现出“电平触发状态机”(level-triggered state machine)这个词。于是我开始了一次深潜,潜入的深度远超我最初的预期,甚至一直追溯到了“电平触发”在电气工程领域的起源。我带着我的深潜机器人一同潜入……
English / 原文
CI was failing. This was unexpected. I have dialed in my agentic workflow to a point where I would be surprised if one of my agents committed a branch that had failing tests. Maybe it's a CI flake or environment issue? Wait, it's SonarQube complaining about App.tsx? Did we pull in a new suspicious dependency from npm or something? Nope. SonarQube is flagging this file for cyclomatic complexity. Haven't seen that one in a while.
Yep. App.tsx consists of about 30 lines of code, except 15 of those lines are actually entire components that Codex decided to write each on a single line. That itself would be ok, just run it through prettier and we're done. But that doesn't explain the cyclomatic complexity. Each of these was a fairly involved component with a good amount of display and business logic. Old self would have carefully refactored it and made sure the code was readable. On the other hand, Codex didn't care that entire components were on a single line, and more importantly, it didn't mind the complexity. It had been happily and reliably iterating on that file through several features.
The CI tool was flagging an issue, perhaps correct, perhaps incorrect. But this is a real system so I had to dive in. After formatting the files, I went through and inspected the components and logic. Did Codex go beyond what a typical dev might have in terms of covering edge cases and did it slightly over-engineer it? Yes, but it was all correct. No complaints from me. All of the complexity was warranted by the business requirements. So I told Codex to make SonarQube happy, which it did by refactoring and splitting things up into 10 files. CI passed; things shipped. Although this particular incident had a quick resolution, you can probably imagine how it could have gone much worse. This was, after all, code I had never seen before.
This is where our industry is headed: Owning a software system will depend a lot less on having written it (or similar systems) by hand; instead, what will become most important is knowing just enough to know when something is wrong, and being willing and able to dive as deep as needed, when needed.
Divebots and golden nuggets
Imagine that you're on a boat (you decide what type of boat you like) and your job is to collect little nuggets of gold from the bottom of the ocean. Up until very recently, if you wanted to get your bag of gold you would need to jump into the water, swim to the bottom, look around, and stuff your bag. Easy peasy if you're in clear, shallow waters, but you can imagine how quickly this can escalate into something much more difficult. So as the shallow water mines started drying up, you and fellow engineers built all sorts of machinery and tooling to extract gold from ever deeper and more dangerous waters. This worked well for the most part, you and your team would carefully assemble, maintain, rotate the machinery and would constantly dive to the seabed mining operation to keep it running. Every so often you'd hear about the collapse of some mining operations, sometimes due to the sheer underwater pressure, other times through accidents, or operator incompetence. The challenge is that this is a very geologically active world, so the seabed keeps changing with some mines drying up and new ones popping up in different places.
Good news though! The last few years have seen the development of ever more sophisticated divebots that can go down and build a mining operation on their own. You just tell them where to build and off they dive and only surface to give you updates and gold nuggets. Things are great, you can now relax on your boat while your divebots do their thing and all you have to worry about is how much gold you can stuff into your boat. This is the Optimists camp.
Until...
"Wait till your divebots go too deep and get lost". "Haha your divebots brought you stuff that looks like gold but is actually shiny octopus poop". As the divebots proliferate you see more and more horror stories. Divebots getting lost and forgetting what they are supposed to be building. Divebots building something so complex and grotesque that they have trouble maintaining it, only for it to be discarded by the next generation of divebots. All of the underwater mining operations went from being carefully designed and engineered cathedrals to more like haphazard mansions, with hidden passages and horrors lurking. The more detached from the operation you are, the more spectacular the failures. This is the Skeptics camp.
Here Be Monsters
The software engineering industry (and I suspect many other industries soon) is living through a version of the above scenario. You probably already know whether Skeptic or Optimist describes you better, even if you're still not sure which camp you want to commit to.
The traditional wisdom is that in order to develop and maintain a non-trivial system you need to have a proper working model of it. I think few people would argue with that. And in software engineering you would acquire that working model by working directly with the code. Years and decades of practice writing and reading code give you the knowledge and tools needed to understand the systems you're responsible for. Every production incident, every late-night debugging session, every successful release. All of these experiences give you the perspective needed to have ownership of a system. In the context of this post, ownership means you're the one who gets called when something breaks.
Agents (divebots) are turning all of that on its head. Divebots produce output much faster than anyone can absorb, and while in complex systems of the past you could assume that the code had at one point gone through the hands of a human, that is no longer true. It is now possible for experienced practitioners to manage fleets of divebots and create software at an unprecedented scale. These operators know the craft and bring their considerable experience to manage and architect large systems that would have taken teams to build in the past. But that exposes what's probably the biggest challenge facing our industry: how do we train the next generation of engineers?
At their extremes, the Optimists and the Skeptics have wildly different answers to this question. On the one hand you have reputable voices saying that the only way to maintain control of these systems is to read every line of code the divebots produce. Be able to code it by hand. Be able to explain what every piece of code does and how it fits into the context of the applications. In the other camp, you have equally reputable voices saying to not even bother looking at the code. Focus your energy on figuring out what to build and forget about how it is built. The models will handle it. I don't think either of these is right.
The fact is that the way that today's senior engineers learned, ie. through coding by hand, endless hours debugging, production incidents, etc. is not a path that is viable for juniors today. To be clear, it is not economically viable, meaning that it is highly unlikely that companies will be willing to sponsor juniors for years while they "learn to do it by hand". That's wishful thinking. An alternative that is often presented is the "make sure you understand every line your agent wrote" advice, or "pair with a senior", or "perform careful code reviews". Again, wishful thinking at all but perhaps a few shops. If you think that the industry at large will adopt these practices, I've got a bridge to sell you. Hit me up.
In order to figure out a viable path for achieving some measure of mastery, we have to look at what it means to own a non-trivial software system. If you think about your typical architect/lead/CTO and how they operate, it becomes clear that to be successful they need to have a model of the system in their head, a chart of the waters. The real question is at what level of granularity? Imagine a legacy 1-million line codebase, it was written and expanded over the years by a number of people. The CTO may have even written parts of it. Now imagine there is a production issue and you're the unlucky SRE trying to figure this out at 2AM while getting angry texts from people in different timezones. What chart of the system do you need? You need a high-level, far-away map of the entire system, and you need to know just enough to know where you need to dive in, where the monsters live , and you need to be able to jump into any unknown codebase, figure out what's happening, push a hotfix, and describe what happened clearly in your incident report.
Note that this is not detailed knowledge of the whole system. The only way we can manage complex systems is by building up abstractions. Each layer lets us build a bit more, but whatever map you have, it is important to remember that it is abstractions all the way down, and no one really understands all the layers. There is a big difference between "I wrote module X and know it inside out" and "I have an appropriate model of the system abstractions and can dive into any module and fix it when it breaks". Coding by hand gives us the former, but the owner of a system, the person who gets called, needs the latter.
So how does this picture get built? And how can someone be expected to dive into unknown waters and fix the mess the divebots made if they've never mined gold nuggets by hand?
Fundamentals, Breadth, and Just-in-Time Depth
Some of the most insidious failures in complex systems are quiet failures. The sort where things mostly work, but there is something off about the system. Maybe it's suddenly slower, or error rates went up, or it works perfectly most of the time but fails every 19th attempt. Not to the point where you're getting paged at 2AM but enough that you get a feeling that something is off. As an owner of a system you need to understand the failure modes of the system. As an industry we have the tools to teach folks how to detect and reason about these failures: fundamentals. And the good news is that we've been teaching them to unwitting CS majors for decades. I'm talking about data structures & algorithms, networking, concurrency, distributed systems, etc. It doesn't have to come from a formal education either, these are topics you can read about and learn on your own.
To paint a simple picture (if you're a senior engineer please bear with me here), imagine you send your divebot on a mission. You're in shallow waters and you send it 2m underwater to collect some gold nuggets. It comes back in 4s and all is good. Next, you send it down 4m. This time though it takes 16s. That's odd. The next mission is 16m down, and it takes 256s. You get the picture. Something is obviously off. In computer science this would be called quadratic complexity, and probably the best way to recognize it is to understand the theory and know that such a thing exists.
Which brings me to the next pillar of ownership: breadth. Most of the successful engineers and engineering leaders I have had the pleasure of working with were able to hold a discussion on almost any topic, whether technical or not. They may have been specialists in certain things, but what was most impressive was their ability to draw upon and weave together seemingly disparate concepts from different disciplines and use that knowledge to solve problems. This is the high-level map of the waters. This is what tells you certain seas are more dangerous than others. The breadth of knowledge is what enables you to say "let's dive here". And to be clear, I'm not talking about expert level knowledge in every domain imaginable, but just enough to know what to look up when something is off. The buoys that guide your ocean exploration.
Someone asked me "how do we teach breadth? a survey class on everything?" and I didn't have a good answer at the time. But after thinking about it some more it seems to me that this is not something you can teach. There is no "Everything 101" you can take. The most we can do is encourage folks to read/explore/be curious. Absorb as much information as you can. Remember the weird incidents, the "oh crap" moments, think about how they connect to your work. And as you gain more experience, make a conscious effort to connect your everyday experiences with your work. I've lost track of how many times that one bit of knowledge I learned while working on a random project years earlier swooped in to save the day. This experience and breadth compounds, but it has to be maintained.
The final pillar of ownership is what I call just-in-time depth. This is the ability and willingness to dive into any problem and figure it out. Even if you're in uncharted waters. Even if you have to get in the cage and swim with the sharks for a bit. Even if you have to gather your team, load up the big proper submarine and dive down past the giant squids to figure out what's wrong with the system. This is the willingness to learn whatever is required to get the job done. It is also the humility to know when a dive is beyond your capabilities and you need to look for help. Not every dive can be done solo; not every dive is worth doing.
Some months ago, while working on my agent orchestrator, I was running into stability issues and lifecycle bugs with my agents and subagents. I knew what I wanted them to do, but the divebots that built the thing had done so rather haphazardly and all of the bugs were coming home at once. As I sat staring at my screen watching my agents crash for the nth time in an hour, and after several failed attempts at having the divebots fix their own mess, I recalled having read a Kubernetes book years earlier (yes I'm a nerd) and the words "level-triggered state machine" were suddenly staring me in the face. So I took a dive, deeper than I originally intended, even as far as the electrical engineering origins of "level-triggered". I brought my divebots along for the ride and re-designed the core architecture from the ground up. It has been rock solid since. This successful rewrite was mainly possible because I happened to remember something I had read years earlier, and was willing to dive in and learn whatever was needed to get the job done.
So you start with a high-level map of the ocean (system), and understand that it is layers of abstraction all the way to the bottom. And since all of those abstractions leak, your job as system owner is to know where to dive and how deep. It is no longer generalist vs specialist, or even the mythical T-shaped folks.

The new way of building things requires a generalist who can dive deep into the unknown, a "quick learner under pressure" and not in the resume-padded way. You will actually need to be able to learn quickly while fighting with sea monsters. I've interviewed many people over the years and when people put "quick learner" in their resume I like to ask them to tell me about a time they had to learn a complex system quickly, how did they do it? What would your answer be?
Owners of the Future
So fundamentals can be learned and breadth is gathered. Just-in-time depth , however, can be practiced. These three pillars are what enable someone to grow their ownership share in a system. Maybe you start in shallow waters, send your divebots down. You have solid fundamentals, decent breadth, so go build something. Just be ready to put on the suit and swim with the monsters when something breaks.
Who will be responsible for the sprawling underwater mining operations in the future? No one knows, but I would bet that it will be those individuals who are able to wield the three pillars above. It will be the kid who took an old radio apart and fixed it, without knowing the first thing about radios, just a desire to listen to music - even if they did end up with a couple of extra screws after putting everything back together.