AI时代程序员的核心竞争力是反驳型人格

前言

脱离工业界 gap 两年后,我重拾老本行做回了后端 senior engineer。入职这一个多月来,我对 AI 编程最直接的感受,是大量日常研发工作已经发生了根本性的变化。

以前拿到一个 ticket,需要自己通读细节,搜索相关代码和历史提交记录,理解调用链,查询 Sentry,翻日志,进入相应的 AWS console 检查运行状态……等到问题大致明确,再开始修改实现、补充测试,一整套流程下来很容易耗掉一两天的时间。

现在,这条路径很大一部分都可以直接交给 AI Agent 一把梭搞定。只要把 MCP 权限设置好,上下文丢进 Claude,它自己可以去访问 GitHub、JIRA、日志系统和 AWS CLI,自己调查问题、验证假设、修改代码并补完测试。过去最痛苦的那些日常体力工作,例如在陌生代码库里追调用链、从大量日志中找出真正有区分度的信号、对照不同环境排除错误假设,如今都能被极大加速。

这对生产力的提升堪称大跃进。而且事实上现代云计算产业早已经为 AI Agent 搭建好了一切基础设施:需求存在 JIRA 系统里,代码可以结构化检索,历史决策沉淀在 PR 和文档中,运行状态进入可观测性平台,云端资源暴露 API 和 CLI,测试与部署通过脚本驱动。过去二十年积累的 DevOps 和 infra 自动化,现在都开始成为 AI Agent 的工具层。

然而,实现速度被大幅放大以后,新的瓶颈也随之暴露:

代码生成的速度,开始远远超过人类理解、验证并对其建立信任的吞吐量。

“貌似正确”的实现已经变得极其廉价

通过配置有效的上下文,AI 已经可以快速生成常规业务逻辑、修复局部缺陷、写迁移脚本、测试、重构,甚至自动化整个 PR 流程。这些代码通常还非常整洁:命名规范、测试齐全、PR 描述也写得头头是道。

过去,这样一份干净整洁的实现,本身就代表了大量工程劳动,而现在它却证明不了任何事情。更麻烦的是,面对同一个问题,AI 很容易给出多个听起来都貌似合理的方案,多个 Agent 还可以继续互相批判和修订,结果讨论得没完没了,根本无法收敛。于是,工程师面临的难题开始从“应该如何实现”转向“哪个方案值得相信”:

AI 放大的是搜索能力;人类 senior 工程师提供的是价值函数。

AI 可以扩大候选方案和风险点的覆盖范围,但最后仍然需要有人去做判断:真正需要保护的系统不变量是什么?哪条故障路径足以推翻当前方案?哪些风险值得付出额外复杂度的代价?

面对同样一堆貌似合理的候选方案,谁能更快、更准确地判断什么值得相信,哪条路径值得一路追到底,正在成为工程师之间越来越重要的区分度。

一个面试里不会有人答错的问题

最近我在审阅一个外部事件接入层时,就遇到了一个很有意思的问题。这个服务从诸如 DocuSign 这样的外部事件源接收 webhook,重新读取上游最新状态,再和自己的数据库快照做差异比较;只有检测到新的状态转换时,才会把内部事件发布到下游。

这里最关键的恢复模型很简单:只要内部事件还没有可靠发布,本地快照就不能提前推进。否则下一次比较会变成“新状态对新状态”,原本那次状态转换再也推导不出来,导致更新静默丢失。

因此,这个系统必须守住两条不变量:

  1. 发布失败时不能推进快照
  2. 如果向下游写入失败后,必须依赖上游驱动重试才能恢复,就不能返回 2xx 给上游

然而在实际工程实现中,这些约束不得不散落到不同层级,最终让系统实际的行为显得匪夷所思——同步发送失败时,上层捕获异常以后仍然继续更新快照;异步路径更隐蔽,异常只进入 Kafka client 回调然后被直接吞掉,调用方甚至不知道消息发布失败。局部看每段代码貌似都没啥大毛病,组合起来以后,却起到了精准击穿系统不变量的效果,保证我们能够同时丢掉外部事件和唯一能够重新推导这次状态转换的信号。

如果把这个问题抽出来,单独拿到系统设计面试里去问,我相信其实没有人会答错。大家都知道事件不能静默丢失,失败以后要保留重试路径,也知道不能随手吞掉决定系统正确性的异常。但现实情况是到了生产代码里,这些简单原则会被第三方库 API 语义、状态转移逻辑与异常处理的繁琐耦合,以及层层叠叠的调用细节所淹没。

真正体现工程师核心价值的,是在大量噪声里持续识别并守护决定系统能否恢复的那几条约束。一旦识别出问题,后面的事情反而很简单:补上针对性的测试,把“发布失败时快照不能前移”这类不变量直接钉进代码库。

AI 代码越干净,审查的成本反而越高

传统代码审查里,低质量的实现会主动暴露自己:结构混乱、边界粗糙、测试不足,作者自己也解释不清楚。AI 很擅长把这些表面坏味道消掉:一个逻辑上走偏了的方案,也可以被包装成代码工整、测试完善的实现。

这会让深度审查变得更痛苦。AI 代码的平均质量可以很不错,真正严重的错误其实很稀疏,但为了确认“这里真的没问题”,审查者往往仍然需要从头建立系统模型,推导整个逻辑链条。大多数时候这个过程耗费了不少认知带宽,最后得到的结论只是这份代码确实没什么问题。

前面的 webhook 案例就是如今代码审查困局的一个缩影。真正需要追问的是“发布失败以后快照到底会不会继续推进”这条跨层路径——如果我们只看局部函数的 diff,每一处都大致合理;把恢复模型重新拼回整体,才会发现这些局部行为已经共同击穿了系统的正确性保障。

所以我越来越觉得,AI 时代 senior 工程师很大一部分价值,可能是体现在:

看到一个逻辑上貌似合理、局部实现也很干净的方案,能够迅速感觉到哪里味道不对。

多 Agent 辩论只是程序员的赛博迷信

如今的 AI 大跃进思潮中,广为流行的一种迷信是:既然一个 Agent 的思维会有误区,那就多放几个 Agent 去互相审查,最终不就能得出正确的方案了?

这种做法在一定程度上是有用处的。多个 Agent 可以增加采样次数,减少单次生成的偶然性,也更容易覆盖分散的风险点。但它主要提高的是搜索范围,并不足以保证收敛到可靠的判断。几个模型共享相近的训练数据和推理习惯,它们的盲区也会高度相关。让几个模型彼此同意,只能说明这个答案在模型分布里足够合理,它们也可能共同遗漏同一条历史契约,或者围绕一个实际上无关紧要的问题反复深挖。

TDD 也只能解决其中一部分问题。如果实现和测试由同一个模型、基于同一份上下文生成,它们很容易共享同一个错误假设。AI 如果没有正确理解系统不变量,又按照自己的理解生成测试,最后所有测试通过也只能说明实现与测试彼此一致,错也错到一起去。

还是回到前面的 webhook 案例:当我们把事件丢失的 bug ticket 丢给 AI,每个 Agent 都有能力分别检查 Kafka 配置、异常处理和快照更新逻辑的具体代码实现,它们甚至可能各自给出不少合理分析。但真正能揪出 root cause 的,是有没有谁把“发布失败以后快照还会不会推进”识别成那条必须一路追到底的路径——而这个点如果不是由人类工程师提出来,AI 并不会主动把相关线索都载入自己的上下文。

让我们回顾 LLM 的基本原理:代码生成之所以进步得很快,一个重要原因是它拥有廉价、密集、可重复的 feedback loop:编译、运行、测试、性能 benchmark 都能迅速从沙盒环境中得到结果,天然就是最有力的强化学习信号。然而系统设计没有同等质量的训练闭环。一套架构是否真的合理,很多时候要经过真实流量、线上故障和长期演进才能暴露,结果可能在几个月甚至几年后才出现,有时候结果还会被组织协作和业务变动等各种因素干扰,整个过程充满了模糊和不确定性。本质上,这里缺少一个廉价、稳定、能够被自动推导的正确性判据。

AI 可以学习大量成功架构的表面模式,也可以把几乎一切技术上的 tradeoff 讲得头头是道,但很难仅靠多 Agent 辩论来完成真实世界的经验校准。而 senior 工程师的直觉正是通过在现实世界中不断捕获稀疏反馈来形成的。

亲自经历过长期 oncall,线上事故、系统迁移、流量雪崩、错误回滚、无数次深夜被报警叫醒之后,才会真正理解哪些风险只是听起来危险,哪些故障路径一旦成立就足以推翻整个方案,这些经验在 AI 时代甚至显得更加重要。人当然从来不是正确性的保障,但这种用真实故障后果所建立的 mental model,目前依然是 LLM 最难复刻的能力之一。

代码审查的抽象层次需要提升

既然人的判断既重要又昂贵,那么我们审查代码还有必要每次都从一行行 diff 开始吗?

现在很多代码本身就是工程师和 AI 一起讨论并生成出来的。作者可能已经探索过 A、B、C、D 四种方案,排除了其中三个,最后只把 C 落成代码。但 diff 只保留了最后的 C。另一个审查者再让自己的 AI 去看,它很可能重新提出 B、D、E,于是双方重复一轮已经发生过的讨论。

针对这个现状,我发现业界已经开始从不同角度提出了“CR Reasoning Trace”这个概念——我把它理解成一份随 PR 一起流转的共享推理上下文。作者在发起代码审查时,就附上一份压缩后的决策记录:解决的是什么问题,考虑过哪些重要方案,为什么排除,最终要维护哪些系统不变量,证据来自哪里,还有哪些地方只是假设。审查者再在这份上下文上继续挑战、补充证据或推翻其中的判断,而不是基于代码 diff 从头建立理解。

前面的 webhook 例子就很适合这样记录。真正有价值的信息是说清楚系统正确性依赖的不变量,至于具体改了哪个 try/catch,代码差异本身已经写得很清楚,并不需要消耗人类的认知带宽去重新理解。这样无论是人还是 AI 来审查,都能从已经成型的系统模型继续往下推导,而不用重复猜作者到底有没有考虑过某些可能性。

这份 trace 当然不应该是把整段 AI 对话原样贴进 PR,那样只会制造更多的噪音。值得保留的是对话中可能影响决策的分支、排除理由、证据、不变量和未验证假设。PR 里附上这样一份 trace 并不会自动提高正确性,甚至有可能退化成 AI 生成的流程表演;但只要大家认可并遵守这个共识,它就能帮助减少重复搜索和无效来回,让真正有分歧的判断更快暴露出来。

至于怎样把这些判断继续沉淀成自动化约束,以及怎样让 AI Agent 获得真正可扩展的验证闭环,将会是下一篇文章讨论的主题。

结语:反驳型人格的工程价值

日常生活中的反驳型人格通常很讨人嫌。别人提出任何想法都要先挑毛病,每句话都要纠正,很容易把正常交流变成输赢游戏。然而在软件工程里,人类面对 AI 给出的看似合理的叙事,永远要习惯性追问一句,它到底凭什么成立?这种高质量反驳非常值钱,也是 senior 工程师核心价值的体现。

AI 会越来越擅长给出答案;与此同时,工程师需要越来越擅长判断——这个答案为什么还不能被相信。

comments powered by Disqus
Published:
2026-08-24
分类:
Tag: