乐于分享
好东西不私藏

让AI编辑器乖乖听话:如何用固定代码规范驯服你的AI助手

让AI编辑器乖乖听话:如何用固定代码规范驯服你的AI助手

你有没有遇到过这种情况:AI帮你写的代码风格一会儿驼峰一会儿下划线,变量名一会儿缩写一会儿全称,明明是同一个项目,写出来的代码像是三个人写的?

今天聊一个实战话题——如何让AI编辑器严格遵循你团队的代码规范

———————————

为什么AI生成的代码需要规范约束?

AI编辑器(Cursor、GitHub Copilot、Windsurf等)本质上是基于海量代码训练的模型。它见过太多风格的代码,所以默认输出的风格是”平均风格”——什么都像,什么都不是。

这在个人项目里还能忍,但一旦进入团队协作,问题就暴露了:

• 同一个功能的函数命名不一致:getUserInfo()、getClientData()、getCustomerRecord() 混着来

• 变量名可读性参差不齐:有人写 yyyymmdstr,有人写 yearMonthDay

• 魔法数字满天飞:一个 525600 在循环里,没人知道是什么意思

• 回调地狱和Promise混用:一半代码用回调,一半用async/await

核心问题:AI没有”记忆”你的团队偏好,除非你主动告诉它。

———————————

解决方案:给AI编辑器喂规范文件

目前主流AI编辑器都支持项目级的规则配置。核心思路是:把你的代码规范写成一份规则文件,放在项目根目录,AI每次生成代码时都会参考这份规则。

Cursor.cursor/rules/*.mdc

GitHub Copilot.github/copilot-instructions.md

Windsurf.windsurfrules

通用AGENTS.mdCLAUDE.md.cursorrules

不同工具叫法不同,但本质相同——一份AI可读的规范文档

———————————

一份实战JS规范应该包含什么?

下面是团队沉淀的核心规则,每一条都是AI最容易犯错的点:

一、变量命名:让AI告别随机风格

规则1:使用有意义的可发音的变量名

Bad

var yyyymmdstr = moment().format('YYYY/MM/DD');

Good

var yearMonthDay = moment().format('YYYY/MM/DD');

规则2:对相同类型的变量使用相同的关键字

Bad – AI最爱的”多样性”

getUserInfo();
getClientData();
getCustomerRecord();

Good – 统一术语

getUser();

这一条极其重要。AI模型见过太多同义词,如果不在规范里明确规定”用户统一用 user,不用 client/customer”,它会随机选择。

规则3:消灭魔法数字

Bad

// 525600到底啥意思?
for (var i = 0; i < 525600; i++) {
  runCronJob();
}

Good

var MINUTES_IN_A_YEAR = 525600;
for (var i = 0; i < MINUTES_IN_A_YEAR; i++) {
  runCronJob();
}

规则4:避免单字符变量名

Bad – AI在forEach里特别爱用单字符

locations.forEach((l) => {
  dispatch(l);
});

Good

locations.forEach((location) => {
  dispatch(location);
});

二、函数设计:让AI写出可维护的代码

规则5:函数参数不超过两个

Bad – 参数爆炸

function createMenu(title, body, buttonText, cancellable) {
  ...
}

Good – 使用配置对象

var menuConfig = {
  title: 'Foo',
  body: 'Bar',
  buttonText: 'Baz',
  cancellable: true
}

function createMenu(menuConfig) {
  ...
}

规则6:单一职责原则

Bad – 把逻辑堆在一个函数里

function emailClients(clients) {
  clients.forEach(client => {
    let clientRecord = database.lookup(client);
    if (clientRecord.isActive()) {
      email(client);
    }
  });
}

Good – 拆分职责

function emailClients(clients) {
  clients.forEach(client => {
    emailClientIfNeeded(client);
  });
}

function emailClientIfNeeded(client) {
  if (isClientActive(client)) {
    email(client);
  }
}

function isClientActive(client) {
  let clientRecord = database.lookup(client);
  return clientRecord.isActive();
}

规则7:函数命名必须反映功能

Bad

dateAdd(date, 1); // 加什么?加到哪里?

Good

dateAddMonth(date, 1); // 一目了然

规则8:使用默认参数代替或运算

Bad – ES5时代的写法

function writeForumComment(subject, body) {
  subject = subject || 'No Subject';
  body = body || 'No text';
}

Good – 现代写法

function writeForumComment(subject = 'No subject', body = 'No text') {
  ...
}

三、类设计:约束AI的面向对象输出

规则9:优先选择ES6类语法

Bad – 原型链写法

var Animal = function(age) {
  this.age = age;
};
Animal.prototype.move = function() {};

Good – 现代类语法

class Animal {
  constructor(age) {
    this.age = age;
  }
  move() {}
}

规则10:使用getter/setter封装属性访问

Bad – 直接操作属性

bankAccount.balance = bankAccount.balance - 100;

Good – 通过方法操作,便于校验和日志

bankAccount.withdraw(100);

四、异步处理:统一AI的异步风格

规则11:统一使用async/await

Bad – Promise链

require('request-promise').get(url)
  .then(function(response) {
    return require('fs-promise').writeFile('article.html', response);
  })
  .then(function() {
    console.log('File written');
  })
  .catch(function(err) {
    console.log(err);
  })

Good – async/await

async function getCleanCodeArticle() {
  try {
    var request = await require('request-promise');
    var response = await request.get(url);
    var fileHandle = await require('fs-promise');
    await fileHandle.writeFile('article.html', response);
    console.log('File written');
  } catch(err) {
    console.log(err);
  }
}

五、注释与格式:让AI不再画蛇添足

规则12:只注释业务逻辑,不注释显而易见的代码

Bad – AI特别爱加这种废话注释

// The hash
var hash = 0;
// Length of string
var length = data.length;
// Loop through every character in data
for (var i = 0; i < length; i++) { ... }

Good – 只在不明显的地方注释

var hash = 0;
var length = data.length;
for (var i = 0; i < length; i++) {
  var char = data.charCodeAt(i);
  hash = ((hash << 5) - hash) + char;
  // Convert to 32-bit integer
  hash = hash & hash;
}

规则13:不要保留被注释掉的代码

Bad

doStuff();
// doOtherStuff();
// doSomeMoreStuff();

Good – 用版本控制,不要用注释保留历史

doStuff();

———————————

规范文件怎么写才能让AI”真正听话”?

光知道规则还不够,关键是怎么写规范文件让AI理解并执行。几个技巧:

1. 用 Bad/Good 对比格式

AI模型对”反例+正例”的格式理解力最强。不要只写”应该怎样”,一定要写”不应该怎样”。

2. 给出明确的优先级

强制规则:变量命名使用 camelCase,常量使用 UPPER_SNAKE_CASE,类名使用 PascalCase

推荐规则:函数参数不超过2个,优先使用函数式编程

3. 针对AI的特殊说明

• 不要生成被注释掉的代码

• 不要添加显而易见的注释

• 不要使用单字符变量名(循环索引除外)

• 错误处理必须包含 console.error 或上报逻辑

• 所有异步操作统一使用 async/await

4. 提供项目专属词汇表

概念
统一用词
禁止用词
用户
user
client, customer, member
获取
get
fetch, retrieve, obtain
创建
create
make, build, generate
删除
delete
remove, destroy, erase

———————————

实操建议

1. 从今天开始:在项目根目录创建规范文件,哪怕先只写10条最重要的规则

2. 持续迭代:每次发现AI犯重复错误,就把对应规则加进去

3. 团队共享:规范文件纳入版本控制,新成员和AI都能即时获取

4. 定期Review:AI工具在快速更新,规范的写法也需要跟着调整

———————————

总结

AI编辑器是工具,不是队友。它没有主观意愿去遵守任何规范——除非你明确告诉它。

一份好的代码规范文件,就是你和AI之间的”合同”:

• 你的职责:把规范写清楚、放对位置

• AI的职责:每次生成代码时参考并遵循

这份”合同”越详细、越有示例、越有对比,AI的执行力就越强。

别再跟AI生成的代码风格做斗争了。写一份规范,让它自己改。