用 Cursor 规则文件统一团队编码规范:从约定到强制的工程实践
用 Cursor 规则文件统一团队编码规范:从约定到强制的工程实践
一、规范落地的真实困境
团队编码规范写在 Wiki 里,没人看。
新同事靠口口相传,风格越来越发散。
Code Review 变成体力活,资深工程师被拉去对格式。
这是很多团队的真实状态。
规范有了,执行靠自觉,效果看运气。
AI 编程助手普及后,出现了一个新思路。
把规范写进 Cursor 的规则文件,让模型在生成代码时直接遵守。
这样规范从"文档"变成了"模型可见的约束"。
本文探讨如何把团队规范工程化,用规则文件实现从约定到强制。
二、规则文件的底层机制
Cursor 支持两种规则载体。
一种是根目录的.cursorrules,全局生效但难维护。
另一种是.cursor/rules/目录,按.mdc文件分模块管理。
每个.mdc文件带 frontmatter。description字段决定何时加载该规则。globs字段按文件类型匹配,实现精准注入。
模型在生成或编辑代码前,会读取匹配的规则。
规则作为系统提示的一部分,约束输出风格。
下面是规则加载与匹配的流程:
flowchart LR A[用户编辑或生成代码] --> B{Cursor 扫描上下文} B --> C[读取 .cursor/rules/*.mdc] C --> D{globs 匹配?} D -->|是| E[加载 description 命中的规则] D -->|否| F[跳过该规则] E --> G[拼接为系统提示] G --> H[模型生成代码] H --> I[输出符合规范的代码] style E fill:#e1f5fe style H fill:#fff3e0关键点在于globs的粒度。
过宽会导致无关规则污染上下文。
过窄会漏掉该生效的场景。
建议按技术域拆分:Python 一套、前端一套、SQL 一套。
每套规则只在该类型文件被编辑时加载,避免互相干扰。
三、生产级规则与集成实现
下面给出一个 Python 后端规则文件的范例。
--- description: Python 后端服务的编码规范 globs: ["**/*.py"] alwaysApply: false --- # Python 后端规范 1. 函数单一职责,单函数不超过 60 行。 2. 所有外部调用必须包裹超时与重试。 3. 异常需记录上下文,禁止裸 except。 4. 数据库操作使用参数化查询,禁止字符串拼接 SQL。 5. 公开函数必须有类型注解与 docstring。仅有规则还不够,要和可执行检查联动。
下面用 pre-commit 把规范落到 CI:
# .pre-commit-config.yaml repos: - repo: https://github.com/psf/black rev: 24.4.2 hooks: - id: black - repo: https://github.com/astral-sh/ruff-pre-commit rev: v0.4.0 hooks: - id: ruff args: ["--fix"] - repo: local hooks: - id: rule-sync name: 校验规则与 lint 配置一致 entry: python scripts/check_rule_sync.py language: system pass_filenames: falsecheck_rule_sync.py负责校验规则文件中的条目。
它确保"必须有类型注解"这类约束,在 ruff 配置里都有对应规则。
避免出现"规则说要,linter 没查"的脱节。
import sys import re from pathlib import Path RULE_FILE = Path(".cursor/rules/python-backend.mdc") def extract_rules(text: str) -> list[str]: """从 mdc 提取编号条目,便于逐项核对""" return re.findall(r"^\d+\.\s+(.*)$", text, re.MULTILINE) def main() -> int: if not RULE_FILE.exists(): # 规则缺失意味着 AI 与 CI 都失去约束源 print("规则文件缺失,请先创建 python-backend.mdc") return 1 rules = extract_rules(RULE_FILE.read_text(encoding="utf-8")) if not rules: print("未解析到任何规则条目") return 1 # 实际项目应逐项校验 pyproject 中的 ruff 规则是否覆盖 print(f"已加载 {len(rules)} 条 Python 后端规范") return 0 if __name__ == "__main__": sys.exit(main())这样规则文件既是 AI 的提示,也是 CI 的检查源。
规范第一次有了"单一事实来源"。
四、边界分析与架构权衡
规则文件不是银弹,落地时有几个坑。
规则与模型的博弈。模型不一定 100% 遵守长规则。
条目超过 15 条后,遵守率明显下降。
建议每条规则都可机器校验,把"软约束"交给 linter。
维护成本。规范演进时,规则文件和 linter 配置要同步改。
不同步就会出现"AI 写的对,CI 报错的错"。
用上面的同步脚本能缓解,但不能根除。
上下文膨胀。每个.mdc都占 token。
规则总字数建议控制在 800 字以内。
超出部分应拆成按需加载的模块。
过度约束抑制创造力。把所有风格都写死,反而限制模型发挥。
只约束"有后果"的项:安全、异常处理、性能。
风格类细节交给 formatter 即可。
规则的版本管理常被忽视。团队规范随技术选型持续演进,规则文件必须同步更新,否则模型会用过时规范生成代码,与当前 CI 冲突,出现"AI 写的对、流水线报错"的尴尬。建议把.mdc纳入版本库,规范变更时同步提交规则更新,并在 PR 标注影响项,让审查者一并核对。新成员 onboarding 应先读规则再动手,而非等被驳回才补课。还应定期统计规则命中率,清理长期零触发的冗余条目,避免上下文无谓膨胀。规则是活文档,不是一次性配置,需要像代码一样被评审与演进。
五、总结
把团队规范写进 Cursor 规则文件,本质是把"约定"变成"约束"。
机制上依赖.cursor/rules/的 globs 精准加载。
工程上要与 ruff、pre-commit 等可执行检查联动。
落地路线:先抽取有后果的高优先级规范,写成带 globs 的 mdc 文件;再接 CI 校验;最后用同步脚本防止规则与配置脱节。规范由此成为单一事实来源,而非一纸空文。
