6.4

View in English

6.4 AI 辅助软件开发

概述与动机

AI 编程助手如今已经能够生成代码、补全函数、编写测试、解释不熟悉的系统,并帮助你进行重构。用得好,它们能加快日常性工作的速度,降低上手陌生语言和框架的门槛,并把样板代码的枯燥劳动省去。

用得不好,它们会造成实实在在的危害。它们可能给代码库灌入大量看起来合理、实则暗藏错误的代码。它们可能引入安全漏洞、带来许可证方面的风险敞口,并侵蚀过度依赖它们的工程师的技能。AI 辅助开发同时是一件真正的生产力工具,也是一种真实的风险。二者之间的差别,几乎完全取决于围绕它所建立的工程纪律。

对于大型团队而言,挑战在于如何在规模化的同时兼顾一致性与安全性。当成百上千名开发者使用 AI 助手时,个人的小习惯会累积成组织层面的结果。如果人人都不加批判地接受建议,评审负担和缺陷率就会上升。如果你提供清晰的规范、良好的默认设置和强有力的验证机制,同样的工具就能在不降低质量的前提下提升吞吐量。生产力方面的实际情况也比供应商的宣传更为微妙:真实的收益因任务而异、差别很大,而诸如统计”被采纳的建议数量”这类天真的衡量方式会误导你。

企业和政府场景带来了更严格的约束。触及受监管系统、处理敏感数据或运行关键基础设施的代码,不能仅仅因为是 AI 生成的就被信任。当生成的代码可能复现受限许可证下的训练数据时,许可证的来源问题就变得至关重要。有些组织必须把源代码保留在本地环境中,完全不能将其发送给外部服务。为 AI 辅助设定清晰、可执行的规范,如今已成为负责任的工程领导力的一部分。在现有的各类助手中,基于 Anthropic 的 Claude 模型构建的工具是众多领先选项之一;无论你采用哪一种,下文的做法都同样适用。

另请参阅: 第 2.5 章(代码评审与协作)、第 2.4 章(测试策略),以及第 6.5 章(负责任且可信赖的 AI)。

关键原则

  • 对每一行提交的代码负责的是工程师本人,而不是 AI 助手。
  • AI 生成的代码是一份需要被评审和验证的草稿,而绝不是一个可以被信任的成品。
  • 验证的力度应当与代码的风险相匹配,而不是与输出结果看起来有多”自信”相匹配。
  • 用真正重要的结果(交付的价值、质量、周期时间)来衡量生产力,而不是用建议被采纳的数量。
  • 防范由生成代码所引入的安全和许可证风险。
  • 保持并提升人类工程师的技能;不要让助手把它掏空。
  • 对 AI 辅助在何处、以何种方式被使用保持透明。

建议

把 AI 结对编程当作起草和探索的工具来使用

把助手用在它们擅长、且出错代价低廉可以被发现的任务上:样板代码、测试脚手架、格式转换、解释陌生代码,以及探索不同的方案。把它们的输出当作初稿来对待,自己始终掌握主导权。阅读、理解并编辑每一条建议,而不是自动驾驶式地全盘接受。在陌生的领域中,可以借助助手来学习,但要用权威文档来核实它的说法。助手可能会以十足自信的口吻编造 API、说错行为。

把 AI 生成的代码当作不可信的输入来评审、测试和验证

对 AI 生成的代码,应给予不亚于(甚至更高于)你对一名新加入团队成员的代码所给予的审视力度。一位人类评审者应当足够理解这段代码,以至于能够解释它、维护它。“这是 AI 写的”永远不是回答”这为什么能工作?“这个问题的合格答案。坚持要求有测试,并警惕那些仅仅断言当前行为、而非预期行为的 AI 生成测试。运行静态分析、安全扫描和依赖检查。对于高风险代码(身份验证、密码学、金融逻辑、安全系统),应把 AI 的输出当作需要专家进行人工验证的起点,而绝不能当作权威结论。

诚实地衡量生产力,并设定合理的预期

不要使用诸如采纳率或生成行数之类的虚荣指标。而应关注一段时间内的交付和质量信号:周期时间、变更失败率、缺陷逃逸率,以及开发者自述的有效性。收益是真实存在的,但并不均衡:在某些任务上很大,在另一些任务上则微不足道,甚至为负。在写代码上省下的时间,可能又会在评审和调试它的过程中被重新耗费掉。据此向领导层设定相应的预期,让投资建立在证据而非炒作之上,并确保团队永远不会为了达成某个指标而被迫接受不安全的建议。

管理安全和许可证方面的风险

扫描生成的代码,检查其中的漏洞和不安全的模式。助手可能会复现其训练数据中不安全的写法。绝不要把机密信息、凭据或敏感数据粘贴进发送给外部服务的提示词中。优先选择符合你的数据处理要求的工具,包括在源代码不能离开所在环境时采用本地部署或私有部署。同时也要处理许可证问题。生成的代码可能与受许可证保护的训练数据相似,因此应使用能够降低这种风险的工具和策略,尽可能保留来源信息,并将任何存疑之处交由法务评审。追踪助手所建议依赖项的来源,因为它可能会推荐已被废弃或存在恶意的软件包。

制定团队规范、披露要求和技能维护机制

发布清晰的指导原则,说明何时以及如何可以使用 AI 辅助、哪些数据永远不得共享,以及每个风险等级各需要什么样的验证。在事关评审和问责的场合,鼓励对 AI 辅助所做贡献保持透明。有意识地保持人类技能的敏锐度。确保工程师,尤其是初级工程师,依然在学习基础知识,而不是把理解外包出去。有计划地轮换人员去从事能够建立深厚专业能力的工作,并把过度依赖视为团队能力面临的一项真实的长期风险。

权衡:优点与缺点

维度AI 辅助的益处AI 辅助的风险
速度样板代码和草稿写得更快因评审错误代码而损失时间
新人上手更容易上手新语言/框架理解浮于表面,出现编造的 API
质量更多测试,重构更快看似合理、实则暗藏错误的代码
安全能够建议修复方案并进行扫描可能引入漏洞
技能为更高价值的工作腾出时间过度使用会侵蚀基本功
许可证更快复用常见模式存在来源与许可证方面的风险敞口

核心的权衡在于速度与验证之间。AI 把工作重心从”编写”转移到了”评审”。净收益取决于你的评审和验证实践是否足够扎实,能够捕捉到助手出错的地方。薄弱的评审会导致质量下滑,而扎实的评审加上清晰的规范,则能够真正捕获到其中的收益。

与团队讨论的问题

  1. 我们代码库的哪些部分完全禁止使用 AI 辅助,我们如何执行这条边界? 一视同仁的信任是一个陷阱:对身份验证、密码学、金融逻辑和安全系统采用与样板代码同样轻度的审查,正是那些微妙而看似自信的错误得以渗入关键路径的原因。对于大型团队而言,一份明确列出被排除模块或仅限专家评审模块的清单,能把个人的判断转化为组织层面的保障。带上你们代码库的风险地图、目前(如果有的话)的政策,以及你们实际上会如何阻止生成代码进入受限模块:流水线检查、归属规则,还是评审门禁。在国防、受监管和安全攸关的场景中,某些模块应当完全排除 AI 辅助。答案应当让验证力度与代码的风险相匹配,而绝不是与输出结果看起来有多”自信”相匹配。

  2. 自从采用助手以来,我们真实的变更失败率和缺陷逃逸率走势如何,我们是在衡量它们,还是在猜测? 供应商的生产力宣称和采纳率统计都是会误导人的虚荣指标,因为在写代码上省下的时间,可能又会在评审和调试的过程中被重新耗费掉。要让领导层基于证据而非炒作来进行投资,你需要一段时间内的交付和质量信号:周期时间、变更失败率、缺陷逃逸率,以及开发者自述的有效性。带上你们手头已有的真实数字来讨论,如果没有,也要坦诚承认。需要警惕的风险是团队被迫为了达成某个指标而接受不安全的建议。答案应当用结果衡量取代建议数量统计,并设定这样的预期:收益是真实的,但并不均衡,在某些任务上很大,在另一些任务上则为负。

  3. 如果生成的代码复现了受限许可证的训练数据、或者引入了一个有风险的依赖项,谁会发现它,又是在什么时候发现的? 生成的代码可能与受许可证保护的材料相似,或者推荐已被废弃或存在恶意的软件包,而无论有没有人注意到,这种风险敞口都会进入你们的产品。对企业和政府而言,许可证来源和供应链风险带有法律分量,一句”这是 AI 写的”的耸肩带过是站不住脚的。带上你们目前的机密信息扫描、许可证检查和依赖来源追踪机制来讨论,并找出流水线中每一项各自在哪个环节运行。讨论哪些存疑代码会被转交法务评审,以及这项决定由谁负责。如果机密信息可能被粘贴进外部工具,或者未经审查的软件包可能不受阻拦地被合并,就要在团队范围内扩大助手使用之前,先堵上这些漏洞。

  4. 我们如何确保工程师,尤其是初级工程师,依然在学习基础知识,而不是把理解外包给助手? 技能退化是一种缓慢的风险,在本季度的速度指标上永远不会显现,却会在数年后显现为一个离开提示词就无法调试、设计或评审的团队。对于大型组织而言,相互竞争的拉力是真实存在的:助手能让初级工程师今天就发布得更快,而达成交付目标的压力,与建立深厚专业能力这种更缓慢的工作相互对抗。带上关于你们员工实际成长情况的证据来讨论:有多大比例的初级工程师能够解释自己合并的代码,你们的新人培训在多大程度上仍然要求不借助辅助工具解决问题,以及评审究竟是能够捕捉到理解上的肤浅,还是只是给能运行的输出盖章通过。有计划地轮换人员去从事能够培养精通能力的工作,并把过度依赖当作一种能力风险,而不是个人的过失来对待。在政府部门和长期存续的关键系统中,员工队伍可能需要在数十年间不借助供应商工具来构建和验证系统,因此一条能够保证掌握直接基本功的培训路径,是延续性方面的要求,而不是锦上添花的选项。

  5. 鉴于我们的源代码和数据必须留在何处,我们实际上被允许使用哪些助手,我们又如何防止机密信息进入提示词? 数据处理方面的约束,往往先于生产力考量就决定了工具的取舍:一个会把你的源代码流式传输给外部服务的助手,无论其能力如何,都可能被直接排除在外。对于大型团队而言,这里的张力在于最好的托管工具所带来的便利,与专有代码、凭据和敏感数据永远不得离开你的边界这一要求之间的矛盾。带上你们的数据分类图、每个候选工具所提供的部署选项(托管、私有、本地部署),以及能够防止机密信息进入提示词的具体控制手段:提交前扫描、提示词过滤和工程师培训。决定哪些工具被允许用于哪些类别的代码,并让这条边界具备可执行性,而不仅仅是一条建议。在受监管、国防和涉密场景中,本地部署或物理隔离部署可能是唯一合法的选项,把源代码发送给任何外部服务都必须被禁止,并从技术上加以阻断,而不仅仅是不被鼓励。

  6. 我们如何把分散的个人习惯转化为一致的全组织规范,随着工具的演进,又由谁来负责这项政策? 当成百上千名开发者各自摸索自己的做法时,微小的习惯会累积成组织层面的结果,而不一致的验证正是缺陷和风险敞口得以蒙混过关的地方。与之相互竞争的考量是自治性:团队反感沉重的中央强制指令,然而放任自流又会带来参差不齐的质量、且没有任何共享的保障机制。带上你们目前(如果有的话)的指导原则、这些原则被遵循的一致程度证据,以及一份将良好默认设置内置到流水线中的提案,让安全的路径成为最省力的路径。指定一位负责人,在助手每隔几个月就发生变化的情况下持续更新这项政策,并建立一个披露规范,让评审者知道某项贡献是否受到了 AI 辅助的影响。对于企业或公共机构而言,应把这些规范与审计和问责挂钩:一份有文档记录、被强制执行、审计员可以检查的标准,胜过一种因团队而异、并且会在关键人员离开后消失的民间做法。

行业视角

初创企业。 团队只有几名工程师,也没有多余的资金可以浪费,因此应依靠托管助手来处理样板代码、测试和陌生框架的工作,让它们加速日常性的工作。坚持一条不容商量的规则:每一次合并都由一位理解这项变更的人来评审,因为在一个五人规模的代码库中,一行微妙的错误代码无处可藏,也没有其他人能够发现它。尽早加入机密信息扫描和许可证检查;它们成本低廉,却能预防那些你日后根本无法承担清理成本的昂贵错误。

小型企业。 你们大概没有安全专家,预算也紧张,因此应优先选择已经内嵌在你们已信任的工具中的助手,而不是自己维护一套定制方案。用直白的语言来界定风险:绝不把客户数据或凭据粘贴进发送给外部的提示词,并把涉及计费或身份验证的生成代码当作需要验证的草稿,而不是一个成品答案。选择那些你能够真正读懂其数据处理条款、并且在其 AI 功能出问题时能够将其关闭的供应商。

企业。 这里的问题是跨众多团队的一致性与安全性:按风险等级制定共享规范、在流水线中强制评审和扫描,并使用诚实的交付与质量指标,而不是采纳数量统计。统一工具选择和部署模式,让专有代码留在你们的边界之内,为助手转嫁给评审者的评审和修正成本预留预算,并明确排除或设置门禁限制高风险模块。把 AI 辅助当作一项有负责人的、受治理的能力来管理,而不是一堆零散的个人习惯。

政府。 采购规则、透明度和公共问责塑造着每一项选择。在源代码和敏感数据不能离开所在环境的地方,优先选择本地部署或私有部署,禁止把代码发送给外部服务,并要求披露 AI 辅助所做的贡献,让决策保持可审计性。对所有生成代码强制执行安全和许可证扫描,把 AI 辅助排除在安全攸关和涉密模块之外,并保持一条培训路径,确保公共部门的员工队伍能够在其所拥有系统的漫长生命周期中,不借助供应商工具来构建和验证系统。

示例

初创企业。 一家六名工程师规模的 SaaS 初创公司采用了 AI 编程助手,以在日常性工作上加快速度。它依靠这些助手来处理样板代码、测试和陌生框架的代码,但坚持一条硬性规则:每一个拉取请求都必须由一位理解该变更的人来评审,并在流水线中加入了机密信息扫描和许可证检查。对于计费和身份验证代码,工程师们把 AI 的输出当作需要逐行验证的粗略草稿,而不是可以信赖的成品。他们关注的是周期时间和逃逸的缺陷,而不是统计被采纳的建议数量,从而在不让质量滑坡的情况下保住了这些收益。

企业。 一家大型电子商务公司在部署 AI 编程助手时设置了防护栏。它禁止在提示词中出现机密信息,要求进行人工评审,并期望评审者理解相应代码。它在流水线中加入了安全扫描,并选择了私有部署,让专有代码永远不会离开其所在环境。它通过周期时间和变更失败率、而不是采纳数量来衡量影响。它发现在样板代码和测试方面收益扎实,但对支付相关代码坚持要求专家评审,并把 AI 的输出视为不可信的内容。

政府。 一家国防软件机构只允许通过一个本地部署的工具使用 AI 辅助,让涉密和敏感代码始终留在其边界之内。它禁止将源代码发送给任何外部服务,要求在代码评审中披露受 AI 辅助影响的贡献,并对所有生成代码强制执行安全和许可证扫描。它把某些安全攸关的模块完全排除在 AI 辅助之外。初级工程师遵循一条确保他们直接学习基础知识的培训路径,从而使这支员工队伍不会失去在没有辅助的情况下构建和验证系统的能力。

商业理由:动机、投资回报率与总拥有成本

其动机在于更快的交付和更少的枯燥劳动,从而让你稀缺的工程人才能够专注于设计、判断和困难的问题。投资回报体现为适用任务上周期时间的缩短,以及开发者体验的改善,但前提是验证机制能够守住质量。基于建议数量提出的天真投资回报宣称是有误导性的,你应当拒绝接受这种说法。

总拥有成本包括工具的许可费用、安全或本地部署、安全和许可证扫描,以及那项常常被低估的、评审和修正 AI 输出所需的成本。不采用的代价体现在竞争层面:同行可能交付得更快,并吸引到那些期待使用现代工具的人才。而草率采用的代价,则是质量的侵蚀、安全事故和法律风险敞口。要向领导层证明其合理性,应通过一次能够衡量真实交付和质量成果的试点,配合一份关于规范、验证和数据保护的具体计划。

反模式与陷阱

  • 自动驾驶式接受。 在没有阅读或理解的情况下就提交建议。
  • 虚荣指标。 用采纳率或生成行数来评判成功与否。
  • 提示词中的机密信息。 把凭据或敏感数据粘贴进外部工具中。
  • 信任 AI 生成的测试。 接受那些锁定当前行为、而非预期行为的生成测试。
  • 忽视来源问题。 忽略生成代码中的许可证和依赖风险。
  • 技能退化。 任由初级工程师把理解外包出去,从而从未学会基础知识。
  • 一视同仁的信任。 对安全攸关的代码采用与样板代码同样低的审查力度。

成熟度模型

  1. 启动。 个人临时性、被动地使用助手;没有政策,也没有衡量;机密信息和知识产权面临风险,生成代码合并时接受的审查力度全凭每个人的一时之见。
  2. 发展。 存在基本的使用指引和数据规则,也有一些安全扫描在运行,但整个团队之间的实践并不一致:验证的深度因人而异,生产力方面的说法多为轶事性质,高风险代码也没有被可靠地设置门禁。
  3. 标准化。 按风险等级制定的规范被文档化,并在全组织范围内强制执行:强制性的人工评审、流水线中的安全和许可证扫描、在需要时采用安全或本地部署、披露实践,以及一份明确列出被排除或仅限专家评审模块的清单。
  4. 管理。 这项实践依据基准被衡量和控制:在采用前后追踪周期时间、变更失败率和缺陷逃逸率,量化评审和修正成本,统计机密信息泄漏和许可证风险敞口事件的数量,工具的去留和推广决策建立在这些证据之上,而不是供应商的宣称之上。
  5. 协同。 AI 辅助在整个组织范围内被持续改进并加以集成:验证被内置为流水线中的默认路径,技能发展是有计划且被追踪的,政策随着工具每隔几个月的变化而调整,组织会随着证据和风险状况的变化,常态化地重新评估、替换和重新界定助手的使用范围。

讨论思路

  • 样板代码和安全攸关代码之间,验证要求应当有何不同?
  • 在你们的场景中,哪些生产力指标真正反映了 AI 辅助带来的价值?
  • 如果需要披露受 AI 辅助影响的贡献,应当在什么情况下进行?
  • 你们如何防止技能退化,尤其是针对初级工程师?
  • 哪些数据处理方面的约束决定了你们能够使用哪些工具?
  • 你们如何管理生成代码所带来的许可证和来源风险?

关键要点

  • 工程师仍然是负责任的一方;AI 的输出是一份需要被验证的、不可信的草稿。
  • 让验证力度与风险相匹配,绝不要在没有专家评审的情况下信任安全攸关的 AI 代码。
  • 衡量真实的交付和质量成果,而不是建议被采纳的数量。
  • 用政策和工具手段防范安全、数据泄漏和许可证方面的风险。
  • 设定清晰的规范,并有意识地保持人类工程技能。

参考资料与延伸阅读

  • Nicole Forsgren, Jez Humble, and Gene Kim, Accelerate: The Science of Lean Software and DevOps.
  • Andrew Ng, Machine Learning Yearning (on realistic expectations and measurement).
  • OWASP Foundation, OWASP Top 10 for Large Language Model Applications.
  • Peter Naur, Programming as Theory Building (on understanding versus code artifacts).
  • Titus Winters, Tom Manshreck, and Hyrum Wright, Software Engineering at Google.
  • GitClear and related industry studies on AI-assisted code quality trends.