Avi Chawla 在博客上写了一篇题为"Anatomy of the .claude/ Folder"的文章,在 Hacker News 上获得 317 分和 160 条评论。
他说:"大多数团队以某种形式采用了 AI,但'使用 AI'和'从 AI 获得可衡量的 ROI'之间的差距比人们意识到的要大。"
但今天我们要讨论的是另一个话题:Claude Code 的 .claude/ 文件夹。
"Claude Code 用户通常把 .claude 文件夹当作一个黑盒子。他们知道它存在。他们看到它出现在他们的项目根目录。但他们从未打开它,更不用说理解里面的每个文件做什么了。"
"那是一个错过的机会。"
两个 .claude 目录
首先,值得提前知道的一件事:实际上有两个 .claude 目录,不是一个。
第一个在你的项目内,第二个在你的主目录中:
项目级文件夹保存团队配置。你把它提交到 git。团队的每个人都得到相同的规则、相同的自定义命令、相同的权限策略。
全局 ~/.claude/ 文件夹保存你的个人偏好和机器本地状态,比如会话历史和自动记忆。
CLAUDE.md
这是整个系统中最重要的文件。当你开始一个 Claude Code 会话时,第一件它读取的是 CLAUDE.md。它把它直接加载到系统提示中,并在整个对话中记住它。
简单地说:你在 CLAUDE.md 中写的任何东西,Claude 都会遵循。
如果你告诉 Claude 总是先写测试再实现,它会。如果你说"永远不要用 console.log 做错误处理,总是用自定义日志模块",它会每次都尊重那个。
项目根目录的 CLAUDE.md 是最常见的设置。但你也可以在 ~/.claude/CLAUDE.md 中有一个用于全局偏好(适用于所有项目),甚至在子目录中有一个用于文件夹特定规则。Claude 读取所有并组合它们。
写什么和不写什么
大多数人要么写太多要么写太少。这里是什么有效。
写:
- 构建、测试和 lint 命令(npm run test、make build 等)
- 关键架构决策("我们使用 Turborepo 的 monorepo")
- 不明显的陷阱("TypeScript 严格模式开启,未使用变量是错误")
- 导入约定、命名模式、错误处理风格
- 主要模块的文件和文件夹结构
不写:
- 属于 linter 或 formatter 配置的东西
- 你已经可以链接的完整文档
- 解释理论的长段落
保持 CLAUDE.md 在 200 行以下。超过那个的文件开始消耗太多上下文,Claude 的指令遵循实际上下降。
CLAUDE.local.md
有时你有一个偏好特定于你,不是整个团队。也许你更喜欢不同的测试运行器,或者你想要 Claude 总是用特定模式打开文件。
在你的项目根目录创建 CLAUDE.local.md。Claude 将它与主 CLAUDE.md 一起读取,它被自动 gitignore 所以你的个人调整永远不会进入仓库。
rules/ 文件夹
CLAUDE.md 对一个项目工作很好。但一旦你的团队增长,你得到一个 300 行的 CLAUDE.md 没人维护每个人忽略。
rules/ 文件夹解决那个。
.claude/rules/ 内的每个 markdown 文件自动与你的 CLAUDE.md 一起加载。而不是一个巨大的文件,你按关注点分割指令:
每个文件保持专注和容易更新。拥有 API 约定的团队成员编辑 api-conventions.md。拥有测试标准的人编辑 testing.md。没人互相踩踏。
真正的力量来自路径范围规则。添加一个 YAML frontmatter 块到一个规则文件,它只在 Claude 用匹配文件工作时激活:
paths:
- "src/api/*"
- "src/handlers/*"
当编辑 React 组件时,Claude 不会加载这个文件。它只在它在 src/api/ 或 src/handlers/ 内工作时加载。没有 paths 字段规则无条件加载,每个会话。
这是当你的 CLAUDE.md 开始感觉拥挤时的正确模式。
commands/ 文件夹
开箱即用,Claude Code 有内置斜杠命令像 /help 和 /compact。commands/ 文件夹让你添加你自己的。
你放到 .claude/commands/ 的每个 markdown 文件变成一个斜杠命令。
名为 review.md 的文件创建 /project:review。名为 fix-issue.md 创建 /project:fix-issue。文件名是命令名。
这是一个简单例子。创建 .claude/commands/review.md:
# Review current changes
Here are the current changes:
```shell
!git diff
Please review them for:
- Security issues
- Performance concerns
- Code style violations
现在在 Claude Code 中运行 `/project:review`,它自动注入真实的 git diff 到提示中,在 Claude 看到之前。感叹号反引号语法运行 shell 命令并嵌入输出。那是让这些命令真正有用而不是只是保存文本的东西。
用 `$ARGUMENTS` 传递命令名后的文本:
运行 `/project:fix-issue 234` 把问题 234 的内容直接喂到提示中。
项目命令在 `.claude/commands/` 被提交和与团队共享。对于你想要在所有项目中无论项目的命令,把它们放在 `~/.claude/commands/`。那些显示为 `/user:command-name` 而不是。
一个有用的个人命令:每日站会助手、一个遵循你的约定生成提交信息的命令、或一个快速安全扫描。
## skills/ 文件夹
你现在知道命令如何工作。Skills 在表面上看起来相似,但触发根本不同。在我们继续之前,这里是区别:
**命令**:你必须输入斜杠命令来触发它们。
**Skills**:是 Claude 可以在没有你输入斜杠命令的情况下自己调用的工作流,当任务匹配技能描述时。命令等你。技能观察对话并在时机对时行动。
每个技能在它自己的子目录中有一个 SKILL.md 文件:
.skills/ security-review/ SKILL.md DETAILED_GUIDE.md
SKILL.md 用 YAML frontmatter 描述何时使用它:
```yaml
description: >
Review code for security vulnerabilities including injection attacks,
authentication bypass, and data exposure.
当你说"review this PR for security issues",Claude 读取描述,识别它匹配,并自动调用技能。你也可以用 /security-review 显式调用它。
与命令的关键区别:技能可以把支持文件捆绑在一起。上面的 DETAILED_GUIDE.md 引用拉入一个详细文档,它就在 SKILL.md 旁边。命令是单个文件。技能是包。
个人技能在 ~/.claude/skills/ 并在所有你的项目中可用。
agents/ 文件夹
当一个任务复杂到足以从专用专家受益时,你可以在 .claude/agents/ 定义一个子代理角色。每个代理是一个 markdown 文件,有它自己的系统提示、工具访问和模型偏好:
这里是一个 code-reviewer.md 看起来像什么:
# Code Reviewer Agent
You are a meticulous code reviewer focused on security and performance.
## Instructions
- Check for security vulnerabilities
- Identify performance bottlenecks
- Suggest improvements
## Tools
- Read
- Grep
- Glob
当 Claude 需要一个代码审查时,它在它自己的隔离上下文窗口中生成这个代理。代理做它的工作,压缩发现,并报告回来。你的主会话不会被数千个 token 的中间探索弄乱。
tools 字段限制代理能做什么。一个安全审计员只需要 Read、Grep 和 Glob。它没有权利写文件。那个限制是故意的和值得明确说明的。
model 字段让你用一个更便宜、更快的模型做专注任务。Haiku 处理大多数只读探索很好。把 Sonnet 和 Opus 留给真正需要它们的工作。
个人代理在 ~/.claude/agents/ 并在所有你的项目中可用。
settings.json
.claude/ 内的 settings.json 文件控制 Claude 允许和不允许做什么。它是你定义 Claude 能运行哪些工具、能读哪些文件、以及是否需要询问前运行某些命令的地方。
完整文件看起来像这样:
{
"$schema": "https://schemas.claude.com/v1/settings.json",
"allow": [
"Bash(npm run *)",
"Bash(make *)",
"Bash(git *)",
"Read",
"Write",
"Edit",
"Glob",
"Grep"
],
"deny": [
"Bash(rm -rf *)",
"Bash(curl *)",
"Read(.env)",
"Read(secrets/*)"
]
}
这里每个部分做什么。
$schema 线在 VS Code 或 Cursor 中启用自动完成和行内验证。总是包含它。
allow 列表包含无需 Claude 询问确认就运行的命令。对于大多数项目,一个好的 allow 列表覆盖:
Bash(npm run *)或Bash(make *)所以 Claude 可以自由运行你的脚本Bash(git *)用于只读 git 命令Read、Write、Edit、Glob、Grep用于文件操作
deny 列表包含完全阻止的命令,不管什么。一个合理的 deny 列表阻止:
- 破坏性 shell 命令像
rm -rf - 直接网络命令像
curl - 敏感文件像
.env和secrets/中的任何东西
如果某个东西不在任何一个列表中,Claude 在继续前询问。那个中间地带是故意的。它给你一个安全网而不必预先设想每个可能的命令。
那所说,你也可以有 settings.local.json 用于个人覆盖。它有与 CLAUDE.local.md 相同的想法。创建 .claude/settings.local.json 用于你不想提交的权限变化。它被自动 gitignore。
全局文件夹
你不经常与这个文件夹交互,但知道里面有什么有用。
~/.claude/CLAUDE.md 加载到每个 Claude Code 会话,跨越所有你的项目。好地方用于你的个人编码原则、偏好风格、或你想要 Claude 记住的任何东西,不管你在哪个仓库。
~/.claude/projects/ 存储每个项目的会话记录和自动记忆。Claude Code 自动保存笔记到它自己作为它工作:它发现的命令、它观察的模式、和架构洞察。这些跨越会话持久化。你可以用 /memory 浏览和编辑它们。
~/.claude/commands/ 和 ~/.claude/skills/ 保存所有项目中可用的个人命令和技能。
结语
Avi 说:"一旦你理解什么活在哪里和为什么,你可以配置 Claude Code 以你的团队需要的方式精确地行为。"
.claude/ 文件夹是控制中枢。它保存你的指令、你的自定义命令、你的权限规则、甚至 Claude 跨越会话的记忆。
理解它,掌控它。
在这个时代,我们需要更多关于控制,少关于黑盒。