你有没有遇到过这种情况------
CLAUDE.md 写了 300 多行,把团队的编码规范、命名规则、部署流程全塞进去了,结果 Claude Code 执行的时候该忘还是忘。换个复杂点的任务,它甚至开始自相矛盾。
我之前也是这么干的。直到某天在 Anthropic 官方文档里看到一句话,大意是:「CLAUDE.md 只是 7 种自定义方式之一,不是唯一的。」
7 种?我数了数自己用过的,只有 CLAUDE.md 和 .claude/commands/ 两种。剩下 5 种听都没听过。
后来我花了一周把这 7 种方式全部摸透,发现一个扎心的事实:大多数人把所有规则一股脑塞进 CLAUDE.md,就像把所有衣服扔进一个抽屉------看起来都在,找的时候全乱。
这篇文章不是再做一遍「7 种方式逐一介绍」的平铺结构------那种文章已经有不少了。我要做的是:先给你 5 个真实场景,让你对号入座;再给你一个决策框架,帮你以后自己判断;最后逐一拆解每种方式的原理、用法和反模式。
说白了,「什么时候不该用」比「怎么用」更重要。
目录
- [先看 5 个场景:你中了几个?](#先看 5 个场景:你中了几个? "#%E5%85%88%E7%9C%8B-5-%E4%B8%AA%E5%9C%BA%E6%99%AF%E4%BD%A0%E4%B8%AD%E4%BA%86%E5%87%A0%E4%B8%AA")
- [一张表:7 种方式速览](#一张表:7 种方式速览 "#%E4%B8%80%E5%BC%A0%E8%A1%A87-%E7%A7%8D%E6%96%B9%E5%BC%8F%E9%80%9F%E8%A7%88")
- 决策框架:该用哪个?
- [逐一拆解:每种方式的原理 + 用法 + 反模式](#逐一拆解:每种方式的原理 + 用法 + 反模式 "#%E9%80%90%E4%B8%80%E6%8B%86%E8%A7%A3%E6%AF%8F%E7%A7%8D%E6%96%B9%E5%BC%8F%E7%9A%84%E5%8E%9F%E7%90%86--%E7%94%A8%E6%B3%95--%E5%8F%8D%E6%A8%A1%E5%BC%8F")
- [1. CLAUDE.md:记忆系统](#1. CLAUDE.md:记忆系统 "#1-claudemd%E8%AE%B0%E5%BF%86%E7%B3%BB%E7%BB%9F")
- [2. Skills:可复用工作流](#2. Skills:可复用工作流 "#2-skills%E5%8F%AF%E5%A4%8D%E7%94%A8%E5%B7%A5%E4%BD%9C%E6%B5%81")
- [3. Hooks:生命周期钩子](#3. Hooks:生命周期钩子 "#3-hooks%E7%94%9F%E5%91%BD%E5%91%A8%E6%9C%9F%E9%92%A9%E5%AD%90")
- [4. Rules:路径级规则](#4. Rules:路径级规则 "#4-rules%E8%B7%AF%E5%BE%84%E7%BA%A7%E8%A7%84%E5%88%99")
- [5. Sub-agents:子智能体](#5. Sub-agents:子智能体 "#5-sub-agents%E5%AD%90%E6%99%BA%E8%83%BD%E4%BD%93")
- [6. MCP Servers:外部工具连接](#6. MCP Servers:外部工具连接 "#6-mcp-servers%E5%A4%96%E9%83%A8%E5%B7%A5%E5%85%B7%E8%BF%9E%E6%8E%A5")
- [7. Settings:配置系统](#7. Settings:配置系统 "#7-settings%E9%85%8D%E7%BD%AE%E7%B3%BB%E7%BB%9F")
- 常见问题
先看 5 个场景:你中了几个?
在讲「怎么用」之前,先对号入座。以下 5 个场景,如果你踩过任何一个,说明你可能用错了方式。
场景一:CLAUDE.md 膨胀症
你的 CLAUDE.md 已经超过 200 行。编码规范 50 行、架构说明 80 行、部署流程 60 行、各种零碎规则 40 行。每次开会后还要往里加。结果 Claude 的遵从率越来越低------它不是不想遵守,是上下文窗口就那么大,塞太多规则它根本「看不过来」。
场景二:每次都要手敲同一段指令
每次让 Claude Code 做 Code Review,你都要粘贴同一段话:「按照我们团队的规范检查......重点关注这几个维度......输出格式是......」粘了 20 次之后你开始怀疑人生。
场景三:Claude 总是忘记「有些目录不能碰」
你在 CLAUDE.md 里写了「不要修改 legacy/ 目录的代码」,但 Claude 偶尔还是会手痒去改。不是它故意违规,是 CLAUDE.md 的规则是「建议」性质的,不是强制的。
场景四:需要 Claude 访问外部系统
你想让 Claude 直接查 Jira 看 ticket 描述、查 Sentry 看线上报错、查数据库看表结构。但 Claude Code 原生不支持这些,你只能手动复制粘贴。
场景五:复杂任务耗尽上下文
一个大重构任务,Claude 需要同时参考 10 个文件、跑测试、改代码。聊到一半发现上下文被压缩了,之前讨论的架构决策全忘了。
如果你中了 2 个以上,接下来的内容对你很有价值。
一张表:7 种方式速览
先给一张全局图,后面逐一展开。
| 方式 | 一句话说明 | 配置文件 | 作用域 | 强制力 |
|---|---|---|---|---|
| CLAUDE.md | 持久化指令,每次会话自动加载 | CLAUDE.md(Markdown) |
组织/用户/项目/本地 | 软(上下文注入,非强制) |
| Skills | 可复用工作流,按需加载 | SKILL.md(目录形式) |
企业/个人/项目/插件 | 软(调用时才加载) |
| Hooks | 生命周期钩子,硬性执行 | settings.json(JSON) |
组织/用户/项目/本地 | 硬(exit code 2 阻断) |
| Rules | 路径级条件规则 | .claude/rules/*.md |
项目级 | 软(CLAUDE.md 子系统) |
| Sub-agents | 专用子智能体,隔离上下文 | .claude/agents/*.md |
组织/CLI/项目/用户 | 硬(工具限制生效) |
| MCP Servers | 连接外部工具和数据源 | .mcp.json / CLI |
本地/项目/用户 | 硬(连接必须建立) |
| Settings | 全局配置:权限、模型、环境变量 | settings.json(JSON) |
组织/用户/项目/本地 | 硬(客户端强制执行) |
关键区分:CLAUDE.md/Skills/Rules 是「建议」 ------Claude 会看到这些内容,但可以自行判断是否遵守。Hooks/Sub-agents/MCP/Settings 是「规则」------违反就会被阻断或无法执行。
图:7 种自定义方式的强制力和作用域对比------「建议」和「规则」的本质区别
决策框架:该用哪个?
拿到一个自定义需求时,按以下 3 个问题走决策树:
问题 1:这条规则需要「每次会话都生效」还是「特定场景才需要」?
- 每次都要 → 问题 2A
- 特定场景 → 问题 2B
问题 2A:规则是「告诉 Claude 怎么做」还是「强制 Claude 不能做某事」?
- 告诉怎么做 → CLAUDE.md(编码规范、命名习惯、项目架构)
- 强制不能做 → Hooks (禁止执行
rm -rf、自动格式化)或 Settings(权限 deny 规则)
问题 2B:这个场景是「一个可复用的工作流」还是「连接外部工具」?
- 可复用工作流 → Skills(Code Review 流程、发布检查清单、文档生成)
- 连接外部工具 → MCP Servers(Jira、Sentry、数据库、Figma)
问题 3:规则只适用于代码库的某个子目录吗?
- 是 → Rules (
.claude/rules/配合paths字段) - 不是 → 回到问题 2A/2B
额外判断:
- 需要隔离上下文、并行执行、限制工具权限 → Sub-agents
- 需要配置模型、权限白名单、环境变量 → Settings
- 快速自定义命令(团队已有历史存量) → Commands (
.claude/commands/,已合并入 Skills 生态)
用一句大白话总结:CLAUDE.md 管「是什么」,Skills 管「怎么做」,Hooks 管「不能做」,Rules 管「哪里适用」,Sub-agents 管「谁来做」,MCP 管「能连什么」,Settings 管「全局开关」。
💬 你目前用得最多的是哪种自定义方式?
- A. 只用 CLAUDE.md,所有规则都往里塞
- B. 用过 Skills 或 Commands,但没深入配置
- C. Hooks / MCP / Sub-agents 都配过,已经是进阶玩家
- D. 还没开始自定义,Claude Code 开箱即用就够了
评论区说说,码哥猜选 A 的最多 😂
图:3 个问题走完决策树------拿到自定义需求时按这个流程选方式
逐一拆解:每种方式的原理 + 用法 + 反模式
1. CLAUDE.md:记忆系统
原理
CLAUDE.md 是 Claude Code 的「长期记忆」。每次会话启动时,Claude 会自动加载这些文件的内容到上下文窗口。它不是一次性指令,而是贯穿整个会话的持久化上下文。
加载顺序(从广到窄,内容拼接而非覆盖):
- 组织级 (最高优先级):macOS 在
/Library/Application Support/ClaudeCode/CLAUDE.md,Linux 在/etc/claude-code/CLAUDE.md - 用户级 :
~/.claude/CLAUDE.md - 项目级 :
./CLAUDE.md或./.claude/CLAUDE.md - 本地个人级 :
./CLAUDE.local.md(gitignore 掉,不提交)
同一层级的 CLAUDE.md 和 CLAUDE.local.md 会拼接,不会互相覆盖。子目录下的 CLAUDE.md 文件在 Claude 读取该目录文件时按需加载。
支持 @path/to/file 语法导入其他文件内容 ,最多 4 层跳转。这个功能很实用------你可以把不同主题的规则拆成独立文件,用 @ 引入,避免单文件过大。
用法示例
markdown
# CLAUDE.md
## 项目架构
本项目是 Spring Boot 3.2 单体,Java 17。
模块结构:api/(接口层)、service/(业务层)、dao/(数据层)
## 编码规范
- 使用 2 空格缩进
- 命名规范:类名 PascalCase,方法名 camelCase,常量 UPPER_SNAKE_CASE
- Controller 不放业务逻辑,只做参数校验和路由
## 构建与测试
- 构建:`./gradlew build`
- 测试:`./gradlew test`
- Lint:`./gradlew spotlessCheck`
## 引入子规则
@docs/database-conventions.md
@api/rest-standards.md
反模式
反模式 1:文件超过 200 行
CLAUDE.md 的内容每次会话都会注入上下文窗口。文件越大,留给实际任务的上下文空间越小。超过 200 行之后,Claude 的遵从率会明显下降------不是它不想遵守,是注意力被稀释了。
解法 :拆分。把长规则移到 .claude/rules/ 里用 paths 字段做路径级匹配,或用 @ 语法引入子文件。
反模式 2:写模糊指令
markdown
# 差的写法
格式化代码,保持风格统一。
# 好的写法
使用 2 空格缩进。行宽 120 字符。导入顺序:java.* → javax.* → 第三方 → 本项目。
Claude 不怕长指令,怕模糊指令。「格式化代码」这种话它理解不了你具体要什么格式。
反模式 3:在 CLAUDE.md 里写流程步骤
如果你发现自己在 CLAUDE.md 里写了「第一步做 X,第二步做 Y,第三步做 Z」------这不是 CLAUDE.md 该干的事。流程步骤应该用 Skills 封装,按需调用,不占日常上下文。
2. Skills:可复用工作流
原理
Skills 是 Claude Code 的「剧本」。把一个可重复执行的工作流打包成一个 Skill,需要的时候调用,不需要的时候不占上下文。
这是和 CLAUDE.md 最关键的区别:CLAUDE.md 的内容每次会话都在上下文里,Skills 的内容只有被调用时才加载。 Skill 的描述(description)会一直留在上下文中供 Claude 判断是否需要调用,但完整内容按需加载。
配置格式
bash
.claude/skills/
└── code-review/
└── SKILL.md
SKILL.md 由 YAML frontmatter + Markdown body 组成:
yaml
---
name: code-review
description: "按团队规范执行 Code Review,检查安全、性能、可读性"
when_to_use: "用户要求 review 代码或提交 PR 前"
argument-hint: "[file-or-pr]"
model: sonnet
effort: high
paths: ["src/**/*.ts"]
allowed-tools: Read, Grep, Glob, Bash(git *)
---
## Code Review 清单
1. 安全检查:SQL 注入、XSS、硬编码密钥
2. 性能检查:N+1 查询、大对象循环创建
3. 可读性:方法不超过 30 行、命名自解释
$ARGUMENTS 指定要 review 的文件或 PR。
几个实用的 frontmatter 字段:
context: fork--- 在隔离的子智能体中运行,不污染主对话上下文disable-model-invocation: true--- 只能用户手动/skill-name调用,Claude 不会自动触发user-invocable: false--- 反过来,只有 Claude 能自动调用,用户不能手动触发model: haiku--- 用更快更便宜的模型执行这个 Skill(适合搜索、探索类任务)
动态上下文注入 :在 SKILL.md 中用 ``!`git diff HEAD``` 语法,Claude 看到内容前会先执行 shell 命令,把输出注入上下文。这个功能非常强大------你可以让 Skill 在执行时自动获取当前 git 状态、最近的变更、测试结果等实时信息。
反模式
反模式 1:把所有 Skill 都设成 disable-model-invocation: true
你可能觉得「我不想让 Claude 自动调用 Skill,万一调错了怎么办」。但如果你全部禁用了自动调用,Claude 永远不知道你有这些 Skill------description 虽然在上下文里,但 Claude 判断「用户没明确要求,我不应该自动调用」。结果就是你的 Skills 库变成了摆设。
解法 :大部分 Skill 保持默认(允许自动调用),只对有副作用的 Skill(如部署、删除)设 disable-model-invocation: true。
反模式 2:Skill body 太长
Skill 的完整内容在调用后会留在上下文中。如果你写了一个 5000 token 的 Skill,每次调用后这 5000 token 就一直占着上下文窗口。Compaction 之后会重新附加,但有上限(单个 Skill 最多 5000 token,总计 25000 token)。
解法 :把参考材料放在 Skill 目录的辅助文件里,SKILL.md 只放核心流程。用 @references/xxx.md 引入。
反模式 3:用 context: fork 跑纯指南类 Skill
context: fork 会创建一个隔离的子智能体来执行 Skill。如果你的 Skill 只是「告诉 Claude 某些规范」而不是「让 Claude 执行一系列操作」,fork 出来的子智能体会拿到指南但没有明确的执行 prompt,效果反而不如不 fork。
3. Hooks:生命周期钩子
原理
Hooks 是 Claude Code 的「自动执行器」。它在特定生命周期事件发生时,自动运行你配置的脚本、HTTP 请求、甚至 LLM 提示。和 CLAUDE.md 最大的区别:Hooks 是强制执行的------exit code 2 会直接阻断操作,不是建议。
配置位置 :settings.json 的 hooks 字段(用户级或项目级)。
支持 30+ 种事件,最常用的几种:
| 事件 | 触发时机 | 典型用途 |
|---|---|---|
PreToolUse |
工具执行前 | 阻止危险命令、安全校验 |
PostToolUse |
工具执行后 | 自动格式化、自动 lint |
SessionStart |
会话初始化 | 加载环境变量、检查依赖 |
Stop |
Claude 完成回复后 | 发送通知、记录日志 |
UserPromptSubmit |
用户输入后 | 输入预处理、关键词替换 |
5 种 Hook 类型 :command(Shell 命令)、http(POST 请求)、mcp_tool(调用 MCP 工具)、prompt(单轮 LLM 评估)、agent(子智能体评估)。
用法示例:在文件编辑后自动运行 Prettier 格式化
json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"hooks": [
{
"type": "command",
"command": "npx prettier --write",
"args": ["${CLAUDE_FILE_PATH}"],
"timeout": 30
}
]
}
]
}
}
exit code 的含义(这是最容易搞错的):
- exit 0:成功,继续执行
- exit 1:非阻断性错误(记录日志,不影响主流程)
- exit 2 :阻断性错误(直接阻止操作)
反模式
反模式 1:用 exit 1 以为能阻止操作
这是最常见的误解。你在 Hook 脚本里检测到危险命令,exit 1 退出------结果 Claude 照样执行了。原因很简单:exit 1 只是非阻断性错误,Claude 收到一个「Hook 报了个错」的提示,但它可以选择忽略。
解法 :要阻止操作,必须 exit 2。或者在 stdout 输出 JSON:{"decision": "block", "reason": "不允许执行 rm -rf"}。
反模式 2:不加 if 过滤器,每个工具调用都触发 Hook
json
{
"matcher": "*",
"hooks": [{ "type": "command", "command": "my-script.sh" }]
}
这会每次工具调用都 spawn 一个新进程。Claude 一次对话可能调用几十次工具,你的脚本就跑几十次。轻则浪费时间,重则拖慢整个对话。
解法 :用 matcher 精确匹配工具名(如 "Bash"、"Edit|Write"),用 if 字段进一步缩小范围(如 "if": "Bash(rm *)")。
反模式 3:在 Hook 里做复杂逻辑
Hook 的设计初衷是「短平快」的自动化操作。如果你发现自己在 Hook 脚本里写了 200 行 Python------停下来,这应该是 Skills 或 Sub-agents 干的事。
4. Rules:路径级规则
原理
Rules 是 CLAUDE.md 系统的子功能,解决一个具体问题:不同目录需要不同的规则。
在单体仓库(monorepo)里,前端目录和后端目录的编码规范可能完全不同。用一个 CLAUDE.md 写两套规则会很混乱。Rules 允许你为不同路径配置不同规则,只有 Claude 访问到对应目录时才加载。
配置方式 :在 .claude/rules/ 目录下创建 .md 文件,用 YAML frontmatter 的 paths 字段指定适用路径。
markdown
---
paths: ["src/api/**", "tests/api/**"]
---
## API 层规范
- Controller 方法必须有 @Validated 注解
- 返回值统一用 ResponseEntity 包装
- 异常用 @RestControllerAdvice 全局处理
markdown
---
paths: ["src/dao/**", "resources/mapper/**"]
---
## 数据层规范
- 禁止在 DAO 层拼接 SQL,必须用 MyBatis XML
- 分页用 PageHelper,不要手写 LIMIT
反模式
反模式 1:Rules 和 CLAUDE.md 写了重复甚至矛盾的规则
Rules 在 CLAUDE.md 之后追加加载,如果两边写了矛盾的内容,Claude 的行为会不可预测。
解法:CLAUDE.md 只写全局规则,Rules 写路径特化规则。全局和局部不要有交集。
反模式 2:paths 写得太宽泛
paths: ["**"] 等于没写------这和直接放 CLAUDE.md 里没区别。Rules 的价值就在于精准匹配。
5. Sub-agents:子智能体
原理
Sub-agents 是 Claude Code 的「分身术」。当你有一个复杂任务时,可以创建一个专用的子智能体来处理。它有自己独立的上下文窗口,不会污染主对话。执行完毕后把结果返回主智能体。
核心价值:
- 上下文隔离:子智能体的执行过程不会撑大主对话的上下文
- 工具限制:可以限制子智能体只能用 Read/Grep 等只读工具,防止它乱改代码
- 并行执行:多个子智能体可以同时跑(最多 5 层嵌套深度)
- 模型路由:可以让探索任务用便宜快速的 Haiku,深度任务用 Sonnet/Opus
配置方式 :在 .claude/agents/ 目录下创建 .md 文件。
markdown
---
name: code-reviewer
description: "审查代码质量、安全性和最佳实践"
tools: Read, Glob, Grep, Bash
disallowedTools: Write, Edit
model: sonnet
maxTurns: 50
isolation: worktree
---
你是一个代码审查专家。分析代码并提供具体、可执行的反馈。
重点关注:安全性、性能、可维护性。
三种调用方式:
- 自然语言:在对话中描述任务,Claude 自行判断是否委派给子智能体
- @提及 :
@code-reviewer 看看 auth 模块的改动,保证运行一次 - 会话级 :
--agent code-reviewer,整个会话使用该子智能体
内置子智能体(不需要你创建):
- Explore:Haiku 模型,只读,用于快速搜索和探索(跳过 CLAUDE.md 和 git status 加载,速度最快)
- Plan:继承当前模型,只读,用于规划和研究
- general-purpose:所有工具,用于复杂多步任务
反模式
反模式 1:description 字段写得太模糊
yaml
# 差的写法
description: "帮我处理一些任务"
# 好的写法
description: "审查 TypeScript 代码的质量、安全性和性能问题,输出结构化的 review 意见"
Claude 靠 description 判断什么时候该委派任务给这个子智能体。写得模糊,它就不知道什么时候用。
反模式 2:复制内置子智能体的功能
你不需要创建一个「explorer」子智能体来做搜索------内置的 Explore 已经做了,而且用了更便宜的 Haiku 模型。自定义子智能体应该做内置子智能体做不了的事。
反模式 3:子智能体嵌套太深
子智能体可以生成子智能体,最多 5 层。但每多一层就多一个上下文窗口的开销。除非确实需要,否则 1-2 层就够了。
6. MCP Servers:外部工具连接
原理
MCP(Model Context Protocol)是 Anthropic 推出的开放协议,让 Claude Code 能连接外部工具、数据库和 API。它解决了 Claude Code 原生「只能操作本地文件和终端」的限制。
有了 MCP Server,Claude 可以直接查 Jira ticket、查 Sentry 报错、查数据库表结构、操作 Figma 设计稿------不需要你手动复制粘贴。
配置方式:
CLI 方式(推荐,一行命令搞定):
bash
# 远程 HTTP 服务
claude mcp add --transport http notion https://mcp.notion.com/mcp
# 本地 stdio 进程
claude mcp add --transport stdio airtable -- npx -y airtable-mcp-server
JSON 方式(.mcp.json,可提交到仓库共享给团队):
json
{
"mcpServers": {
"github": {
"type": "http",
"url": "https://api.githubcopilot.com/mcp/",
"headers": {
"Authorization": "Bearer ${GITHUB_TOKEN}"
}
},
"database": {
"command": "/path/to/db-server",
"args": ["--config", "config.json"],
"env": { "DB_URL": "${DB_URL}" }
}
}
}
三种传输协议:
http(推荐):适合远程服务,自动重连,支持 OAuthstdio:适合本地进程,Claude 启动子进程通信ws(WebSocket):适合需要推送事件的场景
反模式
反模式 1:在 .mcp.json 里硬编码 API Key
json
// 千万别这么写
"headers": { "Authorization": "Bearer sk-xxxxx" }
// 用环境变量
"headers": { "Authorization": "Bearer ${GITHUB_TOKEN}" }
.mcp.json 通常会提交到 Git 仓库。硬编码的密钥会被所有 clone 仓库的人看到。
反模式 2:不信任远程 MCP Server 的安全性
MCP Server 本质上是给 Claude 注入外部数据和工具。如果远程 Server 被攻击者控制,它可以往 Claude 的上下文里注入恶意指令(prompt injection)。企业环境里,用 allowedMcpServers / deniedMcpServers 做白名单控制。
反模式 3:用 SSE 传输(已废弃)
SSE(Server-Sent Events)已经被标记为 deprecated,官方推荐用 http 替代。如果你在文档里看到 SSE 的配置示例,直接换成 http。
7. Settings:配置系统
原理
Settings 是 Claude Code 的「控制面板」。它管理全局行为:权限规则、模型选择、环境变量、UI 偏好等。
配置层级(优先级从高到低):
- 组织级(managed settings):管理员配置,个人无法覆盖
- CLI 参数:命令行传入,临时生效
- 本地项目级 :
.claude/settings.local.json(gitignore) - 项目级 :
.claude/settings.json(提交到仓库) - 用户级 :
~/.claude/settings.json(最广,优先级最低)
权限规则的特殊合并逻辑 :其他设置是「高优先级覆盖低优先级」,但权限规则是跨层级合并 的。也就是说,项目级的 allow 规则和用户级的 allow 规则会合并在一起,不会互相覆盖。
用法示例
json
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"permissions": {
"allow": [
"Bash(npm run lint)",
"Bash(npm run test *)",
"Read(~/.zshrc)"
],
"deny": [
"Bash(curl *)",
"Read(./.env)",
"Read(./secrets/**)"
]
},
"model": "claude-sonnet-4-6",
"language": "chinese",
"autoCompactEnabled": true
}
反模式
反模式 1:直接编辑 ~/.claude.json
这个文件是 Claude Code 内部管理的,手动编辑可能导致不可预期的行为。用户级设置应该改 ~/.claude/settings.json。
反模式 2:不用 $schema 做校验
Settings 是 JSON 格式,少一个逗号就解析失败。加上 $schema 字段后,编辑器会自动校验字段名和类型,提前发现错误。
反模式 3:在 Settings 里写行为指令
Settings 管的是「配置」------权限、模型、环境变量。如果你在 settings.json 里写了「请使用 2 空格缩进」这种行为指令,它不会生效。行为指令应该放 CLAUDE.md。
实战组合:一个真实项目的配置
光讲理论不够,给一个我实际在用的项目配置结构:
bash
my-project/
├── CLAUDE.md # 全局规则(< 100 行)
├── .claude/
│ ├── settings.json # 权限规则 + Hooks
│ ├── rules/
│ │ ├── api-rules.md # API 层专用规则
│ │ └── dao-rules.md # 数据层专用规则
│ ├── skills/
│ │ ├── code-review/
│ │ │ └── SKILL.md # Code Review 工作流
│ │ └── deploy-check/
│ │ └── SKILL.md # 部署前检查清单
│ ├── agents/
│ │ └── security-auditor.md # 安全审计子智能体
│ └── mcp.json # MCP Server 配置
└── .claude/settings.local.json # 本地个人覆盖(gitignore)
CLAUDE.md 里只放全局的、简短的规则(< 100 行)。路径特化的规则拆到 rules/ 里。可复用的工作流拆到 skills/ 里。需要隔离执行的任务用 agents/ 处理。外部工具用 mcp.json 连接。权限和 Hooks 放 settings.json。
这样每个文件各司其职,不会出现一个 500 行的 CLAUDE.md 把所有东西塞在一起的情况。
常见问题
Q: CLAUDE.md 和 .claude/CLAUDE.md 有什么区别?放哪个位置更好?
A: 两个位置都会被加载,效果一样。区别在于文件系统的位置:项目根目录的 CLAUDE.md 更显眼,.claude/CLAUDE.md 更整洁(不污染根目录)。如果你的项目根目录已经有 README.md、package.json 等一堆文件,建议放 .claude/CLAUDE.md。两种都行,选一个团队统一就好。
Q: Skills 和 .claude/commands/ 是什么关系?我之前的 commands 还能用吗?
A: Skills 是 commands 的升级版。Anthropic 已经把两者统一了------commands 文件仍然有效,但新功能(如 context: fork、paths 匹配、辅助文件)只在 Skills 里支持。如果你已有 commands,不需要迁移,它们会继续工作。但新的自定义命令建议用 Skills。
Q: Hooks 和 CLAUDE.md 的规则有什么本质区别?
A: CLAUDE.md 是「建议」,Hooks 是「规则」。 CLAUDE.md 写「不要修改 legacy/ 目录」,Claude 会尽量遵守,但偶尔可能违反。Hook 配置 PreToolUse 检测到对 legacy/ 目录的写操作时返回 exit 2,操作会被直接阻断------Claude 根本没有机会违反。
如果你的规则必须被严格遵守(安全、合规、防误操作),用 Hooks。如果是编码风格、偏好建议,用 CLAUDE.md。
Q: 我需要为每个项目都配置 MCP Server 吗?
A: 不一定。MCP Server 有三个作用域:本地(.mcp.json 在项目目录,只对当前项目生效)、项目(.mcp.json 提交到仓库,团队共享)、用户(~/.claude.json 配置,所有项目通用)。像 GitHub MCP 这种通用的,放用户级;项目特定的数据库 Server,放项目级。
Q: 7 种方式会不会互相冲突?
A: 会,最常见的冲突有两种。一是 CLAUDE.md 和 Rules 写了矛盾的内容------解法是 CLAUDE.md 只写全局规则,Rules 写路径特化规则,不重叠。二是 Hooks 和 Settings 的权限规则冲突------Hooks 在 settings.json 里配置,如果项目级 Hook 阻止了某个操作,但用户级 Settings 的 allow 规则放行了,结果取决于合并逻辑。建议团队统一在一个层级配置,不要分散。
图:每种方式最常见的反模式------踩过才知道为什么不能这么干
说到底,Claude Code 的 7 种自定义方式不是「哪个更好」的问题,是「什么场景用什么」的问题。 把所有规则塞进 CLAUDE.md,就像把所有衣服扔进一个抽屉------你当然能塞进去,但找的时候全乱。拆开来各司其职,Claude 的表现会好很多。
这篇文章把每种方式的原理、用法和反模式都拆了一遍,但最核心的其实是那个决策框架------下次遇到自定义需求,先问自己三个问题,答案自然就出来了。
下一篇打算拆 Claude Code 的 Hooks 实战------30 多种事件怎么选、5 种 hook 类型怎么搭配、真实的自动化工作流怎么搭。感兴趣的关注一下,说实话公众号算法越来越不按常理出牌了,把码哥字节设为星标至少保证你能收到更新,不会错过。如果你身边有同事在用 Claude Code 但还没搞清楚这些配置方式,这篇可以直接甩给他,省他踩一遍。
如果这篇对你有帮助,转发给你的程序员朋友 --- 大家都在摸索 Claude Code 的正确用法,你的分享可能帮他省很多时间。