单位 3 / 12

使用人工智能进行编码和结对编程

收益:

  • 能够通过清晰的输入输出和约束定义将函数、类和模块写入人工智能
  • 能够使用人工智能作为结对编程伙伴,并以可验证的小块逐步取得进展
  • 能够通过编译人工智能生成的代码并通过小示例运行来捕获逻辑和边缘情况错误

结对编程是指两名开发人员处理同一问题,其中一名开发人员编写,另一名开发人员修改。使用人工智能进行编码是这种关系的数字版本:您设定方向、约束和验收标准; AI快速生成草稿;您可以通过编译和测试来验证每个步骤。这里最大的陷阱是告诉AI“从头到尾给我写这个应用程序”并盲目接受200行的块。良好的结对编程分小步进行:每个步骤都应该是可理解的、可测试的和可逆的。

在本单元中,您将学习如何使用清晰的输入输出契约打印函数、类和模块;如何一步步引导AI;我们将了解如何通过使用小示例运行它生成的代码来捕获逻辑和边缘情况错误。目标不是速度,而是经过验证的速度。

概念: 输入输出契约:函数接受什么输入以及它承诺什么输出和错误行为的明确定义。边缘情况:不常见但实际可能发生的输入(空、零、负、非常大、空)。增量开发:从小的工作片段开始并验证每个步骤。

使用网络合约打印代码

高质量代码的基础是在开始工作之前准确定义“你想要什么”。当为 AI 编写函数时,请给出五件事:语言和版本、输入类型和含义、输出、错误条件和约束(性能、外部库禁令、风格)。这可以防止AI猜测。

  1. 写合同。输入、输出、错误、约束。
  2. 要求一个小单位。具有单一职责的功能;这不是一个巨大的模块。
  3. 请求测试块。在代码旁边添加一些示例运行/测试。
  4. 编译并运行。尝试使用边缘情况,用眼睛验证输出。
  5. 转到下一步。一旦一件作品被确认,就在它的基础上进行构建。

合约函数提示:“为 TypeScript 5 编写一个函数。目的:计算购物车中商品的总数。输入:{price: number, amount: number }[] 数组。输出:number(总计)。规则:如果数量或价格为负,则抛出错误;如果为空数组,则返回 0;如果小数错误,则将金额四舍五入到小数点后两位。不要使用外部库。在函数下方添加 5 个测试用例(正常、空、负数量、小数价格、单品)。”

结对指导人工智能

结对编程的良好进展是一种对话,而不是一个大的要求。首先,请求骨架并运行;然后添加边缘状态;然后修复错误。这种方法使代码易于理解,并让您掌控每一步。

增量进度提示:“我们将编写一个读取器,读取 CSV 文件并将行转换为对象。让我们逐步进行,无需我确认每一步即可继续下一步。第 1 步:只需编写将文件拆分为行并分隔标题行的框架。暂时不要添加类型转换或错误处理。保持简短,解释一下。”

解释并证明代码提示的合理性:“解释你刚刚编写的函数,不是逐行解释,而是逐个决策:你做出了哪些设计决策以及原因,你处理了哪些边缘情况以及如何处理,你故意排除了哪些情况?列出代码中我不应该错过的 3 个假设。”

提示:不要在不理解人工智能生成的代码的情况下接受它。 “给我解释一下,你做了什么假设?”该问题既揭示了隐藏的错误,又允许您捍卫该代码,因为该代码仍然是您的责任。将你不理解的代码投入生产就像发送一份合同而不签署它。

弱提示/强提示

弱:“编写一个排序函数。”(结果:哪种语言,正在排序什么,是否稳定,性能约束是什么,代码模糊并且可能不符合要求。)强:“对于 Java 17,编写一个方法,首先按部门(字母顺序)然后按工资(降序)对 List<Employee> 对象进行排序。不要替换原始列表,返回新列表。让空部门排在最后。在注释中解释该方法的复杂性行指定添加一个包含 4 个样本的主测试块。”

强大的提示功能;包括排序标准(两级)、副作用规则(替换原来的)、空行为和测试期望。如果没有这些细节,人工智能就会产生一个看似合理但不正确的解决方案;例如,它可能会损坏原始列表,这将导致其他地方出现无提示错误。

使用边缘情况和小样本进行验证

在愉快的场景中工作的代码不是正确的代码。有意识地强制每个功能产生:

边缘情况类型

输入样本

预期行为

空白输入

空数组/字符串

不是错误,逻辑空结果

零/负

0, -1

定义和正确的行为

很有价值

数百万条记录

溢出/性能控制

空/未定义

缺少空间

受控错误或默认

重复/异常

重复、颠倒顺序

正确结果

迷你箱

情况 1 — 无提示舍入错误。 AI写了一个用小数(浮点)类型收钱的函数; 0.1 + 0.2 得出 0.30000000000000004。当工程师添加规则“四舍五入到 2 位数字并使用整便士”时,该错误得到解决。 3 行规则可以防止每月对账中出现数千美分的差异。

案例 2 — 副作用陷阱。 AI 编写了一种对列表进行“排序”的方法,但会就地修改原始列表。由于另一个模块使用相同的列表,因此出现意外行为。如果提示中包含“更改原始”约束,则该错误永远不会发生;陷入代码审查并妨碍 2 小时的调试。

案例3——逐级盈利。开发人员一次打印150行导入模块;当他发现错误时,他无法找到错误的来源。另一位开发人员将相同的工作分为 5 个小步骤,在 2 分钟内测试每个步骤,并在第 3 步中立即捕获错误。

常见错误

  • 在一个请求中打印大块。难以理解和调试的危险代码就这样诞生了。
  • 索要代码而不提供合同。如果输入-输出-错误不明确,人工智能就会猜测并出错。
  • 只是测试快乐的场景。如果未尝试空、空、负和大输入,则错误将留给生产。
  • 不理解就接受。您不披露的代码是您无法捍卫的债务。
  • 忽略副作用和金钱/日期等敏感类型。具有永恒历史的浮动货币是一个典型的错误来源。

综上所述

使用人工智能编写代码是一种严格的结对编程:清晰的契约、小步骤、每一步的构建和测试。从一开始就给出输入输出错误约束四重奏决定了代码的质量。解释它生成的代码并用边缘情况强制它使隐藏在快乐场景下的错误浮出水面。速度的源泉不是盲目的接受;是快速草稿加上快速验证。

应用任务

选择一个小但真实的函数(例如购物篮总计、日期差异、文本解析)。使用收缩的功能提示进行打印;旁边添加至少 5 个测试场景。使用表格作为指导,运行代码并有意识地尝试 5 个边缘情况。至少在一种边缘情况下找到错误(如果没有,请设计一个新的输入来强制执行该功能),使用人工智能修复它,并通过重新测试来验证修复是否有效。

清单

  • [ ] 我写了一份合约,其中包括输入、输出、错误和约束。
  • [ ] 我以一小步而不是一大块的方式生成了代码。
  • [ ] 我在代码旁边添加了一个测试/示例运行块。
  • [ ] 我有意识地测试了至少 5 个边缘情况。
  • [ ] 我向 AI 解释了代码并回顾了它的假设。
  • [ ] 我纠正了发现的错误,并通过重新测试确认了修复。