
如果你已经装了 Claude Code并且用它写过几段像样的代码大概率遇到过这种状况上午刚跟它说清楚“这个项目用 npm 不要用 pnpm”下午换个会话它又开始pnpm install或者你明明告诉过它“不要动 src/config.js”它一抬手就把配置改了。问题通常不是 Claude 变笨了而是你没把settings.json、CLAUDE.md、memory这三层配置体系理顺。我一开始也犯过这个错——以为只要在对话里交代清楚就够了。后来翻官方文档、看社区分享、自己反复折腾才意识到这三套东西各管一摊settings.json管“让不让做”CLAUDE.md管“该怎么做”memory管“记住你习惯怎么做”。理顺它们之后Claude Code 从“一个聪明的临时工”变成了“一个懂规矩的老同事”。这篇文章把我对三大配置体系的理解、实际配置模板、以及踩过的坑完整梳理一遍适合刚接触 Claude Code、或者已经用了几天但总觉得“它不够听话”的人参考。1. 三种配置的分工先想清楚谁管什么事很多人把配置当成“往某个文件里堆内容”哪个文件都用同一套写法结果就是CLAUDE.md里塞满了环境变量settings.json里写满了项目背景——全乱套。我第一次就是这么干的最后排查问题的时候根本分不清是哪一层导致的行为异常。1.1 一句话记住三个文件各自的职责我的理解是如果把 Claude Code 比作一个加入你团队的新人那么三套配置正好对应三种管理工具settings.json是这个人的“行为边界和工作环境”——允许执行哪些命令、禁止碰哪些文件、API 端点指向哪里、工具执行前后要不要跑脚本。它告诉你“这个人能做什么、不能做什么”。CLAUDE.md是“项目手册”——项目背景、目录结构、构建命令、代码风格、明确不做的坑。它告诉你“在这个项目里该怎么干活”。memory是“老师的评语”——经过一段时间合作后Claude 会自己总结你偏好用什么包管理器、喜欢先跑 typecheck 再提 MR、验证代码时习惯用什么命令。它告诉你“这个人的工作习惯是什么”。看清楚这个分工就能解释很多现象为什么你在CLAUDE.md里写了“不要用 pnpm”它还是会用因为那可能是memory里沉淀了上一项目的旧习惯。为什么你改了settings.json的权限白名单却不生效因为项目级文件覆盖了用户级文件或者有更高优先级的配置在起作用。1.2 从文件位置看三层作用域三个体系都遵守同一套“作用域”逻辑用户级放在~/.claude/目录下对你这台机器上的所有项目生效。项目级放在项目根目录的.claude/目录下CLAUDE.md 直接放根目录只对当前仓库生效建议提交进 Git 给团队共享。本地私有settings.local.json、CLAUDE.local.md这类带.local的文件不入库只在你自己机器上生效。刚上手的人最容易忽略“作用域”。比如你为了某个项目给settings.json加了一条很激进的权限规则后来发现其他项目也在用这套规则那就是把项目级配置写进用户级文件了。1.3 推荐的初始化顺序如果你现在是从零开始配置我建议按这个顺序来先写项目根目录的CLAUDE.md把项目基本情况和常用命令告诉它。没有这份文件后面所有配置都缺少上下文。再调settings.json把权限白名单、禁止项、环境变量改好让它能干活但不乱来。最后根据实际使用情况决定要不要开--memory。它是一把双刃剑开早了容易把还不成熟的工作习惯固化下来。顺序反了会很难受。我见过一上来就开 memory 的用户结果第一周形成的“错误偏好”被反复强化后面花大力气清理。先让项目事实稳定下来再考虑长期记忆。2. settings.json权限边界、环境变量与 hooks 的实操细节settings.json是三个体系里最“硬”的一层。它影响的是 Claude Code 这个工具本身的行为包括权限、网络端点、环境变量注入和自动化钩子。出问题的时候大部分都是这一层。2.1 文件放哪、怎么改标准位置有三个~/.claude/settings.json全局用户设置。项目根/.claude/settings.json项目级设置提交到 Git。项目根/.claude/settings.local.json本机私有设置适合放个人 API Key 之类的敏感信息。在 Claude Code 交互界面里直接输入/config会打开一个可视化编辑器效果等同修改上述文件。我个人习惯直接改文件因为方便对比版本。提示带.local的文件千万不要提交进 Git。API Key、本机专属路径、临时权限都属于“机器私有”范畴。2.2 permissions让不该干的事根本到不了它面前核心结构是permissions里的三个数组allow、deny、ask。分别表示“直接允许”“直接拒绝”“询问我”。{ permissions: { allow: [ Bash(npm run *), Bash(npm test), Bash(git status), Bash(git diff), Read(./src/**), Edit(./src/**) ], deny: [ Bash(rm:*), Bash(git push), Read(./.env) ], ask: [ Bash(git reset --hard), Edit(./package.json) ] } }几个容易看漏的点Bash(npm run *)里的*是通配符匹配“这条命令模式”。Bash(rm:*)则会拦截 rm 命令及参数。Read(./src/**)里**是目录递归匹配Read(./src/*.tsx)只匹配一层。不带参数的Bash表示“所有 Bash 命令”风险很高建议只在完全可信的本地环境里使用。Edit(./package.json)配合ask会让它在改依赖清单前停下来问你。我刚上手时犯过一个错为了省事在allow里加了一条Bash(*)结果它跑git push前都不问我一声。后来改成上面这种“命令白名单 敏感命令 deny”的结构省心很多。另外一个容易被忽略的参数是defaultMode可以设成acceptEdits自动接受文件修改、plan只做计划不动手、bypassPermissions跳过所有权限校验。日常开发我建议acceptEdits因为逐个弹窗确认太影响节奏但如果是在生产环境排查问题强烈建议切到plan模式。2.3 env不写死 API Key也能轻松切换模型env字段用来给 Claude Code 注入环境变量这是接第三方模型的关键。它支持把变量写进 JSON避免你每次启动都在终端 export。{ env: { ANTHROPIC_BASE_URL: https://api.example.com/anthropic, ANTHROPIC_AUTH_TOKEN: sk-your-key-here, ANTHROPIC_MODEL: your-model-name } }ANTHROPIC_BASE_URL是最核心的字段。Claude Code 默认把请求发到 Anthropic 官方端点但你把它指向任何“兼容 Anthropic Messages API 格式”的服务端就能接第三方或本地模型。很多团队内部 API 网关就是这么做的。注意env里不要写死太多东西尤其是 Key。更稳妥的做法是配合~/.claude/settings.local.json放个人 Key项目级settings.json只写ANTHROPIC_BASE_URL这样团队协作时不会互相污染密钥。提示如果你用ANTHROPIC_API_KEY而不是ANTHROPIC_AUTH_TOKEN作用类似。实际环境中两个变量只要有一个被正确设置就能通过认证但同时存在时以AUTH_TOKEN优先。不同的后端服务可能有各自偏好接入前先确认服务方要求哪个字段。2.4 hooks在工具执行前后插入你自己的逻辑hooks是settings.json里最有想象力的一部分。它可以在 Claude Code 执行工具的前后触发你指定的脚本用来做审计、拦截、格式化等。{ hooks: { PreToolUse: [ { matcher: Bash, hooks: [ { type: command, command: node ~/.claude/hooks/audit-bash.js, timeout: 10 } ] } ] } }这个配置的意思是每次 Claude Code 要执行Bash类工具前先跑一次audit-bash.js脚本。我在脚本里做了两件事把命令原文追加到本地日志文件、检查命令里是否包含rm -rf这类危险操作命中则输出 JSON 通知 Claude Code 拒绝执行。hooks 支持的事件还不少PreToolUse、PostToolUse、UserPromptSubmit、SessionStart等都可用。新手不建议一上来做太复杂的事先用PreToolUseBash matcher做命令审计就足够形成“安全感”。等熟悉了再扩展成“自动格式化”“自动跑测试”之类的流程。2.5 一个能直接抄的 settings.json 模板结合上面内容给你一个我目前主力使用的模板{ permissions: { defaultMode: acceptEdits, allow: [ Bash(node:*), Bash(npm run *), Bash(npm test), Bash(npm install), Bash(git status), Bash(git diff), Bash(git add:*), Bash(git commit:*), Bash(git log:*), Read(./src/**), Edit(./src/**) ], deny: [ Bash(rm:*), Bash(git push), Bash(git reset --hard), Read(./.env), Read(./credentials*) ], ask: [ Bash(git checkout:*), Edit(./package.json), Edit(./pnpm-lock.yaml) ] }, cleanupPeriodDays: 30 }cleanupPeriodDays是控制会话历史清理周期的字段。默认保留一定天数内的对话记录便于/resume恢复上下文。设成 30 天是我个人习惯太短会丢上下文太长会占磁盘空间。3. CLAUDE.md项目知识库的正确打开方式如果说settings.json是硬性边界CLAUDE.md就是软性指导。它是唯一一个直接进入上下文窗口、让 Claude 每次会话开始就能看到的文件。用好了它能省掉你 80% 的“重复交代”。3.1 它到底会被谁加载CLAUDE.md的加载逻辑遵循“就近原则”项目根目录的CLAUDE.md在项目根目录启动时自动读取。子目录里的CLAUDE.md从该子目录启动时读取适合给一个超大仓库的特定模块写专项说明。~/.claude/CLAUDE.md全局用户记忆任何项目都会带上。三种文件可以同时存在内容会拼接进上下文。项目级的分量更重因为它离当前工作目录更近。有个容易被忽视的点CLAUDE.md有 Token 上限。官方文档里提到超出一定体积会被截断所以不要在文件里堆“聊天记录”或“完整需求文档”。它应该是精简的项目操作手册。3.2 什么内容值得写进去我总结了一个“三要三不要”要写项目的核心目标和定位几句话讲清楚这个仓库是干什么的。常用命令安装、测试、构建、lint、单测执行方式。架构约定目录结构、关键模块职责、依赖管理约定用 npm 还是 pnpm。明确不能做的事比如“不要格式化生成器输出的代码”“不要修改锁文件”。一次性的操作流程比如发布、数据库迁移。不要写和项目无关的个人偏好那是 memory 或全局 CLAUDE.md 的事。特别长的背景故事。会频繁变动的临时状态比如“今天的部署还在进行中”。下面是一个项目级CLAUDE.md的参考结构# 项目订单中台服务 ## 项目简介 负责订单创建、支付回调、对账导出。Node.js TypeScript Express。 ## 常用命令 - 安装依赖: npm install - 类型检查: npm run typecheck - 单测: npm test - 启动本地: npm run dev ## 架构约定 - 代码入口在 src/index.ts - 路由放在 src/routes/每个路由一个文件 - 数据库操作只允许走 src/db/ 下的封装 - 禁止直接在主进程里写耗时的同步逻辑 ## 明确禁止 - 不要修改 package-lock.json - 不要对 src/generated/ 目录下手动修改 - 不要使用 console.log 排查线上问题统一用 logger这样一份文件Claude Code 每次开工前都看得到它就不会再问你“端口是多少”“测试命令是什么”这种反复出现的问题。3.3 为什么你写的规则“有时灵有时不灵”这是 CLAUDE.md 最让人困惑的地方。我总结了几个最常见的原因文件不在当前工作目录的加载范围内。你在packages/backend/目录启动 Claude根目录的CLAUDE.md可能不会被加载需要在这个子目录也放一份索引文件。文件太大被截断关键规则恰好排在了被截掉的末尾。我的经验是整份文件控制在 100 行以内把“禁止”事项往前放。对话中的指令临时覆盖了文件指示。比如你今天说“这次例外直接用 pnpm 装”后续会话里 Claude 可能带着这次记忆继续操作。规则本身写得太模糊。“代码要写漂亮”这种话它没法执行要写成“不要在 reducer 里写副作用”这种可判断的规则。另外要知道CLAUDE.md是“提示”而不是“硬编码拦截器”。真正强硬的边界要靠settings.json的权限配置。两者的关系是先用 CLAUDE.md 告诉它怎么做如果它不做再用 permissions 强制拦。3.4 维护 CLAUDE.md 的三个小技巧第一每隔一段时间主动删旧规则。项目演进后很多“之前不能做的事”可能已经放开留着反而误导。第二把“新发现的重要约束”随时追加进去。我在开发时一旦因为某个问题踩坑解决后会立刻把对应约束写进 CLAUDE.md不下一次还要再翻聊天记录。第三可以用脚本自动维护。比如在 CI 里跑一个命令把当前分支、最近变更的目录、测试覆盖率写进一个CLAUDE.generated.md再用 Claude Code 的/memory命令把它纳入上下文。这个属于进阶玩法但确实能让知识库始终跟上项目状态。4. memory从会话历史到跨会话长期记忆记忆是三个体系里最“玄”的一个也是很多人又爱又恨的功能。爱它是因为它能自动学习你的习惯恨它是因为它总会“学歪”。我自己的使用经历是从完全不用到重度使用最后学会有节制地用。4.1 记忆的三个层次先对齐Claude Code 里其实有三层记忆会话内记忆当前对话里的一切通过/resume可以接着上次会话继续底层是~/.claude/projects/下按项目路径保存的 JSONL 记录。项目级记忆CLAUDE.md及其.local变体面向一个仓库长期有效。用户级长期记忆~/.claude/CLAUDE.md以及--memory模式自动生成的记忆文件。很多人以为“记忆”就是聊天记录其实不是。聊天记录只是一堆原始素材真正的长期记忆是 Claude 从这些素材里提炼出来的“结论”。4.2 --memory 模式下 Claude 会自己沉淀什么启动时加上--memoryClaude Code 会开启“自动学习”claude --memory之后它会在~/.claude/memory/目录维护一组 Markdown 文件常见的有configuration-claude.md开发环境配置类偏好比如 Node 版本、包管理器。verification-claude.md验证偏好比如“改完代码先跑 typecheck 再跑单测”。tools-claude.md常用工具类偏好比如用 git 时喜欢看 diff。behavior-claude.md行为习惯类偏好比如“提交信息要遵循 Conventional Commits”。history/目录保存更早的会话摘要供它回溯参考。这些文件的内容我实测下来是“它自己总结的规则”不一定每条都对但方向基本符合你日常操作习惯。如果你不想让某个项目参与这个“总结学习”可以用--no-memory启动已有的记忆文件则可以通过删除或编辑对应 md 文件来清理。4.3 记忆串味多项目开发最大的坑这是我的真实翻车案例。当时我同时在维护一个用 pnpm 的 monorepo 和一个用 npm 的普通应用。开了--memory之后Claude 在 npm 项目里频繁建议用 pnpm 安装依赖初始时我还以为它读错了项目配置。排查到最后发现是 memory 里沉淀了“这个开发者喜欢 pnpm”的结论这个结论来自另一个仓库。解决办法分两步先删掉~/.claude/memory/tools-claude.md里的包管理器偏好然后把“该仓库必须用 npm”写进项目的CLAUDE.md。从此以后项目级约束优先于用户级习惯问题消失。经验是如果你同时参与多个技术栈差异很大的项目要谨慎开--memory并且定期 review 记忆文件。记忆是“跨项目”的它不知道你今天在写哪个项目它只知道你“通常”怎么干活。4.4 记忆的隐私边界和清理节奏记忆文件里不要放任何密钥、密码、个人敏感信息。虽然它只存在本机但 Claude Code 的会话数据、记忆数据在需要排障时可能会被上传给官方或第三方服务。我给自己的规则是涉及 token、密码的内容一律不进记忆也不进 CLAUDE.md。清理节奏上我每两周会手动看一眼~/.claude/memory/下面的文件删掉过时条目。尤其是一些“临时偏好”比如某个项目要求在发版前执行某个一次性脚本这种过期规则留在 memory 里以后会造成不可预期的行为。注意记忆文件和会话记录是两个东西。清理~/.claude/projects/里的历史 JSONL 不影响长期记忆清理~/.claude/memory/会影响长期学习结果。不要搞混。5. 报错排查与模型接入配置体系中最容易翻车的地方配置体系本身不难难的是它和“网络环境”“模型选型”“账号权限”纠缠在一起的时候。这一节整理了我在 Windows、Linux 上遇到的三个高频问题以及接入第三方/本地模型的完整思路。很多报错看着吓人实际上都是配置问题。5.1 Windows 安装和常见启动报错官方推荐的安装方式有三种# 方式一npm 全局安装 npm install -g anthropic-ai/claude-code # 方式二PowerShellWindows 原生 irm https://claude.ai/install.ps1 | iex # 方式三ShellmacOS / Linux curl -fsSL https://claude.ai/install.sh | bash装完先跑claude --version确认版本号。如果命令找不到多半是 Node 没装或者 npm 全局目录没进 PATH。我遇到过一个比较典型的 Windows 报错interetopenurl() failed. 0x800...。搜了很多帖子最后发现是我机器上残留了旧的系统代理设置指向了一个已经不存在的本地端口Node 请求外部 URL 时全被带偏。排查步骤是执行npm config get proxy和npm config get https-proxy看有没有异常值。检查系统环境变量里HTTP_PROXY、HTTPS_PROXY、NO_PROXY是否指向失效地址。把失效的代理变量清理掉重启终端再试。如果你的报错不是代理导致还有一个高概率原因是 Node 版本过旧。Claude Code 对 Node 版本有要求建议升级到 LTS 再重装npm uninstall -g anthropic-ai/claude-code npm install -g anthropic-ai/claude-code另外网上有一些“非官方打包版”的 Claude Code 安装包如果你看到“与 64 位版本的 Windows 不兼容”这类提示大概率是用了这种来路不明的包。建议卸掉直接用上面的官方脚本安装。5.2 “your organization has disabled claude subscription access”的处理思路这行报错在团队账号场景里非常常见。它的大意是你当前登录的是组织托管的 Claude 账号而组织管理员在后台关闭了 Claude Code 的访问权限。处理办法按优先级排联系组织管理员在 Claude 管理后台给对应成员开启 Claude Code 权限。这是最合规、最省事的方案。如果是个人项目用你自己的个人 Claude 账号重新登录一次。如果只是临时想跑、不想动订阅账号可以改用 API 认证方式通过ANTHROPIC_API_KEY或settings.json里配置的env端点认证绕开订阅校验。我遇到过不少团队用户其实管理员是支持开启的只是不知道有这个开关。先沟通比改配置快得多。5.3 用 CC Switch 接入 DeepSeek / Qwen / GLM 的原理CC Switch是一个很好用的开源配置切换器本质上是帮你管理不同的settings.json配置组一键切换。大多数人以为它对某个模型做了一些“魔法适配”其实它的底层就是把env字段里的ANTHROPIC_BASE_URL、ANTHROPIC_AUTH_TOKEN、ANTHROPIC_MODEL替换成目标服务商的值。关键点在于目标服务商必须提供“Anthropic Messages API 兼容端点”。比如{ env: { ANTHROPIC_BASE_URL: https://your-model-service.com/anthropic, ANTHROPIC_AUTH_TOKEN: sk-xxx, ANTHROPIC_MODEL: deepseek-chat } }如果你用 DeepSeek、通义千问Qwen、GLM 这类服务商需要考虑三件事是否提供 Anthropic 兼容端点。不兼容的话Claude Code 发过去的请求格式对不上响应会报错。是否支持工具调用/function calling。Claude Code 内部依赖工具调用执行文件编辑、跑命令等操作模型不支持的话体验会大打折扣。上下文窗口是否够大。很多本地/第三方模型上下文窗口远小于 Claude 官方模型Claude Code 每次会塞入不少系统提示和工具定义小窗口模型容易截断。CC Switch 的价值在于它把“切换服务商”做成了几秒钟的事情并且支持多套配置并存。我用它同时维护了“官方模型”“DeepSeek”“本地模型”三套配置随时切。但它的缺点也很明显多套很容易记混当前端点。切换后建议立刻跑一个简单任务确认端点生效不要凭感觉。5.4 调用 LM Studio 本地模型的完整配置如果你不想把代码交给云端 API又想让 Claude Code 跑在本地模型上LM Studio 是目前比较顺手的方案。前提是LM Studio 版本要支持 Anthropic 兼容接口。启动 LM Studio 后在 Developer 模式里打开 Local Server选择启用 Anthropic 兼容端点。启动后它会给你一个本地地址一般是http://localhost:1234/anthropic在 Claude Code 侧配置settings.json的env{ env: { ANTHROPIC_BASE_URL: http://localhost:1234/anthropic, ANTHROPIC_AUTH_TOKEN: lm-studio, ANTHROPIC_MODEL: qwen3-8b } }很多本地服务器不校验收到的 token 内容但按格式填一个lm-studio能保证兼容层正常工作。启动 Claude Code 后再跑一句简单的“你好”确认链路通不通。实测下来本地模型能做基础的代码问答、简单的文件修改但长期项目和复杂重构场景还是力不从心。另外要注意 LM Studio 的 Anthropic 兼容端点是按 Anthropic 消息格式转成 OpenAI 格式的对工具调用的支持取决于你加载的具体模型和 LM Studio 本身无关。所以选模型时优先选明确支持 function calling 的 7B/8B 级别模型。6. 配置优先级与团队协作一套能上线的最终方案单个文件会配了还不够三个文件混在一起时谁说了算多个人协作时哪些传、哪些不传这是配置体系能不能“上线”的分水岭。6.1 谁覆盖谁的完整规则表我整理了一张按“优先级从高到低”排列的对照表优先级配置来源作用范围典型场景1当前对话中的明确指令单次会话临时调整行为、一次性豁免2项目级.claude/settings.json当前项目团队统一权限基线3用户级~/.claude/settings.json所有项目个人默认权限、API 端点4项目根目录CLAUDE.md当前项目项目背景、命令约定5~/.claude/CLAUDE.md所有项目个人通用偏好6memory 自动生成的记忆文件跨项目长期工作习惯注意第 2 和第 4 的“优先级高低”并不是简单覆盖关系。settings 与 CLAUDE.md 管的不是同一类事真正冲突时比如“CLAUDE.md 说该用 npm、settings 里 deny 掉 npm 命令”最终行为是npm 命令根本执行不了CLAUDE.md 里的约定就变成空话。所以我的经验是硬约束放 settings软约束放 CLAUDE.md个人习惯放 memory。三者的目标一致但不要用它们互相打架。6.2 团队协作什么该入库什么必须 ignore推荐的做法是入库提交 Git.claude/settings.jsonCLAUDE.md不入库加入 .gitignore.claude/settings.local.jsonCLAUDE.local.md~/.claude/memory/相关数据它通常不在项目目录内但注意不要手动复制进仓库.gitignore里可以加这么几行.claude/settings.local.json CLAUDE.local.md .claude/settings.json.bak为什么 project 级 settings 要入库因为它包含了团队整体同意的权限基线。比如 deny 掉git push是为了防止误操作推送这类决策应该让所有人都享受到。local 文件则是给个人留的后门比如你个人测试时需要临时允许某个命令、或者需要填自己的 API Key写在 local 里不会污染团队配置。6.3 最终推荐配置清单抄作业版如果你不想从零研究我建议的最小可用方案如下在项目根目录建一份 30 行左右的CLAUDE.md包含命令、架构、禁止事项。建.claude/settings.json权限里 allow 常用命令、deny 危险命令、ask 敏感操作不写任何 API Key。在settings.local.json里配置自己的 API Key 或第三方端点。前端开发用记忆时先以--no-memory跑两周确定 CLAUDE.md 足够稳定后再开--memory。每次换模型或换项目跑一次简单的“上下文验证”——让它读 CLAUDE.md 并复述关键规则确认配置真的生效。这样一个组合足够覆盖个人开发、团队协作、多项目切换和本地模型调试这几类最常见的场景。你先按这套跑起来再根据项目实际情况慢慢调比如权限默认模式要不要从acceptEdits改成plan、hooks 要不要加一条提交前检查。到最后你会发现配置不是一次写完的而是随着使用不断生长的。最理想的状态是你几乎感觉不到配置的存在但 Claude Code 做的事都恰好是你想要的。每次多踩一个坑、多补一条规则、多清理一条过时记忆它就会更贴合你的工作方式。我自己的体会是定期 review 比一次性配全更重要。每两周花十分钟翻一翻~/.claude/memory/和项目的CLAUDE.md删掉已经失效的规则补上新发现的必要约束这套体系就会始终处于“好用但不啰嗦”的状态。