代码结构优化:在开发五子棋的禁手功能(黑棋不能走出三三、四四或长连)时,我有一个核心的协调文件 gomoku-ai.ts。Cursor 的做法是直接将禁手判断的复杂逻辑堆砌到这个协调文件中。而 CC 则展现了更优秀的设计能力,它创建了一个独立的 forbidden-move.ts 文件,专门用于封装所有禁手检测的逻辑,再由 gomoku-ai.ts 进行统一调度,使得代码结构更清晰,职责更分明。
类似的例子还有很多,这让我越来越依赖 CC。Cursor 更像一个初级程序员,优先考虑完成当前任务,对代码质量、复杂度和可维护性的考量不足,倾向于「能加代码就不改代码」。而 CC 在理解意图、分析代码结构以及构建更优代码方面表现更强。当然,它也并非完美,有时也会在「奋战」十分钟后报告任务完成,但却没有解决问题。
I had this tweet two years ago where I said “90% of my skills just went to zero dollars and 10% of my skills just went up 1000x”. And this is exactly what I’m talking about - having a vision, being able to set milestones towards that vision, keeping track of a design to maintain or control the levels of complexity as you go forward. Those are hugely leveraged skills now compared to knowing where to put the ampersands and the stars and the brackets in Rust.
然后按顺序提交给 ACA,效果会好得多。这个是 Cloudflare 的工程师通过 Claude 写的代码,可以看下他们给 Claude 的 prompt:
prompt: Please write tests for this library using vitest. The tests should use a mock or fake KV namespace for storage. Be sure to study README.md and storage-schema.md in addition to oauth-provider.ts to fully understand the functionality. Try to cover all the important logic.Claude initially wrote a separate mock library.prompt: Let's just put the whole test including mocks in one file.Claude spent several minutes thinking and produced the test. It failed immediately due to `cloudflare:workers` not being available.prompt: Looks like for this test to run under node, we need to mock out the `cloudflare:workers` module. We just need to define the `WorkerEntrypoint` class. Can you do that?Claude did this. Yay.Several tests are still failing, but they do run. Will debug in separate commits.
大概半年前,我开始接触 AI 编程助手,例如 Cursor 和 GitHub Copilot。简单试用后,感觉不太顺手,就暂时搁置了。当时我的感受是:
Cursor 的存在感太强了,用起来不太习惯,还是更喜欢 VSCode。
但随着 AIDE 和 AI 编程插件越来越多地出现在视野中,我隐隐意识到这股趋势不可忽视,应该再次尝试。于是开通了 GitHub Copilot 的付费版,开始在一个实际项目中深入使用。
使用一段时间后,我的整体感受是:AI 辅助编程将会是不可逆转的趋势。越早掌握一款得心应手的工具,越早完成与 AI 的磨合,对程序员的个人发展越有益。
我实践的项目是一个基于 Tauri 2 的 Mac App。粗略估计,其中大约一半的代码是由 AI 辅助生成的。例如,编写一个 React 组件来展示 Playlist 下的 Videos,我先是构建了页面的基本结构,然后逐步细化指令,比如为每个 Video 添加序号,设置鼠标悬停 (Hover) 样式等等。这种感觉就像雇佣了一位高效的实习生来协助完成工作。
可能是 GitHub Copilot 的能力有限,或者我的使用技巧还不够成熟,亦或是当前 AI 编程助手普遍的现状,我发现在面对一些需要「跳跃性思维」才能解决的复杂 Bug 时,这些工具能提供的帮助非常有限。比如我曾遇到一个问题:主题切换在开发模式下运行正常,但部署到生产环境并重启应用后就会失效。这个 Bug 有点隐蔽,结果 AI 也如期望那样未能提供有效的解决方案。再比如,如何将 devtools 工具带到生产环境,同时禁用默认的 Cmd+Shift+I 快捷键?AI 给出的方案都不 Work,最终还是翻了下 Tauri 的源码才找到的思路。 目前看来, AI 编程助手更擅长执行指令明确的任务,根据上下文生成代码片段,但在复杂问题分析、根因定位、以及需要创新性解决方案的场景下,仍然需要人类程序员的深度思考和经验判断。如果未来的 AI 通过更高级的算法和更完善的知识库,模拟甚至超越了「跳跃性思维」,这又会是另一个课题,不过目前看来,还不太需要担心。
「信息滞后」也是一个不可忽视的问题(Cursor 在这方面表现稍好)。Copilot 似乎缺乏有效的机制来实时获取和更新最新的技术文档,因此它生成的代码有时会使用过时的 API。在 Tauri 2 项目中这个问题就比较明显,因为 Tauri 2 的 API 与 Tauri 1 相比变化很大。我经常需要在 AI 生成的代码基础上,手动查阅最新的 API 文档并进行替换。这个问题 Cursor 解决得更好一些,但有时也会出现新旧 API 混用的情况。
基于这次 AI 辅助编程的体验,我开始认真思考:AI 辅助编程的崛起究竟意味着什么?它将如何重塑软件开发行业?
程序员这个职业会消失吗?
如果一个没有编程经验的人,通过 AI 辅助编程工具就能开发出像模像样的产品,那么还需要程序员吗?如果对软件产品的要求仅仅停留在「可用」的层面,那么程序员的价值确实会受到挑战。但在实际软件开发过程中,我们不可避免地会遇到难以调试的 Bug,或者需要突破常规的创新思路才能实现的需求。目前的 AI 工具对复杂上下文的理解还不够深入,在处理复杂问题时常常显得力不从心。如果完全放任 AI 自由编程,结果很可能是 Bug 没解决,代码反而变得更混乱,维护性更差。
在注重协作的组织环境中,程序员被 AI 工具淘汰的速度可能会相对放缓。有相关工作经验的同学应该都有体会,在日常工作中,程序员每天的代码产出量其实很有限,相当一部分时间都花费在需求沟通、Bug 修复、梳理遗留代码、编写文档、Oncall、处理依赖冲突、等待编译构建结果等非直接编程相关的工作上。直接将 AI 引入现有复杂项目,一方面可能存在代码泄露的安全风险,另一方面,AI 由于缺乏对遗留代码完整上下文的理解,可能会生成不符合项目规范或非最佳实践的代码,反而增加维护成本。毕竟最终对代码质量和线上问题负责的仍然是人,而不是 AI。如果线上出现重大事故,总不能给 AI 记个 P1 吧。因此,在注重团队协作和代码质量的大型组织中,程序员受 AI 编程工具的直接冲击可能相对较小。但这种状态能维持多久还不好说,当企业看到 AI 带来的生产力提升潜力后,肯定会围绕 AI 进行组织架构和工作流程的效率革新,届时程序员群体必然会受到影响。
AI 编程的崛起,不是程序员的末日,而是一次进化。AI 不会取代所有程序员,但它将深刻地改变程序员的角色和技能要求。
初/中级程序员如何应对日益强大的 AI 编程工具?
首先要有危机意识,拥抱变革。有了危机感,才能激发学习和改变的动力。如果仍然想从事编程行业,那么首要任务是积极学习并掌握一款 AI 编程工具(Copilot 相对轻量,可以作为入门级选择)。要努力做到与 AI 工具默契配合,充分发挥其代码生成和辅助功能,从而显著提升个人生产力,并将节省出来的时间投入到更有价值、更具挑战性的事情上。
接下来,可以认真考虑未来的职业发展方向。如果希望在编程领域持续深耕,可以着重提升高级程序员应具备的核心技能,例如系统设计、复杂业务逻辑分析、问题分解与抽象、疑难 Bug 调试与根因分析、系统性能优化、创新技术方案设计等等。在这个学习和提升的过程中,也可以借助 AI 工具来提高学习效率,例如在阅读学习优秀的开源代码时,可以利用 AI 辅助代码理解,梳理代码逻辑,解答设计思路上的疑问。
如果对产品方向更感兴趣,或者有创业的想法,则可以投入更多时间在产品设计、用户研究、市场分析等方面,利用 AI 工具快速构建 MVP原型,快速验证产品想法,探索商业模式。
AI 编程下的人机协作新范式
可以将 AI 工具使用者与 AI 编程工具之间的关系比作「交响乐团的指挥家与乐团」。程序员如同经验丰富的指挥家,拥有清晰的愿景和目标,负责软件系统的整体架构和模块设计,指导和协调 AI 工具(如同乐团)高效、高质量地完成代码编写(如同乐曲演奏)。AI 工具如同训练有素的乐团,拥有强大的代码生成和辅助能力,但需要指挥家的明确指令和专业引导才能演奏出优美的乐章。
不同的 AI 编程工具都有各自独特的功能和特点,但与它们交互的核心要点是共通的:精细化任务分解和指令设计,以及代码 Review。 在人机协作的新范式下,程序员不仅需要与 AI 工具高效沟通,还需要与团队成员更好地协作,共同利用 AI 提升团队的整体研发效率和代码质量。
半年前我初次尝试 AI 编程助手效果不佳,也是因为没有掌握与 AI 编程工具有效沟通的精髓。可以将这些 AI 工具视为响应迅速、随叫随到的「外包程序员」,每一次代码改动都相当于一次 GitHub 的 Pull Request。要确保每次改动的目标明确具体,代码改动量控制在可审查的范围内。最终目标是代码虽然不是完全由自己编写的,但对代码的整体逻辑和关键细节都非常熟悉,这样即使 AI 无法解决某些深层次的 Bug,自己也能凭借对代码的深入理解,逐步分析和定位问题根源。
小结
AI 辅助编程的崛起既是挑战,也是机遇,基本上是不可逆转的趋势。如果半年前有人这么跟我说,我可能会将信将疑,但现在对此更加确信。即使只是体验了入门级的 Copilot,也已经真切感受到了它带来的效率提升。尽早找到适合自己的 AI 编程工具,积极完成与 AI 的磨合过程,然后将效率提升所节省出的宝贵时间,投入到扩展和丰富自身技能库上,不断学习和掌握更高级的技能,让自己成为拥抱 AI 浪潮的弄潮儿,而不是被技术浪潮无情淘汰的落伍者。
No matter what kind of startup you start, it will probably be a stretch for you, the founders, to understand what users want. The only kind of software you can build without studying users is the sort for which you are the typical user.
即使你吃自己的狗粮,结果仍然可能不如意,比如需求提炼不够精确,产品不够惊艳,缺少推广途径等等。NVIDIA CEO 黄仁勋在早年的一次分享中有提到:
If you want to be successful, I would encourage you to develop a tolerance for failure. However, there’s something crucial about failure: if you fail often enough, you might actually become a failure, which is fundamentally different from being successful. So the real question becomes: how do you teach someone to fail, but fail quickly, and change course the moment they recognize a dead end?
The way to approach this is through what we call “intellectual honesty.” This means continuously assessing whether something makes sense, and if it’s the wrong decision, being willing to change your mind.
To achieve this, you have to nurture a tolerance for risk-taking and teach people how to fail—quickly and with minimal cost. Innovation demands a bit of experimentation; experimentation requires exploration, and exploration inevitably involves failure. Without a tolerance for failure, you’d never experiment; without experimentation, you’d never innovate; and without innovation, you’ll never succeed. Otherwise, you’ll just end up being, well… a dweeb.