news 2026/10/5 15:13:05

AI时代,为何软件工程基础依旧重要?

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AI时代,为何软件工程基础依旧重要?

AI时代,为何软件工程基础依旧重要?

摘要

在AI编程工具快速发展的背景下,一种观点认为"代码可以变得廉价",软件开发流程应当从传统的"设计-编码-测试"转向"规格描述-AI生成代码"的范式。然而,实践经验表明,这种观点忽略了软件工程中的若干基础原则。本文基于AI工程实践中的经验总结,系统梳理了GRIME需求澄清技能、普适语言(Ubiquitous Language)技能、测试驱动开发(TDD)作为AI反馈循环约束、以及深层模块(Deep Modules)接口设计委托法等实践方法,并分析了软件熵、设计概念等核心概念在AI辅助开发场景下的意义。

本文的核心论点是:AI工具并未降低软件工程基础的重要性,反而对代码质量、模块设计和反馈机制提出了更高要求。高质量的代码库能够显著提升AI编程效能,而糟糕的代码库则会阻碍AI价值的充分发挥。

技术原理与核心方法

2.1 GRIME:需求澄清技能

GRIME(Requirement Clarification Skill)是一种通过与AI进行逐层深入提问、直至达成"共同设计概念"(Shared Design Concept)的交互方法。其核心思想是:AI不应急于进入编码阶段,而应主动对用户的需求进行系统性提问,逐层剖析设计决策树中的每个分支,直到双方对系统架构达成共识。

该方法的流程可描述如下:

# GRIME 需求澄清流程伪代码defgrime_requirement_clarification(user_initial_plan):""" GRIME 需求澄清技能主流程 参数: user_initial_plan: 用户的初步计划或想法(自然语言描述) 返回: 可转化为PRD的对话内容 """design_tree=parse_design_tree(user_initial_plan)questions=[]# 逐层分析设计树的每个分支forbranchindesign_tree.branches:# AI针对每个细节提出问题branch_questions=generate_questions(branch)questions.extend(branch_questions)# 逐个解决决策之间的依赖关系resolved_decisions=[]forquestioninquestions:answer=ask_user(question)resolved_decisions.append(resolve_dependency(question,answer))# 持续提问直到双方满意(可达40-100个问题)whilenotconsensus_reached(resolved_decisions):follow_ups=generate_follow_ups(resolved_decisions)forfuinfollow_ups:answer=ask_user(fu)resolved_decisions.append(answer)# 达成共同设计概念shared_concept=build_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. 扫描代码库,查找专业术语terms=scan_codebase_for_terms(codebase_path)# 2. 生成包含术语表的markdown文件markdown_content=generate_terminology_markdown(terms)# 3. 保存普适语言文件output_path=save_markdown_file(markdown_content)# 4. 将文件传递给AI,同时供开发者阅读context={'terminology_file':output_path,'purpose':'确保AI与开发者使用统一的领域术语'}returnoutput_path,context# 使用示例term_file,context=ubiquitous_language_skill('./my-project')# 在与AI对话时始终携带term_file作为上下文

该技能的核心价值在于:减少开发者与AI之间的"语言鸿沟"。当AI使用与代码库中一致的术语时,生成的代码更贴近开发者的意图,规划效率显著提升。

2.4 TDD作为AI反馈循环约束

测试驱动开发(TDD)在AI辅助开发中的角色不同于传统开发。传统TDD的核心约束是"先写测试、让测试通过、再重构",而在AI场景中,TDD被用作一种反馈循环约束机制,解决AI语言模型的以下倾向性问题:

  1. 倾向于一次性生成大量代码
  2. 不善于利用反馈信息进行迭代改进
  3. 倾向于跳过类型检查和测试步骤
# TDD反馈循环约束伪代码defai_tdd_workflow(ai_agent,module_spec):""" AI辅助TDD工作流:通过测试驱动约束AI行为 参数: ai_agent: AI编程代理 module_spec: 模块规格说明 """# 阶段1:先编写测试用例(人类或AI共同定义)test_cases=write_test_cases(module_spec)# 阶段2:让AI在测试约束下生成代码implementation=ai_agent.generate_code(spec=module_spec,constraints={'must_pass_tests':test_cases,'step_size':'small',# 小步操作'no_skip_testing':True})# 阶段3:运行测试,获取反馈test_results=run_tests(test_cases,implementation)# 阶段4:根据测试结果重构iftest_results.failed:# 基于失败原因迭代修复implementation=fix_based_on_feedback(implementation,test_results.failures)# 阶段5:重构优化refactored_code=refactor(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_code=explore_codebase(codebase,target_module)# 步骤2:封装为深层模块deep_module=create_deep_module(code=related_code,interface_designer='human',# 接口由人类设计implementation_delegated_to='AI'# 实现委托给AI)# 步骤3:在接口处编写测试interface_tests=write_interface_tests(deep_module.interface)# 步骤4:将实现细节委托给AIai_implementation=delegate_implementation(module=deep_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辅助开发项目中,建议遵循以下工程实践要点:

  1. 需求澄清优先:在让AI进入编码模式之前,使用GRIME方法进行充分的需求澄清。不要跳过这一步直接让AI生成代码。

  2. 建立普适语言:定期扫描代码库,更新术语表文件,确保AI与开发者使用统一的领域术语。将该文件作为AI对话的常驻上下文。

  3. TDD约束AI行为:

    • 先编写测试用例,再让AI生成实现代码
    • 设置小步操作约束,避免AI一次性生成大量代码
    • 强制要求AI在每次代码变更后运行测试
  4. 深层模块封装:

    • 识别代码库中的相关代码区域
    • 由人类设计清晰的接口契约
    • 将实现细节委托给AI
    • 在接口边界处编写充分的测试
  5. 静态类型检查:使用TypeScript等静态类型语言,为AI生成代码提供类型约束,减少类型错误。

  6. 持续投资系统设计:借鉴Kent Beck的理念,每天对系统设计进行投资,避免系统熵增导致的不可维护性。

4.2 工具链建议

  • 静态类型:TypeScript/Python类型注解,为AI提供类型上下文
  • 自动化测试:pytest/unittest等框架,作为AI的反馈循环
  • 浏览器权限:为语言模型提供前端应用的可视化权限,便于理解UI逻辑
  • 普适语言文件:维护一个持续更新的术语表markdown文件

局限性与客观评价

5.1 方法的局限性

  1. 缺乏量化实验支撑:本文所讨论的方法主要基于经验性观察和实践总结,缺少严格的对照实验和量化数据来证明其有效性。GRIME技能获得的星标数(约13,000个)只能说明其社区关注度,不能直接等同于工程效果。

  2. 适用场景有限:深层模块委托法明确不适用于金融等关键场景。对于高可靠性要求的系统,接口的任何破坏性变更都可能造成严重后果,因此不能完全依赖AI处理实现细节。

  3. 认知负担转移:虽然深层模块通过隐藏实现细节减轻了AI的认知负担,但人类需要同时记住模块接口和AI的实现方案,“实际上会让大脑更吃力”。这在小型团队或快速原型场景中可能不经济。

  4. GRIME的提问成本:GRIME方法要求AI提出40-100个问题才能达成共识,这在简单任务中可能过度工程化。对于小型脚本或一次性工具,这种投入可能不成比例。

  5. 术语表维护成本:普适语言技能需要持续维护术语表文件,随着代码库演化,术语可能过时或产生歧义,增加了额外的维护负担。

5.2 假设的局限性

  1. AI能力假设:方法假设AI能够理解复杂的接口契约并生成符合契约的实现代码。然而,当前AI在复杂逻辑生成方面仍存在局限,生成的代码可能需要大量人工审查和修改。

  2. 人类接口设计能力假设:方法假设人类能够设计出良好的接口。但实际上,接口设计本身是一项需要专业技能的工程活动,并非所有开发者都具备此能力。

  3. 代码库质量假设:方法的有效性依赖于代码库具有一定的质量基础。对于已经高度劣化的"垃圾代码"库,引入这些实践可能需要先进行大规模的代码重构,成本较高。

5.3 潜在改进方向

  1. 自动化GRIME:研究如何将GRIME的提问策略自动化,减少人工参与,同时保持需求澄清的质量。

  2. 量化评估框架:建立实验框架,通过A/B测试等方法量化比较不同开发范式下的代码质量、开发效率和缺陷率。

  3. 混合委托策略:研究不同模块类型(关键/非关键)下的最优委托策略,为不同场景提供差异化的AI协作方案。

  4. 接口演化支持:开发工具支持接口版本的自动管理和迁移,降低接口变更带来的维护成本。

参考与延伸阅读

  • 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) - 相关技能资源仓库
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/5 15:00:32

DeepSeek-Coder:ERP二次开发的语义翻译器与智能杠杆

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/5 14:56:11

AI客服质量闭环实践:从人工抽检到全量评估的技术路径

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/5 14:51:29

串行通信仿真实战:UART/RS232/RS485物理层建模与调试

1. 串行通信不是“线连对了就能通”——从实验室烧板子到工业现场掉线,我踩过的坑全在这儿串行通信这个词,听起来像教科书里一页翻过去的冷知识,但只要你拆过一台老式PLC、调过温控仪的485总线、或者用USB转串口线刷过单片机固件,…

作者头像 李华
网站建设 2026/10/5 14:47:34

YALMIP+SDPT3:Matlab半定规划建模与求解实战指南

1. YALMIP不是“另一个优化工具箱”,而是Matlab里最灵活的建模层 很多人第一次听说YALMIP,是在解决一个带逻辑约束的混合整数规划问题时——比如“如果电压越限,则必须启动备用机组;否则禁止启动”,或者“某变量只能取…

作者头像 李华