将AI集成到应用开发中的核心挑战,不在于其协助能力,而在于我们能在多大程度上放心地将控制权委托给它。
尽管AI智能体可以完美地执行那些曾被认为人类专属的任务,但它们同样可能在紧接着的下一段代码中犯下令人震惊的错误。
这些错误尖锐地提醒我们,即使是最先进的AI编程助手,仍然缺乏对世界运行方式的理解。这一根本区别将当前的生成式AI与通用人工智能(AGI)的愿景区分开来。考虑到这一点,让我们来看看AI智能体如何成为出色的开发加速器,却无法取代人类开发者。
LLM的推理并非逻辑推理
即使是复杂的智能体AI——构建于拥有日益庞大的上下文窗口和复杂工作流程的大型语言模型(LLM)之上——也依赖于语义模式匹配。它们无法对底层的因果关系和相互依赖提供真正的洞见。
让人类难以理解这一点的是,LLM在阐述其决策过程时具有令人信服的方式,常常模仿一种逻辑递进,暗示其对因果关系的理解,而实际上它们并不具备这种理解。它们通过拼凑统计上可能性高的人类推理文本片段来实现这一点。虽然这看起来像是逻辑推理,但它基于从训练数据中得出的概率计算,而非对步骤之间因果关系的直接理解。
LLM模仿逻辑推理,但无法掌握因果关系。
将这比作一位主演医疗电视剧的演员,他多年来记住了数千小时的对话、纪录片和真实咨询记录。他可以完美地进行鉴别诊断,像经验丰富的医生一样自信地用专业词汇滔滔不绝地说出症状、检测结果和治疗方案。他知道"向左臂放射的胸痛"通常出现在关于心脏病的场景中,"全血细胞计数和代谢指标组"跟在"我们来做些检查"之后,而担忧的表情伴随着关于肿瘤的讨论。
一位对医疗话题表现出表面理解的医疗剧演员,是比喻AI无法掌握因果关系的绝佳例子。
他们的表演如此令人信服,以至于任何观众都会相信他们懂医。但他们根本不知道阿司匹林为什么能稀释血液,心脏病发作时会发生什么,或者为什么一种治疗有效而另一种会致命。他们只是在背诵他们记住的各种医疗对话的变体,拼凑那些在统计上共同出现的片段,却不理解这些模式代表了真实的生物过程,其中顺序和因果关系 literally 意味着生与死。翻译到应用开发中,这通常意味着出色的结果之后紧接着灾难性的失败,反之亦然。
统计模式而非因果真相
LLM非常擅长在难以想象的大量文本中寻找并连接模式。尽管这些文本中有许多描述了世界的运作方式,但LLM并不理解这些描述的实际含义。相反,它将文本转换成数字——向量——这些数字捕获的是统计关系,而非因果真相。然后,模型将这些数字翻译回人类语言,而在这一切之下,它始终只是在跟踪和 shuffling 数字,而不是意义。例如,"charge"、"payment"和"credit card"这些词可能在向量空间中位置接近,因为它们经常在文本中共同出现,而"profile"、"lookup"和"fetch"则形成另一个集群——但模型实际上并不知道一组涉及金钱,而另一组不涉及。
LLM只处理词组之间的统计关系。
事物并非表面所见
由于编程语言是高度结构化的,这种数值上的 shuffling 可以产生优秀的代码。虽然AI模型并不像开发者那样"理解"代码,但它可以可靠地将输入模式映射到输出,将框架映射到样板代码,将语法映射到语义,其方式常常看起来与人类代码无异。例如,当被要求"用Python和Flask构建一个REST API"时,模型无法推理HTTP或数据库——它只是回忆起@app.route
通常出现在函数定义之前,GET请求常常映射到返回jsonify
,而错误处理经常涉及try/except
块。结果往往是结构良好的Flask代码,即使它源于模式回忆而非真正的理解。
人类需要保持在循环中,以应对AI缺失的上下文和推理能力。
例如,为重试逻辑加固微服务听起来很简单——然而实际情况并非如此。要求AI助手"在失败时添加重试",你可能会得到一段在任何错误时都重试所有操作的代码。这对于幂等的(或无状态的)读取操作(例如"获取配置文件")来说没问题,因为重复调用只会返回相同的数据。
将相同的逻辑应用于非幂等操作——扣款、创建订单、发送电子邮件、查询数据库——你就会招致灾难:重复扣款、重复订单、通知风暴、数据库中的重复记录。解决方法并非魔术,而是判断力。人类首先对操作进行分类——幂等与非幂等——仅在瞬态错误时重试,并且对于任何有副作用的操作,都需要幂等性密钥和服务端去重。虽然这仍然为人类开发者节省大量时间,但他们仍然需要将其技能和专业知知融入其中,否则灾难可能并且将会随机发生。
理解模式匹配的局限性很棘手
原则上,模式匹配难道不能识别出对信用卡扣款需要采用与检索客户资料或产品信息不同的API调用重试方法吗?是的,它可以,但人类无法事先知道这一点,因为这取决于该特定模型的训练数据是否包含了执行标准POST或GET请求的重试函数。
模型未能建立操作类型与其现实后果之间的联系;它仅仅回忆统计关联。为了让模型避免这个错误,训练数据需要包含清晰、一致且重复出现的配对,将操作类型与重试策略及其后果联系起来。
理想情况下,数据会明确对比可以安全重试的代码与必须避免重试的代码。或许它还包括了事后分析或警告,描述了误用重试时发生的情况。然而,模型是否摄入了足够的训练数据来做出这种区分,我们人类无法确定。更棘手的是,由于其概率性质,模型可能在某一次做出了区分,但在接下来的三次尝试中却没有。
这个例子说明了为什么简单地添加更多训练数据通常不是答案,因为必要的数据可能并不以书面形式存在。或者更糟的是,训练数据可能包含了强化错误概括的内容。无论哪种情况,人类用户都无法知道是否如此,并且需要全面理解特定问题应如何解决。
AI的价值是真实的,开发团队可以受益
只要清楚地理解其局限性,AI智能体可以显著提高人类开发者在整个开发生命周期中的生产力。从收集需求并将其转化为用户故事,一直到检测并部署应用程序,AI智能体可以为人类提供建议、自动化验证和快速原型设计,从而显著缩短迭代周期。
AI智能体应被视为力量倍增器,可以处理开发的机械性方面,例如基于现有示例和文档生成样板代码、编写测试用例和记录API。另一方面,人类则负责真正理解业务影响、决定架构权衡,以及解决需要应用抽象逻辑能力的复杂问题。
AI对SDLC的生产力影响
下表分析了AI对软件开发生命周期(SDLC)中不同活动的生产力影响,以及AI对每项活动的能力、所需的人力参与程度和每项活动的风险水平。
AI对SDLC活动的生产力影响
活动 | AI的生产力影响 | AI能力描述 | 人力参与需求 | 风险水平 |
---|---|---|---|---|
需求收集 | 低 – 中 | 根据笔记、会议记录、电子邮件和其他材料生成用户故事。 | 高 – 确保故事在成本、风险和回报方面与当前业务优先级保持一致。 | 高 – 被误解的需求将贯穿整个项目。 |
架构与设计 | 低 | 建议模式、识别瓶颈并生成初始图表,作为人类构建的坚实起点。 | 关键 – 考虑系统范围影响、做出战略权衡并监控技术趋势。 | 高 – 糟糕的架构决策难以逆转且成本高昂。 |
代码生成 | 高 | 构建定义良好的样板代码并解决精确定义的问题。保持文档更新。 | 中 – 掌控业务逻辑和边缘情况。 | 中 – 通常难以完全掌控AI编写的代码。 |
代码审查 | 中 | 捕获语法错误、发现安全漏洞、发现性能问题并建议优化。 | 高 – AI会遗漏依赖于上下文的问题和架构问题。 | 中 – 人类需要对审查负全责。 |
测试 | 高 | 创建单元测试、集成测试、自动化回归测试并发现边缘情况。 | 低 – 对于测试生成,但 高 – 对于测试策略。 | 中 – 人类必须对测试的完整性和相关性负责。 |
调试 | 高 | 分析堆栈跟踪并就已知错误建议修复方法。 | 中 – 指导调试过程。 | 低 – 错误的修复通常很容易发现。 |
文档编写 | 高 | 生成API文档、自述文件、内联注释、用户指南和变更日志。 | 低 – 对于面向用户的文档。 | 低 – 不正确的文档通常可以在没有重大影响的情况下得到纠正。 |
部署与CI/CD | 中 | 创建部署清单、构建IaC模板、生成流水线配置。 | 高 – 生产部署需要仔细检查。 | 高 – 任何问题都会直接影响生产环境。 |
监控 | 中 | 添加检测、分析日志并生成警报规则。 | 中 – AI在没有上下文的情况下难以确定优先级。 | 中 – 误报会浪费时间。 |
来源:Torsten Volk, Omdia • 获取数据 • 使用 Datawrapper 创建
结论
宣布AI智能体正在接管开发者工作的技术领导者们,对AI当前能力产生了不切实际的期望。这导致许多企业高管认为开发者工时不再是他们所能构建内容的限制因素。金融分析师可以创建自己的投资组合再平衡工具;医疗保健管理员可以构建患者排班系统;供应链经理可以开发库存优化仪表板;或者营销总监可以构建个性化的活动自动化平台,而无需编写一行代码。虽然他们可以为许多此类业务任务实现概念验证,但架构、开发和交付企业级软件仍然极大地依赖于人类开发者的技能和经验。
然而,AI智能体可以通过为人类开发者完成大量基础性工作来显著加速SDLC。创建测试用例、用监控代理自动检测复杂软件、记录数万行主机代码以及精确定义复杂的基础设施清单,仅仅是AI智能体可以帮助人类开发者的几个例子。
人类与AI智能体之间的SDLC必须是协作的、迭代的并接受持续监督。确定如何最优地调整流程、开发工具和企业文化以满足这些要求,是智能体辅助应用开发的下一个前沿领域。弄清楚如何为人类编码者提供最佳AI支持,其回报有望带来显著的生产力提升,使人类开发团队能够更快、更高质量地交付更多功能。
[注]本文译自: AI agents are accelerators, not developer replacements