与 AI 结对编程

发表于

为您每周带来有关 Swift 和 SwiftUI 的精选资讯!

在过去的两周时间里,在 AI 的辅助下,我在一个不熟悉的开发环境中使用陌生的语言和框架启动了博客的重建工作。通过这次重建过程,我希望能够对新的语言和框架有一定的掌握。本文记录了我与 AI 一起工作的一些体会。

维基百科:

结对编程(Pair programming)是一种敏捷软件开发的方法,两个程序员在一个计算机上共同工作。一个人输入代码,而另一个人审查他输入的每一行代码。输入代码的人称作驾驶员,审查代码的人称作观察员(或导航员)。两个程序员经常互换角色。

在结对编程中,观察员同时考虑工作的战略性方向,提出改进的意见,或将来可能出现的问题以便处理。这样使得驾驶者可以集中全部注意力在完成当前任务的“战术”方面。观察员当作安全网和指南。结对编程对开发程序有很多好处。比如增加纪律性,写出更好的代码等。

契机

我计划从明年开始,在我的博客上同步发布文章的中英文版本(目前英文版本发布在 Medium)。同时,我也打算更新博客的外观设计。为此,我决定对博客进行一次全面重构。

这次重构不仅仅是为了改变外观,更是一个挑战自我、学习新技术的机会。我选择使用一种全新的编程语言,目标是在完成重构的同时,深入理解这种新语言和框架,以及之前不太熟悉的开发环境。

在以往的项目中,我虽然使用过一些 AI 服务,但更多的是试水而非深度体验。因此,这次重构成了一个绝佳的契机,让我深入感受在 AI 的紧密配合下的工作效果及其优缺点。

为了确保 AI 在此次重构中扮演关键角色,我设定了以下规则:

  • 在获取信息方面,传统搜索引擎的使用比例不得超过 20%。
  • 不向其他开发者求助。

换言之,AI 将成为我在这次开发和学习过程中的主要信息来源、合作伙伴和助手。这种合作,在某种意义上,类似于一场与 AI 的“结对编程”,其中 AI 还担任着老师的角色。

在这次“结对编程”中,我使用了 GitHub Copilot、ChatGPT、Claude 和 Warp(AI 助手)等服务,将它们视为这次编程旅程中的关键伙伴。

与 AI 的合作之旅

选择技术栈

在选择技术栈的这一阶段,我主要依赖于 ChatGPT 和 Claude。通过向它们详细阐述我的技术背景和具体需求,在多轮交流后逐渐明确了我所需的开发语言、框架和编辑器。

与 AI 的对话既自由又发散。每当 AI 提出建议或提示后,我都会就其中某些特定方向或细节进行更加深入的探讨,并定期总结我的理解,向 AI 进行再次确认。与几个月前相比,GPT-4 和 Claude 2 不再仅仅迎合提问者,它们会及时且礼貌地指出我的理解中的错误,有效避免了我在错误的道路上越走越远。最终,我选择了 TypeScript、Astro、TailWindCSS 以及 VSCode 这一组合,用于博客的重构。

AI 在这个阶段为我提供了极大的帮助,提高了我获取有效信息的效率,并帮助我迅速做出决策。能取得这样的效果,应该归结于以下原因:

  • 明确的需求:我的需求既明确又普通,易于 AI 理解,这简化了整个沟通过程。
  • 成熟的技术选择:我选择的技术栈由成熟的项目构成,它们在互联网上拥有活跃的社区和丰富的文档,这些信息为 AI 提供了可靠的语义资源,确保了 AI 对这些技术的深入了解。
  • 结合个人经验:凭借我在其他开发语言上的经验,我在讨论中使用了自己熟悉的语言、框架和开发环境作为参考,以帮助 AI 更好地理解我的需求。这也使我更容易理解 AI 提供的建议。
  • 多 AI 平台的互补:在此阶段,我同时在 ChatGPT 和 Claude 上进行讨论。尽管在大多数情况下,两者回答的信息内容区别不大,但偶尔还是会出现一些不同的回答方向,这就相当于多了一个人在讨论。
  • 人的判断力不可或缺:尽管与传统搜索相比,AI 提供的资料量已经减少了,但是,如果使用者的分析能力不足、决策不果断,仍然会迟迟无法做出选择。这在与生成式 AI 进行讨论时经常会遇到的情况。使用者必须具备较强的分析和决断能力,否则过多的自由反而会影响最终获得良好的结果。

搭建开发环境

虽然我平时也使用 VSCode,但之前从未将其作为主力开发工具。对于安装 Node. js 和使用 NPM,我的了解也相对有限。在这方面,AI 的帮助使我能够顺利构建开发环境。

对于解答命令行操作和在操作中遇到的问题,Warp 提供的 AI 助手使用起来最为方便。遇到错误时,我只需点击 ⚡️按钮,AI 助手即会自动将相关的命令和输出作为上下文提交给 AI。相较之下,在 GitHub Copilot 中,为了确保上下文的完整性,我需要手动选择需要解释的输出内容,再通过右键菜单中的 AI 选项或使用快捷命令 @workspace /explain #terminalSelection 进行操作,这比 Warp 略显繁琐。

与 Xcode 提供的集成式测试环境不同,在 VSCode 中,开发者需要根据所使用的语言和框架选择合适的测试框架和插件。在这一过程中,我遇到了一些困难。最初按照 AI 的建议尝试安装 Jest,但由于与 Astro 的配合问题,一直无法成功。在多次与 AI 的讨论无果后,我转向搜索引擎,但仍未找到解决方案。最终,我在网上找到了一篇文章。文章提到了我之前在配置中没有接触到的知识点。我将这个知识点告知了 AI,并提供了更多上下文信息。最终,在 AI 的指导下成功配置了 Jest 框架。

然而,在后续的单元测试中发现,Jest 无法与 Astro 的运行时环境协同工作。通过查阅 Astro 的官方文档,我发现 ViTest 是更合适 Astro 的测试框架。安装 ViTest 过程十分顺利,且能完美运行涉及 Astro 代码的测试。

因此,在这个项目中,我最终配置了两个测试框架:针对 Astro 的测试使用 ViTest,而其他测试仍使用 Jest。

不知道是否是我的配置问题,通过快捷命令,GitHub Copilot 默认生成的测试代码是基于 Jest 的。为了生成适合 ViTest 的测试代码,我需要通过对话方式明确提出要求。

从这个经历中,我意识到,即使有 AI 和搜索引擎的帮助,最权威的信息源仍然是官方文档。尽管 AI 对这些文档有相当程度的了解,但有时仍会漏掉关键信息。由此可见,官方文档的权威性不可被替代,仍是首选的信息渠道。

通过阅读代码,学习新语言

阅读 Astro 提供的官方模板是我了解 Astro 和学习 TypeScript 的最好途径。在这个阶段,AI 扮演了决定性的助手角色,极大地提高了我学习的效率。

在 Astro 项目中,astro 文件可能包含 TypeScript、JavaScript、HTML、CSS 以及 Astro 特有的标记和用法等多种元素。对于我这样之前没有相关经验的人来说,在没有 AI 的帮助下,基本上是无从下手的。

通过让 AI 对代码作出详细的解释,我逐步理解了其结构和逻辑。虽然 Astro 相对于其他框架而言历史较短,但 AI 知识库对其有相当充分的了解。AI 能够清晰地指出代码中各个部分的含义,对于我不理解的地方,我会继续询问以获得更详尽的说明。

在这个讨论过程中,我充分利用了自己对其他开发语言和框架的了解,作为与 AI 对话的参考。我还会定期总结自己的理解,让 AI 帮助我纠正任何理解上的偏差。此外,随着讨论内容的增加,我也会定期要求 AI 对之前的讨论进行阶段性的总结,并进行记录。

这一阶段的代码解释和讨论主要在 GitHub Copilot 中进行。尽管 GitHub Copilot 总体表现良好,但在使用过程中需要注意以下几点:

  • 如果没有特定选择代码,GitHub Copilot 仅解释当前编辑窗口中可见的代码部分。
  • 为了提供更多的代码给 GitHub Copilot,需要手动选择想要提交的代码,以使其成为当前问题的上下文。
  • GitHub Copilot 不支持跨文档讨论,需要用户自行整合不同文档内容,以形成完整的上下文。
  • GitHub Copilot 的回答长度有限,如果答案过长,提示信息可能会覆盖掉已经给出的部分,此时需要求助于 ChatGPT 或 Claude。
  • 在某些问题上,GitHub Copilot 的回答质量可能不及 ChatGPT。

总的来说,AI 在辅助学习方面给我带来了巨大惊喜。未来,我计划在学习过程中更多地融入 AI 的使用。

编码实践

根据提示自动创建代码是开发者能够第一时间感受到 AI 强大功能的最佳方式。尤其是 GitHub Copilot 可以揣摩开发者的意图,实时生成质量不低的代码,一度引发开发者群体的热烈讨论。对我而言,这个功能固然十分优秀,但就我目前的需求而言,它反而成了阻碍。

在这次的博客重构中,我不仅要创建一个新的博客,还希望能够在这个过程中更多地了解和掌握新的语言和框架。在启用 GitHub Copilot 的情况下,只要我给出足够的提示(注释),GitHub Copilot 就会快速给出结果。一开始,我觉得这是个不错的方式。但是随着使用的增加,我发现自己在很短的时间里便养成了面向 AI 编程的习惯:更注重注释对代码生成的影响,而不是构思具体的代码实现。这与我想通过本次重构来掌握一门新语言的愿望是相悖的。依赖于 AI 给出的代码结果只会让我产生错觉,认为自己已经掌握了,但实际上并没有。

发现了这种情况后,我只在自己无法独立实现的情况下才会启用 GitHub Copilot 的实时代码生成功能。无论写得好坏,我都会先尝试自己写一遍,然后让 AI 帮助我找到问题,并逐步改进代码的可读性和实用性。在这个过程中,我会向 AI 咨询语法细节,同时让 AI 指导我使用更符合 TypeScript 的编程范式以及更纯正的代码实现方式。

由于同一个功能的代码会被反复创建多次,因此提前创建单元测试非常重要。在不断修改代码的过程中,经常会出现修改或优化错误的情况。有了测试,问题可以及时发现。

在 VSCode 中,无论是 Jest 还是 ViTest,都可以启用自动测试,即在代码修改后可以立即运行一遍测试。希望 Xcode 也能提供类似的能力。

随着 AI 拥有快速编写代码的能力,许多开发者担心自己会被 AI 取代。作为一名开发者,我认为只有保持自身技能的不断提升,展现出 AI 无法替代的价值,才是避免被取代的关键。过度依赖 AI 确实可以在短期内提高某些方面的工作效率或完成之前无法完成的成果,但长期来看,开发者可能会逐渐失去自身优势,最终从 AI 工具的使用者转变为 AI 工具的助手:人肉提示词生成器。

最后

经过这段时间与 AI 产品紧密合作的经历,我深刻认识到了在有效利用 AI 的同时,保持个人技术成长和独立思考的重要性。AI 的迅猛发展是不可阻挡的,它将无疑将在未来( 事实上现在已经开始了 )深刻影响我们的生活和工作的方方面面。在这个 AI 日益普及的时代,那些希望继续蓬勃发展的人必须学会如何妥善利用 AI,并在这个时代发挥和展现自己的独特价值。

博客的重构工作仍在进行中,预计将于年底完成。

每周一晚,与全球开发者同步,掌握 Swift & SwiftUI 最新动向
可随时退订,干净无 spam