---
title: "settings.json 全局 vs 项目层级"
wiki: cli
category: "配置管理"
slug: global-vs-project-settings
url: https://learnagent.wiki/cli/cards/global-vs-project-settings
tags: ["settings", "配置", "Claude Code", "用户配置", "项目配置"]
last_updated: 2026-04-22
reading_time: 15
---

> Claude Code 的所有配置——能允许哪些工具、敏感目录要不要拦、用哪个模型、要不要挂钩子、要不要自动加 `Co-Authored-By`——最终都汇聚到一个名字叫 `settings.json` 的 JSON 文件里。但这个文件不止一份。Claude Code 把它**沿用户、项目、个人覆盖三层叠起来**，叫法不严格统一，本卡用三个固定的中文称呼：

# settings.json 全局 vs 项目层级

## 基础概念

Claude Code 的所有配置——能允许哪些工具、敏感目录要不要拦、用哪个模型、要不要挂钩子、要不要自动加 `Co-Authored-By`——最终都汇聚到一个名字叫 `settings.json` 的 JSON 文件里。但这个文件不止一份。Claude Code 把它**沿用户、项目、个人覆盖三层叠起来**，叫法不严格统一，本卡用三个固定的中文称呼：

- **用户级**（user / global）：跟着你这个人走，所有项目共用。位置 `~/.claude/settings.json`。
- **项目级**（project / shared）：跟着这个仓库走，**会进 git**，团队所有人共享。位置 `<repo>/.claude/settings.json`。
- **local 级**（local / personal）：跟着"你 + 这个仓库"走，**默认进 .gitignore**，只属于你自己这台机器。位置 `<repo>/.claude/settings.local.json`。

在团队 / 企业场景之上，还有一层 **企业 managed settings**，由 IT 推下来强制生效，普通用户不能改、也不能覆盖；放在 macOS 的 `/Library/Application Support/ClaudeCode/managed-settings.json`、Linux 的 `/etc/claude-code/managed-settings.json`、Windows 的 `C:\Program Files\ClaudeCode\managed-settings.json`（也支持 MDM / 注册表）。本卡聚焦个人/团队最常打交道的那三层，企业 managed 只在"覆盖优先级"那张图里提一下。

为什么要分这么多层？**核心动机就一个：让"团队约定"和"个人偏好"互不打架，又能互相补强**。比如团队希望所有人都禁止 `curl` 工具直接访问外网（写在项目级），但你个人喜欢用 `iTerm2 + acceptEdits` 模式跑得更顺手（写在 local），而你所有项目都希望默认显示中文（写在用户级）。三层叠起来，互相不冲突。

### 三层叠加的合并方向

```mermaid
flowchart TB
    Default[内置默认值] --> User[用户级<br/>~/.claude/settings.json]
    User --> Project[项目级<br/>.claude/settings.json<br/>会进 git]
    Project --> Local[local 级<br/>.claude/settings.local.json<br/>默认 gitignore]
    Local --> CLI[命令行参数 / 临时 flag]
    CLI --> Managed[企业 managed settings<br/>不可被覆盖]
    Managed --> Final[最终生效配置]

    style Managed fill:#ffe0e0
    style Local fill:#e0f5ff
    style Project fill:#fff5d0
    style User fill:#e8ffe8
```

阅读这张图的两条规则：

1. **从上往下，下面的覆盖上面的。** 用户级是地板，local 级是顶（在你能改的范围里），命令行是临时插队，managed 是天花板谁都顶不动。
2. **不是整份 JSON 互相替换，而是按字段合并。** 标量字段（如 `model`）由高优先级的那层赢；对象字段（如 `env`）逐键合并；**数组字段（如 `permissions.allow` / `permissions.deny`）会被拼接 + 去重**，不是覆盖。这一点最容易踩坑，单独抽出来在"常见误区"里讲。

### 核心要素

| 要素 | 三层各自的位置 | 适合放什么 |
|------|---------------|-----------|
| **用户级** | `~/.claude/settings.json` | 跨项目通用偏好：默认 `model`、`outputStyle`、`includeCoAuthoredBy`、个人想全局放行的 `permissions.allow`（比如 `Bash(ls *)`） |
| **项目级** | `<repo>/.claude/settings.json` | 团队约定：项目硬性 `permissions.deny`（拦 `.env`、拦 `curl`）、项目的 `hooks`、绑定的 `model`、是否自动信任 `.mcp.json` |
| **local 级** | `<repo>/.claude/settings.local.json` | 个人临时放行：试某个新工具时的一次性 `allow`、本地特殊路径（`Read(/Volumes/...)`）、个人想覆盖团队默认的 `defaultMode` |
| **企业 managed** | `/Library/.../managed-settings.json` 等 | 公司硬性策略：白名单模型 `availableModels`、强制登录方式 `forceLoginMethod`、`allowManagedHooksOnly` |

## 基础用法

### 第一步：看清三份文件分别在哪、有没有

```bash
# 用户级（全局，所有项目共用）
ls -la ~/.claude/settings.json

# 项目级（要在仓库根目录跑）
ls -la .claude/settings.json

# local 级（同样在仓库根目录）
ls -la .claude/settings.local.json
```

如果文件不存在很正常——Claude Code 第一次需要写入时会自动创建。**`.claude/settings.local.json` 在被首次创建时，Claude Code 会自动把它追加到项目的 `.gitignore`**，不需要你手动 ignore，但养成检查习惯没坏处：

```bash
grep -n "settings.local.json" .gitignore || echo "未找到，建议手动加一行 .claude/settings.local.json"
```

### 第二步：查看当前真正生效的配置

进 Claude Code 内部，输入：

```text
/status
```

`/status` 会列出所有 settings 来源（包括是否有企业 managed），帮你确认哪一层在生效。要交互式调配置则用：

```text
/config
```

`/config` 提供菜单式编辑，所有改动落到对应的 JSON 文件里。

### 第三步：典型字段配在哪一层

**示例 A：用户级（所有项目通用偏好）**

```json
// ~/.claude/settings.json
{
  "$schema": "https://json.schemastore.org/claude-code-settings.json",
  "model": "claude-sonnet-4-6",
  "outputStyle": "concise-zh",
  "permissions": {
    "allow": [
      "Bash(ls *)",
      "Bash(cat *)",
      "Read(~/.zshrc)"
    ],
    "defaultMode": "default"
  },
  "attribution": {
    "commit": "Co-Authored-By: Claude <noreply@anthropic.com>"
  }
}
```

**示例 B：项目级（团队共享，进 git）**

```json
// <repo>/.claude/settings.json
{
  "permissions": {
    "deny": [
      "Bash(curl *)",
      "Read(./.env)",
      "Read(./.env.*)",
      "Read(./secrets/**)"
    ],
    "allow": [
      "Bash(npm run lint)",
      "Bash(npm run test *)",
      "Bash(npm run build)"
    ]
  },
  "hooks": {
    "PreToolUse": [
      { "matcher": "Bash", "hooks": [{ "type": "command", "command": "scripts/log-bash.sh" }] }
    ]
  },
  "enabledMcpjsonServers": ["filesystem", "github"]
}
```

**示例 C：local 级（仅你这台机器，不进 git）**

```json
// <repo>/.claude/settings.local.json
{
  "permissions": {
    "allow": [
      "Bash(docker compose *)",
      "Read(/Volumes/external-dataset/**)"
    ],
    "defaultMode": "acceptEdits"
  },
  "env": {
    "MY_LOCAL_DEBUG_FLAG": "1"
  }
}
```

合并以后实际生效：

- `model` 取用户级的 `claude-sonnet-4-6`（项目和 local 都没改）。
- `permissions.deny` 完全保留项目级那 4 条（用户和 local 都没写 deny）。
- `permissions.allow` = 用户的 3 条 + 项目的 3 条 + local 的 2 条，**8 条全部生效，去重之后即是结果**。
- `defaultMode` = local 的 `acceptEdits` 赢（覆盖了用户级的 `default`）。
- `env.MY_LOCAL_DEBUG_FLAG=1` 生效。

## 同类工具对比

不同终端 Agent 都有自己的"全局 vs 项目"配置模型。理解差异有助于在多工具切换时不踩坑：

| 维度 | Claude Code | Codex CLI（OpenAI） | Gemini CLI（Google） | Cursor |
|------|------------|---------------------|---------------------|--------|
| 配置文件名 | `settings.json` | `config.toml` | `settings.json` | `.cursor/rules/*.mdc` + Settings UI |
| 用户级路径 | `~/.claude/settings.json` | `~/.codex/config.toml` | `~/.gemini/settings.json` | Cursor 应用内 Settings → User Rules |
| 项目级路径 | `<repo>/.claude/settings.json` | `<repo>/.codex/config.toml`（**会向上递归查找**） | `<repo>/.gemini/settings.json` | `<repo>/.cursor/rules/*.mdc` |
| 个人/local 层 | ✅ `settings.local.json`（自动 gitignore） | ⚠️ 只能用 `-c` 命令行覆盖或额外 profile | ❌ 没有独立 local 文件 | ❌ 无独立 local 概念 |
| 企业/managed 层 | ✅ macOS plist / Linux `/etc` / Windows 注册表 | ✅ `requirements.toml`（强约束）+ `managed_config.toml`（默认值） | ✅ system overrides 作为最高优先级 | ✅ Team Rules（仅 Team/Enterprise） |
| 数组字段合并行为 | **拼接 + 去重** | 同名键由优先级高的覆盖（按 toml key） | 数组合并、`mcpServers` 同名取高优 | 规则文件**叠加**进 system prompt |
| 项目层是否受信任开关保护 | ❌ 默认信任 | ✅ 项目未 trust 时跳过 `.codex/` 层 | ⚠️ 取决于工作区信任 | ⚠️ 取决于工作区信任 |

**核心区别用一句话说：Claude Code 是"个人 / 团队 / 个人覆盖团队"三明治结构，且 local 层默认 gitignore；Codex 没有专门 local 层，靠 profile + `-c` 替代；Gemini 走"系统覆盖一切"路线，企业管控更强；Cursor 没有标量 settings 合并问题，规则全部叠加进 prompt。**

迁移建议：从 Cursor 转 Claude Code 的人最容易把所有规则塞进项目级，忘了 local；从 Codex 转过来的人则容易忽略"数组合并 vs 字段覆盖"这条差异。

## 常见误区

| 误区 | 准确理解 |
|------|----------|
| 以为项目级和用户级是"二选一"——配了项目就不读用户 | 三层一直都在叠加。即便项目级写了 `model`，用户级里的 `outputStyle`、`env`、`hooks` 仍然生效，只是同名字段被项目级覆盖 |
| 以为 `permissions.allow` 在项目级写一遍就会覆盖用户级 | **数组字段是"拼接 + 去重"，不是覆盖**。要"撤销"用户级的某项 allow，只能用项目级的 `permissions.deny`，因为 deny > allow |
| 把敏感个人路径（如 `Read(/Volumes/work-secrets/**)`）写到项目级 | 项目级会进 git，团队人手一份。涉及个人本地路径、机器特有目录、临时实验放行，统统写到 `settings.local.json` |
| 以为 `.claude/settings.local.json` 必须自己手动 gitignore | Claude Code 在首次创建该文件时会自动追加到 `.gitignore`。但接手已有仓库时仍建议 grep 一下确认，避免历史 commit 残留 |
| 用 `claude config` 改完之后找不到改了哪一层 | 没有指定 scope 时默认改用户级。要指定具体层，需要直接编辑文件，或在 `/config` 菜单里看清"Source"列。`/status` 是排错神器 |
| 把 hooks 写到 local 级，期望队友也能用 | local 不进 git，队友拉不到。**团队级 hooks 必须写项目级 `.claude/settings.json`**，local 只用来个人临时挂钩 |
| 以为修改用户级 `~/.claude/settings.json` 立刻全局生效 | Claude Code 进程启动时读取一次，热重载支持有限。改完关键字段（permissions / hooks / model）建议重启 Claude Code 或重新进入 session |
| 把企业 managed 当成"高级用户级" | managed 是**强制天花板**，普通 settings 改不动。如果 IT 在 managed 里写了 `availableModels: ["claude-haiku-4-5"]`，你在用户级写 `model: "claude-opus-4-7"` 也启动不了 |

## 优劣势分析

| 优势 | 劣势 |
|------|------|
| **三层结构刚好对应"个人 / 团队 / 例外"，覆盖了真实协作场景** | 三层都可能有同名字段，**新手容易迷失"现在到底哪层在生效"**，需要 `/status` 才能确认 |
| **数组拼接 + 去重的合并策略**，让团队和个人各加各的 allow，互不删除对方 | 数组合并机制不直观——想"用项目级关掉用户级的某条 allow"做不到，只能 deny 反制 |
| **`settings.local.json` 自动 gitignore**，避免最常见的"个人路径泄露到 git"事故 | 自动追加 `.gitignore` 只在**首次创建**时执行，接手历史仓库要自己检查 |
| **企业 managed 层支持 MDM/plist/注册表/远程下发**，大企业可以做到强治理 | 企业 managed 一旦覆盖，普通用户**完全无法看到**自己被加了什么策略，排错全靠 `/status` |
| **JSON Schema 已上线**（`https://json.schemastore.org/claude-code-settings.json`），编辑器有补全和校验 | settings 字段在快速演进，`includeCoAuthoredBy` 已被 `attribution` 替代，跟不上版本就会写错配置 |
| **跨项目偏好（用户级）和项目约定（项目级）独立演进**，切项目时模型/语言不会被重置 | local 级**不会自动同步到任何地方**，换电脑要手动迁移 |

## 思考题

<details>
<summary>初级：项目级里写了 `permissions.allow: ["Bash(npm run *)"]`，但我作为团队的一员，这台机器上已经在用户级写了 `permissions.allow: ["Bash(npm run lint)"]`，那进入这个项目以后，我能跑 `npm run test` 吗？</summary>

**参考答案：**

能。**数组字段是合并不是覆盖**，所以最终生效的 `permissions.allow` 是：

```
["Bash(npm run lint)",  // 来自用户级
 "Bash(npm run *)"]     // 来自项目级
```

通配符 `Bash(npm run *)` 已经包含了 `npm run test`，所以放行。

需要警惕的反向场景：如果项目级写了 `permissions.deny: ["Bash(curl *)"]`，而你在用户级写了 `permissions.allow: ["Bash(curl *)"]`，**deny 永远赢 allow**，所以你这台机器上的 `curl` 仍然会被拦——这就是为什么团队约定优先放在 `deny` 而不是删 `allow`。

</details>

<details>
<summary>中级：团队规定所有人都不能让 Agent 自动 push 到 main，但我个人做了一个发布机器人，需要在某个特定仓库下放行 `Bash(git push origin main)`，最佳实践是把这条规则放在哪一层？为什么不能放用户级？</summary>

**参考答案：**

**最佳实践：放在该仓库的 `.claude/settings.local.json`**。理由有三层：

1. **不能放用户级**。用户级会污染你**所有项目**——只要你在任何仓库打开 Claude Code，`git push origin main` 都会被放行，等于绕过了团队约定在所有项目上的兜底。
2. **不能放项目级**。项目级会进 git，等于把你的"个人例外"推给了团队所有人，违背团队规则。
3. **local 级正好合适**：仅你这台机器、仅这个仓库、不进 git。即便如此还要再叠一层保护——团队的项目级 `.claude/settings.json` 通常会写 `permissions.deny: ["Bash(git push origin main)"]`，而 **deny 优先级高于 allow**，所以 local 级的 allow 反而会被项目级 deny 压住。

正确做法是和团队沟通后，在项目级用更细粒度的规则，比如：

```json
// 项目级 deny 改为更精确的形式，给"机器人 user 名"开一个口子
{
  "permissions": {
    "deny": ["Bash(git push origin main)"],
    "allow": ["Bash(GIT_AUTHOR_NAME=release-bot git push origin main)"]
  }
}
```

或者使用 `hooks` 在 PreToolUse 阶段动态判断，这部分见 `/cli/cards/lifecycle-hooks`。

**结论一句话：local 级解决"我个人例外"，但当例外和团队 deny 冲突时，必须回到项目级用更精确的 allow 规则，而不是去 local 里偷偷绕过。**

</details>

## 参考资料

1. Claude Code 官方 settings 文档：<https://code.claude.com/docs/en/settings>（查询日期 2026-04-22）
2. Claude Code 官方 IAM / 权限文档：<https://code.claude.com/docs/en/iam>（查询日期 2026-04-22）
3. Claude Code GitHub Issue #18964 - settings 与 memory 优先级一致性讨论：<https://github.com/anthropics/claude-code/issues/18964>（查询日期 2026-04-22）
4. eesel AI - Claude Code settings.json 完整指南（2026 版）：<https://www.eesel.ai/blog/settings-json-claude-code>（查询日期 2026-04-22）
5. Egghead - Organizing Personal and Project Settings in Claude Code：<https://egghead.io/organizing-personal-and-project-settings-in-claude-code~q7qsw>（查询日期 2026-04-22）
6. Codex CLI 配置参考（用于横向对比）：<https://developers.openai.com/codex/config-reference>（查询日期 2026-04-22）
7. Gemini CLI 配置参考（用于横向对比）：<https://geminicli.com/docs/reference/configuration/>（查询日期 2026-04-22）
8. Cursor Rules 官方文档（用于横向对比）：<https://cursor.com/docs/context/rules>（查询日期 2026-04-22）

---
*Source: https://learnagent.wiki/cli/cards/global-vs-project-settings*
*Markdown mirror of https://learnagent.wiki, served as text/markdown for LLM ingestion.*