欢迎光临
我们一直在努力

别让 AI 乱写代码:用规则文件给编码助手立规矩

AI 编码助手确实能大幅提速,但用过一段时间的人都会发现一个共同的烦恼:它很聪明,但记不住"规矩"。同一个助手,这次话聊得好好的,代码质量不错;换个话题、换个会话,它可能又用了一套完全不同的写法。团队协作时,这种"随机性"会被放大成实实在在的返工成本。

这篇文章想聊清楚一件事:怎么把团队踩过的坑、达成的约定,变成 AI 每次都会主动遵守的"规矩",而不是每次现场口头提醒。

一、先说痛点:AI 编码助手最容易让人抓狂的四个场景

1. 风格漂移

同一个助手,今天写代码习惯用 camelCase 的 getter 命名,明天可能换成一套更"啰嗦"的命名方式;这次生成的 Controller 直接返回了 Entity,下次又老老实实做了 VO 转换。没有约束的话,AI 的输出风格会随着上下文、提示词的微小变化而漂移,团队代码库越用越像"拼贴画"。

2. 隐性约定丢失

每个稍微上了年头的项目里,都有一堆"只有老员工才知道"的规矩:比如"Controller 层不能直接查数据库,必须走 Service",或者"某个金额字段传输前必须做精度处理"。这些约定从来没有写进任何文档,AI 自然也无从知晓——于是它一本正经地写出了一段"技术上能跑,但踩了隐性红线"的代码,等到评审或者上线才暴露问题。

3. 红线被无视

更让人心惊的场景是:AI 完成一次代码修改后,"贴心"地自动执行了 git commit && git push,或者自己顺手跑了一遍测试、甚至改了几条数据库数据来验证效果。这些操作单独看都不算错,但如果没有事先获得确认,很容易在没人注意的时候造成不可逆的后果。

4. 重复交"学费"

如果你观察过团队里不同人跟 AI 的对话,会发现大家都在提示词里反复重复同样的话:“记得用我们项目的这种写法”“别忘了这里要加权限校验”。这些经验从来没有被沉淀下来,每个人都在为同样的坑重新交一次学费,AI 换一个会话就把这些"叮嘱"忘得一干二净。

二、解决方案:把约定写成 AI 会自动读的规则文件

核心思路并不复杂:**不要指望在每次对话里现场"教育" AI,而是把团队的约定写成文件,让 AI 在每次会话开始时就自动加载它们。**主流 AI 编码工具基本都支持这类机制,只是各家读取的文件名和位置并不统一——具体怎么在多个工具之间协调,第三部分的教程会展开讲。这里先抓住四个通用的设计原则,跟用什么工具无关。

1. 分层加载:红线全局生效,细则按场景触发

规则不是越多越好,也不是"一个文件囊括所有"。比较实用的做法是分两层:

  • 全局强制规则:不管在改什么文件、聊什么话题,都必须遵守,典型的就是"安全红线",比如不能未经确认执行破坏性操作
  • 场景触发规则:只在特定场景下才需要加载,比如只有改动数据库相关代码时,才提醒"金额字段必须用什么类型、精度怎么处理"

这样既保证红线不会被稀释,又避免所有规则堆在一起,互相干扰、上下文过载。

这个"分层"思路不只体现在规则内容上,规则文件本身也要分层——单个文件不是越写越长就越好。一份跨工具主规则文件超过 150~200 行,就该考虑按模块拆成多份,根目录留通用约定,具体模块的细节下沉到对应子目录里,教程第 1 步会给出具体做法。

2. 可执行,而不是写百科

很多人写规则文件的第一反应是"把项目规范文档搬过来"——这恰恰是最容易失败的做法。规范文档是给人看的,规则文件是给 AI 用的操作指令,两者的写法完全不同。

一条好的规则应该包含反例和正例的直接对比,而不是抽象的原则陈述。比如与其写"请遵守良好的命名规范"(AI 根本不知道"良好"具体指什么),不如直接给一段错误写法和一段正确写法,让它照着模仿。

3. 反馈闭环:一次踩坑,一条新规则

规则文件不是一次性写完就完事的静态文档。理想的状态是:每当评审中发现一次 AI 写的代码有问题,或者线上出了一次因为 AI “自作主张"导致的小事故,就应该把这次教训直接转化成一条新规则,追加进去。这样规则库会随着团队实际踩坑的经验持续变厚,而不是停留在"上线那天写的几条”。

4. 统一入口,物理收敛:别让"闭环"闭到了不同的地方

这一点容易被忽略,但恰恰是团队用了不止一种 AI 工具之后最先暴露的问题:反馈闭环说"踩坑就补规则",但补到哪去同样重要。你在 Claude Code 里说"记住这个",它默认写进 CLAUDE.md;你在 Cursor 里说"把这个变成规则",它默认建一个新的 .mdc 文件。用得越久,同一条约定就越容易在几份文件里各长出一个不完全一致的版本,最后没人知道该信哪份。

靠"大家记得手动同步"是不可持续的,得从结构上把"写的落点"收敛成一处:让工具专属文件本身不承载独立内容,而是指向共享文件的引用(CLAUDE.md 用 @AGENTS.md 导入),并在每份入口文件顶部写一条明确的"落点元规则",告诉 AI 新的通用规则该往哪写。教程第 6 步会给出具体做法。

三、动手教程:给一个虚构项目 acme-order-service 立规矩

光讲原理有点空,我们用一个虚构的通用 Java 微服务项目 acme-order-service(一个订单服务)走一遍完整流程,从零建立规则、验证生效,到把一次踩坑经验转化成新规则。

步骤 1:建立规则文件

这里要先纠正一个容易踩的坑:不同 AI 编码工具读取规则的文件名和目录并不统一,随手建一个自己起名的目录,只有你自己在用的那个工具会读,换个同事用别的工具,规则直接形同虚设。目前几种主流工具的实际情况是:

工具实际读取的文件说明
多数工具(原生或兼容) 项目根目录的 AGENTS.md 目前最接近"通用标准"的一份,很多工具都会自动读取
Cursor .cursor/rules/ 目录下的 .mdc 文件 Cursor 专属格式,支持按文件路径精确触发,也兼容读取 AGENTS.md
Claude Code 根目录的 CLAUDE.md 优先认自己这份,不会自动读 AGENTS.md,需要手动引用

实用的做法不是选一个"正确答案",而是分层:把团队通用的约定写进 AGENTS.md,作为跨工具的主规则;只有确实需要某个工具专属能力(比如 Cursor 按文件类型精确触发)时,才补一份该工具专属的文件,并在里面引用 AGENTS.md,避免同一条规则维护两份。

对于 acme-order-service,目录结构大致是:

acme-order-service/
├── AGENTS.md # 跨工具主规则,团队里用什么工具都先读这份
├── CLAUDE.md # 只有一行 @AGENTS.md,让 Claude Code 复用同一份规则
└── .cursor/
└── rules/
└── safety.mdc # 仅 Cursor 团队成员需要:按需精细化补充

有一点要提前说清楚:不能把 AGENTS.md 本身做成一个目录——工具查找的是这个精确文件名,改成同名目录反而会让工具找不到文件。真正支持的做法是允许在子目录里再放一份 AGENTS.md,工具会读取离当前编辑文件最近的那一份。等 acme-order-service 规模变大、比如拆出一个支付模块之后,目录会长成这样:

acme-order-service/
├── AGENTS.md # 根目录:通用约定、命名规范、安全红线
├── CLAUDE.md
├── .cursor/rules/safety.mdc
└── payment/
└── AGENTS.md # 支付模块专属补充,只写这个模块特有的东西

这里有个坑:不同工具处理"根目录 + 子目录都有 AGENTS.md"的方式并不一致——有些工具会把根目录到当前目录逐级拼接读取(子目录那份是"追加"),有些工具只认最近的一份、直接忽略上层文件。所以 payment/AGENTS.md 里不要重复抄根目录已经写过的规则,只写"支付模块特有"的内容,通用红线永远只在根目录维护一份,不然又会回到"规则被写散、多份内容各自漂移"的老问题。

步骤 2:写第一条规则——Service 层命名规范

在 AGENTS.md 里新增一节,内容不写空泛原则,直接给对比示例:

# AGENTS.md

## Service 层命名规范
– Service 接口以业务名 + `Service` 结尾,禁止用模糊词(如 Stuff、Helper、Manager)
– 接口方法用具体动词开头(create / cancel / query),禁止用 handle、process、doXxx 这类模糊动词
– 入参使用具体的 Request/DTO 类型,禁止直接传 Map 或多个零散参数

### 反例
public interface OrderStuff {
void doOrder(String id, String type, Map<String, Object> data);
}

### 正例
public interface OrderService {
OrderResult createOrder(CreateOrderRequest request);
void cancelOrder(Long orderId);
}

如果团队里有人用 Claude Code,只需要在根目录建一个 CLAUDE.md,内容就一行:

@AGENTS.md

这样 Claude Code 每次启动也会把 AGENTS.md 的内容合并进来,不用把规则再抄一份。

步骤 3:写第二条规则——高危操作红线

同样追加到 AGENTS.md:

## Git 操作红线

严禁在没有用户明确同意的情况下执行 `git commit`、`git push` 或其他会
修改远程仓库状态的操作。

完成代码修改后:
1. 先展示改动内容摘要
2. 等待用户明确说"提交"或"可以了"之后,才允许执行 commit
3. 任何情况下都不允许自行执行 push

这条属于"任何场景都必须遵守"的红线,如果团队主力用 Cursor,可以再补一份 .cursor/rules/safety.mdc,把同样的红线设成"始终生效"(不依赖模型主动判断要不要读取),作为双重保险:


alwaysApply: true

# 高危操作红线(同 AGENTS.md,Cursor 强制加载版)

严禁未经用户明确同意执行 git commit / git push。

步骤 4:实测验证

规则写完不代表就万事大吉,一定要验证它真的生效。找一个小改动让 AI 去做,比如"给订单服务加一个查询订单状态的接口",观察两件事:

  • 它生成的接口和方法命名,是否符合刚写的命名规则(而不是随手起个 OrderUtil.getStatus())
  • 改完代码之后,它是否老老实实停下来等你确认,而不是自己执行了 git commit

如果发现规则没生效,先排除"文件放错了工具认的位置"这个最常见的坑(比如用的是 Claude Code,却只写了 .cursor/rules/);确认文件位置没问题后,通常是规则内容还是太抽象、缺少具体的反例正例对比——回到步骤 2、3 把规则写得更具体。如果团队里有人用 Cursor、有人用 Claude Code,最好都各自验证一遍,别假设一个工具测通过了,别的工具也一定生效。

步骤 5:把一次踩坑经验变成新规则

假设过了几天,评审时发现 AI 生成的一段代码里,把一个可能抛异常的调用套了个空的 try-catch,异常被原地吞掉,业务出错时完全没有日志可查。这就是一次典型的"隐性约定"——"不允许吞异常"从来没写下来。

这时候不要只是在这次对话里说一句"别这样写",而是立刻把它变成一条新规则,追加到 AGENTS.md:

## 异常处理规范

严禁出现空的 catch 块或吞掉异常不做任何处理的写法。

### 反例
try {
orderClient.notify(order);
} catch (Exception e) {
// 忽略
}

### 正例
try {
orderClient.notify(order);
} catch (Exception e) {
log.error("订单通知失败, orderId={}", order.getId(), e);
throw new OrderNotifyException("订单通知失败", e);
}

因为写进的是 AGENTS.md 而不是某个工具专属的文件,团队里不管谁在用什么工具,这条新规则都能同步生效,不需要再手动同步到别的文件。

这样下次同类问题出现的概率就会明显降低——规则库会随着真实踩坑经验持续增厚,而不是停留在项目刚启动那天写的那几条。

步骤 6:防止规则被写散——把落点从结构上收敛掉

规则库用了几个月之后,最容易出的问题不是"没有规则",而是"规则散在好几个地方,而且互相不一致"。最简单也最该先做的动作,是加一条"落点元规则",写在每份入口文件的最上面:

> 新增的通用业务规则、命名规范、安全红线,一律写进 AGENTS.md。
> 本文件只允许存放该工具专属能力相关的内容,不允许新增业务规则。

CLAUDE.md 和 .cursor/rules/ 下的文件顶部都加上类似的一句,相当于给 AI 一个"该往哪写"的明确指引,而不是让它凭默认行为决定。

即便加了元规则,也建议每隔一段时间人工扫一眼各工具专属文件里有没有混进本该属于 AGENTS.md 的内容——这算是规则库的"技术债清理",跟代码重构是一个道理,不做的话规则库迟早会积累到没人敢信任的地步。

小结

规则文件解决的是"记忆"问题:把团队达成的约定、踩过的坑,变成 AI 每次会话都会自动带上的隐性上下文,而不是靠人一次次现场提醒。它不需要多复杂的工具,核心就是四点——分层加载、可执行的反例正例、闭环反馈、把落点从结构上收敛掉。最后这一点在只用单一 AI 工具时不明显,但团队用的工具一多,往往就是决定规则库能不能长期维护下去的关键。下一篇我们会聊另一个问题:光有规则还不够,AI 还需要"记住"这个项目本身的业务逻辑和历史决策,这就是知识库自动沉淀要解决的事。

系列文章

本系列共四篇文章,建议按顺序阅读,构建完整的 AI 辅助开发工作流:

  • 规则文件 – 如何用规则文件定义 AI 编码助手的红线约束,解决“AI 写代码不守规矩”的问题。(本文)
  • 知识库 – 如何搭建项目知识库,让 AI 记住设计决策和历史背景,解决“AI 每次会话都要重新认识项目”的问题。
  • 技能包 – 如何用技能包封装可复用的方法论和检查清单,解决“AI 的工作流程不标准、同一件事每次做法都不一样”的问题。
  • 三层协同 – 如何让规则、知识库、技能包在实际任务中协同工作,形成闭环的 AI 辅助开发体系。
  • 赞(0)
    未经允许不得转载:171主机测评 » 别让 AI 乱写代码:用规则文件给编码助手立规矩
    分享到: 更多 (0)

    评论 抢沙发

    • 昵称 (必填)
    • 邮箱 (必填)
    • 网址