用 Claude Code 一段时间后,会发现真正决定它"好不好用"的,不是模型本身,而是 .claude/ 目录里那几个文件

.claude/ 不是一个目录,是两个,作用域和职责完全不同
跟着登录用户走,所有项目共享。放全局偏好——模型默认值、个人快捷指令、跨项目的记忆
典型目录结构:
~/.claude/
├── settings.json # 全局配置(model / theme / env / permissions)
├── CLAUDE.md # 全局指令(所有项目都会加载)
├── commands/ # 全局 slash 命令
├── agents/ # 全局 subagent
├── skills/ # 全局 skill
└── projects//
├── *.jsonl # 会话 transcript
└── memory/ # 自动记忆系统
projects/ 下面那一坨是 Claude Code 自动维护的"账本",不需要手动碰,但知道它在哪能解决很多奇怪问题——比如想看上次那次会话到底发了什么,直接读 jsonl 就行
放在项目根目录,只在这个项目里生效。是给团队成员或这个仓库定制专属行为的地方
/.claude/ ├── settings.json # 项目共享配置(建议提交到 git) ├── settings.local.json # 个人覆盖(应该 gitignore) ├── commands/ # 项目专属 slash 命令 ├── agents/ # 项目专属 subagent ├── skills/ # 项目专属 skill └── rules/ # 按主题拆分的规则模块
加载优先级:用户级 → 项目级 settings.json → 项目级 settings.local.json
git 提交建议:
| 提交进 git | gitignore |
|---|---|
CLAUDE.md | .claude/settings.local.json |
.claude/settings.json | (以及任何放本地 API Key 的私有文件) |
.claude/commands/、.claude/skills/、.claude/agents/、.claude/rules/ |
一个常见误区:把所有自己的偏好都堆到项目
settings.json里,结果跟同事发生 git 冲突。个人偏好走settings.local.json,团队约定才走settings.json。
常用顶层 key:model / theme / env / permissions / hooks。重点说 permissions,它的语法变体最多也最容易写错:
{
"$schema": "https://json.schemastore.org/claude-code-settings.json",
"model": "claude-opus-4-8",
"permissions": {
"allow": [
"Bash(pnpm *)", // pnpm 全部子命令(空格 + 通配)
"Bash(git add:*)", // git add 任意参数(冒号 + 通配)
"Read", "Edit", "Grep", "Glob", // 工具名直写 = 全放行
"WebFetch(domain:github.com)", // 仅放行指定域名
"Skill(commit)", // 放行某个 skill
"mcp__ide__getDiagnostics" // 放行某个 MCP 工具
],
"deny": [
"Bash(rm -rf *)",
"Bash(curl *)",
"Read(./.env)",
"Read(./.env.*)",
"Read(./secrets/**)"
]
}
}
加 $schema 后,VS Code、Cursor 这类编辑器会给字段补全和拼写校验——权限规则写错比代码写错更难察觉,写一次就值回票价
几条原则:
"Bash(*)" 一把梭python、bash、npm run * 这种,收益小、安全代价大rm -rf、git push --force、git reset --hard,让 Claude 每次都弹确认一个常见的安全盲区:Read(./.env) 阻止内置 Read 工具读 .env,但同时放行了 Bash 的话,cat .env 照样能读到——Read/Edit 的 deny 规则只约束内置文件工具,不约束 Bash 子进程。要做严格的路径隔离,需要启用 sandbox
跟 settings.json 同结构,用法差异只在一条:它必须进 .gitignore。Claude Code 自动创建它时已经做了这件事,你只要别去掉就行
适合放:本地路径的环境变量、个人调试用的临时权限、个人偏好的 model 切换
.claude/ 目录之外但跟它密切相关的文件——它会被自动注入到每次对话的 system prompt
项目级 CLAUDE.md 建议按五块来组织(参考京东内部一位同事的归纳):
find,浪费时间也浪费 token不要放:
ls)经验:CLAUDE.md 越短越好用。150 行以内能 hold 住,超过 200 行有效信息会被稀释,遵循度明显下降
还有一条比"写什么"更重要的建议——写"不要做什么"比"要做什么"更重要。模型默认行为已经够好,CLAUDE.md 真正的价值在纠偏:明确禁止用
npm、明确禁止any类型、明确禁止改某个配置文件,这类硬约束比"请遵循 SOLID 原则"有用一万倍
.claude/ 下真正能改变 Claude Code 行为的几类对象,按使用频率排序:
每个文件是一条 /foo 命令:
/.claude/commands/.mdcommands/git/commit.md → /git:commitdescription、argument-hint、allowed-tools、model 等$ARGUMENTS 占位用户传入的参数!some-shell-command 前缀会先执行 shell 命令,输出内容嵌进 prompt@path/to/file 引用文件内容适合"重复性强、模板化、自己每次说一段长 prompt 嫌烦"的场景,比如 /new-post 思考 标题 直接生成草稿
带独立上下文的"子 Claude":
/.claude/agents/.mdname、description;可选 tools(工具白名单,缺省继承全部)、modelAgent(...) 调用,也可基于 description 自动委派什么时候用:
看起来跟 subagent 像,机制完全不同:
/.claude/skills//SKILL.md——注意是目录,可以带脚本、模板、参考资料等附属文件name 和 description适合定义"按部就班的流程"——比如"发 PR 前的 review 步骤"、“生成某类规范文档”
CLAUDE.md 写到几百行就开始失控——信息被稀释,模型遵循度下降。这时把内容迁到 .claude/rules/ 下,一个主题一份 markdown,递归发现,多人维护互不干扰
两种加载模式:
例如 .claude/rules/api.md:
---
paths:
- "src/server/api/**/*.ts"
---
# API 约定
- 所有 handler 必须做输入校验
- 对外错误返回统一结构 { data, error }
- 禁止把内部堆栈直接返回给客户端
API 约定只在改 src/server/api/ 文件时进上下文,前端组件改动不会被无关规则污染
加载顺序:用户级 ~/.claude/rules/ 先加载,项目级 .claude/rules/ 后加载——后者优先,项目规则不会被个人偏好覆盖
和 CLAUDE.md 的分工:
模型遵循度的差距来自信息密度——一份 200 行的 CLAUDE.md 加上若干 paths 触发的 rules,比一份 1000 行什么都塞的 CLAUDE.md 靠谱得多
把 commands / agents / skills / hooks 打成一组分发的形式。本身不在 .claude/
下展开,而是通过 settings 的 enabledPlugins 字段启用、或经由 plugin marketplace 安装。适合给团队下发一套配套能力,避免每个仓库都重新拷贝
/.claude/output-styles/.md 定义一份替换主对话 system prompt 的"风格"。通过 /output-style 命令切换。适合在不同场景间切人格——比如代码评审模式 vs 教学讲解模式。日常用得不多,了解为主
这一节讲的是你不需要手动维护、但应该知道存在的部分
~/.claude/projects// 下每个 *.jsonl 是一次会话的完整 transcript。每行一个 JSON,记录了所有 user/assistant/tool 消息
什么时候它有用:
fewer-permission-prompts 的例子)自动记忆系统住在 ~/.claude/projects//memory/。结构是:
MEMORY.md:索引文件(每条一行,自动加载到上下文).md:每个独立记忆一个文件,有 frontmatter它存的是跨会话需要保留的、且不能从代码或 git 推出的事实——你的角色背景、反复纠正过的偏好、项目里的非显性约定
不该存的:代码片段、文件路径、git 历史、临时状态
如果你刚开始整理自己的 .claude/,从下面这套起步就够:
~/.claude/settings.json # 全局 model + 主题 + 跨项目高频权限 ~/.claude/CLAUDE.md # 你的工作风格偏好(< 50 行) /.claude/settings.json # 项目高频只读命令权限 /.claude/settings.local.json # 个人本地覆盖 /CLAUDE.md # 项目命令 + 架构骨架 + 隐性约定
commands/ agents/ skills/ rules/ 都不是必备,等你发现自己反复在做某件事时再加。过早配置等于过早优化
配好 commands 之后,日常迭代会变成这样的链条:
Input:实现 X 功能 Claude:(读 CLAUDE.md 了解项目规范,按规范写代码) Input:/review Claude:(按 review.md 的维度做代码审查,输出问题列表) Input:/lint Claude:(运行 pnpm lint,修复发现的问题) Input:/commit Claude:(分析改动,生成规范提交信息,执行 git commit)
每一步都是可被打断、可被回滚的小动作。比直接说"帮我搞定这个 feature 并提交"靠谱得多,因为模型在每一步都拿到了你这一刻明确的意图,不会"自作主张"地连贯执行十几个不该连贯执行的动作
这是
.claude/配置的最大价值——把含混的"AI 帮我写代码"拆成一连串明确的、可观察的、可控制的步骤
.claude/ 配好了不等于用得好。下面这几条,是踩过的坑里能转化为 rule / hook / prompt 习惯的:
让 AI 重构时,rule 里默认要求用注释替代删除,删除由工程师确认后再做。AI 一旦"自信地"删错文件,回滚成本远高于多看一眼注释行
如果开发、编译、测试环境路径不一致(典型:Docker 容器内 /code/... 对 IDE 终端 /data/home/.../code/...),把这个映射写进 CLAUDE.md。贴一段编译错误时 AI 能自动换算到 IDE 路径,不用人工对照
rule 里告诉 AI 跑测试用 scripts/test.sh,而不是让它每次自己拼 pytest --cov=...。脚本化的好处是统一入口,AI 一看就知道系统怎么跑,失败时也好定位是流程问题还是代码问题
大型项目编译几分钟到几十分钟,让 AI 写一点编译一次会拖死节奏。rule 里写明:只有显式说"编译"时才执行——日常生成代码先攒着,攒完一组任务再统一编译
AI 写实现代码很快,写单测时却最爱 mock 一切——主分支根本没被覆盖。两条配套习惯:rule 里要求优先覆盖核心调用链,少 mock;review 单测时优先看断言充不充分,而不是看是否通过
AI 给的方案和代码不一定对。怀疑某处不对劲又说不清时,直接问"这里是不是不优雅?“或"再 review 一下这份设计”。模型被反问时往往会主动承认问题,比你自己挑错快。这条不需要写进 rule,写进自己的 prompt 习惯就行
.claude/ 的所有这些文件、目录、配置项,本质上都是在做同一件事:把你和 agent 之间反复重复的对话固化下来
第一次让它做某件事时,多说几句无所谓;第二次还要重复同样的话,就该想想是不是该写成一条 rule、一个 command、一份 skill。用 Claude Code 这类 agent 的核心实践原理就一句话:使用过程中不断增加配置调教 agent
不要追求一次性配齐完美的 .claude/,那是过早优化,等你发现自己反复在做某件事时再加。让配置跟着真实使用一起长大,每一条新增的规则背后都该有一次"我又重复说了"的不耐烦——那才是它该被沉淀下来的信号