乐于分享
好东西不私藏

从Copilot到AutoCode:AI正在吃掉软件开发,程序员还有几年好日子

从Copilot到AutoCode:AI正在吃掉软件开发,程序员还有几年好日子

AI正在吃掉软件开发:自编程Agent的技术全景与底层拆解

真龙现身


2024年3月,Cognition AI发布了一段演示视频:一个叫Devin的AI,独立阅读了Upwork上的一个自由职业任务,把代码仓库clone下来,理解了项目结构,编写了代码,跑了测试,修了bug,最后提交了PR。整个过程没有人类插手。那个周末,我的技术群里炸了。

有人兴奋,有人焦虑,有人在算自己还有几年可干。一年半过去了,Devin已经进入付费商用阶段,Cursor Agent可以自己在你的电脑上改代码,GitHub Copilot Workspace能从issue自动生成完整PR,OpenCode在SWE-bench上刷到了接近人类高级工程师的水平。

这不是营销号喜欢说的"AI取代程序员"那种粗糙叙事。你如果写过代码,或者带过团队,你就会知道:真正的变化比那个复杂,也更有意思。我想从技术角度,把这件事说清楚。

这篇文章不是科普,是技术拆解。我会从AI编程Agent的系统架构讲起,把代码生成、语义理解、自主规划、多步调试这条链路逐层拆开。如果你在写代码,或者在做模型,你应该读完。

一、从Token补全到自主编程:AI编程的三层进化

要理解今天的AI编程Agent,得先看清这条进化路径。如果把2021年到2025年铺开看,AI编程经历了三个明显不同的阶段,每个阶段背后的技术范式完全不同。

第一层:代码补全时代(2021-2023)

GitHub Copilot在2021年6月发布技术预览版时,背后的模型是Codex,也就是GPT-3在代码数据上fine-tune的版本。它的工作原理本质上是一个条件语言模型:给定光标前的代码上下文(函数签名、注释、前面的代码行),预测接下来最可能出现的token序列。

这个阶段的技术特征很明确:单轮生成,无状态,无理解。模型看一段上下文,吐一段代码。它不知道代码库的整体结构,不知道函数之间的调用关系,不知道这个项目在做什么。你写一个函数签名,它帮你补全函数体。仅此而已。

Copilot v1 架构(简化): 输入: [文件路径, 光标前N行代码, 光标后M行代码, 其他打开的标签页摘要] 输出: 多行代码建议(ghost text) 核心技术: Codex(GPT-3 + GitHub语料fine-tune),无检索增强,无仓库级上下文 局限性: 看不到import引入的外部函数实现,不知道测试文件的存在

即使是这个"原始"版本,也已经改变了程序员的工作方式。GitHub在2022年的调研数据显示,使用Copilot的开发者完成任务平均快55%。当然这个数字有营销成分,但任何人用过都知道,写样板代码的效率确实提升了数倍。问题在于,Copilot只是让码字变快了,并没有改变"编程"这件事本身的结构。

关键瓶颈在哪?在于它没有"意图理解"。你写了一句注释说"实现一个LRU缓存",它确实能写出来,但如果你在另一个文件里已经有一个LRU缓存的实现,它不知道。如果你的项目用的是guava的缓存,它可能给你写了个ConcurrentHashMap的实现。它没有项目级的语义模型。

第二层:对话式编程时代(2023-2024)

GPT-4在2023年3月发布后,一切都变了。不是因为GPT-4的代码能力比Codex强多少(其实差距没那么大),而是因为它有了指令遵循能力。你可以跟它多轮对话,描述需求,让它修改,指出错误,让它重写。

这个阶段出现了两个重要的技术方向。一个是ChatGPT Canvas/Claude Artifacts这种"对话+预览"模式,你把需求说清楚,它给你生成代码并在旁边渲染结果。另一个是Cursor这样的AI-first IDE,把模型内嵌到编辑器里,你选中一段代码,Ctrl+K,描述你想做的修改,它帮你改。

对话式编程的核心技术变化: 1. 检索增强生成(RAG):将代码仓库向量化,提问时检索相关代码片段注入prompt 2. 多轮对话状态管理:模型记住之前说过的话和改过的代码 3. Diff级别的代码编辑:不再生成整个文件,而是生成精确的行级修改 4. 上下文工程:精心设计system prompt + 文件结构摘要 + 最近修改历史

这一层的关键突破是RAG。Copilot在2023年底升级后,引入了"基于仓库的上下文"。它会在后台对你的整个代码库建索引,当你写代码时,自动检索相关的代码片段、类型定义、相似的函数实现,把这些信息作为额外上下文塞进模型的prompt里。这让模型第一次有了"全仓库视角"。

技术细节值得展开。代码仓库的检索和自然语言的检索不一样。代码的语义单元不是句子,是AST节点、函数签名、类型关系。Copilot的做法是:先用tree-sitter做语法解析,提取出每个函数/类/接口的签名和注释,然后用一个专门的代码embedding模型(不是通用文本embedding模型)做向量化。这个embedding模型是在大量代码数据上训练的,它知道"LRU cache"和"ConcurrentHashMap"和"LinkedHashMap"之间的关系。

Cursor的做法更进一步。Cursor没有用一个通用的embedding模型,而是fine-tune了一个小模型专门做代码相关性判断。当你写代码时,Cursor后台先生成一批候选相关文件,然后用这个小模型(比GPT-4小两个数量级,推理成本极低)快速打分,选出最相关的几个文件作为上下文。这套pipeline的价值在于:用便宜的模型做粗糙的筛选,省下昂贵的上下文token给真正有用的内容。

到这里,AI编程的本质仍然是"人在回路"。人描述需求,AI生成代码,人审查和修改。AI是一个超级自动补全工具,不是Agent。它没有目标,没有计划,没有执行闭环。

第三层:Agent时代(2024至今)

这是目前正在发生,也是变化最快的一层。Agent的核心区别在于:它不再等待人类的每一步指令,而是接受一个高层次的目标,自己分解任务、规划步骤、执行操作、检查结果、在失败时重试。

Devin是第一个被广泛关注的编程Agent。它的工作流程是这样的:你给它一个任务描述(比如"在React项目中添加一个暗色模式切换功能"),它首先启动一个受控的沙箱环境(Docker容器),在这个环境里clone仓库、安装依赖。然后它开始规划:先分析现有代码结构,找到需要改的文件,估算工作量,生成一份执行计划。接着逐步执行:修改CSS变量文件、添加主题切换逻辑、修改组件、写测试、跑测试、修bug。最后生成一个PR描述,推送分支。

全是它自己做的。你没有告诉它"先改哪个文件再改哪个文件",你只说了"加一个暗色模式"。

编程Agent与对话式AI的核心区别
                    对话式AI              编程Agent 交互模式            多轮对话,人主导        目标驱动,自主执行 任务粒度            函数/文件级别           功能/项目级别 上下文窗口          单次对话                跨会话的持久记忆 工具使用            无或有限                文件系统/Shell/Browser/测试框架 错误处理            人发现问题后修正        自主检测错误,自主修复 执行环境            用户本机                隔离沙箱 验证闭环            人类review             自动化测试+自主review

这个对比表揭示了一个本质变化:从"工具"到"同事"。工具等你来用,同事自己干活。

二、拆解一个编程Agent:四层系统架构

如果你读过我的技术文章,你知道我喜欢拆。任何复杂的系统,拆开来看都是几个简单模块的排列组合。编程Agent也不例外。我研究了Devin、OpenCode(开源版)、SWE-Agent、Aider这几个代表性系统后,发现它们的架构高度趋同,都在用同一个四层框架。

第零层:感知层——代码理解

Agent面临的第一个挑战,是人一眼就能做到的事:看懂一个代码库。

一个中型的React项目可能有300个文件,几万行代码。模型一次能看多少?即使是200K token的上下文窗口,也只能装下大约15万行代码(假设每行平均10个token,包含缩进和空格的开销)。看起来够了?不够。因为prompt里还要放系统指令、工具描述、执行历史、当前状态、输出格式约束。实际可用空间远小于理论窗口。

所以所有编程Agent的第一层,都是一套代码理解系统。这套系统要做的是:从巨大的代码库中,提取出对当前任务最相关的一小部分,以最紧凑的形式喂给模型。

OpenCode的做法我比较熟悉,因为它是开源的。它的代码理解管线分了四步:第一步,用tree-sitter对所有源文件做语法解析,生成完整的AST。第二步,从AST中提取符号表(函数、类、类型、常量的定义位置和签名)。第三步,构建文件间的依赖图(import/export关系、函数调用链)。第四步,根据任务描述做语义检索,找出相关的文件子集,然后把它们的AST结构化摘要(不是原始代码,而是类型签名、函数签名、关键注释、调用关系)注入prompt。

OpenCode代码理解管线的关键设计: 1. AST → 符号表:用tree-sitter(支持40+语言)做增量解析,只重新解析变化的文件 2. 依赖图:用module resolution算法模拟Node.js/Python的import解析,构建精确的调用链 3. 语义检索:embedding模型用voyage-code-2,代码专用embedding 4. 上下文压缩:不是直接塞代码,而是生成"结构骨架"(类型+签名+注释),信息密度提升3-5倍

这里有一个非常聪明的设计决定:不送原始代码,送结构化摘要。为什么?因为模型不需要看到for循环的每一行实现,它只需要知道"这个函数接受一个User对象,返回一个过滤后的Order列表"。类型签名和注释往往已经包含了这个信息。这种压缩策略让相同token预算下可覆盖的代码范围扩大了3到5倍。

Devin在这层做得更重。它不只是做静态分析,还会在沙箱里实际运行代码,抓取运行时信息。比如:实际调用了哪些API、响应体的结构是什么样的、中间件的执行顺序。这些运行时信息被结构化后也作为上下文的一部分。这就是为什么Devin在处理那些文档不全、API行为不直观的项目时表现更好,它不仅仅"读代码",它在"跑代码来看它到底干了什么"。

第一层:思考层——任务规划与分解

有了代码理解之后,下一个核心问题是:Agent怎么决定"先做什么,后做什么"?

这个问题在AI Agent领域有一个特定的名称:planning。所有Agent都需要planning能力,编程Agent尤其如此,因为编程任务天然具有复杂的依赖关系。

目前主流的planning策略有三种:ReAct模式、Plan-and-Execute模式和Tree-of-Thought变体。我逐个拆。

ReAct(Reasoning + Acting)是最基础的Agent范式。模型在每个步骤做三件事:观察当前状态(我看到了什么)、推理下一步(我应该做什么)、执行动作(做)。然后循环。Devin的早期版本用的就是这个模式:先看代码,想想要改什么,改掉,看看结果,再决定下一步。

ReAct的优点是灵活,每一步都可以根据上一步的结果动态调整。缺点也很致命:长任务会出错。一个任务如果需要50步,每一步有2%的概率走偏,50步之后正确的概率是0.98的50次方,大约36%。这就是Agent领域的"累积误差"问题。

Plan-and-Execute模式试图解决这个问题。思路是:先花token做详细的计划,再逐步执行。SWE-Agent和OpenCode都采用了这个策略。模型在接到任务后,第一个动作不是直接写代码,而是输出一个结构化的执行计划:

Plan-and-Execute示例(添加暗色模式): Step 1: 在src/styles/中添加theme.css,定义CSS变量(预估:10行代码,涉及3个文件) Step 2: 修改src/index.tsx,用ThemeProvider包裹App(预估:5行代码,涉及1个文件) Step 3: 修改src/components/Header.tsx,添加切换按钮(预估:20行代码,涉及1个文件) Step 4: 逐一检查15个组件,将硬编码颜色替换为CSS变量引用(预估:50行代码,涉及15个文件) Step 5: 添加单元测试,验证主题切换逻辑(预估:30行代码,涉及2个文件) Step 6: 运行全部测试,修复可能的breakage Step 7: 生成PR描述并推送

计划一旦生成,Agent就按照顺序执行。每完成一步,检查和计划的偏差,决定是否调整后续步骤。这种方式比纯ReAct的"走一步看一步"更稳定,因为它有一个全局视角,不会在第二步就忘了第七步要做什么。

还有一种更激进的做法是Tree-of-Thought的变体。模型在规划阶段同时生成多个候选方案,然后对每个方案做一次快速的"心理模拟"(mental simulation),评估可行性和风险,选择最优方案执行。Cognition AI的论文提到他们在Devin中使用了类似的技术,但具体实现没有公开。

这里有一个容易被忽视的细节:planning的质量严重依赖代码理解的深度。如果你对代码库的理解有偏差,再好的planning策略也会生成一个漂亮的错误计划。这就是为什么Devin花了大量工程精力在代码理解和运行时探测上,planning层本身其实没有用特别复杂的算法。

第二层:执行层——工具使用与环境交互

计划做好了,下一步是执行。编程Agent的执行层是一个工具调用系统。模型不直接生成代码并"期望它正确",而是通过一组标准化的工具与环境交互。

一个典型的编程Agent工具集包括:文件系统工具(读、写、搜索、列出目录),Shell工具(执行命令、查看输出、检查退出码),浏览器工具(查文档、搜StackOverflow),Git工具(查看diff、创建分支、提交),以及测试工具(运行测试套件、查看失败详情)。

工具调用的关键在于"格式约束"。模型被训练成以特定的结构化格式输出工具调用。OpenAI从GPT-4开始支持原生的function calling,Anthropic有tool use,开源模型则通过微调来学习工具调用格式。

关键设计决策:沙箱隔离 vs 本机执行 Devin: Docker沙箱(每个任务独立容器,任务结束后销毁) OpenCode: Docker沙箱(可配置,默认沙箱) Cursor Agent: 本机执行(直接操作用户的终端和文件系统) GitHub Copilot Workspace: 云端Codespace(GitHub托管的开发环境) Aider: 本机执行(直接操作用户的本地仓库)  沙箱的优势:安全,可复现,不污染用户环境 本机的优势:不需要配置环境,上下文更丰富,用户可以直接介入

这里有一个重要的工程挑战:错误恢复。Agent在执行Shell命令时,命令可能因为各种原因失败:缺少依赖、权限不足、文件不存在、网络超时。一个成熟的Agent必须能识别错误类型、分析原因、尝试修复。比如:pip install失败了,Agent需要读取错误信息,判断是依赖版本冲突还是网络问题,然后采取相应的修复策略。

我测试OpenCode的时候,有一次它尝试安装一个不存在的npm包,报错了。它自动读了错误信息,判断可能是包名拼写错误,去npm registry搜了相似的包名,找到了正确的包,改了package.json,重新安装,成功了。这个行为不是被显式编程的,是模型的推理能力+工具链的组合效果。

第三层:验证层——自调试与闭环修复

这一层是整个系统最难的地方,也是区分"能用的Agent"和"真正好的Agent"的分水岭。

写完代码之后,Agent必须验证自己的输出是否正确。验证分三个层次:语法层(代码能不能编译/解释)、功能层(代码行为是否符合预期)、回归层(改动有没有破坏已有的功能)。

语法层最简单,跑一下编译器或linter就行。功能层需要测试:Agent要么运行已有的测试看是否通过,要么自己写测试然后运行。这就是为什么好的编程Agent必须能"理解测试":不是看懂测试代码的字面意思,而是理解测试在验证什么行为,然后确保自己的代码能满足这些验证。

自调试循环是编程Agent和代码生成工具最本质的区别。代码生成工具是"生成即结束",Agent是"生成、测试、修复、再测试"的闭环。这个闭环的存在,意味着Agent的输出质量不再由单次生成决定,而是由这个迭代修复过程的上限决定。

SWE-bench是衡量编程Agent能力的基准测试。它收集了来自12个Python开源项目(Django、Flask、SymPy等)的真实issue和对应的修复PR。Agent的任务是:给出一个issue描述和代码仓库,自动生成修复代码。评测指标是"修复率":Agent生成的修复有多少能通过这个项目的全部测试。

2024年初,即使是GPT-4直接生成修复,SWE-bench的修复率只有个位数。到2025年中,Devin的修复率超过30%,OpenCode的优化版本接近40%。注意,这个进步主要不是来自模型能力的提升,而是来自自调试闭环的工程设计。同样的模型,配上更好的工具链和更智能的错误分析,修复率可以从5%飙升到40%。这就是工程的价值。

SWE-bench Verified 修复率演进(近似数据): 2024年1月,GPT-4直接生成: ~3% 2024年3月,Devin(Cognition AI): ~14% 2024年8月,SWE-Agent(Princeton): ~18% 2024年12月,Agentless(UIUC): ~27% 2025年2月,OpenCode + Claude 3.5 Sonnet: ~33% 2025年6月,OpenCode + Claude 4: ~40%(未公开验证) 人类高级工程师平均水平: ~65-70%(估计)

40%的修复率听起来不高,但你得理解这40%是什么:完全自主,零人类干预,Agent自己读issue、找文件、改代码、跑测试。如果把它看作一个"自动修bug机器人",每天晚上跑一次,把仓库里所有能自动修的issue修掉,第二天早上工程师只需要处理剩下的60%。节省的时间非常可观。

更值得关注的是"Agentless"这个项目的有趣发现。Agentless的思路是:不需要一个复杂的Agent循环,只需要两步就够了。第一步,用模型定位需要修改的文件和函数。第二步,用模型直接生成补丁。没有多轮交互,没有工具调用,没有自调试。就是这么简单的两步,修复率达到了27%,超过了当时大部分Agent方案。这说明什么?说明很多Agent的复杂性可能是不必要的,简单的流水线如果每一步做得足够好,效果不比复杂的Agent差。

架构的复杂性不等于效果。在Agent设计中,每一步的准确率比循环次数更重要。一个两步的简单流水线,如果每步准确率90%,最终成功率81%。一个十步的复杂Agent,如果每步准确率95%,最终成功率只有60%。

这不是说Agent循环没用。复杂的任务确实需要多步推理和迭代修复。但这个观察提醒我们:不要被"Agent"这个词迷惑,不要把复杂当深刻。每一步的质量,尤其是第一步的"定位"能力,决定了整个系统的上限。

三、横向对比:2025年四大编程Agent的架构差异

市场上现在至少有六个值得关注的编程Agent产品。我不打算罗列功能清单,那没意义。我拆的是架构层面的差异,这些差异决定了它们各自擅长什么、不擅长什么。

Devin:重工程,重沙箱,重闭环

Devin的架构哲学是"让Agent在一个完全可控的环境里工作"。每个任务启动一个独立的Docker容器,预装好必要的工具链。Agent在这个容器里clone仓库、安装依赖、修改代码、运行测试。任务结束后,容器销毁,不留痕迹。

这个设计的优点是安全和可复现。不管Agent做了什么,它永远不会影响用户的本机环境。缺点是启动成本高:每次任务都要等容器启动、等依赖安装。对于小任务(改一个函数),这个开销比实际工作时间还长。

Devin的另一个核心设计是"运行时探测"。它在修改代码之前,会先跑一遍项目,观察实际的运行时行为。比如:这个API端点实际返回的数据结构和类型定义不一样怎么办?文档说返回数组,实际返回的是包裹在data字段里的数组。这种文档和实现的偏差在真实项目中极其常见,纯静态分析发现不了。Devin通过"先跑一遍看看到底怎么回事"来规避这个问题。

OpenCode:开源,可定制,社区驱动

OpenCode是一个开源的编程Agent框架,你可以用自己的模型、自己的工具、自己的沙箱配置来运行它。它的设计理念和Devin不同:不是做一个端到端的黑盒产品,而是提供一套可组合的组件,让开发者按需拼装。

OpenCode的架构拆开来有三个核心模块:CodebaseContext(代码理解+上下文管理)、AgentLoop(规划+执行的主循环)、TerminalInterface(可插拔的终端后端,支持本地、Docker、SSH远程)。每个模块都可以独立替换。你想用GPT-4当planning模型、Claude当coding模型、本地小模型当embedding模型?可以,换个配置就行。

OpenCode在SWE-bench上的高修复率(接近40%),很大程度上来自它对上下文管理做了极限优化。它不是简单地把相关文件的内容塞进prompt,而是做了一层"上下文蒸馏":用一个较小但足够聪明的模型,先读一遍相关文件,生成一个紧凑的结构化摘要(只有类型签名、函数签名、关键行为和依赖关系),然后用这个摘要去替换原始代码。

OpenCode的上下文蒸馏流(简化): 1. 检索得到N个相关文件(N可能很大,比如50个) 2. 对每个文件,用一个小模型(如GPT-4o-mini)生成结构化摘要    摘要格式: {文件路径, 导出符号列表, 每个符号的签名+简要行为描述} 3. 将所有摘要拼接,送入主模型的prompt 4. 主模型需要查看某个文件的详细实现时,调用read_file工具按需获取  效果:同样的token预算,可覆盖的代码范围扩大了3-5倍

这个设计非常巧妙。它把"理解代码库"这件事拆成了两个粒度:粗粒度的"知道有什么"(用便宜的模型做摘要),细粒度的"知道具体怎么实现的"(在需要的时候按需获取)。人类程序员其实也是这么看代码的:先扫一眼项目结构和API,然后深入读自己需要改的那部分。

Cursor Agent:IDE集成的极致体验

Cursor Agent走了一条不同的路:不做独立的Agent服务,而是把Agent能力嵌入到IDE里。你在VS Code fork的Cursor编辑器里写代码,Agent就在旁边看着。你给它一个自然语言指令,它直接在你的终端里执行命令,在你的文件系统里修改文件。

这个设计最大的优势是"上下文天然丰富"。Devin和OpenCode需要费很大力气去做代码理解和上下文构建,因为Agent是从外部接入的,它需要自己从零建立对项目的心智模型。Cursor Agent不一样:它就在你的IDE里,你的LSP服务器已经解析了所有代码,你的git状态是已知的,你最近打开的文件、光标位置、终端历史,全部是现成的上下文。

代价是安全风险。本机执行意味着Agent的一个错误命令可能删掉你的文件、改掉你的配置、甚至(如果权限足够)影响系统。Cursor对此的处理方式是:执行前预览、步骤级确认、可回滚的修改。但这些保护机制本身也是可以被绕过的,因为Agent有Shell访问权限。

GitHub Copilot Workspace:从Issue到PR的全链路

Copilot Workspace的定位和其他几个产品都不一样。它不是帮你写代码的,它是帮你"从Issue出发,生成完整PR"的。你打开一个GitHub Issue,Copilot Workspace自动启动一个云端Codespace,分析Issue内容,规划实现方案,修改代码,运行测试,最后生成一个PR给你review。

它的优势在哪里?在于GitHub的生态整合。它天然知道这个仓库的CI配置是什么、代码规范是什么、测试框架是什么。它在生成代码时会参考仓库中已有的代码风格,生成的内容更容易通过code review。而且因为它运行在GitHub的云端环境里,环境配置是零成本的:仓库clone下来就用,依赖都在。

弱项也很明显:只能在GitHub生态内工作,只支持有限的语言和框架,定制化程度不如OpenCode。

这四款产品代表了两种不同的路线:Devin和OpenCode走的是"独立Agent"路线,强调自主性和通用性。Cursor和Copilot Workspace走的是"嵌入式Agent"路线,牺牲一些通用性换取更好的集成体验。未来哪种路线会赢?我的判断是:短期看嵌入式,长期看独立Agent。因为嵌入式Agent的天花板是"IDE能做到的",独立Agent的天花板是"计算机能做到的"。

四、核心技术挑战:为什么AI编程Agent还没有"吃掉"软件开发

看完前面的技术拆解,你可能会问:这些东西听起来都很厉害,那为什么我日常写代码还没有完全被Agent接管?为什么SWE-bench上最好的修复率也只有40%,而不是90%?

答案藏在几个基础性的技术瓶颈里。这些问题不是工程优化能解决的,它们涉及到当前大模型架构的根本限制。

瓶颈一:幻觉与代码正确性的张力

这是所有LLM应用的根本问题,在编程领域尤其致命。一句话:模型会信心十足地生成完全错误的东西。

具体到编程Agent,幻觉有三种表现形式:API幻觉(调用不存在的函数或方法,或者用了错误的参数签名),逻辑幻觉(代码的推理链路有问题,比如循环边界错了、条件判断反了),上下文幻觉(忘记了前面改过的东西,导致代码不一致)。

API幻觉可以通过更好的代码理解和工具使用来缓解。模型不是凭空生成API调用,而是先搜索项目中实际存在的函数和类型,从真实定义中提取签名,然后生成调用。这种方式把API幻觉率降低了大约70%。但逻辑幻觉更难处理:模型对"这个逻辑对不对"缺乏真正的判断力,它只是在模仿训练数据中的模式。

测试是当前唯一有效的缓解手段。这就是为什么验证层(自调试闭环)如此关键:不是让模型少犯错,而是让模型能自己发现错误并修复。

瓶颈二:上下文窗口的物理限制

即使是最新的模型支持200K甚至1M token的上下文窗口,编程Agent能真正有效利用的上下文远小于理论值。这是两个原因导致的。

第一个原因是注意力稀释。模型虽然是"理论上"能关注上下文中的任意位置,但实际研究表明,模型对长文本中部的信息利用效率显著低于开头和结尾。如果你把15万行代码塞进窗口,模型可能只真正"读懂"了前3万行和后3万行,中间的细节被忽略了。

第二个原因是Agent特有的"上下文膨胀"。Agent在一次任务中会经历多轮工具调用,每一轮的工具调用结果(命令输出、文件内容、错误信息)都会被添加到上下文中。一个50步的任务,上下文可能膨胀到50万到100万token。即使你每次把旧内容移到外部存储、只保留摘要,模型仍然会丢失细节。

这个问题的根本解,不是继续扩大窗口,而是更好的上下文管理策略。哪些信息需要放进窗口?哪些只需要一个指针(比如文件路径+行号,让模型在需要时按需读取)?哪些可以丢弃?这是一个未完全解决的问题。

瓶颈三:软件工程的隐性知识

软件工程中有大量不会被写在代码注释里的隐性知识。

为什么这个函数故意没有做空值检查?因为调用方保证了参数非空。为什么这个循环用了while而不是for?因为需要在中途改变迭代条件。为什么这个端口号硬编码?因为这个服务在Kubernetes里用环境变量覆盖了这个配置。这些决策背后的原因,模型从代码里看不到。它们存在于设计文档中、Slack聊天记录中、Jira评论中、以及最关键的:老员工的脑子里。

GitHub Copilot Workspace试图部分解决这个问题,它可以直接读取Issue和PR评论中的讨论。但大部分信息仍然在ChatGPT的上下文窗口之外。这意味着,当Agent修改一个复杂系统中的代码时,它有很高的概率破坏那些"文档没有写但确实存在的"约束。

瓶颈四:安全性与信任鸿沟

这个问题在Cursor Agent这种本机执行的Agent上最严重,但所有编程Agent都面临。

如果Agent有权限修改文件、执行Shell命令、推送代码,那么它的每一个错误都可能是灾难性的。删掉生产数据库的连接字符串,修改.env文件中的API密钥,在package.json中引入一个拼写错误的恶意包。这些不是理论上的风险,已经有过真实案例。

目前的缓解策略是"最小权限原则+人类review"。Agent只能操作被明确授权的文件和目录,所有修改在合并前必须经过人工review。但这又引入了一个效率悖论:如果你必须review Agent的每一行改动,那Agent节省了多少时间?

答案取决于任务的类型。对于重复性高、风险低的任务(比如"把所有console.log替换为logger.info""升级所有依赖到一个具体的版本范围"),Agent改动量大但review负担轻,因为改动模式统一,reviewer扫一眼就知道对不对。对于创造性高、风险高的任务(比如"重构认证模块"),Agent的改动可能比人类写的更危险,review负担反而更重。

编程Agent的真正价值不是"取代人的编程能力",而是"降低重复性编程工作的边际成本"。它让大规模、低风险的重构和代码迁移变得可行。它让每个工程师都有了一个不知疲倦的初级搭档。但它还没有解决"理解业务逻辑""做出架构决策""知道什么不该做"这些真正高级的工程问题。

五、对程序员意味着什么:一个技术人的冷静分析

我做了六年量化,带了十五个人的技术团队。我见过太多"这个技术要颠覆一切"的叙事,最后发现都是"这个技术改变了工作效率的分布,但没有消灭工作岗位"。

编程Agent大概率也属于这一类。

初级岗位的挤压效应

这是最确定的变化。如果你的日常工作是写CRUD、调样式、修简单bug、写单元测试,那么Agent已经在做这些事了,而且做得越来越快。不是说初级岗位会消失,而是初级岗位的定义在变化:过去初级工程师的核心价值是"能写代码",未来的核心价值是"能指挥Agent写代码+能判断代码对不对"。

这意味着什么?意味着对"代码理解力"和"系统思维"的要求前置了。过去你可以先学会写,再学会读懂别人的代码,再学会设计系统。现在你可能需要在学会写之前,就先学会读和判断。因为"写"这个动作被自动化了。

高级岗位的价值放大

对于高级工程师和架构师,编程Agent不是威胁,是杠杆。一个高级工程师加上一个编程Agent,可以在同样时间内完成过去需要一个高级加两个中级工程师才能完成的工作量。

这是因为高级工程师的核心能力不是"写代码快",而是"知道写什么代码"。架构决策、技术选型、边界定义、代码review、性能优化、安全审查。这些东西Agent目前做不了,短期内也做不了。它们需要全局视角、业务理解、经验直觉,这些是LLM在当前架构下难以建立的。

我自己的亲身体验:用Cursor Agent,我可以把一个需要两天的重构任务压缩到半天。但前提是我必须对重构方案有非常清晰的想法,知道改动的边界在哪里,知道哪些地方Agent可能犯错。Agent帮我执行,我负责校验和决策。如果没有这个前提,Agent写出来的代码可能比我手写的更快,但也更容易出错,而且出错了我不一定能立刻发现。

工作流的重构

比起"要不要学AI",更实际的问题是"怎么改变工作流来用好AI"。

第一个改变是"先想后写"。过去很多人习惯边写边想,打开IDE就开始敲代码,思路在敲的过程中逐渐成形。有了Agent之后,这个模式行不通了。你必须在动手之前把需求、边界、约束想清楚,然后清晰地表达给Agent。表达能力(prompt engineering)成为了一种新的生产力工具。

第二个改变是"测试驱动开发的回归"。TDD(测试驱动开发)在Agent时代获得了新的生命力。为什么?因为测试是Agent最可靠的"校验者"。你写好测试,交给Agent实现,Agent跑测试,失败了自动修复,直到全部通过。这个循环不需要你参与。如果你的代码库有完备的测试覆盖,Agent的自主编程能力会大幅提升。

第三个改变是"code review的内涵变化"。过去code review的主要工作是检查逻辑正确性和代码风格。Agent可以处理代码风格,甚至可以部分处理逻辑正确性(通过运行测试)。code review的核心变成了"这个改动在系统层面有没有问题?有没有破坏隐性的约束?有没有引入安全风险?" review的层次从"代码本身"上升到了"系统层面"。

不要恐慌,但要清醒

每次技术浪潮,都有两种极端声音图一乐:一种是"天塌了大家要失业了",一种是"这东西没啥用放心吧"。两种都不对。现实是:技术改变了生产力的分布,有些人的工作方式变了,有些工作的市场需求变了,但软件工程这个职业不会消失。

原因很简单:软件工程的难度不只在"写代码"。理解用户的真实需求、定义正确的功能边界、处理异常情况、做出恰当的架构权衡、维护一个存活多年的系统、在无数种可能的实现方案中选出最合适的那一个。这些事情,不会因为AI能写代码就自动消失。

但有一件事是确定的:不会用AI编程的工程师,在效率上会被会用AI的碾压。这不是"要不要学"的问题,是"什么时候学"的问题。而且答案很可能是"现在"。

六、展望:编程Agent的下一步是什么

最后聊聊我看到的几个趋势。不是预测,是已经能看到苗头的方向。

第一个方向是"多Agent协作"。单个Agent的能力有上限,但如果把不同的Agent组织起来呢?一个Agent负责读需求文档,一个Agent负责写代码,一个Agent负责测试,一个Agent负责review。像一条生产线,每个环节由专门的Agent处理。Anthropic的MCP协议和OpenAI的Agent SDK都在往这个方向走。

第二个方向是"垂直领域专用Agent"。通用编程Agent的准确率在复杂项目上还不够高,但如果把Agent限定在特定领域呢?比如"React前端Agent",它被fine-tune在React项目上,知道React的最佳实践、常见的反模式、社区惯用的第三方库。它的上下文可以被预设好,不需要每次都从零理解项目。这种"专用化"能大幅提升准确率。

第三个方向是"全生命周期Agent"。现在的编程Agent主要集中在"写代码"这个阶段。但软件开发还有需求分析、系统设计、性能测试、部署配置、监控告警、故障排查。如果Agent能覆盖整个生命周期,它的价值就不只是一个"代码生成器",而是一个"软件工程全流程助手"。

未来最值钱的程序员,不是写得最快的,也不是懂得最多的算法题的。而是能用AI把"一个想法变成可运行系统"的速度拉到最短的那种人。这种能力,我称为"AI时代的工程生产力"。

我们站在一个很有意思的转折点上。AI编程Agent不是完美的,它们会犯错,会写bug,会生成不优雅的代码。但它们确实在改变软件开发这件事的速度和方式。就像二十年前IDE替代了文本编辑器,十年前Git替代了手动版本管理,Agent会成为下一个基础设施级别的工具。

写得动代码的人,不会被AI淘汰。写不动的人,本来就在淘汰的路上。AI只是加快了这条路的修葺速度。

我,程飞,靠写字吃饭。不接软文,不带货,不卖课。您觉得这篇值一包烟钱,就赏一个。觉得不值,关了就完了。感谢每一个赏饭的人。