1. 项目概述:当AI成为你的“野生”搭档
最近和几个团队的朋友聊天,大家不约而同地提到了同一个痛点:用AI辅助写代码,效率是上去了,但产出的代码质量却像开盲盒。有时候,它能给你一个惊艳的解决方案;但更多时候,它生成的代码风格混乱、命名随意、结构松散,完全不符合团队的编码规范。你不得不花大量时间去“驯服”这些代码,把时间从“创造”拉回到了“格式化”和“重构”。这感觉就像请了一个能力超强但毫无纪律的实习生,他确实能干活,但留下的烂摊子也得你来收拾。
这个项目标题“AI写的代码总是不规范?这个Skill拯救你”,精准地戳中了这个普遍存在的“效率反噬”问题。它指向的并非一个具体的工具,而是一种解决方案的思路或能力(Skill)。结合热词来看,核心场景集中在TypeScript和Python这两个当前AI编码辅助最活跃的生态中。无论是前端开发、后端服务还是数据分析脚本,我们都需要一种方法,将AI的“野性”创造力,规训到符合项目规范和工程化要求的轨道上。这不仅仅是让代码“好看”,更是为了可维护性、团队协作和长期的项目健康。接下来,我们就深入拆解,如何构建或运用这样一个“规训”AI的Skill,让它从“野生搭档”变成“职业队友”。
2. 核心思路:构建AI的“编码规范意识”
要让AI写出规范的代码,我们不能只停留在事后用Prettier或Black格式化一下。格式只是表象,深层次的是命名约定、设计模式、异常处理、模块化程度等。核心思路是给AI注入“上下文”和“约束”,在它生成代码的那一刻,就引导其走向正轨。
2.1 理解AI代码生成的“黑盒”与“可引导性”
像Codex、Claude或ChatGPT这类大模型,本质上是基于海量代码数据进行概率预测。它学到了无数种编码风格和模式,但并不知道“你”的团队具体遵循哪一套。因此,它的输出是“平均风格”或“常见风格”,不一定是“规范风格”。
关键在于,这些模型具有极强的上下文理解能力。你的提示词(Prompt)和提供的上下文,就是引导它的方向盘。一个空泛的“写一个Python函数计算平均值”的指令,得到的结果可能千奇百怪。但如果你在指令中附上详细的规范要求、甚至是一段示例代码,AI模仿和遵循的能力就会大幅提升。这个“Skill”的本质,就是系统化、自动化地构建这个高质量的引导上下文。
2.2 Skill的两种实现路径:即时规训与集成规训
根据实施阶段,这个Skill可以分为两种路径:
路径一:即时规训(Prompt Engineering + 上下文增强)这是最直接、最灵活的方式。核心在于精心设计你的提示词,将规范作为需求的一部分明确传递给AI。
- 基础版:在提问时追加规范描述。例如:“用TypeScript写一个用户登录的API接口,要求:1. 使用ES6+语法和async/await;2. 函数和变量名使用camelCase,类名使用PascalCase;3. 使用JSDoc格式注释;4. 对请求参数进行校验,使用
zod库;5. 错误处理使用try-catch,并返回统一的错误响应格式。” - 进阶版:提供“规范示例”作为上下文。这是更有效的方法。你可以先给AI看一段你们项目中公认的、符合规范的代码片段,然后说:“请参考以上代码的风格和规范,实现一个具有类似功能的X模块。”AI的模仿能力会得到极大发挥。
路径二:集成规训(IDE插件/工具链集成)这种方式将规训过程自动化,集成到开发工作流中。例如,一些AI编程助手插件允许你设置“项目规范描述文件”或连接到团队的ESLint、Pylint配置。AI在生成代码建议时,会主动参考这些配置,使建议更贴合项目规范。这需要工具本身的支持,是未来更理想的方向。
注意:无论哪种路径,都无法保证100%的规范符合率。AI可能会误解或遗漏某些复杂约束。因此,这个Skill的最终环节永远是“人工审查”。它的目标是大幅降低审查和修改的成本,而不是完全取代人工判断。
3. 实战构建:为TypeScript和Python打造规训Skill
下面,我们以最常见的两种语言为例,将“即时规训”路径具体化、可操作化。你可以将这些视为可复用的“提示词模板”或“上下文模板”。
3.1 TypeScript项目规训实战
TypeScript的规训重点在于类型安全、现代语法、一致的命名和模块组织。
第一步:创建你的“规训上下文库”不要每次从头开始写提示词。建立一个文本片段库,存放各种规范描述和示例代码。例如:
- 文件命名规范:“我们使用
kebab-case命名文件,如user-service.ts。组件使用PascalCase,如UserProfile.tsx。” - 命名约定示例:
// 变量/函数:camelCase const userName: string = ‘John’; function fetchUserData(id: number) { /* ... */ } // 类/接口/类型别名/枚举:PascalCase interface UserProfile { /* ... */ } class AuthService { /* ... */ } type ApiResponse<T> = { /* ... */ } // 常量:UPPER_SNAKE_CASE const MAX_RETRY_COUNT = 3; const DEFAULT_API_TIMEOUT = 5000; - 错误处理模式:
// 使用Result类型或统一的错误响应 type Result<T, E = Error> = { success: true; data: T } | { success: false; error: E }; async function getUser(id: string): Promise<Result<User>> { try { const response = await apiClient.get(`/users/${id}`); return { success: true, data: response.data }; } catch (error) { console.error(`Failed to fetch user ${id}:`, error); return { success: false, error: error instanceof Error ? error : new Error(‘Unknown error’) }; } }
第二步:组合使用,生成高质量提示当需要AI编写一个“用户服务模块”时,你的提示词可以这样组织:
请参考以下项目规范,编写一个TypeScript的UserService类。 【项目规范】 1. 代码风格:使用严格的ESLint配置(已附Airbnb风格要点)。请使用箭头函数、async/await,避免`var`。 2. 命名约定(示例如下): - 变量/函数:camelCase - 类/接口:PascalCase - 常量:UPPER_SNAKE_CASE 3. 类型定义:必须为所有函数参数、返回值、变量显式定义类型或利用类型推断。优先使用`interface`定义对象结构。 4. 错误处理:统一使用try-catch包装异步操作,并抛出定义好的业务错误类(如`ValidationError`, `NotFoundError`)。 5. 模块化:一个类一个文件。使用具名导出(`export class UserService`)。 【具体任务】 创建一个`UserService`类,包含以下方法: 1. `getUserById(id: string): Promise<User>`:根据ID获取用户,如果不存在则抛出`NotFoundError`。 2. `updateUserProfile(userId: string, profileData: Partial<UserProfile>): Promise<User>`:更新用户资料,需验证`profileData`的合法性。 3. `searchUsers(query: string, page: number = 1): Promise<PaginatedList<User>>`:搜索用户,支持分页。 请生成完整的类代码,并包含必要的导入语句和JSDoc注释。通过提供如此详尽的上下文,AI生成的代码在规范性上会有质的飞跃。
3.2 Python项目规训实战
Python的规训重点在于PEP 8、类型提示、异常处理、依赖管理和项目结构。
第一步:明确并封装核心规范Python社区有PEP 8,但团队可能有额外约定。
- PEP 8核心摘要:“遵循PEP 8:4空格缩进,行宽79字符(可放宽至88-99),函数和变量名用
snake_case,类名用PascalCase,常量用UPPER_SNAKE_CASE。” - 类型提示强制要求:“所有函数必须使用类型提示(Type Hints)。使用
from typing import List, Dict, Optional, Union等。” - 异常处理规范:
# 不要捕获所有异常,要具体 try: value = int(some_string) except ValueError as e: # 而不是 except Exception: logger.warning(f“Failed to convert {some_string} to int: {e}”) value = None # 自定义异常类 class ServiceError(Exception): """业务逻辑异常基类""" pass class UserNotFoundError(ServiceError): pass - 依赖与导入规范:“使用
requirements.txt或pyproject.toml管理依赖。导入顺序:标准库、第三方库、本地模块。使用绝对导入或相对导入,避免循环导入。”
第二步:针对不同场景的规训提示
- 场景A:编写一个FastAPI接口
请按照以下规范编写一个FastAPI端点: 【规范】 1. 代码风格:严格遵循PEP 8,使用`black`格式化风格。 2. 类型提示:所有函数参数、返回值必须使用类型提示。使用Pydantic的`BaseModel`定义请求/响应模型。 3. 错误处理:使用FastAPI的`HTTPException`或自定义异常处理器。业务错误使用自定义异常类(如`BusinessError`)。 4. 依赖注入:使用FastAPI的`Depends`管理数据库会话等依赖。 5. 异步支持:优先使用`async/await`。 【任务】 创建一个用户注册端点`POST /api/v1/users/register`。 请求体:`username`(字符串,必填),`email`(邮箱格式,必填),`password`(字符串,最小长度6)。 响应:201状态码,返回创建的用户ID和`username`。 需要检查`username`和`email`是否已存在(假设有一个`UserRepository`类提供`get_by_username`和`get_by_email`方法)。 密码需要经过哈希处理(使用`passlib`的`CryptContext`)。 - 场景B:编写一个数据处理脚本
请编写一个Python脚本,用于处理CSV数据,并遵循以下项目约定: 【约定】 1. 使用`pandas`进行数据处理,`pathlib`处理路径。 2. 脚本顶部需要有详细的文档字符串(Docstring),说明功能、输入、输出。 3. 配置参数(如文件路径)应从命令行参数或环境变量读取,而不是硬编码。 4. 使用`logging`模块进行日志记录,而不是`print`。设置合理的日志级别(INFO, ERROR)。 5. 函数应保持单一职责,一个函数只做一件事。 【任务】 脚本`clean_sales_data.py`: 1. 读取指定路径的`sales_raw.csv`文件。 2. 清洗数据:删除重复行,填充`amount`字段的空值为0,将`date`字段转换为datetime类型。 3. 按`product_category`分组计算每日销售总额。 4. 将结果保存为`sales_summary_{当前日期}.csv`。 5. 记录处理开始、结束时间以及处理的总行数。
4. 高级技巧:将Skill固化为开发流程
仅仅依靠手动编写复杂的提示词,长期来看仍有优化空间。我们可以通过一些工具和流程,将这个Skill固化,使其更稳定、更自动化。
4.1 利用IDE插件与代码片段
大多数现代IDE或编辑器(如VS Code)支持用户自定义代码片段(Snippets)和强大的AI插件。
- 自定义Snippet触发AI提示:你可以创建一个Snippet,比如输入
tsai-service并按下Tab,它不仅仅插入一段模板代码,而是触发一个预置的、包含了你所有规范描述的注释块,你只需要在其中填写具体的功能描述。这相当于一个规范的“填空”模板。 - 配置AI插件上下文:一些AI编程助手允许你设置“全局指令”或“项目上下文”。你可以将本章第3节中整理的“规训上下文库”内容,粘贴到插件的自定义指令框中。这样,该插件在所有对话中都会默认参考这些规范,无需每次重复。
4.2 创建“规范守护”的CI/CD流水线
这是最终极的保障,确保任何代码(无论是人写的还是AI生成的)在进入仓库前都必须通过规范检查。
- 静态代码分析:在Git的
pre-commit钩子或CI流水线(如GitHub Actions, GitLab CI)中集成检查工具。- TypeScript:
ESLint(代码质量) +Prettier(代码格式化) +TypeScript编译器 (tsc --noEmit) 进行类型检查。 - Python:
black(格式化) +isort(导入排序) +flake8或pylint(代码质量) +mypy(静态类型检查)。
- TypeScript:
- AI代码专项检查:你甚至可以编写一个简单的脚本,利用代码抽象语法树(AST)分析,检测一些AI可能常犯的“坏味道”,比如过于复杂的嵌套、魔法数字、缺少注释的关键函数等,并将其作为CI流水线中的一个检查项。
- 门禁策略:设置流水线规则,只有所有检查都通过的代码才能合并到主分支。这样,即使AI生成了不规范代码,也无法进入代码库,从流程上保证了质量底线。
4.3 构建团队共享的提示词知识库
对于团队协作,维护一个共享的、不断优化的“AI编码规训提示词库”至关重要。可以使用团队Wiki、Notion页面或一个简单的Git仓库来管理。内容可以按语言、框架、任务类型(如“CRUD接口”、“数据清洗脚本”、“单元测试”)进行分类。每个条目都包含:任务描述、核心规范要点、最佳示例提示词、生成的代码样例以及常见的AI“跑偏”点及纠正方法。新成员 onboarding 或遇到新任务时,先来这个知识库查找,能极大提升AI使用的效率和代码质量的一致性。
5. 避坑指南与效果评估
在实际操作中,即使有了完善的Skill,也会遇到各种问题。以下是一些常见的坑和应对策略。
5.1 常见问题与排查
| 问题现象 | 可能原因 | 解决方案 |
|---|---|---|
| AI完全忽略规范,自由发挥。 | 提示词中规范描述过于靠后或被淹没;规范描述太抽象。 | 将核心规范放在提示词最前面,并使用“必须”、“要求”等强约束词。提供具体示例代码比文字描述有效十倍。 |
| AI理解了部分规范,但混淆了其他部分。 | 规范条目过多或存在内部矛盾。AI的上下文窗口有限,可能丢失信息。 | 简化规范,一次只强调最重要的3-5条。对于复杂规范,分步骤引导:先让AI生成骨架,再让其按规范填充细节。 |
| 生成的代码功能正确,但使用了不推荐的库或过时的API。 | AI的训练数据可能包含旧版本代码。 | 在提示词中明确指定技术栈和版本,如“使用Python 3.10+和pandas 1.5+的特性”。可以追加指令:“请使用现代、社区推荐的最佳实践来实现。” |
| 代码风格符合,但架构设计糟糕(如函数过长、职责不单一)。 | AI缺乏对“好设计”的深层理解,它模仿的是代码形态,而非设计思想。 | 在任务描述中加入设计约束,如“请将函数拆分为不超过30行的小函数,每个函数职责单一”、“请使用策略模式来避免复杂的if-else判断”。事后人工审查设计是必须的。 |
5.2 效果评估与迭代
如何判断这个“Skill”是否有效?不能凭感觉,需要简单评估。
- 人工审查耗时比:记录使用“规训提示词”前后,审查和修改AI生成代码所花费的时间。目标是将耗时降低50%以上。
- 静态检查通过率:观察在CI流水线中,AI生成的代码首次提交时,能通过
ESLint/pylint等检查的比例是否显著提升。 - 代码相似度:随机抽取几段AI生成的代码和团队手写的历史代码,让团队成员进行“盲测”,看是否能轻易分辨。理想情况是难以区分。
这个Skill本身也需要迭代。当你发现AI在某个特定模式上反复犯错时(例如,总是忘记给某个类型的参数加类型提示),就把这个案例和修正后的、更精确的提示词补充到你的“规训上下文库”或团队知识库中。这是一个持续的人机协作优化过程。
最终,这个“拯救不规范代码的Skill”,其内核不是某个神秘工具,而是一套将人类工程智慧转化为机器可理解约束的方法论。它要求我们从模糊的抱怨(“AI写的代码真烂”)转向精确的指令和系统的上下文管理。当你掌握了这套方法,AI就不再是那个需要你跟在后面收拾残局的“野生”搭档,而是一个真正能理解团队规则、高效产出可用代码的“职业”伙伴。这其中的关键,始终在于你如何清晰、系统地向它传达“我们这里,代码应该这么写”。