AI时代,为何软件工程基础依旧重要? AI时代为何软件工程基础依旧重要摘要在AI编程工具快速发展的背景下一种观点认为代码可以变得廉价软件开发流程应当从传统的设计-编码-测试转向规格描述-AI生成代码的范式。然而实践经验表明这种观点忽略了软件工程中的若干基础原则。本文基于AI工程实践中的经验总结系统梳理了GRIME需求澄清技能、普适语言Ubiquitous Language技能、测试驱动开发TDD作为AI反馈循环约束、以及深层模块Deep Modules接口设计委托法等实践方法并分析了软件熵、设计概念等核心概念在AI辅助开发场景下的意义。本文的核心论点是AI工具并未降低软件工程基础的重要性反而对代码质量、模块设计和反馈机制提出了更高要求。高质量的代码库能够显著提升AI编程效能而糟糕的代码库则会阻碍AI价值的充分发挥。技术原理与核心方法2.1 GRIME需求澄清技能GRIMERequirement Clarification Skill是一种通过与AI进行逐层深入提问、直至达成共同设计概念Shared Design Concept的交互方法。其核心思想是AI不应急于进入编码阶段而应主动对用户的需求进行系统性提问逐层剖析设计决策树中的每个分支直到双方对系统架构达成共识。该方法的流程可描述如下# GRIME 需求澄清流程伪代码defgrime_requirement_clarification(user_initial_plan): GRIME 需求澄清技能主流程 参数: user_initial_plan: 用户的初步计划或想法自然语言描述 返回: 可转化为PRD的对话内容 design_treeparse_design_tree(user_initial_plan)questions[]# 逐层分析设计树的每个分支forbranchindesign_tree.branches:# AI针对每个细节提出问题branch_questionsgenerate_questions(branch)questions.extend(branch_questions)# 逐个解决决策之间的依赖关系resolved_decisions[]forquestioninquestions:answerask_user(question)resolved_decisions.append(resolve_dependency(question,answer))# 持续提问直到双方满意可达40-100个问题whilenotconsensus_reached(resolved_decisions):follow_upsgenerate_follow_ups(resolved_decisions)forfuinfollow_ups:answerask_user(fu)resolved_decisions.append(answer)# 达成共同设计概念shared_conceptbuild_shared_concept(resolved_decisions)# 产出物可转化为PRD的对话内容returnconvert_to_prd(shared_concept)GRIME方法的关键在于提问而非执行。传统的AI编程工具倾向于在收到需求后立即开始生成代码而GRIME要求AI先成为提问者通过系统性提问来消除需求中的模糊性和隐含假设。2.2 软件熵与设计概念软件熵Software Entropy是本文引用的核心概念之一源自《实用程序员》The Pragmatic Programmer。其定义为事物趋向混乱和崩溃的自然趋势。在软件工程语境下软件熵表现为代码库随每次局部修改而逐渐劣化的现象——每次为修复bug或添加功能而做的临时改动都可能引入新的复杂性使得后续修改更加困难。设计概念Design Concept源自弗雷德里克·P·布鲁克斯Frederick P. Brooks的《设计之设计》。其定义为多人共同设计某物时在参与者之间流转的、关于所构建事物的瞬态概念。设计概念不是可写入文档的静态资产而是构建事物过程中参与者的隐形理论。在AI辅助开发场景中这两个概念具有特殊意义软件熵在AI生成代码的场景下加速增长如果开发者不审查AI生成的代码直接将其纳入代码库代码质量会持续下降。设计概念在人与AI协作中更为脆弱AI无法像人类团队成员一样共享设计概念因此需要通过显式的沟通机制如GRIME来建立和维护。2.3 普适语言技能Ubiquitous Language Skill普适语言技能基于领域驱动设计DDD中的普适语言概念。在DDD中普适语言指开发团队内部对话、代码表达及与领域专家交流均源自同一领域模型确保术语的一致性。在AI辅助开发场景中普适语言技能的工作流程如下# 普适语言技能实现流程defubiquitous_language_skill(codebase_path): 普适语言技能扫描代码库生成术语表 参数: codebase_path: 代码库根目录路径 返回: 普适语言markdown文件路径 # 1. 扫描代码库查找专业术语termsscan_codebase_for_terms(codebase_path)# 2. 生成包含术语表的markdown文件markdown_contentgenerate_terminology_markdown(terms)# 3. 保存普适语言文件output_pathsave_markdown_file(markdown_content)# 4. 将文件传递给AI同时供开发者阅读context{terminology_file:output_path,purpose:确保AI与开发者使用统一的领域术语}returnoutput_path,context# 使用示例term_file,contextubiquitous_language_skill(./my-project)# 在与AI对话时始终携带term_file作为上下文该技能的核心价值在于减少开发者与AI之间的语言鸿沟。当AI使用与代码库中一致的术语时生成的代码更贴近开发者的意图规划效率显著提升。2.4 TDD作为AI反馈循环约束测试驱动开发TDD在AI辅助开发中的角色不同于传统开发。传统TDD的核心约束是先写测试、让测试通过、再重构而在AI场景中TDD被用作一种反馈循环约束机制解决AI语言模型的以下倾向性问题倾向于一次性生成大量代码不善于利用反馈信息进行迭代改进倾向于跳过类型检查和测试步骤# TDD反馈循环约束伪代码defai_tdd_workflow(ai_agent,module_spec): AI辅助TDD工作流通过测试驱动约束AI行为 参数: ai_agent: AI编程代理 module_spec: 模块规格说明 # 阶段1先编写测试用例人类或AI共同定义test_caseswrite_test_cases(module_spec)# 阶段2让AI在测试约束下生成代码implementationai_agent.generate_code(specmodule_spec,constraints{must_pass_tests:test_cases,step_size:small,# 小步操作no_skip_testing:True})# 阶段3运行测试获取反馈test_resultsrun_tests(test_cases,implementation)# 阶段4根据测试结果重构iftest_results.failed:# 基于失败原因迭代修复implementationfix_based_on_feedback(implementation,test_results.failures)# 阶段5重构优化refactored_coderefactor(implementation,principles[depth_over_shallowness,simple_interfaces])returnrefactored_code核心原则可概括为反馈速率即速度限制Feedback rate is your speed limit。开发推进速度受限于反馈循环的速率应边写代码边测试、小步谨慎推进。2.5 深层模块与接口设计委托法深层模块Deep Modules概念源自John Ousterhout的软件设计哲学。其核心区分是深度模块大量功能隐藏在简单接口后隐藏复杂性。使用者只需理解简单的接口契约无需了解内部实现细节。浅层模块功能较少接口复杂。每个模块暴露较多细节使用者需要理解大量接口才能正确使用。在AI辅助开发中深层模块的优势尤为明显AI需要理解代码逻辑、导航代码库、理解模块间依赖关系。浅层模块的大量细小接口会增加AI的认知负担而深层模块通过清晰的边界简化了AI的理解路径。接口设计委托法的工作流程# 深层模块封装流程defdeep_module_encapsulation(codebase,target_module): 将代码库中的相关代码封装为深层模块 流程: 1. 探索代码库寻找优化机会 2. 将所有相关内容封装在深层模块中 3. 由人类设计并控制接口 4. 将模块内部实现细节交给AI处理 5. 在接口处进行测试和验证 # 步骤1探索代码库定位相关代码related_codeexplore_codebase(codebase,target_module)# 步骤2封装为深层模块deep_modulecreate_deep_module(coderelated_code,interface_designerhuman,# 接口由人类设计implementation_delegated_toAI# 实现委托给AI)# 步骤3在接口处编写测试interface_testswrite_interface_tests(deep_module.interface)# 步骤4将实现细节委托给AIai_implementationdelegate_implementation(moduledeep_module,constraints{interface_contract:deep_module.interface.spec,test_suite:interface_tests,style_guide:deep_module_principles})# 步骤5验证verify(deep_module,ai_implementation,interface_tests)returndeep_module该方法的适用边界可用于应用中非关键部分、多数模块不适用于金融等关键场景因为精心设计和控制的接口若被破坏可能损害整体设计。对比分析3.1 开发范式对比维度传统规格到代码范式GRIME 深度模块范式需求澄清编写规格说明后直接交给AIAI主动提问达成共同设计概念代码审查忽略代码只看规格人类设计接口AI实现细节反馈机制出问题后改规格、重新生成TDD约束下的小步迭代代码质量持续下降软件熵增长通过接口测试和深度模块控制AI角色执行者生成代码战术型程序员前线中尉人类角色规格编写者战略思考者 接口设计师适用场景简单脚本、原型中大型项目、长期维护代码库3.2 模块设计对比维度深度模块浅层模块功能覆盖大量功能功能较少接口复杂度简单复杂复杂性隐藏充分隐藏暴露较多细节AI理解难度低只需理解接口契约高需遍历大量接口AI导航效率高边界清晰低模块间依赖复杂接口破坏影响局部仅限该模块全局影响多个依赖方推荐度推荐用于AI辅助开发不推荐3.3 反馈机制对比维度无测试反馈单元测试反馈TDD约束反馈反馈延迟高集成/运行时才发现中提交前手动运行低每次代码变更自动运行问题定位成本高中低AI迭代质量低盲目生成中有反馈但不强制高强制小步验证代码覆盖率通常较低取决于开发者习惯较高测试先行重构安全性低中高工程实践要点4.1 实践 checklist基于上述方法在实际AI辅助开发项目中建议遵循以下工程实践要点需求澄清优先在让AI进入编码模式之前使用GRIME方法进行充分的需求澄清。不要跳过这一步直接让AI生成代码。建立普适语言定期扫描代码库更新术语表文件确保AI与开发者使用统一的领域术语。将该文件作为AI对话的常驻上下文。TDD约束AI行为先编写测试用例再让AI生成实现代码设置小步操作约束避免AI一次性生成大量代码强制要求AI在每次代码变更后运行测试深层模块封装识别代码库中的相关代码区域由人类设计清晰的接口契约将实现细节委托给AI在接口边界处编写充分的测试静态类型检查使用TypeScript等静态类型语言为AI生成代码提供类型约束减少类型错误。持续投资系统设计借鉴Kent Beck的理念每天对系统设计进行投资避免系统熵增导致的不可维护性。4.2 工具链建议静态类型TypeScript/Python类型注解为AI提供类型上下文自动化测试pytest/unittest等框架作为AI的反馈循环浏览器权限为语言模型提供前端应用的可视化权限便于理解UI逻辑普适语言文件维护一个持续更新的术语表markdown文件局限性与客观评价5.1 方法的局限性缺乏量化实验支撑本文所讨论的方法主要基于经验性观察和实践总结缺少严格的对照实验和量化数据来证明其有效性。GRIME技能获得的星标数约13,000个只能说明其社区关注度不能直接等同于工程效果。适用场景有限深层模块委托法明确不适用于金融等关键场景。对于高可靠性要求的系统接口的任何破坏性变更都可能造成严重后果因此不能完全依赖AI处理实现细节。认知负担转移虽然深层模块通过隐藏实现细节减轻了AI的认知负担但人类需要同时记住模块接口和AI的实现方案“实际上会让大脑更吃力”。这在小型团队或快速原型场景中可能不经济。GRIME的提问成本GRIME方法要求AI提出40-100个问题才能达成共识这在简单任务中可能过度工程化。对于小型脚本或一次性工具这种投入可能不成比例。术语表维护成本普适语言技能需要持续维护术语表文件随着代码库演化术语可能过时或产生歧义增加了额外的维护负担。5.2 假设的局限性AI能力假设方法假设AI能够理解复杂的接口契约并生成符合契约的实现代码。然而当前AI在复杂逻辑生成方面仍存在局限生成的代码可能需要大量人工审查和修改。人类接口设计能力假设方法假设人类能够设计出良好的接口。但实际上接口设计本身是一项需要专业技能的工程活动并非所有开发者都具备此能力。代码库质量假设方法的有效性依赖于代码库具有一定的质量基础。对于已经高度劣化的垃圾代码库引入这些实践可能需要先进行大规模的代码重构成本较高。5.3 潜在改进方向自动化GRIME研究如何将GRIME的提问策略自动化减少人工参与同时保持需求澄清的质量。量化评估框架建立实验框架通过A/B测试等方法量化比较不同开发范式下的代码质量、开发效率和缺陷率。混合委托策略研究不同模块类型关键/非关键下的最优委托策略为不同场景提供差异化的AI协作方案。接口演化支持开发工具支持接口版本的自动管理和迁移降低接口变更带来的维护成本。参考与延伸阅读John Ousterhout.A Philosophy of Software Design. O’Reilly Media, 2018. 提出深度模块与浅层模块的区分定义软件复杂性Andrew Hunt David Thomas.The Pragmatic Programmer: Your Journey To Mastery(20th Anniversary Edition). Addison-Wesley, 2019. 提出软件熵概念车灯之外的盲区隐喻Frederick P. Brooks Jr.The Design of Designs: Essays and Annotations. Addison-Wesley, 2012. 提出设计概念Design Concept理论Kent Beck.Test-Driven Development: By Example. Addison-Wesley, 2002. TDD方法论的经典著作Eric Evans.Domain-Driven Design: Tackling Complexity in the Heart of Software. Addison-Wesley, 2003. 领域驱动设计普适语言概念来源AI Hero (YouTube/Twitter) - AI工程实践相关内容分享mac pocock skills (GitHub) - 相关技能资源仓库