编码约束的艺术:CLAUDE.md / AGENTS.md 设计指南

同样的 Claude Code,有人让它写出的代码像资深工程师的作品,有人让它写出的代码像实习生交的作业。差距的 80% 不在工具本身,而在于你有没有写好那个约束文件。这篇文章告诉你如何用不到 200 行文字,让 AI 的输出质量提升一个量级。


一个实验:有约束 vs 没约束

先看一个真实对比。同样的需求——“帮我写一个用户注册接口”——同一个模型,两种输出:

没有任何约束文件时:

# AI 生成的代码
def register(username, password):
    db.execute(f"INSERT INTO users VALUES ('{username}', '{password}')")
    return {"status": "ok"}

有 CLAUDE.md 约束时:

# AI 生成的代码
def register_user(username: str, password: str) -> dict:
    """注册新用户。密码使用 bcrypt 哈希存储。"""
    if len(password) < 8:
        raise ValueError("密码至少 8 位")

    password_hash = bcrypt.hashpw(password.encode(), bcrypt.gensalt())

    with get_db() as db:
        existing = db.fetch_one("users", where={"username": username})
        if existing:
            raise ConflictError("用户名已存在")

        user = db.insert("users", {
            "id": uuid4(),
            "username": username,
            "password_hash": password_hash,
            "created_at": datetime.utcnow()
        })

    return {"user_id": str(user["id"]), "username": username}

差在哪?

维度 无约束 有约束
SQL 注入 直接拼接字符串 ❌ 参数化查询 ✅
密码存储 明文 ❌ bcrypt 哈希 ✅
输入校验 无 ❌ 密码长度检查 ✅
错误处理 无 ❌ 用户名重复检测 ✅
类型标注 无 ❌ 完整类型标注 ✅
数据库操作 裸 SQL ❌ ORM 封装 ✅

这 6 个差异,全部来自一个不到 100 行的 CLAUDE.md 文件。 AI 没有变,变的是你给它的约束。


两个文件的定位:CLAUDE.md vs AGENTS.md

很多人的第一个疑问是:这两个文件有什么区别?我需要都写吗?

CLAUDE.md                           AGENTS.md
─────────                           ─────────
平台:Claude Code 专属              平台:跨工具通用
作用域:Claude Code 行为规则         作用域:所有 AI Coding Agent 共用
格式:Markdown,自由结构             格式:Markdown,自由结构
位置:项目根目录                     位置:项目根目录
触发:Claude Code 启动时自动读取     触发:Codex/Cursor/Copilot 等各自读取

谁读哪个文件

                    ┌─────────────┐
                    │  你的项目    │
                    ├─────────────┤
                    │ CLAUDE.md   │ ← Claude Code 读
                    │ AGENTS.md   │ ← Codex CLI 读
                    │             │ ← Cursor 读(部分)
                    │             │ ← Copilot 读(部分)
                    └─────────────┘

什么时候只要一个,什么时候要两个

场景 写哪个 策略
只用 Claude Code CLAUDE.md 只写这一个,全量规则放里面
用 Claude Code + Codex 两个都写 AGENTS.md 放通用规则,CLAUDE.md 引用并补充 Claude Code 特有规则
只用 Cursor/Copilot AGENTS.md 部分 IDE 会读 AGENTS.md
团队混用多个工具 两个都写 AGENTS.md 是公约,CLAUDE.md 是特化

协同策略

┌──────────────────────────────────────┐
│           AGENTS.md                  │
│  "所有 AI 工具共同遵守的规则"          │
│                                      │
│  - 项目技术栈                         │
│  - 代码风格                           │
│  - 安全红线                           │
│  - 架构约定                           │
└────────────┬─────────────────────────┘
             │ 引用
             ▼
┌──────────────────────────────────────┐
│           CLAUDE.md                  │
│  "Claude Code 特有的规则"             │
│                                      │
│  - @include AGENTS.md(或直接引用)    │
│  - Hooks 配置说明                     │
│  - Memory 类型约定                    │
│  - Permissions 策略                   │
│  - 本项目的 Skills 使用说明            │
└──────────────────────────────────────┘

五条设计原则

写好约束文件的秘密不在于"写得多",而在于"写得对"。这五条原则来自几十个项目的实践经验。

原则一:具体(Specific)

❌ "写干净的代码"
   → 什么叫干净?AI 不知道。它的标准和你的标准不一样。

✅ "函数不超过 30 行;类不超过 200 行;一个文件不超过 500 行"
   → AI 会用这个数字做判断依据。

技巧:把抽象的形容词(“好”、“干净”、“优雅”)全部替换成可量化的标准。

抽象要求 具体写法
“好的错误处理” “所有 IO 操作必须有 try/except,异常信息用中文”
“清晰的命名” “布尔值用 is_/has_ 前缀,函数用动词开头”
“完善的测试” “每个公开函数至少有 happy path + 异常 case + 边界值 3 个测试”
“高性能” “数据库查询单次不超过 1000 行,循环内禁止 SQL 查询”

原则二:约束(Constraints)

❌ "你是一个 Python 专家"
   → 这只是身份标签,不等于行为约束。

✅ "默认使用标准库。需要第三方库时必须先确认。数据校验用 Pydantic。
    异步用 asyncio 而非 threading。"
   → 这是行为边界,AI 知道什么能做、什么不能做。

约束的核心是画框。框越小,AI 的输出越可控:

无约束                    有约束
────────                  ────────
AI 可以                   你只允许
用任何库                  用 FastAPI + SQLAlchemy
写任何风格                用 Black + 类型标注
选任何方案                先读现有代码,再复用模式

原则三:禁忌(Forbidden)

比告诉 AI "做什么"更重要的,是告诉 AI “绝对不能做什么”。

# CLAUDE.md 中的禁忌区

## 绝对不能做的事
- 不要把密钥/Token 硬编码到源码中(用环境变量)
- 不要跳过 pre-commit hooks
- 不要在没有 review 的情况下修改数据库迁移文件
- 不要删除注释——除非注释明确标注了"TODO: remove"
- 不要使用 eval() 或 exec()
- 不要拼接 SQL 字符串(必须用参数化查询)

禁忌区的价值在于防住最坏的情况。宁可多写一条禁忌,也别等出了问题再后悔。

原则四:短小(Concise)

约束文件不是文档,是命令。AI 每一行都会读,但注意力是有限的。

200 行以内    → AI 会认真读每一行
200-500 行    → AI 会浏览,但可能漏掉细节
500 行以上    → AI 只会抓关键词,大量规则被忽略

策略:如果规则超过 200 行,拆成多个文件。

CLAUDE.md            ← 入口文件(<100 行),放最重要的规则 + 索引
  │
  ├─ .claude/rules/testing.md     ← 测试相关规则(按需引用)
  ├─ .claude/rules/security.md    ← 安全相关规则
  └─ .claude/rules/api-design.md  ← API 设计约定

原则五:更新(Updated)

过期的约束比没有约束更危险。 因为 AI 会严格执行你写的规则,即使它已经不符合现状。

真实的灾难案例:

CLAUDE.md 写着:"所有 API 用 REST 风格"
但项目实际已经在迁移到 GraphQL。

结果:AI 生成了 300 行 REST 代码,全部白写。

习惯:每次技术决策变更后,检查约束文件是否需要同步更新。


分模块 vs 单文件:什么时候怎么拆

项目规模         策略                  文件结构
────────        ────                  ────────
个人小项目       单文件 CLAUDE.md       根目录一个文件
(<10 个文件)    所有规则写一起

中型项目         单文件 + 引用           CLAUDE.md(入口)
(10-50 个文件)  核心规则在入口            ↓ 引用
                 细节在独立目录          .claude/rules/*.md

大型项目         分层约束               AGENTS.md(通用公约)
(>50 个文件)    通用 + 工具特化          CLAUDE.md(Claude Code 特化)
                                        .claude/rules/(分模块规则)
                                        .cursor/rules/(Cursor 规则)

一个实用的中型项目 CLAUDE.md 模板

# 项目名称

## 技术栈
- Python 3.12+,FastAPI,SQLAlchemy 2.0,PostgreSQL
- 前端 React 18 + TypeScript + Tailwind CSS
- 部署 Docker + GitHub Actions

## 代码规范
- 所有 Python 代码用 Black 格式化(line-length=100)
- TypeScript 用 Prettier + ESLint
- 函数不超过 40 行,文件不超过 400 行
- 公开 API 必须有 docstring(Google 风格)

## 安全红线
- 禁止硬编码密钥、Token、密码
- 所有用户输入必须校验和转义
- SQL 查询必须参数化
- 文件上传限制大小和类型

## 架构约定
- 数据库迁移用 Alembic,不要直接改表
- API 返回统一格式:{ "code": 0, "data": ..., "message": "" }
- 异步操作用 asyncio,不要混用同步阻塞调用
- 日志用 structlog,不要用 print

## 规则索引
- 测试规则:`.claude/rules/testing.md`
- API 设计规范:`.claude/rules/api-design.md`

AGENTS.md 多平台通用写法

如果你同时在用 Claude Code 和 Codex CLI,需要确保两个工具的行为一致。AGENTS.md 就负责这件事。

关键:写"工具无关"的规则

❌ Claude Code 专属写法:
  "使用 /skill 命令来运行测试"
  → Codex 没有 /skill 概念,这条规则对 Codex 无效

✅ 工具无关写法:
  "修改代码后必须运行测试套件,确保所有已有测试通过后再提交"
  → 所有工具都能理解和执行

推荐的 AGENTS.md 内容分区

# AGENTS.md

## 项目身份
本项目是 XXX,主要服务 XXX 场景。
(帮 AI 理解它在什么项目里工作)

## 技术决策
- 为什么选了 A 方案而不是 B 方案
(帮 AI 理解技术背景,避免生成不合架构的代码)

## 通用规范
- 代码风格
- 命名约定
- 注释语言
(所有工具都能执行)

## 安全要求
- 通用安全红线
(SQL 注入、XSS、密钥管理等)

## 测试要求
- 什么情况下需要测试
- 测试框架和风格

常见误区与反模式

误区一:写教程而不是写规则

❌ "FastAPI 是一个现代 Python Web 框架,它的特点是..."
   → AI 不需要你教它 FastAPI。它比你还熟。

✅ "本项目用 FastAPI 2.0+,所有路由放在 api/ 目录下,用依赖注入管理数据库连接。"
   → 告诉 AI 这个项目怎么用 FastAPI,不是教它 FastAPI 是什么。

核心判断:如果你写的内容是在"解释概念",删掉。只保留"决策和约定"。

误区二:复制粘贴别人的 CLAUDE.md

GitHub 上有很多"最佳实践 CLAUDE.md 模板"。问题是:每个项目的约束都不同。

一个金融系统的安全要求 vs 一个个人博客的安全要求,能一样吗?模板可以参考结构,但内容必须自己写。

误区三:写一次就不再更新

约束文件是活文档。一个维护良好的 CLAUDE.md 应该随着项目演变而更新。建议在 PR Review 中增加一项检查:“这次改动是否需要更新约束文件?”

误区四:规则太松散,没有优先级

当你写了 50 条规则,AI 不可能每条都 100% 遵守。你要告诉它哪些是"死命令",哪些是"最好遵守":

## 🔴 硬性规则(违反必须拒绝代码)
- SQL 参数化
- 密钥不入库

## 🟡 推荐规则(尽量遵守,违反需说明理由)
- 函数不超过 40 行
- 测试覆盖率 > 80%

## 🟢 建议(参考即可)
- 优先用标准库
- 变量名尽量见名知意

5 分钟自检清单

写完约束文件后,用这个清单验证:

□ 我不在的时候,一个新同事能靠这个文件理解我的代码标准吗?
□ 有没有任何抽象的形容词("好"、"干净"、"优雅")?有的话替换成具体标准。
□ AI 读了之后知道绝对不能做什么吗?
□ 这个文件超过 200 行了吗?超过了就拆分。
□ 最近的技术决策反映在这个文件里了吗?
□ 我用别的 AI 工具(Codex / Cursor)时,这些规则还能生效吗?

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐