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 里非常好用。
四、把规则写好的几条原则
来自实战的硬经验:
- 一条规则只管一件事:
react-components.mdc、api-conventions.mdc、testing.mdc分开,别揉成一个大文件。 - 短:单条尽量控制在 50 行内,最多别超过 500 行。太长说明该拆了。
- 给正反例:
// ❌ 差/// ✅ 好的对照,比十句解释都管用——AI 极擅长照着例子模仿。 - 写成可执行的指令,而非愿望:"用
zod校验所有外部输入" > "注意数据安全"。 - 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)
还没有评论,来抢沙发





