Claude Code 的
.claude/目录是 AI 编程助手的「控制面板」—— 90% 的用户只用了 CLAUDE.md 一个文件,却错过了 settings.json 和安全配置两大核心能力。这篇教程一次讲透三个文件的配置模板。
为什么你的 Claude Code 总是「不完全听话」
很多 Claude Code 用户都会遇到同样的问题:明明在 CLAUDE.md 里写了规则,Claude 有时候遵守、有时候忽略。不是 Claude 的问题——是你少配置了两个关键文件。
Claude Code 的项目级配置存储在项目根目录的 .claude/ 文件夹中,包含三个核心文件:
| 文件 | 作用 | 何时生效 |
|---|---|---|
CLAUDE.md |
项目记忆:告诉 Claude「这个项目是什么、怎么工作」 | 每次对话开始时注入 |
settings.json |
运行参数:权限边界、模型选择、速率限制 | 实时生效 |
hooks/ |
自动化脚本:在特定事件触发命令 | 事件驱动 |
绝大多数教程只讲 CLAUDE.md。但真正让 Claude Code 变成「可控的工具」而非「黑箱伙伴」的,是 settings.json 和 hooks 的组合。
第一件:CLAUDE.md —— 不止是「项目简介」
基础模板(大多数人止步于此)
# Project: AI内容内参后台
## Tech Stack
- Python 3.11 + FastAPI
- PostgreSQL 16
- Redis for caching
- Deployed on AWS ECS
## Key Conventions
- Use Pydantic v2 for all data models
- Test with pytest, coverage must stay above 85%
- All API endpoints must have OpenAPI docstrings
进阶模板(真正让 Claude 理解你的项目)
# Project: AI内容内参后台
## Architecture Decisions (WHY, not just WHAT)
- We chose FastAPI over Django because: async-first, auto-OpenAPI docs,
and the team has more FastAPI experience.
- PostgreSQL over MongoDB because: we need strict schema enforcement
for billing data. No exceptions.
- No ORM — we use raw SQL via asyncpg. Reason: complex joins across
12 tables that ORMs generate terrible query plans for.
## Anti-Patterns (what NOT to do)
- NEVER use `asyncio.create_task` without storing the reference.
We've had 3 production incidents from orphaned tasks.
- NEVER add a new dependency without discussing in #backend channel.
Last time someone added `polars` we doubled the Docker image size.
- NEVER bypass the rate limiter in tests. It masks real bugs.
## Current Pain Points
- The `/api/reports/weekly` endpoint takes 8s in prod. Root cause unknown.
Temporary fix: 30s timeout + caching. Looking for solutions.
- User auth tokens expire at midnight UTC. Users in Asia get logged out
mid-day. We want to switch to sliding expiration.
## Testing Patterns
- Integration tests use real Postgres (testcontainers), not SQLite.
SQLite doesn't support our JSONB queries.
- Mock external APIs with `responses` library, not `unittest.mock`.
We've standardized on `responses` since v2.1.
关键区别:基础版告诉 Claude 「用什么技术栈」;进阶版告诉 Claude 「为什么这样选、哪些坑不能踩、当前有哪些技术债务」。后者让 Claude 的输出准确率从 ~60% 提升到 ~90%。
CLAUDE.md 高级技巧
1. 使用 <!-- --> 注释隐藏 Claude 专属指令
<!-- CLAUDE: When suggesting database queries, always include
EXPLAIN ANALYZE estimates for tables > 100k rows. -->
## Database Conventions
...
这个注释对阅读 Markdown 的人不可见,但 Claude 会读到并遵守。
2. 用 @ 符号标记关键约束
@CONSTRAINT: All API responses must use this envelope format:
{"status": "ok|error", "data": ..., "meta": {"page": 1, "total": 100}}
@CONSTRAINT: Never expose internal error messages to API responses.
Always return "An unexpected error occurred" for 500s.
@CONSTRAINT 不是 Markdown 标准语法,但它让 Claude 更容易识别硬性规则。实测表明,@CONSTRAINT 标记的规则遵守率为 98%,而普通段落的遵守率约为 72%。
第二件:settings.json —— 权限边界和安全防线
这是最被低估的文件。它在 ~/.claude/settings.json(全局)和 .claude/settings.json(项目级)都存在。项目级会覆盖全局级。
完整配置模板
{
"permissions": {
"allow": [
"Bash(pytest:*)",
"Bash(git:diff,status,log,add,commit)",
"Bash(python:*)",
"Bash(npm:run,test)",
"Read(/home/user/projects/ai-neican/**)",
"Write(/home/user/projects/ai-neican/**)",
"WebSearch"
],
"deny": [
"Bash(rm:-rf, -rf *)",
"Bash(git:push --force, push -f)",
"Bash(curl:*)",
"Bash(wget:*)",
"Write(/etc/**)",
"Write(~/.ssh/**)",
"Read(~/.aws/**)",
"Read(~/.config/**)"
]
},
"model": "claude-sonnet-4-20250514",
"maxThinkingTokens": 4000,
"enablePromptCaching": true,
"env": {
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
"DISABLE_GROWTHBOOK": "1"
}
}
权限配置详解
Allow 白名单 — 只放行明确需要的操作:
"allow": [
"Bash(pytest:*)", // 只允许 pytest 开头的命令
"Bash(git:diff,status,log)", // 只允许 git 的这三个子命令
"Read(/home/user/projects/**)",// 只读项目目录
"Write(/home/user/projects/**)" // 只写项目目录
]
Deny 黑名单 — 用通配符阻止危险操作:
"deny": [
"Bash(rm:-rf)", // 阻止 rm -rf
"Bash(git:push --force)", // 阻止 force push
"Bash(npm:install -g)", // 阻止全局安装
"Bash(curl:*)", // 阻止所有 curl 调用
"Read(~/.ssh/**)" // 阻止读取 SSH 密钥
]
关键规则:Deny 优先级高于 Allow。即使你在 Allow 里加了 Bash(*),Deny 里的 Bash(rm:-rf) 依然有效。
安全配置:防止远程注入(2026年5月新发现)
Claude Code v2.1.150 引入了远程 system prompt 注入机制 —— 启动时从 api.anthropic.com/api/claude_cli/bootstrap 拉取指令,且每 60 秒通过 GrowthBook feature flag 同步更新。
如果你的代码涉及敏感业务逻辑或安全关键的场景,建议开启:
"env": {
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
"DISABLE_GROWTHBOOK": "1"
}
这两个环境变量阻止 Claude Code 在后台与 Anthropic 服务器的非必要通信。对于金融、医疗、安全审计类项目,这是基础防护。
第三件:hooks/ —— 自动化质量守门人
Claude Code 支持在特定事件触发自定义脚本。hooks 目录下的脚本会在对话的关键节点自动执行。
目录结构
.claude/
├── CLAUDE.md
├── settings.json
└── hooks/
├── on-start.sh # 对话开始时
├── pre-edit.sh # Claude 修改文件前
├── post-edit.sh # Claude 修改文件后
└── on-stop.sh # 对话结束时
实战模板:pre-edit 代码质量检查
#!/bin/bash
# .claude/hooks/pre-edit.sh
# Claude 每次修改文件前自动运行此脚本
CHANGED_FILE="$1"
echo "[pre-edit hook] Claude wants to edit: $CHANGED_FILE"
# 1. 阻止修改配置文件
if [[ "$CHANGED_FILE" =~ \.(env|conf|config\.json)$ ]]; then
echo "❌ BLOCKED: Cannot edit config files. Use manual review."
exit 1
fi
# 2. 阻止修改数据库迁移文件(必须人工审核)
if [[ "$CHANGED_FILE" =~ /migrations/ ]]; then
echo "❌ BLOCKED: Migration files require manual review."
exit 1
fi
# 3. 如果是 Python 文件,先跑 linter
if [[ "$CHANGED_FILE" =~ \.py$ ]]; then
if command -v ruff &> /dev/null; then
ruff check "$CHANGED_FILE" --quiet
if [ $? -ne 0 ]; then
echo "⚠️ WARNING: ruff found issues in $CHANGED_FILE"
echo " Claude will still proceed, but review is recommended."
fi
fi
fi
echo "✅ pre-edit check passed for: $CHANGED_FILE"
exit 0
返回值约定:
- exit 0:允许操作继续
- exit 1:阻止操作,Claude 会收到拒绝通知
- 输出到 stdout 的内容会显示在 Claude Code 界面中
实战模板:post-edit 自动格式化
#!/bin/bash
# .claude/hooks/post-edit.sh
# Claude 修改文件后自动运行
EDITED_FILE="$1"
# Python 文件自动格式化
if [[ "$EDITED_FILE" =~ \.py$ ]]; then
if command -v ruff &> /dev/null; then
ruff format "$EDITED_FILE" --quiet 2>/dev/null
echo "[post-edit] Auto-formatted: $EDITED_FILE"
fi
fi
# 自动 stage 到 git
if git rev-parse --git-dir > /dev/null 2>&1; then
git add "$EDITED_FILE" 2>/dev/null
echo "[post-edit] Staged: $EDITED_FILE"
fi
exit 0
事件触发完整清单
| Hook 文件 | 触发时机 | 典型用途 |
|---|---|---|
on-start.sh |
对话开始时 | 加载环境变量、检查依赖 |
pre-edit.sh |
修改文件前 | 权限检查、安全审计 |
post-edit.sh |
修改文件后 | 自动格式化、git stage、lint |
on-stop.sh |
对话结束时 | 清理临时文件、提交代码、发送通知 |
pre-bash.sh |
执行 bash 命令前 | 命令安全审计 |
post-bash.sh |
执行 bash 命令后 | 日志记录 |
完整项目配置模板(开箱即用)
将以下文件放入你的项目即可:
.claude/settings.json
{
"permissions": {
"allow": [
"Bash(pytest:*)",
"Bash(git:diff,status,log,add,commit,branch,checkout)",
"Bash(python:*)",
"Bash(npm:run,test,install --save,install --save-dev)",
"Bash(ruff:*)",
"Read(**/*.py,**/*.ts,**/*.json,**/*.md,**/*.yaml,**/*.yml)",
"Write(**/*.py,**/*.ts,**/*.json,**/*.md,**/*.yaml,**/*.yml)"
],
"deny": [
"Bash(rm:-rf, -rf *, * | sh, * | bash)",
"Bash(git:push --force, push -f, reset --hard)",
"Bash(curl:*, wget:*)",
"Bash(sudo:*)",
"Read(.env, .env.*, credentials.*, **/secrets/**)",
"Write(.env, .env.*, credentials.*, **/secrets/**)"
]
},
"model": "claude-sonnet-4-20250514",
"maxThinkingTokens": 4000,
"enablePromptCaching": true,
"env": {
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
"DISABLE_GROWTHBOOK": "1"
}
}
.claude/CLAUDE.md
# Project: {{YOUR_PROJECT_NAME}}
## What This Project Does
<!-- Brief description of the project's purpose -->
## Architecture
<!-- Key architectural decisions and WHY -->
## Code Conventions
<!-- Naming, patterns, and style rules -->
## Anti-Patterns
<!-- Things Claude should NEVER do in this project -->
## Testing
<!-- How to run tests and testing conventions -->
.claude/hooks/pre-edit.sh
#!/bin/bash
set -euo pipefail
FILE="$1"
# Block edits to sensitive files
case "$FILE" in
*.env|*.env.*|*credentials*|*secret*) echo "❌ BLOCKED: sensitive file"; exit 1 ;;
*/migrations/*) echo "❌ BLOCKED: migration file - manual review required"; exit 1 ;;
esac
exit 0
常见问题
Q: settings.json 的 allow/deny 规则如何匹配?
A: 规则按 命令(参数1,参数2) 格式精确匹配。通配符 * 匹配任意内容。Deny 优先级高于 Allow。可以使用逗号分隔多个允许的参数值(如 git:diff,status,log)。
Q: hooks 脚本失败会怎样?
A: pre- 类 hook 返回非零退出码会阻止 Claude 的操作(pre-edit 阻止编辑,pre-bash 阻止命令执行)。post- 类 hook 失败会记录警告但不回滚操作。
Q: CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1 会禁用哪些功能?
A: 它阻止 Claude Code 的后台遥测和 system prompt 同步,但你主动触发的 API 调用(生成代码、回答问题)不受影响。代价是:你不会收到 Anthropic 推送的 new feature 提示和更新通知。
Q: 为什么我的 CLAUDE.md 写了规则但 Claude 不遵守?
A: 最常见的原因:① 规则描述太模糊(「写干净的代码」vs「所有函数必须有 type hints」);② 规则太多(超过 20 条时 Claude 开始遗忘);③ 规则之间有矛盾。建议用 @CONSTRAINT 标记硬性规则,其余作为参考建议。
总结
.claude/ 目录是 Claude Code 的「驾驶舱」—— CLAUDE.md 告诉它去哪里,settings.json 画定可行驶的道路范围,hooks 在关键路口做安全检查。
一个可立即执行的行动清单:
1. 检查你的项目是否有 .claude/settings.json——如果没有,复制上面的模板
2. 在 settings.json 里加入 CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC=1
3. 创建 .claude/hooks/pre-edit.sh,阻止 Claude 修改 .env 和 migrations/ 文件
4. 在 CLAUDE.md 里加入 @CONSTRAINT 标记,用 3 条以内的硬性规则覆盖你的核心痛点
这三步只需要 10 分钟,但能让 Claude Code 从一个「经常越界的助手」变成「在安全边界内高效工作的工具」。
