从 ChatGPT 3.5 发布开始,我就一直在使用大模型写代码。当时 ChatGPT 3.5 的编程能力还不是很强,只要需求稍微复杂一点,生成的代码就不太可靠。因此,那时我仍以手写代码为主,AI 主要用于查资料和处理一些简单问题。
后来,我又陆续用过 GPT-4 和 Claude,此后也一直在尝试 OpenAI 和 Anthropic 发布的新模型。随着模型能力不断增强,我在工作中需要手写代码的场景也越来越少。最近一年,我更是基本没有手写过代码,只有偶尔刷 LeetCode 时才会自己写一下。
这种变化也逐渐影响了我的开发方式。现在开发一个新功能时,我通常会先把需求理清楚并列出相关要点,再把需求发给 AI,让它检查我的理解有没有问题,还有哪些地方需要补充。一般经过几轮讨论,就能把实现方案确定下来。
方案确定后,我再让 AI 开始生成代码。代码完成后,我负责检查和测试。如果发现问题,就把错误信息和我的反馈继续发给 AI,让它修改。
现在我基本都是按照这个流程来开发需求。不过,我不会把需求交给 AI,等它生成代码后就直接使用。我还是会查看它具体改了什么,是否符合需求,有没有影响原来的功能,以及是否存在安全和性能方面的问题。
AI 有时会一次修改很多文件,如果每次都从头到尾逐行检查,Review 会花费大量时间。所以我通常会先了解这次修改涉及哪些业务流程和模块,再结合代码改动、自动化测试和实际运行结果进行检查。
在过去一两年里,很多程序员的工作方式都发生了类似的变化。随着代码生成质量不断提高,我也开始思考:如果大部分代码都可以交给 AI,那么程序员以后还能做什么?
这篇文章会结合我自己的工作经验,对这个问题做一次梳理。因为其中不少内容来自个人实践,所以难免会有偏颇,欢迎大家一起讨论。
Vibe Coding 改变了什么
我觉得 Vibe Coding 带来的最大变化,是大大缩短了从需求分析到功能实现所需的时间。
以前如果要开发一个自己不熟悉的功能,通常需要先查资料、读文档、找示例,然后再一点点把代码写出来。如果中间遇到问题,还要继续搜索资料并反复调试。在整个过程中,查找资料和调试花费的时间最多,真正花在写代码上的时间反而比较少。
现在这些工作有很大一部分可以先交给 AI。无论是实现新功能、分析 bug,还是理解现有项目,只要把问题和相关背景描述清楚,AI 通常都能快速给出思路和代码。对于需求比较明确的开发任务,使用 AI 可以明显缩短查资料、编写代码和排查问题的时间。
开发成本降低以后,团队在相同时间内可以完成更多功能,代码变更也会变得更加频繁。但开发速度提高,并不代表就能提高产品的交付质量。如果需求分析、代码审核、测试和发布流程没有跟上,一些没有经过充分测试的改动就可能进入生产环境,导致产品问题频发。
而且功能实现得越容易,团队越有可能跳过需求评审而直接开始开发。以前一个需求要投入几天甚至几周,大家通常会认真考虑是否值得做。现在开发成本降低了,更需要在开始之前判断这个需求能不能解决实际问题,避免最后做出一个没有价值的功能。
以前程序员会把大量时间花在写代码上。随着越来越多的代码可以通过 AI 生成,程序员需要把更多精力放在分析需求、设计方案和验证结果上。
不懂开发的人能不能做出产品
一个完全不懂软件开发的人,也可以通过 Vibe Coding 做出网站、App 或者小程序。
网上经常可以看到"不会写代码,几个小时做出一个产品"这样的标题。按照现在 AI 的能力,几个小时确实可以做出几个页面、接入数据库、实现登录和基本的增删改查,再把它部署到云平台。
不过,这时得到的通常只是一个用于演示的 Demo。
等真正有人开始使用后,就会发现 Demo 和产品的差别。比如用户重复点击后生成了两条数据,网络中断后页面和后台的状态对不上,更新功能后原来的数据无法正常读取。这时,做产品的人就得去查日志、核对数据,弄清楚问题出在哪一步。
小项目不一定需要一开始就搭建完整的监控和告警系统,可以先保留必要的日志,定期备份数据,并确保发布出错后有办法恢复。等用户数量增加,或者某类故障开始频繁出现,再根据实际情况补充对应的工具和流程。
一个原本不懂开发的人,如果能在真实使用中发现并解决这些问题,也会逐渐接触到测试、部署、故障排查和数据维护,而不只是让 AI 把功能生成出来。
AI 时代更需要软件工程
大模型的上下文大小有限,项目代码、业务文档、设计方案这些内容很难一次性都放进上下文中。所以当这些信息不完整时,AI 可能会重复实现项目中已经存在的功能,也可能修改了公共逻辑,却没有同步处理其他受到影响的模块。
AI 可以参与需求分析、代码生成、测试和 Review,但它并不了解项目的全部背景。所以采用什么方案、代码能不能上线,仍然要由团队决定。
用可交互 Demo 确认需求
Vibe Coding 改变的不只是程序员写代码的方式,也在改变产品、设计、开发和测试之间的协作方式。
以前产品经理编写需求文档,设计师制作原型和视觉稿,开发人员再根据这些内容实现功能。需求文档和设计稿可以描述页面结构和主要流程,但很难完整展示操作中的状态变化。例如表单提交失败后是否保留输入内容、重复点击是否会产生多次请求、加载和空数据状态怎样切换,通常要在页面可以实际操作后才能确认。
现在产品经理可以借助 AI 快速制作可交互的 Demo,把需求文档中的流程提前做出来。团队可以直接体验页面跳转、表单操作和各种状态,再根据实际效果修改需求。相比只看文档和设计稿,这种方式更容易发现流程是否顺畅、信息是否完整,以及有哪些情况没有考虑到。
设计师也可以使用 AI 快速生成不同的页面方案,再根据产品定位和使用场景继续调整。等主要流程和需求边界确认以后,程序员再根据 Demo 和相关文档进行正式开发,测试人员也可以根据验收条件准备测试场景。
Demo 主要用来确认需求和交互,不能直接代替正式开发。程序员仍然要结合现有项目完成代码实现,处理权限、数据校验、异常流程和兼容性等问题。
把项目规则写进文档
同一个功能,在不同项目里的写法可能完全不一样。
有的项目要求所有接口都返回统一的数据格式,例如 { code, message, data };有的项目则直接返回业务数据,发生错误时再使用另一套错误响应格式。有的项目允许在 Controller 中查询数据库,有的项目则规定所有数据库操作都必须放在 Service 或 Repository 中。
开发者长期参与项目以后,通常知道当前项目应该遵守哪套规则。但 AI 不一定了解这些背景。如果没有相关上下文,它可能会按照自己的理解生成代码,导致功能虽然可以运行,但代码风格却和项目原来的写法不一致。
为了减少这种情况,团队最好把这些规则写下来,包括目录怎样划分、文件和变量怎样命名、接口怎样返回错误、日志需要记录哪些信息,以及新增功能需要补充哪些测试。通用规则可以放在 AGENTS.md 或项目文档中,让 AI 在修改代码前先读取这些内容。
除了通用规范,项目中的业务背景也需要适当记录下来。
项目代码是长期迭代出来的,有些看起来不太合理的逻辑,背后可能有具体的业务原因,也可能是为了处理以前出现过的问题。这些信息如果没有留下记录,后来维护代码的人很难知道当初为什么这样写,AI 也容易误删仍然有用的逻辑。
可以在模块目录下放一份 README.md,简单说明当前目录的作用、包含哪些模块,以及模块之间怎样分工。例如,一个常见的 Web 项目会把接收请求、处理业务规则和读写数据库拆到不同模块中。README 可以说明当前目录负责哪一步、会调用哪些模块,以及哪些逻辑不应该放在这里。
每次 PR 合并后,可以让 AI 根据代码改动更新对应目录的 README.md,再由提交者检查内容是否准确。这样能够降低文档维护成本,也更容易让文档跟上代码变化。
把 UI 规范整理清楚
多人同时使用 AI 开发前端页面时,很容易出现 UI 风格不统一的问题。如果项目里没有明确的设计规范,模型只能根据当前需求自行选择布局和样式。不同人分别生成的页面,很可能按钮大小不同、表格间距不同,甚至连弹窗、表单和操作区的布局都不一致。
团队可以把常用组件和页面规则写清楚,包括字体大小、颜色、间距、圆角、按钮类型、表单布局、表格样式、弹窗宽度,以及加载、空数据和错误状态应该怎样展示。
例如,新增和编辑页面使用抽屉还是弹窗,危险操作使用什么颜色,删除前是否需要二次确认,表格操作按钮放在哪里,这些都可以提前确定。
如果项目已经有组件库,可以让 AI 开发页面前先查找仓库中已有的组件和相似页面,能复用就不要重新实现;同时参考现有页面的布局和样式,让新页面保持原来的 UI 风格。
PR 要容易评审
一个 PR(代码合并请求)最好只完成一件事,不要把业务功能、代码重构和性能优化混在一起。
例如,需求只是给订单列表增加一个"退款状态"筛选条件,正常情况下只需要修改查询参数、后端接口和页面筛选项。
但 AI 生成代码时,可能顺便重构了查询方法、修改了其他页面的筛选组件或者重新格式化了一批文件。最后一个很小的需求变成了多个文件的大范围改动。
评审者既要确认退款筛选是否正确,又要检查那些额外修改会不会影响原来的功能。遇到这种情况,最好删掉与当前需求无关的改动,确实需要的重构则单独放到另一个 PR 中。
PR 的范围越清楚,评审者就越容易理解这次修改的目的,也越容易发现真正重要的问题。
大型重构也不要一次改完,可以拆成几个能够单独理解、验证和回滚的 PR。这样其中一步出现问题时,不需要撤回全部改动。
现在我通常会在人工 Review 前,先让 AI 根据需求和代码 diff 检查一遍,看看有没有无关改动、遗漏的异常场景,或者可能影响其他模块的地方。AI 给出的结果只作为第一轮筛查,开发者还要结合业务和现有代码再 Review 一遍。
测试不能只根据实现来写
让 AI 写完业务代码后,再让它根据这段代码生成测试,是一种很常见的做法。但如果 AI 看到的只有实现代码,它写出来的测试往往只是在验证这段代码当前的行为。
例如,订单退款后应该进入 refunded 状态,但代码错误地把状态更新成了 completed。如果让 AI 直接根据这段实现补测试,它很可能也会断言结果是 completed。测试虽然通过了,但业务逻辑却是错的。
因此,在生成测试之前,还要把需求和验收条件告诉 AI。订单在什么情况下可以退款、已经发货的订单怎样处理,这些规则都应该一起提供给 AI,再让它生成测试。
除了正常流程,还要根据功能补充异常场景。例如用户可能连续点击多次提交按钮,第三方接口也可能超时。测试需要根据实际业务来判断应该覆盖哪些情况,不能只看现有代码写了什么。
普通业务逻辑需要有单元测试,核心流程和其中长期稳定的关键规则还要用端到端(E2E)测试覆盖。每次部署到测试环境或生产环境前都跑一遍,确认主要流程仍然可以从头走通。这样也能在发布前多一道检查。
高风险代码要重点审核
不同代码出错后造成的影响不同,审核时也不能采用同样的标准。
修改按钮颜色或者页面间距,只需要确认页面显示正常。新增查询条件、调整表单字段这类影响范围较小的改动,主要检查是否符合需求,以及有没有影响原来的功能。
支付、权限、金额计算、数据库迁移和生产环境配置则需要检查得更仔细。审核这类代码时,要确认数据会怎样变化,执行失败后能不能恢复,重复执行会不会产生问题,以及这次修改会影响哪些已有功能。
支付就是这类高风险功能。
支付流程通常会涉及回调处理、订单状态更新和发货等多个环节。支付平台有时会重复发送同一个回调,因此回调处理需要保证幂等,避免同一笔订单被重复记账或者重复发货。
订单状态和发货记录如果需要一起更新,还要考虑其中一步执行失败后怎么处理。支付成功后可能继续触发通知或者奖励发放,某个环节失败以后,需要确定是重新执行整个流程,还是只重试失败的部分。
后续发生退款时,还要结合原来的支付记录、订单状态和发货结果继续处理。商品是否已经发出、奖励是否已经发放,都会影响退款流程。相关逻辑通常分散在多个模块中,开发时需要把整个流程和状态变化一起梳理。
为了保证支付流程可靠,开发时需要处理幂等、事务、重试和补偿,并通过测试验证不同状态下的结果。功能上线以后,还要通过日志和监控确认回调、状态更新和后续任务是否正常执行。
团队可以提前列出高风险模块,并明确对应的审核人员。无论代码是手写的还是 AI 生成的,最终都要有人批准合并,并对上线后的结果负责。
程序员以后应该提升什么能力
理解业务和产品
在过去的软件开发流程中,最常见的分工是产品经理编写需求、设计师负责出图、程序员负责实现。在这种协作方式下,程序员更多关注的是怎么实现,只需要按照需求完成对应的功能。
现在 AI 已经能够根据明确的需求完成功能实现,单纯把需求转换成代码的能力已经不像以前那样稀缺了。程序员需要更多地参与需求分析,理解功能背后的目的,并判断当前方案是否真的能解决问题。
例如,当产品经理提出增加签到功能时,可以先问清楚签到的目的是什么。是希望用户每天打开应用,还是希望已经离开的用户重新回来?目标不同,后面的方案也会不同。
如果输入给 AI 的内容只有"开发一个签到功能",模型会直接生成签到页面、签到接口和奖励逻辑。至于用户为什么不活跃、签到能不能改善活跃度,以及有没有更简单的办法,仍然需要团队自己分析。 签到能不能提高活跃度,光靠讨论也很难确定。可以先看看现有数据,找一些用户了解他们为什么不再使用,或者先做一个小范围版本,观察实际效果后再决定是否继续投入。
目标问清楚以后,还要继续确认功能边界。以签到功能为例,哪些用户可以签到、是否支持补签、奖励发放失败后怎么处理,都需要在开发前确定。需求文档如果没有写到这些内容,开发时还是得一项项确认。
这些信息没有写清楚,AI 就会按照自己的理解进行补充。有时它的理解符合项目要求,有时却可能偏离实际需求。
判断方案和控制风险
使用 AI 生成代码以后,程序员还要判断它给出的方案是否适合当前项目。
例如,用户提交表单后需要发送一条通知,AI 可能会建议接入消息队列,把通知发送和失败重试放到异步任务中。这种做法适合请求量较大、不能阻塞主流程的场景。但如果当前请求很少,发送失败后直接重试就能满足需求,引入消息队列反而增加了部署和维护工作。
项目发展到一定规模以后,消息队列可能确实有必要。但当前阶段是否需要使用,要看请求量、失败后的影响,以及团队有没有能力维护这套系统。
方案确定以后,还要继续检查它会带来哪些风险。例如增加了哪些依赖,修改失败后能不能恢复,上线以后怎样观察运行情况。把这些问题提前考虑清楚,后面的开发和维护会轻松很多。
提升审美
AI 生成的 UI 很容易出现千篇一律的问题,例如重复使用渐变色、圆角卡片、大标题和数据面板。即使换一个项目,最后生成的 UI 仍然可能是相似的风格。
所以程序员还需要具备基本的视觉判断能力。页面完成后,要对照设计稿检查布局、组件尺寸、间距、字体和颜色,再实际操作一遍,确认弹窗、表单校验和加载状态是否符合设计。
AI 能提高学习效率,但不能代替练习
除了写代码,AI 对学习新知识的帮助也很大。
以前接触一个陌生领域时,通常要自己搜索资料,再从官方文档、博客和问答网站里查找相关内容。遇到一个具体问题时,可能需要同时了解几个不同的概念,再把这些信息组合起来,才能找到合适的解决方法。
现在可以先问 AI,让它解释基本概念、说明不同做法分别适合什么场景,或者根据当前的问题列出需要了解的知识。遇到不理解的地方,也可以继续追问,不需要每次都重新搜索。
我以前刚开始做后端开发时,对很多后端和云服务方面的知识都不熟悉。遇到 AWS 容器化部署、S3、Route 53 和 DNS 解析之类的问题时,经常需要同时查阅几份文档。官方文档虽然写得很完整,但刚接触这些服务时,我也很难判断应该先看哪一部分。
现在再遇到类似问题,我会先把目标、运行环境和报错信息发给 AI,让它帮我分析可能的原因和排查顺序。这样可以少走很多弯路,不用一开始就盲目搜索。
不过,这种方便也容易让人产生一种已经学会了的感觉。
这和看教程差不多。看别人操作时总觉得每一步都懂,等关掉教程自己动手时,才发现很多地方还是不会。AI 可以帮助我们查资料、解释概念,也可以在遇到问题时提供思路,但最后还是要自己实现和调试。
我以前学习新知识时,经常会问自己三个问题:
- 它是什么?
- 为什么要这样做,可以不这样做吗?
- 有没有更好的方式?
现在这些问题都可以拿去问 AI,不过不能只看它给出的答案。还要自己试一下,看看它说得对不对,放到实际项目里能不能用。
保留编码和调试能力
程序员仍然需要保留编码和调试能力。
只有亲自写过、改过和调试过代码,才会逐渐熟悉模块之间的调用关系、状态怎样变化,以及出现故障时应该按照什么顺序排查。这些经验也能帮助程序员判断 AI 生成的代码有没有问题。
初学者使用 AI 时,最需要注意的是黑盒问题。如果看不懂生成的代码,只知道它可以运行,那么这段代码对自己来说就是一个黑盒。项目出现问题后,既不知道原因在哪里,也不知道应该修改哪一部分,只能继续把报错发给 AI,再用新生成的代码替换原来的实现。
这种方式用得多了,代码很容易越改越乱。当前的报错消失以后,新的修改又可能影响其他模块。由于不清楚每次改动的原因,后面即使发现问题,也很难判断哪些代码应该保留,哪些代码应该撤回。
平时可以自己做一些感兴趣的小项目,也可以刷刷 LeetCode。在不用 AI 的情况下,自己把代码写完并解决其中的问题,可以避免长期依赖 AI 以后,连基本的编码和调试都不知道该怎么下手。
工作中的大部分代码可以交给 AI 生成,但代码生成以后,自己要能看懂,也要知道它为什么这样改。AI 连续修改几次都没有解决问题时,程序员还得能够自己继续排查。
了解 AI 工程应用
程序员还需要了解一些 AI 工程应用方面的知识。
大多数应用开发者不需要训练大模型,也不需要深入研究底层算法。平时可以先了解 RAG、Tool Calling、AI Agent 和结构化输出等技术,知道它们分别适合解决什么问题。
以后很多软件可能都会加入智能搜索、文档问答、内容生成和自动执行任务等功能。程序员需要了解这些功能怎样接入现有系统,以及接入过程中要处理哪些问题。
例如,AI Agent 在读取文件、发送邮件或者操作数据库时,只能获得当前任务需要的权限,不能访问无关数据,也不能执行超出范围的操作。
模型返回的数据也不能直接使用。即使要求它返回 JSON,系统仍然要检查字段类型、取值范围和业务规则。遇到模型超时、返回错误或者结果不完整时,程序也要有对应的处理方式。
还要考虑提示词注入、敏感数据泄露、调用成本、重试策略和结果追踪等问题。这些都属于 AI 功能接入真实系统以后必须处理的工程问题。
产品工程师和技术专家
AI 的出现会让更多程序员有机会成为产品工程师。
产品工程师通常在某一项技术上有足够的深度,同时也能够参与产品、设计、前后端、测试、部署和运营。遇到一个需求时,他可以从问题分析开始,一直跟到功能上线和用户反馈。
在过去,一个程序员可能因为不懂设计、后端或者部署,很难独立做出一个完整产品。现在,他可以使用 AI 生成自己不熟悉部分的方案和代码,再经过检查与修改,把想法更快地变成可以使用的产品。
产品工程师仍然需要和产品经理、设计师、测试人员协作。区别在于,他会关注完整的交付过程,从业务目标、方案设计一直跟到上线和用户反馈,不会在完成自己负责的代码后就结束。
技术专家也会长期存在。
数据库、编译器、分布式系统、安全和基础设施等领域,依然需要长期研究特定问题的技术专家。这些领域往往涉及复杂的性能、可靠性和安全问题,需要根据系统的实际运行情况长期分析和验证,不是把代码生成出来就算解决了。
AI 更擅长处理规则明确、重复性较高的任务。按照现有页面增加一个相似的管理页面,或者按照固定格式补一组接口,这类工作已经可以交给 AI 完成大部分内容。
但真实项目中的方案不能只看代码能不能生成,还要判断它是否符合业务目标、能否接入现有系统,以及团队能不能长期维护。产品工程师需要决定功能应该怎样做,技术专家则要解决性能、可靠性和安全方面的问题。这两种方向都会长期存在。
总结
Vibe Coding 已经明显改变了程序员的工作方式。无论是在现有项目中增加功能、修改业务逻辑,还是排查问题,AI 都可以参与需求分析、方案讨论、代码修改和测试。
以后程序员可能不再需要花那么多时间直接编写代码,但仍要把需求想清楚,判断方案是否适合项目,并对最终的改动和运行结果负责。
代码可以交给 AI 生成,最终能不能合并、能不能上线,以及上线后出现问题应该怎样处理,还是要由程序员和团队决定。