AI时代,解决正确的问题
在AI之前,实施能力是稀缺的。一个糟糕的需求可能会浪费几个工程师的时间。有了AI,这种能力会大幅扩展。一个糟糕的需求现在可以非常便宜地产生数百个错误的更改。因此,瓶颈向上游移动:朝着问题定义、上下文、约束、决策和验证方向。
如果方向错了,所有额外的速度只会让你更快地到达错误的地方。
目标是在实施之前尽可能减少不确定性。一个决策越难以逆转,它就越值得准备。
本文介绍了一个实用的框架,通过6个步骤实现这一点。每个步骤产生一个简短的文档,使决策变得明确、持久,并且人类和代理都可以使用。这是理解、决定和同意的内容的共享记录。
有了这个框架,你可以构建:
- 正确的东西:真正解决实际问题的解决方案。
- 正确的方式:不浪费金钱、时间或资源。
- 尽可能高效:在开发过程中有足够的清晰度,以防止返工、等待或猜测。
结果是协调一致。人类和AI代理都从同一本手册工作:对问题和预期解决方案的清晰、共同的理解。这可以防止猜测、返工和意外。
1、为什么这很重要
软件开发中最困难的问题很少是纯粹的技术问题。它们是关于沟通和协调:将模糊的问题转化为正确解决方案的关键组成部分。即使是最优秀的工程师,如果利益相关者无法就他们正在构建什么、为什么或为谁而达成一致,也无法挽救一个项目。不协调会拖慢团队速度,使优秀的工程师筋疲力尽,因为他们缺乏完成工作所需的结构和方向。
涉及代理使这些风险更大。一个在错误方向上工作一天的工程师可能造成的损害有限。同一个工程师部署一整队代理可以造成更大的损害:一个错误的假设不再停留在一个文件中,它会被复制到每个代理生成的更改中,在人类审查之前触及相同的模式。
然而,许多团队将需求视为一次性的事件,然后冲刺进入开发,假设其余部分会自行解决。你不会没有蓝图就建造房子。为什么你会在没有适当准备的情况下构建软件项目?
是的,这需要前期投资。但"我们没有时间"一旦你计算了合规违规、声誉损害、竞争优势和大规模返工的成本,往往会被证明是一句非常昂贵的话。
2、错误的代价
在需要的地方投入精力
并非每个决策都值得相同程度的分析。这是框架背后的原则之一:
一个决策越难以逆转,在做出决策之前你就应该消除越多的不确定性。
选择按钮上的标签是高度可逆的。快速决定,如果需要的话以后调整。选择数据契约、系统边界或集成架构可能不是,而且纠正错误的代价很高。这就是需要仔细审查的地方。
这并不意味着预测一切。这意味着在错误决策会实际让你付出代价的地方投入准备精力,并有意地让其余部分保持灵活。
3、何时使用此框架
并非每个软件更改都需要六个文档。
错误修复、小型内部脚本或一次性原型通常不值得这种程度的准备。对每个更改应用完整框架会产生官僚主义而不是清晰度。
当错误方向的代价很大时,框架变得有价值。当以下几项为真时使用它:
- 多个利益相关者或团队需要协调。
- 问题或期望的结果不明确。
- 解决方案依赖于现有系统、数据或组织约束。
- 重要的架构或数据决策将难以逆转。
- 多个人或AI代理将并行工作。
- 错误可能造成重大的财务、运营、合规或声誉损害。
- 项目足够大,返工会实质性地影响其结果。
你也不必以相同的详细程度使用每个步骤。对于相对较小的项目,框架可能只是几页决策。对于大型复杂项目,每个步骤可能需要大量的发现和讨论。
重点不是完成六个文档,而是在开始实施之前减少重要的不确定性。
当协调和错误的代价证明其合理时,使用该框架。
该框架不是实验的替代品。当假设不确定时,原型、探索或其他实验可能是减少不确定性的最快方式。结果应该反馈到相关步骤中,而不是默默地改变项目的方向。
4、框架
项目准备框架通过一次处理一个决策领域来系统地减少不确定性。每个步骤都在前一个步骤的基础上构建,将最重要的问题提前,同时变更成本仍然较低。解释、假设、决策和推理记录在相关利益相关者可以审查的共享文件中。
该框架是顺序的,但不是瀑布式的。后续发现可以使之前的决策无效。当这种情况发生时,返回、更新受影响的工件并使更改的决策变得明确。目标不是防止变更,而是防止未确认的变更。
下表是框架的概览。
前四个步骤确立了我们所知道的和我们打算构建的内容。这些步骤已经涉及决策和决策所有权。因此,第5步不引入治理。它将构建、启动和运行解决方案所需的决策结构转化为明确的协议。
人们应该能够质疑决策,但分歧应该导致决策者做出决定,而不是让决策在某人的收件箱中无人回应。
5、框架逐步详解
在本章中,我们将逐步介绍框架。每个步骤详细说明了目标、"战事故事"/示例、从该故事中学到的经验教训以及如何创建文档的说明。
我创建了GitHub上的项目准备框架仓库,其中包含关于框架中每个步骤的单页文档和一些"战事故事"。我非常希望将其作为一个社区项目,所以如果你有鼓舞人心的故事、改进或补充,请贡献。
5.1 业务前提条件
为解决正确的问题奠定基础
这一步解决了最昂贵的项目失败之一:解决错误的问题。它确保你专注于真正的业务问题,即利益相关者实际想要解决的问题,并有明确的范围。它尽早获得支持和协调,防止在没人需要的东西上浪费精力。
工程师可以阅读生成的文档来理解他们工作背后的"为什么",这使得日常决策更容易,开发更清晰,歧义更少,风险更低。
Webhook一位客户曾经告诉我们他们急需一个webhook。我们放下一切开始构建。当我们完成时,发现客户并不真正知道什么是webhook,他们实际上需要的是一个API。 我们向一个不存在的问题交付了一个完美的技术解决方案。
经验教训 客户拥有问题,你拥有解决方案。如果你让客户定义解决方案,你就没有做好你的工作。关于业务目标的简短采访本可以立即发现这一点。
如何做: 创建 PID.md(产品启动文档),定义业务问题、目标、用户和成功指标。
5.2 IT前提条件
我们能在现有环境中解决这个问题吗?
几乎每个解决方案都必须与现有系统和流程集成。成功与否在很大程度上取决于现有环境实际上能够支持什么。
这一步通过理解数据、系统和依赖关系来评估在现有环境中解决问题的可行性。我们确保每个利益相关者在开发开始之前都了解什么是可能的,什么是不可能的。
实时仪表板我们花了几个冲刺构建一个系统来处理实时数据以用于仪表板。结果发现数据源根本无法提供实时数据,只能每12小时提供一批。产品运行完美,只是无法插入公司现有的生态系统。
经验教训 这正是你想要尽早失败的事情。理想情况下,我们会发现我们"正在为一个没有铁路的组织建造火车"。
如何做: 创建 discovery-report.md,在技术问题破坏项目之前主动发现它们。
5.3 功能需求
解决方案必须实现什么?
在这里我们定义解决方案实际必须能够做什么。我们的目标是在优化实现之前理解用户、预期行为、频率和范围。用户故事对此很有帮助。这里的清晰度也使下一步变得更容易,因为理解良好的能力和目标更容易转化为技术决策。
这是我经常看到被跳过的步骤。热情的工程师被技术可能性所吸引,忽视了客户实际要求的内容。
基本自动化我们曾经花了几个冲刺完全自动化一个每个人都认为至关重要的流程。最终,我们花了100多小时自动化一些每月只需要10分钟手动完成的事情。 此外,还创建了一个漂亮的UI。第一个问题是是否有可用的API。他们自己就是开发人员,从未打算使用UI。
经验教训 跳过功能需求,你冒着在客户需要自行车时交付法拉利(带有法拉利价格标签)的风险。
在打开IDE之前,确保了解用户是谁,他们希望如何使用解决方案以及使用频率。能发现这个问题的对话只需要几分钟,而重建则需要几周时间。
如何做: 创建 functional-requirements.md 并在其中总结所有要求。还要添加用户故事列表,确定某些用户希望如何、以及多久使用一次解决方案。
5.4 技术需求
如何使解决方案成为现实?
有了前几步的文档,大部分迷雾已经消散,你的技术选择方向应该相当明确。尽管如此,将其转化为具体计划并做出深思熟虑的技术选择仍然至关重要,将每个前面的步骤联系起来:"我们的业务目标是X,我们现有的系统做Y,我们的功能需求说Z,所以这就是我们需要构建的"。
架构发生在构建之前,而不是期间。
跳过这个,你会在半成品上进行心脏手术,在构建过程中改变方向,或者在午夜修补你应该在几个月前发现的漏洞,以赶上截止日期。
数据库心脏手术我们选择PostgreSQL是因为它是我们团队的默认选择。后来我们发现领域模型在不同客户之间根本不同且变化频繁。我们已经将这些假设深深地编码到我们的模式和应用程序中。最终的迁移并不困难,因为PostgreSQL是一个糟糕的数据库。它之所以困难,是因为我们在理解领域之前做出了昂贵的架构决策。
经验教训: 适合这项工作的工具不是你最了解的那个,而是适合问题的那个。关于数据模型及其预期演变的几次对话本可以节省数周的返工和数据库迁移。
如何做: 这一步是关于在组织约束内为你的解决方案选择最佳技术契合点。在 technical-requirements.md 中总结你的发现和背后的推理。对于每个重要决策,问 "如果我们做错了,以后更改的成本会是多少?"
5.5 治理
谁做什么,谁决定?
至此,业务问题、环境、功能需求和技术方向都已经处理完毕。现在我们使执行的决策结构变得明确。没有治理,即使是最周密的计划也会因为混乱、延迟和缺乏责任而瓦解。治理不是官僚主义,而是赋能行动。
绕圈子一个项目停滞了几周,因为没人知道谁可以批准关键的设计变更。请求在三个团队之间的电子邮件链中流传,每个人都假设其他人有权限。当找到合适的人时,截止日期早已过去,导致客户失望和团队沮丧。
经验教训 当没人确定谁做决定或谁需要参与时,决策会陷入困境并消亡。一个RACI矩阵或关于谁负责的简短会议本可以节省数周的麻烦。
如何做: 创建 governance.md,明确决策、升级、沟通和批准。包括一个 RACI矩阵,详细说明每个剩余决策的负责人、问责人、咨询人和通知人,以及早期步骤中如果他们领域出现问题时需要继续参与的人员。这些共同使项目保持前进,而不是在某人的邮箱中停滞。
5.6 规划
何时、按什么顺序、由谁?
至此你已经了解了要构建什么、为什么重要以及必须在什么约束下构建。现在我们将解决方案分解为可操作的任务,具有明确的依赖关系、时间表和所有者。目标是制定一个具有明确任务的路线图,允许代理或同事同时处理许多任务,从而顺利到达终点线。
跳过这一步,你最终会得到相互等待的团队、太大或太模糊的任务,以及错过截止日期。
一团糟我们开始了一个看起来简单的项目,每个人都立即开始工作。没有人先映射依赖关系:两个开发人员构建了依赖于尚未设计的API的功能。另一个团队集成到后来改变的接口。当我们发现问题时,几个人必须停止、撤销工作并按正确的顺序重做。
经验教训 如果我们能在任何人开始编码之前弄清楚谁需要什么、从谁那里得到以及按什么顺序,我们本可以避免这种堆积。良好的规划使依赖关系、排序和交付成果变得明确和可见。在我们的情况下,这将节省很多沮丧和浪费的时间。
如何做: 一个好的任务应该小到可以理解,有明确的结果,并且使其依赖关系显而易见。这让人或编码代理能够在可能的情况下独立工作,而不是每个人都排队在同一个瓶颈后面。
6、整合
框架实践
考虑一个想要构建AI辅助系统来处理传入案例的组织。最初的请求听起来很简单:"使用AI读取传入文档,提取相关信息,并自动决定如何处理每个案例。"
团队可以立即开始构建。相反,他们通过框架工作。
立即构建,这会以熟悉的方式出错。几周后,源文档变得不一致,关键数据在另一个系统中,案件工作人员实际上不希望AI做决定。他们希望帮助找到缺失的信息并确定他们的队列优先级。法律要求人在循环中,这使得架构现在难以添加。团队围绕没人检查的需求构建了技术上令人印象深刻的东西。
而是通过框架运行,每个这样的发现都会在变得昂贵之前浮出水面。
- 业务前提条件揭示了真正的问题:不是"自动化决策",而是"减少手动准备时间,同时让案件工作人员负责"。
- IT前提条件在任何代码依赖于它们之前,揭示数据不一致性和解决方案必须适应的身份模型。
- 功能需求将范围缩小到分类、摘要和可追溯性,放弃没人需要的自主决策。
- 技术需求从一开始就将人在循环中和可追溯性构建到架构中,而不是以后改造。
- 治理分配所有权,这样"AI能决定这个吗?"在生产中提出之前就有答案。
- 规划安排工作顺序,以便在团队扩大规模之前验证文档质量假设。
理想情况下,所有这些都不比上面的版本花费更多时间。它只是在实施之前而不是之后花费时间,当纠正错误的假设不再便宜时。
7、结束语
AI使实施变得便宜。因此,决定实施什么变得更加重要。
AI使实施变得更快、更便宜。只有当它指向正确的问题时,这种能力才有价值。项目准备框架并不能消除不确定性,它帮助团队找到真正重要的不确定性。它使由此产生的决策变得明确,并保存人类和AI代理需要在文档中行动的上下文。
项目准备框架是应对此转变的一种方式。它并不试图消除不确定性、预测一切或将开发变成严格的瀑布流程。它帮助团队识别重要的不确定性、做出明确的重要决策、分配所有权,并保存人类和AI代理有效工作所需的上下文。
优秀的工程从来不是关于编写最多的代码或花费最多的令牌。现在比以往任何时候都更多地,它是关于在约束下做出好的决策,并将这些决策转化为创造真正价值的系统。代理软件开发不会改变这一点,它只是提高了犯错的价格。
在你的下一个计划中尝试项目准备框架。如果它有问题、你有建议或改进,或者想分享战事故事,请在仓库中提出问题。
原文链接:Solving the Right Problem in the Age of AI
汇智网 翻译整理,仅供学习交流之用。