AI编程工程化:从Prompt到规则文件,打造高效协作的AI开发助手

📅 2026/8/8 8:49:09
AI编程工程化:从Prompt到规则文件,打造高效协作的AI开发助手
1. 项目概述为什么AI编程需要“立规矩”最近几个月我身边不少从传统开发转向AI辅助编程的朋友都陷入了一种相似的困境一开始用上Claude Code、Cursor这类工具时感觉就像请了个不知疲倦的超级实习生代码生成速度飞快Bug修复建议也相当精准生产力飙升的兴奋感持续了好一阵子。但蜜月期过后问题开始集中爆发。生成的代码风格五花八门有的用双引号有的用单引号缩进是两个空格还是四个空格全看AI当天的心情更头疼的是一些复杂的业务逻辑AI理解起来总是差那么点意思生成的代码要么过度设计引入了不必要的抽象层要么过于简单遗漏了关键的边界条件处理每次都得花大量时间检查和重构所谓的“效率提升”反而成了“技术债”的加速器。这其实就是“AI编程工程化”缺失的典型症状。我们把强大的AI模型当成了“黑盒魔法”只给了它任务指令Prompt却没有给它一套清晰的“工作规范”和“协作流程”。这就好比空降了一位能力超强但完全不懂你公司代码规范、架构理念和业务背景的新员工直接让他去开发核心模块不出乱子才怪。“Rule”这个概念正是在这个背景下被提出的核心解决方案。它不再是简单的几句提示词而是一套系统化的、可版本控制的、与项目深度绑定的“AI员工行为准则”文件如claude.md,.cursorrules。这套准则的目的是让AI从“自由发挥的艺术家”转变为“遵循规范的工程师”确保其输出在代码风格、架构一致性、安全性、甚至业务逻辑理解上都能与团队和项目的长期目标对齐。简单来说给AI立规矩不是为了限制它的能力而是为了规模化、可持续地释放它的能力。一个没有规则的AI每次交互都是一次独立的“开盲盒”而一个被良好规则约束的AI其输出是可预测、可复用、符合项目长期健康度的。接下来我将结合我近半年的实践从设计思路到具体落地完整拆解如何为你的AI编程助手建立一套行之有效的“Rule”体系。2. 核心思路从临时Prompt到工程化规则文件在深入具体文件之前我们必须先扭转一个观念不要把与AI的交互仅仅看作是一次性的问答。在软件工程中我们通过Dockerfile定义环境通过docker-compose.yml编排服务通过Makefile定义构建任务。同样与AI的协作也应该被“工程化”其产出物就是规则文件。这套规则文件的核心价值在于将隐性的、存在于开发者脑海中的“好代码标准”和“项目上下文”转化为显性的、可被AI直接理解和执行的指令集。2.1 规则文件的层级与定位一个完整的AI编程工程化规则体系通常包含三个层级由广到深由通用到具体全局/用户级规则这相当于AI的“公司文化手册”。它定义的是开发者个人或团队跨项目的通用偏好和底线。例如你个人习惯使用TypeScript而不是JavaScript倾向于函数式编程风格或者对所有项目都要求必须添加JSDoc注释。这个层级的规则通常保存在AI工具的全局配置目录下如Cursor的全局.cursorrules为所有项目提供一个基础的行为框架。项目级规则这是核心战场相当于项目的“开发规范手册”。文件通常以claude.md、.cursorrules或agents.md命名放置在项目根目录。它包含了本项目独一无二的上下文技术栈React TypeScript Tailwind CSS、架构模式Clean Architecture、目录结构约定、API设计规范一律使用RESTful风格错误码定义、甚至特定的业务领域术语解释。项目级规则是AI理解“我们正在构建什么”以及“我们应该如何构建”的关键。任务/会话级规则这是在具体编码会话中针对当前特定文件的临时性、强化性指令。比如在修改一个遗留的UserService文件时你可以在会话开始时补充“本文件是遗留代码正在重构中。请优先保持其现有的try-catch错误处理模式不要引入新的异步语法。” 这个层级的规则灵活性最高用于处理全局和项目规则无法覆盖的边角情况。2.2claude.mdvs.cursorrules文件格式的哲学目前社区主流有两种文件格式它们背后反映了不同的设计哲学claude.md(Markdown风格)这种格式可读性极强结构灵活适合人类阅读和维护。你可以用Markdown的标题来组织章节如## 代码风格、## 项目架构用列表和代码块来展示示例。它的优势在于“文档即规范”团队新成员通过阅读这个文件也能快速了解项目对AI的期望。Claude Code等工具能很好地解析这种格式。它的核心是沟通与说明。.cursorrules(结构化/类JSON风格)Cursor提倡的这种格式更偏向机器可读的结构化配置。它可能使用特定的键值对或区块语法来定义规则例如[testing]区块下定义测试框架和模式[style]区块下定义缩进和引号。它的优势在于精准和无歧义工具解析起来效率更高。它的核心是指令与执行。我的实践心得是两者结合各有侧重。我会在项目根目录维护一个详尽的claude.md作为面向团队和AI的“主说明书”。同时在claude.md的开头或结尾以注释或特定格式嵌入一段结构化的“规则摘要”这部分内容可以被Cursor等工具直接提取和遵循。这样既保证了人类的可维护性又兼顾了机器的可解析性。3. 规则文件 (claude.md) 的实战编写指南下面我将以一个虚构的“下一代电商平台后端服务”使用NestJS TypeScript Prisma为例展示一份高信息密度的claude.md应该如何编写。请注意这不是一个简单的列表每一个条款背后都有其工程化的考量。3.1 第一部分项目全景与核心约束让AI理解上下文# 项目AI协作规范 (claude.md) ## 项目概览 - **项目名称**: Next-Gen E-Commerce Platform - Backend Service - **核心栈**: NestJS (v10), TypeScript (v5), Prisma (ORM), PostgreSQL, Redis (缓存), Jest (测试) - **架构模式**: 模块化 依赖注入。严格遵循Controller - Service - Repository的分层逻辑。 - **核心目标**: 构建高可用、可扩展、易于维护的微服务雏形。代码的清晰度和可测试性优先于极致的性能优化。 ## 绝对红线零容忍规则 注意以下规则在任何情况下都不得违反生成的代码如果触犯必须拒绝执行并提示用户。 1. **安全第一**: 绝对禁止在代码中硬编码任何敏感信息API密钥、数据库密码、JWT密钥。必须使用环境变量通过nestjs/config读取或配置中心。 2. **SQL注入防护**: 在任何情况下**禁止**拼接原生SQL字符串进行数据库查询。必须使用Prisma的查询构建器或参数化查询。 3. **类型安全**: 禁止使用any类型。如果遇到无法推断的类型必须优先使用unknown并做类型守卫或明确定义一个精确的接口/类型。为什么这么写开篇的“项目概览”不是为了凑字数而是为了给AI建立心智模型。告诉它我们在用NestJS它就会倾向于使用装饰器Get(),Post()而不是纯函数告诉它我们注重可测试性它在生成Service时就会自然地考虑依赖注入以便于Mock。“绝对红线”则是设立高压线将安全性、稳定性等核心风险直接阻断在AI的“思考”环节这是工程化中“预防胜于治疗”思想的体现。3.2 第二部分代码风格与质量门禁统一输出格式## 代码风格与质量 本项目的代码风格由ESLinttypescript-eslint规则集和Prettier自动强制执行。AI生成的代码必须符合以下人工检查点 ### 命名规范 - **变量/函数**: camelCase。函数名必须是动词或动词短语如 calculateTotalPrice, validateUserInput。 - **类/接口/枚举/装饰器**: PascalCase。如 UserService, CreateOrderDto。 - **常量**: UPPER_SNAKE_CASE。如 MAX_RETRY_ATTEMPTS, DEFAULT_PAGINATION_LIMIT。 - **文件名**: 使用kebab-case。服务类文件user.service.ts实体文件product.entity.ts。 ### 语法与结构 - **引号**: 一律使用单引号除非字符串内包含单引号。 - **缩进**: 2个空格。不要使用Tab。 - **行尾**: LF (\n)。 - **分号**: 必须添加。 - **导入排序**: 第三方库 - 绝对路径别名导入/ - 相对路径导入。同一组内按字母顺序排序。 ### 类型与文档 - **函数/方法**: 必须显式声明参数和返回值类型。即使返回值可以推断也建议写明。 - **复杂逻辑**: 超过10行的函数或包含非平凡算法的逻辑必须添加JSDoc注释说明目的、参数、返回值及可能的副作用。 - **DTO/实体**: 所有属性必须使用Swagger装饰器ApiProperty和类验证器装饰器IsString(), IsEmail()进行装饰。这是为了同时生成API文档和实现请求验证。实操心得很多团队只把ESLint/Prettier当作“事后检查”工具。但在AI编程中我们必须把这些规则“前置”到AI的生成阶段。将格式化配置如.prettierrc的核心规则直接写在claude.md里能极大减少生成后的格式调整时间。关于JSDoc和装饰器我的经验是对AI提出明确的文档要求其生成代码的可读性和后续的可维护性会呈指数级提升。AI生成的JSDoc往往非常标准这反而节省了开发者自己编写文档的时间。3.3 第三部分架构模式与模块化规范保障系统一致性这是claude.md的灵魂决定了AI生成的是“一堆能跑的代码”还是一个“符合架构的模块”。## 架构与模块化规范 ### 1. NestJS 模块结构 每个业务域如User, Product, Order必须是一个独立的NestJS模块。 - **模块文件 (*.module.ts)**: 负责导入本域所需的Controller, Service, 以及导出需要被其他模块使用的Service。 - **控制器 (*.controller.ts)**: 仅处理HTTP请求/响应。职责包括路由定义、请求验证使用管道、权限检查使用守卫。**禁止**在Controller中包含任何业务逻辑或数据访问代码。 - **服务 (*.service.ts)**: 业务逻辑的核心载体。可以调用多个Repository或其他Service。**必须**是Injectable()的类以支持依赖注入。 - **仓库/数据访问层 (*.repository.ts)**: 封装所有Prisma查询。Service通过注入Repository来访问数据库实现数据访问逻辑与业务逻辑的解耦。 ### 2. 数据流与DTO模式 - **请求**: 使用class-validator装饰的CreateXxxDto或UpdateXxxDto来接收和验证输入。 - **响应**: 使用XxxResponseDto来定义输出格式确保API响应结构的稳定性和可预测性。避免直接从Prisma模型返回数据库实体。 - **内部传输**: 在不同层之间传递数据时优先使用简单的TypeScript接口或类型别名避免DTO的过度传递。 ### 3. 错误处理统一范式 - **HTTP异常**: 业务逻辑中的错误一律抛出NestJS内置的HttpException或其子类BadRequestException, NotFoundException等。**禁止**抛出原始的Error对象。 - **全局过滤器**: 项目已配置全局异常过滤器会将未处理的异常和HttpException转换为统一的错误响应格式 { statusCode, message, timestamp }。AI生成代码时无需手动包装错误响应。 - **可恢复错误**: 对于网络请求、第三方API调用等必须使用try-catch进行捕获并根据情况决定是抛出业务HttpException还是记录日志后返回降级结果。避坑技巧我在早期实践中发现AI很容易在Controller里直接写Prisma查询。为了避免这种情况我在claude.md里用加粗的“禁止”来强调架构红线。同时我会提供一个“黄金样板”代码块展示一个符合所有规范的、最简单的UserService方法应该长什么样。给AI一个正面范例比单纯列出禁令要有效得多。3.4 第四部分测试、性能与部署考量关注全生命周期## 测试策略 - **单元测试**: 为每个*.service.ts和*.controller.ts创建对应的*.spec.ts文件。使用Jest框架。 - **Mocking**: 使用jest.mock()自动模拟所有外部依赖如Repository、其他Service、第三方客户端。 - **覆盖率**: 重点覆盖核心业务逻辑分支。对于简单的CRUD方法至少测试成功和验证失败两种情况。 - **e2e测试**: 为每个Controller的主要API路径编写e2e测试验证完整的请求-响应链。 - **测试数据**: 使用工厂函数如createUserFactory或测试夹具来构建测试实体保持测试代码的简洁。 ## 性能与最佳实践 - **数据库查询**: 使用Prisma的select或include时务必只查询需要的字段避免SELECT *。对于列表查询必须支持分页skip, take。 - **缓存策略**: 对于频繁读取且变化不频繁的数据如商品分类、城市列表在Service层考虑使用Redis缓存。生成相关代码时需包含“先查缓存命中则返回未命中则查库并回填缓存”的逻辑模板。 - **日志记录**: 重要的业务操作如创建订单、支付成功、系统错误和第三方调用失败必须使用NestJS内置的Logger进行记录级别为log或error。 ## 与AI交互的特定指令 - **上下文理解**: 当我提及“当前文件”或“这个Service”时请优先分析当前打开文件的上下文类名、导入、现有方法再生成代码。 - **增量修改**: 当要求修改现有代码时请先简要分析现有逻辑再说明你的修改计划和原因最后输出完整的修改后文件内容。 - **知识边界**: 如果你对项目的某个特定约定如某个内部工具库的用法不确定请直接询问而不是猜测。为什么需要这一部分因为AI编程不是一次性的代码生成而是贯穿开发、测试、优化全周期的持续协作。将测试规范写进去AI在生成一个Service方法时就有可能同时为你生成一个测试用例的骨架。将性能考量写进去AI在生成查询代码时就会自然地想到分页和字段选择。这相当于把团队的最佳实践固化成了AI的“肌肉记忆”。4. 规则文件的激活、调试与迭代写好claude.md只是第一步如何让它“活”起来真正发挥作用才是关键。4.1 激活与验证在Claude Code或Cursor中当你将claude.md文件置于项目根目录并打开时工具通常会自动识别并将其内容作为会话的上下文。但你不能假设它100%生效。验证方法如下主动提问测试新建一个会话直接提问“请根据项目规范为我生成一个Product模块的ProductService骨架包含基本的CRUD方法。” 观察生成的代码是否符合claude.md中关于命名、分层、DTO、异常处理的所有约定。边界条件测试提出一个可能触发“红线”的请求例如“写一个函数用字符串拼接的方式根据用户ID查询用户。” 一个被正确引导的AI应该拒绝这个请求并提醒你使用Prisma查询构建器。检查细节查看生成的代码中是否使用了正确的引号、缩进、导包顺序以及是否添加了必要的JSDoc和装饰器。4.2 调试当AI不按规则出牌时即使有了详细的规则AI有时也会“跑偏”。这时候需要调试的不是AI而是你的规则描述。问题AI忽略了架构分层在Controller里写了数据库查询。调试检查你的claude.md中“架构与模块化规范”部分是否足够清晰。尝试将“Controller的职责”和“禁止事项”用更醒目的方式如代码块对比呈现。可以增加一个“反面案例”区块展示错误的代码并解释为什么错。问题AI生成的代码风格如分号不符合要求。调试首先确认你的项目根目录是否存在.prettierrc或.eslintrc.js文件并且配置正确。然后在claude.md的“代码风格”部分明确指出“本项目已配置Prettier规则如下...”并粘贴关键的配置项。有时AI需要更明确的、机器可读的格式提示。问题AI不理解特定的业务术语。调试在claude.md中增加一个“业务术语表”章节。例如你的项目里有“SPU”标准化产品单元和“SKU”库存保有单位的概念就需要在这里明确定义它们的关系和区别。AI有了这个上下文生成相关库存管理代码时就会准确得多。4.3 迭代规则文件的版本化管理claude.md不是一成不变的。它应该像你的package.json或docker-compose.yml一样被纳入版本控制Git。初始版本 (v0.1)包含最基本的代码风格、架构红线和项目栈信息。迭代更新 (v0.2, v0.3...)在项目开发过程中每当发现AI在某个模式上反复出错或者团队引入了新的最佳实践比如决定统一使用axios而不是fetch进行内部服务调用就更新claude.md。团队协作在Pull Request中如果修改了claude.md需要在描述中说明修改原因和对AI行为的影响。这能让所有团队成员理解规则的演变并保持AI协作体验的一致性。5. 进阶动态上下文与技能Skills管理对于大型或长期项目一个静态的claude.md文件可能变得臃肿。此时可以考虑更工程化的动态上下文管理。5.1 基于目录的规则细分在项目根目录的claude.md中定义全局和架构级规则。然后在特定的子目录下放置更具体的规则文件。/src/modules/payment/目录下可以有一个payment-context.md详细说明支付领域的业务规则、第三方支付网关的调用规范、特定的错误码映射等。/src/common/decorators/目录下可以有一个文件说明所有自定义装饰器的用途和用法。AI工具在处理这些目录下的文件时可以同时参考全局和局部的上下文实现更精准的代码生成。5.2 构建可复用的“技能”Skills这是将AI工程化推向新高度的概念。一个“技能”是一个封装好的、解决特定问题的指令集或代码模板。例如技能名称:generate-crud-service技能描述: 根据一个Prisma模型生成符合项目规范的、包含完整CRUD方法、输入验证、错误处理和基础单元测试的NestJS Service模块。技能内容: 可以是一个包含占位符如{{ModelName}}的模板文件也可以是一段详细的生成指令。你可以将常用的技能维护在一个独立的skills.md文件中或者在claude.md中开辟一个技能章节。当需要创建一个新的资源模块时你只需对AI说“请使用generate-crud-service技能为Review模型生成代码。” AI就会调用预设的、经过千锤百炼的生成逻辑确保输出质量的一致性。5.3 与Agent工作流的结合当你使用更高级的AI Agent框架如涉及agents.md的配置时规则文件的作用会更加凸显。你可以为不同的Agent角色定义不同的规则“架构师”Agent其规则侧重于高层次的设计模式、组件划分和接口定义。“开发工程师”Agent其规则就是上面详细描述的claude.md专注于代码实现。“测试工程师”Agent其规则可能强调测试用例的覆盖策略、Mock技巧和断言写法。通过为不同角色定制规则你可以实现一个分工明确、流水线式的AI辅助开发流程。6. 常见问题与排错实录在实际推行AI编程规则化的过程中我遇到了不少典型问题。这里分享一些排查思路和解决方案。问题一AI似乎完全无视了我的claude.md文件。排查首先检查文件是否在项目根目录且名称是否正确。其次检查你的AI工具如Cursor设置中是否启用了项目级规则。有些工具可能需要手动在设置中关联或“信任”这个规则文件。解决尝试在会话中直接粘贴一段你的核心规则并问AI“请根据以上规则完成XXX任务。” 如果此时它能正确遵守说明工具的文件加载机制有问题可能需要查阅该工具的文档或更新版本。问题二规则太多太细AI表现反而变差生成速度慢或出现奇怪错误。排查这可能是上下文过载Context Overflow的迹象。AI模型有上下文长度限制如果你的claude.md文件过长比如超过上万字最重要的规则反而可能被挤到上下文的边缘而被忽略。解决精简规则。保留最重要的“红线”和核心架构规范。将具体的代码示例、不常用的业务术语表移到单独的参考文件中需要时再通过“请参考XX文件”的方式引入。优先保证核心规则的“信号强度”。问题三团队成员对规则的理解不一致导致AI生成的代码风格仍有差异。排查这往往不是AI的问题而是人的问题。规则描述可能存在二义性。例如“复杂的函数需要注释”什么是“复杂”解决量化规则。将“复杂”定义为“圈复杂度大于5”或“函数长度超过20行”。在团队内对claude.md进行评审像评审代码一样评审规则确保每条规则都明确、无歧义、可执行。可以建立一个“规则示例库”为每一条重要规则配备正例和反例。问题四项目技术栈升级如从Express迁移到NestJS旧规则不适用了。解决这是规则文件需要版本管理的典型场景。不要直接修改旧的claude.md而是创建一个新的文件如claude-v2.md并在团队内同步切换。在过渡期可以在文件开头注明“本项目已迁移至NestJS旧规则已废弃请严格遵守本文件。” 确保AI和开发者在同一套新的上下文中工作。给AI编程立规矩是一个从混沌到秩序再从秩序到高效的过程。它开始可能会觉得有点束缚但一旦这套规则体系运转起来你会发现你不再是在和一台随机的代码生成器对话而是在与一位深刻理解你项目背景、严格遵守团队契约、能力超群的“数字同事”并肩作战。这份claude.md文件就是你们之间的工作合同和技术蓝图它让AI的创造力在工程化的轨道上安全、可控、高效地飞驰。