Vibe Coding 工程化进阶(二):用 Rules 把团队规范变成 AI 的"条件反射"

AI 工程45 阅读约 9 分钟

上一篇的 AGENTS.md 是"全局常驻记忆"。但有些规范并不需要时时刻刻挂在上下文里——比如"React 组件该怎么写"只在你碰 .tsx 时才有意义。把它们也塞进 AGENTS.md,既浪费 token 又稀释重点。Rules(规则系统)就是为"精准、按需注入"而生的。

一、为什么有了 AGENTS.md 还需要 Rules

一句话区分:

AGENTS.md 回答"这个项目是什么";Rules 回答"做某类事情时该怎么做"。

AGENTS.md 是一份、always-on、讲全局。Rules 是多份、可按条件触发、讲具体场景。它们互补:

AGENTS.md Rules
数量 一份(可分层) 多份,按主题拆
生效 总是 可按文件类型/场景触发
适合 技术栈、命令、雷区 某类文件的写法、某个领域的范式

当你发现 AGENTS.md 越写越长、而且很多条目"只在某些场景才用得上"时,就该把它们拆成 Rules。

二、Rules 的格式:.cursor/rules/*.mdc

在 Cursor 里,项目规则放在 .cursor/rules/ 目录,每条是一个 .mdc 文件,带 YAML frontmatter:

---
description: TypeScript 编码规范
globs: **/*.ts
alwaysApply: false
---

# 错误处理

不要吞掉异常,必须记录上下文并向上抛出语义化错误。

\`\`\`typescript
// ❌ 差
try { await fetchData() } catch (e) {}

// ✅ 好
try {
  await fetchData()
} catch (e) {
  logger.error('Failed to fetch', { error: e })
  throw new DataFetchError('Unable to retrieve data', { cause: e })
}
\`\`\`

三个 frontmatter 字段决定它何时生效

  • description:这条规则是干嘛的(也用于"按需召回",见下)。
  • globs:文件匹配模式,命中的文件被涉及时自动挂载。
  • alwaysApply:是否每次都生效。

三、4 种触发模式(最关键的认知)

frontmatter 的不同组合,对应 4 种截然不同的注入时机:

模式 配置 触发时机 典型用途
Always alwaysApply: true 每次对话都注入 全项目铁律(少用,等同 AGENTS.md)
Auto Attached globs: **/*.tsx 涉及匹配文件时自动注入 某类文件的写法(最常用)
Agent Requested 只写 description 模型根据描述自己判断要不要拉取 偶尔用到的领域知识
Manual 都不配 @规则名 手动引用 一次性、特殊场景

用对模式比写对内容更重要。 最常见的错误是把什么都设成 alwaysApply: true——那跟把所有东西塞进 AGENTS.md 没区别,上下文很快被撑爆、重点被稀释。

经验法则:默认用 Auto Attached(globs)。能用文件类型圈定范围的,就别让它常驻。

Rules 同样支持分层:子目录下的 .cursor/rules/ 只对该目录生效,monorepo 里非常好用。

四、把规则写好的几条原则

来自实战的硬经验:

  1. 一条规则只管一件事react-components.mdcapi-conventions.mdctesting.mdc 分开,别揉成一个大文件。
  2. :单条尽量控制在 50 行内,最多别超过 500 行。太长说明该拆了。
  3. 给正反例// ❌ 差 / // ✅ 好 的对照,比十句解释都管用——AI 极擅长照着例子模仿。
  4. 写成可执行的指令,而非愿望:"用 zod 校验所有外部输入" > "注意数据安全"。
  5. scope 精准globs 写准,别用 **/* 一网打尽(那又变成 always 了)。

五、一套前端规则示例(拿去改)

.cursor/rules/react-components.mdc —— 写 .tsx 时自动生效:

---
description: React 组件编写规范
globs: **/*.tsx
alwaysApply: false
---

# React 组件规范
- 一律函数组件 + Hooks,不写 class 组件
- 可复用逻辑抽成自定义 Hook(`use` 前缀)
- props 用 TypeScript interface 显式声明,不用 any
- 列表渲染的 key 用稳定唯一 id,禁止用数组 index
- 副作用的依赖数组必须完整,不要靠 eslint-disable 绕过

.cursor/rules/data-fetching.mdc —— 数据层规范:

---
description: 数据请求与状态管理规范
globs: **/{composables,hooks,api}/**
alwaysApply: false
---

# 数据请求
- 服务端状态用数据请求库管理(React Query / useAsyncData),
  不要手动塞进全局 store
- 区分"服务端状态"和"客户端 UI 状态",前者别放 Redux/Pinia
- 所有外部响应用 zod 在边界处校验后再使用

.cursor/rules/testing.mdc —— 按需召回(Agent Requested):

---
description: 编写或修改测试时遵循的测试策略与约定
alwaysApply: false
---

# 测试约定
- 测行为不测实现;测试名描述"做什么"而非"怎么做"
- 优先 React Testing Library 的用户视角查询(getByRole 等)
- 一个 it 只断言一个行为;避免 snapshot 滥用

注意第三个没写 globs、只有 description——这样它平时不占上下文,只有当模型判断"现在在搞测试"时才会主动把它拉进来

六、别忘了它和 AGENTS.md 一样要"养"

和上一篇一个道理:Rules 是活的

AI 反复在某类文件上犯同一种错 → 这就是一条新规则的信号。把它沉淀成对应 globs 的规则,让这个错从此自动消失。

团队里更进一步:Rules 进 Git、走 Code Review。规则本身就是代码资产——它让"资深同事脑子里的隐性规范"变成"全队、每次、自动生效"的显性约束。这是 Vibe Coding 从个人技巧升级为团队能力的核心机制之一。

七、小结

  • Rules 解决 AGENTS.md 装不下、且需要"按场景精准注入"的规范。
  • 4 种触发模式:Always / Auto Attached(globs,最常用)/ Agent Requested(按需召回)/ Manual。用对模式 > 写对内容
  • 一条一事、要短、给正反例、指令化、scope 精准。
  • Rules 进版本库、当代码资产维护,是团队规范"自动化执行"的载体。

下一篇换个维度:前面两篇都在教 AI "怎么想、怎么写",但它始终被困在你的代码库里。MCP(Model Context Protocol) 给它接上外部世界——读 Figma、跑浏览器、查实时文档、连数据库,让 AI 从"只会写代码"变成"能动手干活"。

相关文章

评论 (0)

还没有评论,来抢沙发