AI 友好架构:AI 编程最佳范式,构建 10x 效率提升的代码库(万字长文)
生成式 AI 在你代码库里表现不佳,原因有很多。但追根溯源,很可能是这么一个扎心的事实:你的代码库对 AI 不够友好。而更扎心的是,它对人也不见得友好。团队里缺乏一致的规范和最佳实践,代码库的可读性、可维护性和可扩展性自然是每况愈下。
这篇文章会有点长,核心就是想聊聊怎么打造一个对 AI 友好的架构,顺带也整理一下这些年我看到的团队协作实践。我们先从软件工程里一个很微妙的点开始说起。

引子 1:软件工程 - 团队实践优于最佳实践
说句实在话,软件工程里没有绝对的“最佳实践”。一个实践好不好,关键看它适不适合你的团队。在把 AI 拉进开发流程之前,很有必要把自己团队现有的那套工程实践先理一理。
代码命名规范的产生:构建统一的语言
就拿一个金融场景来举例。假设你们有个产品叫“稳享灵动慧利”,代码里该怎么命名它?
- 直接翻译:SteadilyEnjoyAgileWisdomAndBenefits
- 挑选重点:AgileBenefitController
- 拼音全称:WenXiangLingDongHuiLi
- 拼音首字母:WXLDHL
- ……
通常来说,方案1和2基本不会有人选。技术负责人会告诉你,别人看不懂——这不光是考虑新人或外包,你自己隔几个月回来看这段代码也是一脸懵。方案3和4反而是最常选的。所以你看,这事没有对错,团队内部能达成一致,就比什么都强。
代码检视在检视什么:维护团队最佳实践
拼音用多了,又会带来新问题。比如,“用户”被翻译成“YongHu”,福建的同事可能一不小心就写成“YongFu”。怎么避免?一个简单的办法就是代码检视。你指望 Sonarlint 之类的工具来纠偏?它可管不了这种“文化差异”。所以,代码检视在一定程度上解决了这个问题。
我们期望的代码检视,核心目标一般是这几个:
- :命名、风格、注释这些,得统一。
规范一致性
- :通用的逻辑模式、代码重用,该用就得用。
保持最佳实践
- :代码改动得和业务逻辑对得上。
业务逻辑正确
- :逻辑错误、性能问题,能揪出来自然最好。
潜在的 bug
但说真的,想靠代码检视来发现所有潜在的 bug,挺难的。大多数人很难对业务逻辑了如指掌,更别提把所有边界条件都考虑到了。而且评审的时间也有限,不可能覆盖所有代码。所以,代码检视的初衷,更多还是为了让团队在规范和最佳实践上步调一致。
遏制面条式代码:分层筑结构,内聚定边界
我们常常在微观层面抠代码质量,却不知不觉间忽略了宏观架构的“腐化”,结果就是可维护性越来越差,最终陷入“面条式代码”的泥潭。这背后的原因,很大程度上是我们没有从结构层面去思考:新代码应该放在哪?相关的逻辑要怎么组织?代码放错了地方,毫无章法地增长,人看不过来,AI 同样也会一脸懵逼。
解决之道在于构建清晰的结构,这主要靠两个相辅相成的策略:
- :在宏观上,通过分层(比如表现层、业务逻辑层、数据访问层)来划分系统的主要职责区域。这强制性地把不同类型的关注点隔离开(界面逻辑不该和数据存储逻辑混在一起),给代码库提供了一张高层级的导航图。
架构分层
- :在微观上,也就是每一层内部,强调内聚性。功能上紧密相关的代码模块,应该聚合在一起。比如,所有和“用户认证”相关的逻辑都集中管理,而不是东一块西一块。这样,每个模块的功能才够单一、够明确。
逻辑内聚
当现有的设计已经不够用了,重构就成了我们的改进手段——把不同职责的代码,按照逻辑关系,清晰地划分到不同的“层”或者“模块”中去。
引子 2:尝试并理解 AI 代码生成的限制要素
现在,我们用 AI 编程,通常有几种方式:
- :比如 ChatGPT,需要手动输入上下文。
网页聊天式生成
- :直接在 IDE 里生成代码,能选择或自动带上上下文。
IDE 插件式生成
这两种模式的核心区别,就在于是否带有用户代码的上下文信息。
理解基于上下文的 AI 代码生成:龙生龙,凤生凤
用过 AI 插件的代码补全功能,你肯定能感受到:它生成的代码质量,比网页聊天那种要强太多了。拿 AutoDev 示例项目里的 BlogController 来说。如果我们想生成一个 delete blog 的 API 接口,在 getBlog 方法后面加个注释:
@RestController
@RequestMapping("/blog")
public class BlogController {
BlogService blogService;
public BlogController(BlogService blogService) {
this.blogService = blogService;
}
@ApiOperation(value = "Get Blog by id")
@GetMapping("/{id}")
public BlogPost getBlog(@PathVariable Long id) {
return blogService.getBlogById(id);
}
// delete blog by id
然后触发 AI 补全,它生成的代码可能是这样的:
@ApiOperation(value = "Delete Blog by id")
@DeleteMapping("/{id}")
public void deleteBlog(@PathVariable Long id) {
blogService.deleteBlogById(id);
}
看到了吗?那个 @ApiOperation 就是 AI 根据你前面代码的规范“照葫芦画瓢”生成的。而 deleteBlog 这个命名,也自然受到了你前面命名规范的影响。所以说,你基于别人的代码去修改时,会发现 AI 的质量不尽如人意,原因就在这里。好的代码会让 AI 生成更好的代码;反过来,屎山也更容易让 AI 产出屎山。当好代码和坏代码混在一起时,那就只能看运气了。
如果你想让 AI 生成一大段代码(比如多个方法),但缺乏足够的上下文,补全式模型的效果就会大打折扣,它可能会生成一些不存在的假方法。现在的补全式模型为了效果更好,往往会过度拟合,这也导致它们难以生成那种大段的、有逻辑关联的代码。
理解好的问题表达的重要性:欲速则不达
在生成式 AI 时代,你提问的质量,直接决定了生成代码的质量。我们经常遇到两种情况:
- :比如“实现一个用户管理功能”,AI 很可能生成不完整或根本不符合预期的代码。
模糊的需求描述
- :总想用一两句话就搞定所有事,结果生成的代码里藏着不少坑。
问题过于急迫或简单
给 AI 下指令,比如让它实现一个用户管理功能。它首先得能从当前的代码库里理解什么是“用户”,什么是“管理”,然后才能相对准确地生成代码。否则,AI 就只能凭自己的理解瞎猜,质量自然好不到哪去。
所以,我们得先定义一下:在 AI 时代,什么样的提问才算好问题?当然,这个可以交给 AI 自己去研究,比如用 Google DeepResearch 来做。
核心要素初步识别
通过一些初步探索,我发现有效的提示词通常包含几个关键要素:清晰的任务指令、充分的背景信息、具体的细节描述、明确的角色设定、期望的输出格式,以及合适的语气和风格。提供范例和设定约束条件也是很重要的技巧。
总结一下,有效的提示词需要清晰和具体,比如:
- :清晰地告诉 AI 你要它做什么(比如“写一个 Python 函数”、“重构这段 Ja va 代码”、“生成 SQL 查询”)。避免模糊或模棱两可的表述。
明确任务指令
- :AI 需要上下文才能理解它要完成的任务是什么。这包括:
提供充分背景信息
- :项目的目标、使用的技术栈(语言、框架、库版本)、架构模式等。
项目背景
- :相关的代码片段、接口定义、类结构或函数签名,让 AI 了解当前的实现方式和约束。
现有代码
- :如果任务涉及特定业务领域,提供相关的术语、规则或概念(比如 DDD 中的通用语言)。
领域知识
- :详细说明需求,包括输入、输出、预期行为、边界条件或错误处理。比如,别只说“计算阶乘”,改成“写一个 Python 函数 factorial,接收一个整数 n,返回它的阶乘。如果 n 小于 0,返回 None”。
具体细节描述
把这些提示词工程技巧用好,特别是充分利用现有代码库的上下文和领域知识,能显著提高 AI 生成代码的准确性,让它更好地融入项目。
理解受限的小参数理解能力:巧妇难为无米之炊
现在的 AI 编程工具里,通常会集成很多不同的模型,比如补全模型、快速应用模型、聊天模型、推理模型等等。这些模型的参数大小不一,有的高达 175B,有的却只有 6B。通常来说,参数越大,模型的理解能力就越强。有传闻说,早期的 Copilot 应用里,补全采用的是约 12B 的 Codex 模型,而聊天用的则是约 175B 的 GPT-3.5 模型。当参数量变小,比如采用 3B 的补全模型时,模型就很难理解复杂的需求,对中文的理解能力也会变得非常有限。这时候就可能出现,你用很简单的中文描述,模型却搞不懂的情况。
所以,如果你想实现复杂的需求,就得借助参数大的模型。模型越大,生成质量越好,但速度也越慢。针对不同的场景,需要采用不同的生成策略。
构建 AI 友好编程:从实践到模式
想用一篇文章把 AI 友好型架构讲透,不是件容易的事。我尽量用模式化的方式去抽象,这样你在不同场景下也能灵活运用。这些模式的目标,就是创建一个既便于人类协作,又能被 AI 高效理解、分析和改进的代码环境。
模式:领域知识丰富上下文与问题定义
问题
实践方式:领域语言与提示词工程优化用户输入
解决方案
实现示例
- :通过静态代码分析拿到所有类名、函数名信息,交给模型分析、理解和生成,最终输出一个 domain.csv 文件,包含中英文和描述信息。
构建术语表
- (可选)。
用户介入编辑术语表
- :用户在 AutoDev 输入框内点击“优化提示词”,系统就能把术语表中的上下文信息带入需求中。
优化提示词
举例
再详细一点的定义示例:“(角色:资深 Ja va 工程师)使用 Spring Boot 框架,实现一个‘客户账户管理’限界上下文的核心功能,包括:(1)处理 POST 请求 /customers/register 用于客户注册,接收包含 'name', 'email', 'password' 的 JSON,验证 email 格式和密码强度,成功后保存至数据库并发布‘CustomerRegistered’领域事件。(2)处理 POST 请求 /accounts/activate/{token} 用于账户激活……” 这种方式提供了更清晰的业务术语、技术约束和具体行为描述。
实践方式:将需求工程应用于 AI 交互
解决方案
实现示例
- 用户构建自己的 Jira MCP 服务器。
- 将 MCP 服务器配置到项目中使用。
- 将检索到的 Jira Issue 的摘要、验收标准、附件设计文档等内容,按照“领域术语表 + 需求模板”的格式汇总,交给模型处理。
举例
模式:基于项目知识与规范的智能生成
问题
解决方案
实践方式:借助 Project Rule 预先定义项目上下文
问题
解决方案
实现示例
举例
.cursorrules, .github/copilot-instructions.md, IDE 设置)创建配置文件。其内容可能包含:
- :用自然语言描述:
规则内容
- :如命名约定、代码格式化标准。
编码规范与风格指南
- :指定使用的框架、库版本,禁用或推荐特定库。
技术栈与库约束
- :如微服务、事件驱动,DDD 限界上下文划分,SOLID 原则的特定应用。
架构模式与设计原则
- :内部/外部 API 的调用方式、认证要求、数据格式。
API 使用约定
- :标准异常处理流程、日志级别与格式。
错误处理策略
- :项目的核心业务术语及其含义。
领域术语
- :支持全局、项目级、特定文件类型/路径的规则设置,甚至动态激活规则。
作用域管理
把这些工具的规则配置功能用好,团队能显著提升 AI 代码助手的实用性,让它更好地融入项目的实际开发流程。
实践方式:持续的项目知识捕获与注入
解决方案
实现机制
举例
augment.memories 文件,供后续对话使用。以下是之前记录的一些用户偏好示例:
- 用户希望使用 jetBrains jewel 仓库作为修复项目错误的参考。
- 只使用 JetBrains JewelUI 组件,而不是 Material 组件。
- 用户希望使用 JetBrains jewel 中的发送按钮图标,而不是重启图标。
潜在的挑战
小结:手动的知识获取
需要强调的是,“项目知识驱动的上下文注入”这个模式能成功实施,高度依赖于团队持续进行有效的知识管理。这包括对
显式知识
隐式知识
模式:自文档化代码增强语义化表达
问题
实践方式:语义化命名与结构化设计
解决方案
实现示例
- :使用描述性强的变量、函数和类名,比如用
命名规范
calculateInvoiceTotal()而不是calc()。 - :遵循设计模式和编码规范,确保代码模块化、可重用。
结构化设计
实践方式:适应于 AI 理解的编程范式
问题
解决方案
实现示例
- :在静态强类型语言中,明确的类型注解提供了关于数据结构、函数签名和预期数据流的形式化信息,AI 可以利用这些信息生成类型安全且符合接口的代码。
利用类型系统
- :通过嵌入形式化的前置条件、后置条件和不变量,精确描述组件的责任和期望行为。
采用契约式设计
- :
拥抱函数式编程原则
- :无副作用,输入相同则输出相同,简化 AI 的推理过程。
纯函数
- :避免状态修改,使代码状态更易预测和跟踪。
不可变性
- :模块化和声明式风格可能更易于 AI 理解结构和意图。
高阶函数与组合
当然,语义丰富性和实用性之间需要权衡。像高级类型系统和契约式设计这些技术,为 AI 提供了丰富的语义信息,但采用成本和复杂性也更高。不过,AI 的理解能力确实会随着更明确的语义信息而提高。
模式:验证优先开发
验证优先开发
在代码生成语境下,
幻觉
背景问题
实践方式:生成-审查-测试-优化循环
解决方案
实现示例
- :使用 AI 工具根据提示快速产出代码、测试用例、文档等。
生成
- :结合人工审查与自动化工具(静态分析、风格检查、复杂度分析、安全扫描)评估生成产物。
审查
- :采用全面、自动化的验证策略,涵盖功能正确性、性能效率、安全漏洞扫描、鲁棒性及语义正确性。
测试
- :根据审查与测试结果,通过人工修改或优化提示词进行改进,形成持续闭环迭代。
优化
检查策略
由于幻觉检测是一个活跃的研究领域,目前的最佳实践通常是结合多种手段:
- :将 AI 生成的代码与官方文档、可靠代码库或 API 规范进行比对验证。
事实核查与交叉引用
- :核查生成内容是否与项目现有代码约定、架构模式、设计风格保持一致。
一致性检查
- :利用强类型语言特性和静态分析工具,捕捉明显的幻觉,如调用未定义变量、错误函数等。
静态分析与类型检查
- :检查生成内容中引用的外部库、模块或 API 是否实际存在,并确认版本兼容性。
依赖关系验证
- :部分 AI 工具提供置信度分数,低置信度可能提示存在幻觉风险,但高置信度也不能完全排除错误。
置信度评分(谨慎使用)
- :当前阶段,经验丰富的开发者通过人工走查仍是识别复杂幻觉和微妙逻辑错误最有效的方式。
人工审查的重要性
- :针对怀疑存在幻觉的部分,设计特定测试用例验证其功能正确性与边界条件。
针对性测试
模式:面向 AI 理解的代码重构
代码重构是改进现有代码结构和质量而不改变其外在行为的过程。
问题
- :当单个函数或文件过长时,AI 模型容易因 token 限制或困惑于多重责任而无法有效理解全局逻辑。
上下文超载
- :缺乏清晰的方法划分与命名,令 AI 难以提取关键业务意图,生成的补全或重写质量不高。
可读性差
实践方式:应用经典重构技术优化代码结构与可读性
代码重构是改进现有代码结构和质量而不改变其外在行为的过程。它通过消除代码异味、提高模块化和可读性,降低复杂度,从而让 AI 工具更容易进行分析和生成高质量代码。
解决方案
实现示例
- 识别“上帝类”或“神对象”:通过静态分析工具定位文件中责任过多的区域。
- 提炼函数:将长方法中的逻辑块拆分为独立、具名的小方法,比如把“数据校验”、“业务处理”、“日志记录”分别提炼出来。
- 提炼类:将相近职责或状态数据抽离到新的类中,减少主类耦合度。
- 重命名:统一变量、方法、类的命名规范,使其业务意图对 AI 更直观。
- 移除死代码与临时代码:剔除无用方法和注释,降低上下文噪声。
实现方式:借助 AI 辅助分析进行结构性重构
AI 直接重构的问题
- :多层调用链与高耦合使得开发者和 AI 都难以把握整体结构,重构风险高。
模块依赖不透明
- :缺乏数据支撑,易遗漏高价值改动点或误伤核心功能。
重构决策凭印象
解决方案
具体方法
- 利用静态分析或 LSP 工具,生成目标类/方法的调用点列表、调用频次及调用层级图。
- 用 AI 对这些结果进行自然语言摘要,帮助快速理解各调用方的上下文。
- 基于调用热度和耦合度,制定分阶段重构策略:先从高频、深层调用处入手,后续再优化低频、可替换模块。
实现示例
/usage 命令,可以帮助你分析代码的调用情况。
- :使用
分析代码调用情况
/usage:com.example.service.OrderService来分析指定代码的调用情况,了解它的具体使用场景,为后续重构提供依据。 - :基于分析结果,由 AI 评估并决定最适合的重构策略。
确定重构策略
- :AI 调用其 IDE 能力来执行具体的重构操作,并修复过程中可能出现的错误。
执行重构与修正
相比于让 AI 直接修改代码,借助 IDEA 的内置重构功能来执行,效果会好得多。
注意事项
进行这些重构时,应该采用小步快跑、持续集成和自动化测试的方式,确保不破坏现有功能。通过有针对性的重构,可以系统性地改善代码库结构,让它更易于 AI 理解、导航和生成高质量代码。
定义 AI 友好架构
AI 友好架构是一种将成熟的软件架构原则与生成式 AI 的能力相结合并进行调整的软件构建方法。它的核心目标是创建一个既便于人类协作,又能被 AI 高效理解、分析、生成和持续演进的代码资产与系统环境,从而显著提升开发效率。
将上面提到的模式总结一下,有几个关键点:
- :AI 友好的代码库首先必须对人类友好,遵循一致的团队规范、清晰的代码结构,具备良好的可读性和可维护性。
人类友好是基础
- :通过 DDD 的通用语言、领域术语表、提示词工程和需求工具集成,为 AI 提供清晰的任务背景。同时,利用项目规则、Agent 记忆和 RAG 技术,注入项目特定的规范、技术栈和历史决策。
显式化的上下文与意图
- :让代码自文档化,通过语义化命名、结构化设计、类型系统、契约式设计或函数式编程,让代码本身就能传达其功能和意图,减少 AI 理解的障碍。
代码本身的语义表达
- :采用“验证优先开发”模式,建立“生成-审查-测试-优化”的迭代循环,管理 AI 的不确定性和潜在幻觉,确保最终产出的质量和可靠性。
适应 AI 生成特性的流程
- :通过面向 AI 理解的代码重构,应用经典重构技术,并借助 AI 辅助分析,持续改进代码结构,降低复杂度。
持续优化的结构
基于上面这些模式,AI 友好的架构可以被看作一个多层次的系统:
- :强调清晰的领域知识定义、结构良好且语义丰富的代码库,为 AI 理解和操作奠定基础。
第一层:基础知识与结构层
- :通过精确的需求信息和项目特定知识,为 AI 提供必要的上下文。
第二层:交互情境化层
- :AI 在此层进行代码生成,并通过严格的验证优先开发流程确保产出质量。
第三层:引导生成与验证层
- :利用验证结果反馈优化提示词、更新知识库、触发代码重构,并通过持续的知识管理确保持续改进。
第四层:持续改进反馈层
当然,AI 友好的架构并不是一成不变的。它会随着技术发展、团队需求和项目演变而不断调整和优化。通过这种方式,团队才能在快速发展的 AI 技术环境中,保持高效的开发流程和高质量的代码产出。
总结
AI 编程不是银弹,它需要团队共同努力。通过结合领域知识、项目规范、代码结构和验证流程,团队才能有效地利用 AI 编程助手的能力,提升开发效率和代码质量。