AI代码生成规范实践:从ESLint到系统提示词的规则化引导
1. 项目概述:当AI学会“守规矩”
最近在折腾AI辅助编程,我发现一个挺有意思的现象:你让大模型帮你写段代码,它确实能写出来,功能上可能也没啥大毛病。但问题是,这代码的风格、格式、命名习惯,可能跟你团队里用了好几年的规范完全是两码事。你拿到手,还得花不少时间去调整缩进、改命名、补注释,甚至重构逻辑,才能让它“入乡随俗”。这感觉就像请了个能力超强的外援,但他不懂你公司的“企业文化”和“工作流程”,磨合成本反而上去了。
这就是aiagentwithdhruv/ai-coding-rules这个项目要解决的核心痛点。它不是一个具体的工具库,而是一套方法论和规则集,旨在“训练”或“引导”AI代码生成工具(比如 GitHub Copilot、Cursor、ChatGPT 的代码模式等),让它们生成的代码从一开始就符合你预设的、特定的编码规范。简单说,就是给AI编程助手戴上“紧箍咒”,让它念出来的“经”(代码)符合你的“庙规”。
这个项目特别适合那些已经建立了成熟编码规范(无论是团队约定、行业标准如 Airbnb JavaScript Style Guide,还是项目特定的 linting 规则)的开发者或团队。如果你经常需要复审和修改AI生成的代码以符合规范,或者你希望将AI生成的代码无缝、直接地集成到现有代码库中,那么这个项目所探讨的思路和方案,就是你接下来需要深入了解的。
2. 核心理念与架构设计拆解
2.1 从“生成后修复”到“生成即合规”的范式转变
传统的AI编码辅助工作流,可以概括为“生成-审查-修复”三步走。开发者提出需求,AI生成代码草稿,然后开发者手动或借助 ESLint、Prettier、Black 等工具进行格式化和静态检查,最后再根据检查结果修改代码。这个过程存在明显的效率断层。
ai-coding-rules倡导的理念,是推动工作流向“引导生成-直接集成”演进。其核心思想是:将编码规范作为“上下文”或“系统提示”的一部分,前置注入到AI的推理过程中。这样,AI在构思和输出代码时,就会将这些规则作为硬性约束条件来考虑,从而在源头保证代码的合规性。
这种转变带来的好处是多方面的:
- 提升效率:减少了后期人工调整和格式化的工作量,让开发者能更专注于代码的逻辑和功能本身。
- 保证一致性:无论是哪个开发者、使用哪个AI工具,只要应用同一套规则,生成的代码风格就是统一的,极大维护了代码库的整洁度。
- 降低心智负担:开发者无需在“实现功能”和“遵守规范”之间频繁切换上下文,可以更流畅地进行开发。
2.2 规则定义的层次化结构
一套有效的AI编码规则,绝不是简单地把 ESLint 配置文件丢给AI就能解决的。它需要被精心设计和组织,以适应AI模型的理解和生成方式。ai-coding-rules项目隐含的架构通常包含以下几个层次:
基础格式规则:这是最表层、也是最容易实现的。包括缩进(2空格 vs 4空格 vs Tab)、行尾分号、字符串引号类型(单引号 vs 双引号)、行最大长度等。这些规则相对独立,可以直接转化为明确的指令,如“使用2个空格进行缩进”、“省略行尾分号”。
命名与语法约定:涉及变量、函数、类、文件的命名规范(如 camelCase, PascalCase, snake_case, kebab-case),导入语句的顺序与分组,箭头函数与普通函数的选用场景等。这部分需要结合具体语言和框架的惯例来定义。
代码结构与设计模式:这是更深层次的规则。例如,要求函数保持单一职责、控制函数的行数、优先使用纯函数、特定的错误处理模式(try-catch vs 错误码)、状态管理的方式等。这些规则更抽象,需要更详细的描述和示例来让AI理解。
项目特定约定:每个项目都可能有一些独特的“潜规则”。比如,API响应必须用特定的包装器函数处理,日志必须通过某个统一的工具类记录,某些工具函数必须从特定的内部工具库导入等。这部分规则是确保AI生成代码能与现有项目无缝集成的关键。
注意:规则的制定需要权衡严格性与灵活性。过于严苛的规则可能会限制AI的创造力,导致它生成出虽然合规但笨拙或低效的代码。一个好的实践是,先从基础格式和核心命名规范开始,逐步加入更复杂的结构规则,并根据生成结果进行微调。
2.3 与不同AI工具的集成策略
不同的AI编程工具,其规则注入的“接口”和方式各不相同。ai-coding-rules需要提供适配多种主流工具的实施方案:
- GitHub Copilot / Cursor:这类深度集成在IDE中的工具,主要依靠注释(Comment)和上下文(Context)。规则可以写在当前文件的头部注释中,或者放在一个独立的、被频繁引用的“规则说明”文件中。Copilot 会读取这些上下文并尝试遵循。更高级的用法是利用 Cursor 的
.cursorrules文件或 Copilot 的 Workspace 级别的设置。 - ChatGPT / Claude / 通用大模型API:对于通过聊天界面或API调用的模型,规则主要通过系统提示(System Prompt)来注入。你需要精心设计一段系统提示词,清晰、结构化地阐述所有编码规范。提示词的质量直接决定了规则被遵循的程度。
- 自定义AI代码生成流水线:如果你基于 OpenAI API、Anthropic API 或开源模型自建了代码生成服务,那么你可以在服务端将编码规则固化到每次请求的系统提示中,实现最强制、最统一的管控。
3. 核心规则集构建与表述实战
3.1 将ESLint/Prettier配置“翻译”为AI指令
你的项目很可能已经有了.eslintrc.js和.prettierrc文件。直接把这些配置文件的内容粘贴给AI是低效的,因为AI不直接“执行”这些配置。你需要做一次“转译”。
举例对比:
ESLint 规则 (
.eslintrc.js):module.exports = { rules: { 'indent': ['error', 2], 'quotes': ['error', 'single'], 'semi': ['error', 'never'] } };对应的AI编码规则指令:
代码格式规范: 1. 缩进:使用 2 个空格,禁止使用 Tab 字符。 2. 引号:字符串统一使用单引号 (''),仅在字符串内需要包含单引号时使用双引号 ("")。 3. 分号:行尾禁止使用分号 (;),除非是为了避免语法歧义(如以 `(`, `[`, `` ` ``, `/`, `+`, `-` 开头的行)。 4. 最大行宽:限制为 100 个字符,超出应合理换行。
你需要将配置文件中“声明式”的规则,转化为AI能理解的“描述式”自然语言指令,并附上关键例外情况。
3.2 编写高效的系统提示词(System Prompt)
对于通过API或聊天界面使用的模型,系统提示词是你的主战场。一个高效的提示词结构如下:
你是一个资深的{编程语言}开发者,严格遵守以下{项目名称}的编码规范。 **一、代码风格与格式** 1. 缩进:使用2个空格。 2. 命名: - 变量、函数:使用 camelCase。 - 类、组件、类型:使用 PascalCase。 - 常量:使用 UPPER_SNAKE_CASE。 - 私有成员:以单个下划线 `_` 开头。 3. 引号与分号:字符串使用单引号,行尾不加分号。 4. 导入顺序:先第三方库,再内部绝对路径导入,最后是相对路径导入。每组之间空一行。 **二、代码结构与最佳实践** 1. 函数设计:函数应简短,专注于单一任务。如果函数超过20行,考虑是否可拆分。 2. 错误处理:使用 try-catch 进行异步错误捕获,同步错误使用错误对象抛出,禁止使用 `console.error` 直接输出。 3. 异步操作:统一使用 `async/await`,避免直接使用 `.then()` 链式调用。 4. 组件/模块:每个文件只导出一个主要组件或类,辅助函数或子组件应在文件内部分定义。 **三、项目特定约定** 1. API调用:必须使用 `src/utils/apiClient` 封装的 `request` 函数。 2. 状态管理:对于全局状态,使用 `useContext` 或 Redux Toolkit,禁止在组件内滥用 `useState` 管理复杂共享状态。 3. 日志记录:使用 `src/utils/logger` 模块的 `logInfo`, `logError` 方法,禁止直接使用 `console.log`。 **输出要求:** - 只输出最终的、符合上述所有规范的代码块。 - 除非必要,不添加解释性注释,代码应自解释。 - 使用JSDoc或TypeDoc格式为公共函数和类添加注释。实操心得:系统提示词不是一成不变的。你需要把它当作一个可迭代的产品。在实际使用中,观察AI在哪些规则上频繁“犯错”,然后回头强化提示词中对应部分的表述,可以增加反面示例(“不要怎么做”),或者提供更明确的正面代码片段作为“Few-shot”示例。
3.3 创建活的“规则上下文文件”
对于 Copilot 或 Cursor,一个非常有效的技巧是创建一个名为_coding_rules.md或STYLE_GUIDE.md的文件,放在项目根目录或docs/文件夹下。这个文件详细记录了所有规范,并且你可以在其他文件的开头通过注释引用它,例如:
// 本文件遵循项目编码规范,详见:./docs/_coding_rules.md // 接下来,当你在这个文件中编写代码或让AI补全时,Copilot/Cursor 会关联到那个规则文件,并尽力遵守。这个规则文件本身应该结构清晰、举例丰富。它不仅服务于AI,也服务于团队的新成员,成为一份活的开发文档。
4. 主流IDE与工具集成实操
4.1 在 VS Code + GitHub Copilot 中应用规则
GitHub Copilot 主要从两个方面学习规则:当前文件的上下文和相似文件中的模式。
利用文件头部注释:在任何
.js、.ts、.py等文件的开头,用注释写明关键规则。// @ts-check // 编码规则:缩进2空格,单引号,无分号,函数不超过30行,使用async/await。 // API调用请使用 `import { apiClient } from '@/lib/api';`当你在该文件内触发补全时,Copilot 会参考这些指令。
创建规则模板文件:建立一个
template.copilot.js文件,里面包含了你理想中的代码结构、导入语句和函数样式。当你新建一个功能类似的文件时,先复制这个模板的内容,Copilot 会基于这个强上下文生成风格一致的代码。使用 Copilot Labs 的自定义指令(早期访问功能):在 Copilot Labs 面板中,有时会有自定义指令的输入框,你可以在这里输入项目级的规则。但注意,这个功能可能不稳定或仅限于实验通道。
4.2 深度集成:Cursor AI IDE 的.cursorrules文件
Cursor 对此的支持更为原生和强大。你可以在项目根目录创建一个.cursorrules文件(或放在.cursor/目录下)。这个文件的内容会作为全局上下文自动注入到所有与Cursor AI的交互中。
.cursorrules文件示例:
# 项目编码规范 ## 通用规则 - 语言:TypeScript (React) - 缩进:2空格 - 引号:单引号 - 分号:否 - 行宽:100 ## React 特定规则 - 组件:使用函数式组件和 React Hooks。 - 命名:组件使用 PascalCase,如 `UserProfile`。 - Props:使用 TypeScript 接口定义,前缀为 `I`,如 `IUserProfileProps`。 - 状态管理:简单状态用 `useState`,复杂跨组件状态考虑使用 `Zustand`(本项目已安装)。 ## 项目约定 - API:所有HTTP请求必须通过 `src/services/api.ts` 中的封装函数。 - 工具函数:工具类函数应放在 `src/utils/` 目录下,并使用 `export const` 导出。 - 样式:使用 CSS Modules,文件命名为 `*.module.css`。 ## 示例(良好的代码片段) ```typescript // 良好的组件示例 interface IButtonProps { label: string; onClick: () => void; variant?: 'primary' | 'secondary'; } export const Button: React.FC<IButtonProps> = ({ label, onClick, variant = 'primary' }) => { const buttonClass = `btn btn-${variant}`; return ( <button className={buttonClass} onClick={onClick}> {label} </button> ); };当你在 Cursor 中使用“Chat”或“Edit”指令时,AI 会严格遵守 `.cursorrules` 中的约定。这是目前将编码规则与AI编程助手结合得最紧密、最有效的方式之一。 ### 4.3 通过 API 调用实现定制化代码生成 如果你有开发能力,最彻底的方式是构建一个中间层服务。这个服务接收用户自然语言需求,然后拼接上你预定义好的系统提示词(包含所有编码规则),再调用 OpenAI 或 Anthropic 的 API,最后将生成的、符合规范的代码返回给用户。 **简化流程示例:** 1. 用户前端输入:“写一个函数,从用户API获取数据并过滤出活跃用户。” 2. 你的后端服务接收到请求。 3. 服务端构造最终提示词: ``` [系统提示词,包含前述所有编码规则] 用户需求:写一个函数,从用户API获取数据并过滤出活跃用户。 请生成符合上述所有规范的TypeScript代码。 ``` 4. 调用 `openai.ChatCompletion.create` 或 `anthropic.messages.create`。 5. 将API返回的代码内容直接返回给前端。 这种方式实现了规则的**强制化**和**中心化管理**,确保所有通过该服务生成的代码都符合标准。 ## 5. 效果评估、迭代与常见问题排查 ### 5.1 如何评估规则的有效性? 制定规则不是一劳永逸的,你需要一个评估和迭代的循环。 1. **抽样审查**:定期(如每周)随机抽取一批AI生成的代码片段,进行人工审查。检查点包括格式、命名、结构是否符合规则。记录“违规”点。 2. **静态分析工具**:将AI生成的代码保存到临时文件,然后用项目本身的 ESLint、Prettier、MyPy 等工具去检查。统计错误和警告的数量。目标是让这个数字趋近于零。 3. **“直接可用率”指标**:定义一个“直接可用”的标准(例如,无需任何格式修改,仅需逻辑审查)。计算AI生成的代码中,达到此标准的比例。这个比例应该随着规则优化而上升。 ### 5.2 常见问题与调优指南 即使有了规则,AI也可能会“犯错”或产生不符合预期的输出。以下是常见问题及解决思路: | 问题现象 | 可能原因 | 解决方案 | | :--- | :--- | :--- | | **AI完全忽略格式规则**(如坚持用4空格) | 规则提示词权重不足,或被后续对话淹没。 | 1. **强化系统提示**:在系统提示词开头用“你必须”、“严格遵循”等强指令。<br>2. **对话中重申**:在每次请求代码时,都简要重申关键格式要求。<br>3. **使用更具体的模型**:某些模型(如专门微调过的代码模型)对格式指令更敏感。 | | **命名规范时好时坏** | 规则描述不够具体,或AI对上下文中的命名模式学习有冲突。 | 1. **提供明确示例**:在规则中给出 `goodName` vs `bad_name` 的对比。<br>2. **利用上下文**:在请求生成代码的文件里,多写几个符合规范的变量或函数,AI会倾向于模仿。 | | **AI生成过于冗长或复杂的代码** | 规则只约束了“形式”,未约束“复杂度”和“设计”。 | 在规则中加入**设计原则**,如“优先使用简洁明了的实现”、“如果一个函数做了不止一件事,请拆分它”、“避免嵌套过深的回调”。 | | **项目特定约定被忽略**(如未使用指定工具函数) | AI不知道这个约定,或不知道在何处导入。 | 1. **在规则中提供导入路径的精确示例**。<br>2. **在生成代码前,先让AI“看到”相关工具函数的定义或用法示例**(通过上下文提供)。 | | **规则之间发生冲突** | 规则描述存在二义性或矛盾。 | 审查并精简规则,确保优先级清晰。例如,“保持代码简洁”和“添加详尽错误处理”可能有冲突,需要说明平衡点,如“在关键路径添加错误处理,但避免过度保护”。 | ### 5.3 规则维护与团队协作 1. **版本化规则**:将你的规则文件(如 `.cursorrules`、系统提示词模板)纳入版本控制系统(如 Git)。这样,规则的变更可以被追踪,团队成员可以同步更新。 2. **设立规则管家**:指定一名或轮流担任的“规则管家”,负责收集大家在AI编码中遇到的不合规问题,定期评审和更新规则集。 3. **新手引导**:将规则文件作为新成员 onboarding 的必读文档。并指导他们如何在自己的开发环境中配置(如设置 Cursor 项目,或配置代码片段模板)。 ## 6. 进阶场景:动态上下文与规则分层 对于大型或复杂的项目,一套固定的规则可能不够用。你可能需要更精细化的控制。 1. **目录/模块级规则**:不同目录可能有不同规范。例如,`src/components/` 下的 React 组件规则,和 `src/server/api/` 下的后端API路由规则肯定不同。你可以在不同目录下放置各自的 `.cursorrules` 或规则说明文件。 2. **基于文件类型的规则**:在系统提示词中,可以根据请求生成的文件后缀(`.tsx`, `.py`, `.sql`)动态切换不同的规则子集。 3. **将规则作为“知识库”查询**:在更复杂的集成中,可以将编码规范整理成结构化的知识库(甚至是一个向量数据库)。当AI需要生成代码时,先根据当前任务(如“创建React表单组件”)从知识库中检索出最相关的几条规则,作为动态上下文注入。这实现了规则的按需、精准应用。 **踩坑实录**:我曾尝试为整个项目制定一份极其详尽的规则,结果发现AI的生成速度变慢,且有时会“困惑”,输出一些僵化的代码。后来我意识到,规则并非越多越好。**核心原则是“关键约束优先”**。首先保证命名、格式、项目核心约定这些“硬性”规则,然后再逐步添加关于代码结构、设计模式的“软性”指导。规则的优化是一个与AI模型特性、项目实际情况不断磨合的过程。 最终,`aiagentwithdhruv/ai-coding-rules` 所代表的方法,其价值不在于提供一个开箱即用的规则包,而在于提供了一套将人类团队知识(编码规范)有效“编译”成AI可理解指令的**框架和思路**。它要求你更深入、更结构化地思考自己团队的开发规范,并将其转化为一种可执行的、自动化的约束力。这个过程本身,就是对团队工程能力和代码质量意识的一次升级。当你看到AI生成的代码几乎能直接提交时,那种顺畅感,会让你觉得前期的这些“调教”工作都是值得的。