Claude Code 完全指南:环境搭建 + 五大扩展机制
Claude Code 完全指南:环境搭建 + 五大扩展机制
一份可以直接照搬的实操手册。
上半篇解决「装得上、跑得起来」,下半篇解决「用得顺、管得住」——
Skill / Plugin / Hook / MCP / Agent 五大扩展机制逐个拆解。
目录
- 一、环境搭建
- 二、先建立全局认知
- 三、Rule(规则):CLAUDE.md 记忆系统
- 四、Skill(技能):可复用的能力包
- 五、Plugin(插件):把一整套配置打包分发
- 六、Hook(钩子):事件驱动的确定性自动化
- 七、MCP:给 Claude 接上外部世界
- 八、Agent(子代理):隔离上下文里分身干活
- 九、组合拳:一个真实项目的配置全景
- 十、速查表
一、环境搭建
1.1 安装 claude-code
这里分享一个非常方便的 claude-code 安装方案(离线包,走本地代理,不受网络限制)。
地址:https://github.com/DeepTrial/claude-code-offline

我这里的环境是 WSL2,所以直接使用一键安装命令:
bash <(curl -fsSL https://raw.githubusercontent.com/DeepTrial/claude-code-offline/main/setup-claude-code.sh) --auto-download
1.2 配置 ~/.claude/settings.json
以下差不多是 claude-code 的核心配置文件,位于用户主目录下的 .claude/settings.json。
这个文件的作用是告诉 claude-code 如何连接模型服务、使用哪个模型,以及一些交互行为上的偏好设置。
{
"env": {
"ANTHROPIC_AUTH_TOKEN": "sk-xxxxxxxxxxxxxxxxxxxxxxxxxx",
"ANTHROPIC_BASE_URL": "http://127.0.0.1:3000",
"ANTHROPIC_DEFAULT_FABLE_MODEL": "deepseek-v4-pro[1M]",
"ANTHROPIC_DEFAULT_FABLE_MODEL_NAME": "deepseek-v4-pro",
"ANTHROPIC_DEFAULT_HAIKU_MODEL": "deepseek-v4-pro",
"ANTHROPIC_DEFAULT_HAIKU_MODEL_NAME": "deepseek-v4-pro",
"ANTHROPIC_DEFAULT_OPUS_MODEL": "deepseek-v4-pro[1M]",
"ANTHROPIC_DEFAULT_OPUS_MODEL_NAME": "deepseek-v4-pro",
"ANTHROPIC_DEFAULT_SONNET_MODEL": "deepseek-v4-pro[1M]",
"ANTHROPIC_DEFAULT_SONNET_MODEL_NAME": "deepseek-v4-pro",
"CLAUDE_CODE_SUBAGENT_MODEL": "deepseek-v4-pro[1M]",
"CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC": "1",
"CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS": "1"
},
"includeCoAuthoredBy": false,
"permissions": {
"defaultMode": "auto"
},
"skipAutoPermissionPrompt": true,
"hasCompletedOnboarding": true,
"systemLanguage": "zh",
"tui": "fullscreen"
}
1.3 配置项逐条解读
首先要说的是 env 环境变量部分,这是整个配置的核心,它决定了 claude-code 实际调用的是哪套模型服务:
| 配置项 | 含义 |
|---|---|
ANTHROPIC_AUTH_TOKEN |
认证令牌。填你本地代理服务(如 one-api、new-api 等)生成的密钥,格式通常是 sk- 开头的一串字符。注意不要泄露到公开仓库 |
ANTHROPIC_BASE_URL |
模型服务的接口地址。这里指向本机的 http://127.0.0.1:3000,说明 claude-code 通过本地代理转发请求,而不是直连 Anthropic 官方。代理部署在别的机器或端口时改成对应地址即可 |
ANTHROPIC_DEFAULT_*_MODEL |
分别指定 Sonnet、Opus、Haiku 等不同档位模型实际映射到的后端模型。这里统一映射到 deepseek-v4-pro,其中带 [1M] 后缀的表示启用 100 万 token 的超长上下文窗口,适合处理大文件或长对话 |
ANTHROPIC_DEFAULT_*_MODEL_NAME |
与上面的模型 ID 对应的展示名称,主要用于在界面上显示,保持和模型 ID 一致即可 |
CLAUDE_CODE_SUBAGENT_MODEL |
子代理(subagent)使用的默认模型。claude-code 在并行执行子任务时会用到它,这里同样指向 deepseek-v4-pro[1M],保证子任务也有足够的上下文能力。详见 第八节 |
CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC |
设为 1 表示关闭非必要的网络请求,减少隐私数据外发,也降低延迟 |
CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS |
开启实验性的多智能体协作功能,允许 claude-code 以团队协作的方式并行处理更复杂的任务 |
再看 env 之外的几个顶层配置项:
| 配置项 | 含义 |
|---|---|
includeCoAuthoredBy |
设为 false 表示不在生成内容末尾追加 "Co-authored-by" 署名信息 |
permissions.defaultMode |
设为 auto 表示默认自动放行常见操作(如读写文件、执行命令),减少频繁弹窗确认,提升使用流畅度 |
skipAutoPermissionPrompt |
设为 true 表示跳过自动权限确认提示,配合上面的 auto 模式使用,基本可以实现「无感」操作 |
hasCompletedOnboarding |
标记是否已完成首次引导流程,保持 true 即可 |
systemLanguage |
界面语言,这里设为 zh 即中文界面 |
tui |
终端 UI 模式,fullscreen 表示使用全屏交互界面,视觉效果更沉浸 |
整体来看,这份配置的核心思路是:通过本地代理把 claude-code 的请求转发到 DeepSeek 模型上,
既绕开了网络限制,又能用上大上下文窗口,同时通过权限自动放行让日常使用更顺手。
你只需要把 ANTHROPIC_AUTH_TOKEN 换成自己代理生成的密钥,再按实际部署地址调整 ANTHROPIC_BASE_URL,
就可以直接跑起来了。
1.4 验证安装
配置完成后找个目录输入:
claude .

二、先建立全局认知
claude-code 现在已经可以正常使用了。但开箱即用只是起点——真正拉开效率差距的,
是它的扩展机制。下面这五个概念分别从不同维度扩展了 claude-code 的能力边界。
很多教程把它们混在一起讲,其实它们各司其职、互为补充。记住一句口诀:
规则定「规矩」,技能定「做法」,插件定「分发」,子代理定「角色」,钩子定「时机」。
| 维度 | 规则 Rules | 技能 Skills | 钩子 Hooks |
|---|---|---|---|
| 一句话定位 | 持久记忆与规范 | 可复用的能力包 | 事件驱动的自动化 |
| 回答的问题 | 「永远该遵守什么?」 | 「这类任务该怎么做?」 | 「何时必须执行什么?」 |
| 载体 | CLAUDE.md / .claude/rules/*.md |
SKILL.md + 脚本资源文件夹 |
settings.json 中的 hooks 块 |
| 触发方式 | 会话启动时注入上下文 | 模型按 description 自动匹配,或手动 /skill 调用 |
生命周期事件触发,确定性执行 |
| 是否依赖模型判断 | 是(模型「读到并遵守」) | 是(模型「判断该用它」) | 否(shell 命令必然执行) |
| 典型场景 | 构建命令、代码规范、架构约定 | 提交信息规范化、代码审查、部署流程 | 保存后自动格式化、拦截危险命令、桌面通知 |
| 共享方式 | 提交到版本库,团队共享 | 项目内共享或插件市场分发 | settings.json 随仓库共享 |
另外两个概念:
- Plugin(插件) 是分发单位——它不解决新问题,而是把 Skill / Hook / MCP / Agent 打包成一份可安装、可版本化的资产,让别人一条命令就能复刻你的整套配置。
- MCP(Model Context Protocol) 是接入单位——它让 Claude 能连上外部系统(数据库、Jira、浏览器、你的内部 API),把你的工具变成它的工具。
一个高效的工作流通常几者并用:
CLAUDE.md 让 Claude 知道项目背景与红线;任务匹配到某个技能时,Skills 给出标准化的操作步骤;
Hooks 则在编辑文件、执行命令的关键节点上,以 shell 脚本的形式强制执行格式化、校验、通知等动作——无论模型是否「记得」。
三、Rule(规则):CLAUDE.md 记忆系统
3.1 为什么需要它
Claude Code 每次启动都是全新会话——它不记得上次讨论过的架构决策。
CLAUDE.md 就是为解决这个而生:一个随会话自动加载的 Markdown 文件,把项目上下文、规范和红线一次性交代清楚。
没有 CLAUDE.md 时,你可能每个会话都要重复输入:「我们用 Keil 构建」「提交信息用中文」「别动 vendor 目录」。
写进 CLAUDE.md 之后,Claude 在每次会话开始时就会读到它们。
判断标准很简单:
凡是你要对 Claude 重复第二遍的话,就该写进 CLAUDE.md。
3.2 加载层级(按优先级从宽到专)
CLAUDE.md 不止一个文件,而是一套分层体系。四个层级的内容会全部拼接进上下文,
而不是后者覆盖前者;越具体的层级排在越后面,也越容易「压过」前面的表述:
| 层级 | 路径 | 作用 |
|---|---|---|
| 企业策略 Managed Policy | macOS:/Library/Application Support/ClaudeCode/CLAUDE.mdLinux/WSL: /etc/claude-code/CLAUDE.mdWindows: C:\Program Files\ClaudeCode\CLAUDE.md |
IT/DevOps 统一部署,不可被覆盖 |
| 用户级 User | ~/.claude/CLAUDE.md配套 ~/.claude/rules/*.md |
个人偏好,作用于你所有的项目 |
| 项目级 Project | ./CLAUDE.md 或 ./.claude/CLAUDE.md配套 ./.claude/rules/*.md |
提交到版本库,团队共享同一份上下文 |
| 本地级 Local | ./CLAUDE.local.md |
个人项目私有,记得加进 .gitignore |
子目录级 CLAUDE.md(如 ./src/driver/CLAUDE.md)是另一套机制:它不在启动时加载,
而是当 Claude 读写该目录下的文件时按需注入。适合放「这个模块特有的约定」,不占用常驻上下文。
⚠️ 一个常见误解是把「用户级」放在启动顺序的最前面就以为它优先级最高。
实际顺序是文件系统根目录 → 当前工作目录,越靠近你启动位置的规则读得越晚,也就越占优。
同一目录下,CLAUDE.local.md排在CLAUDE.md之后。
3.3 三步上手
第 1 步 · /init 生成初稿
在项目根目录运行 /init,Claude 会分析代码库,自动生成包含构建命令、目录结构、约定的 CLAUDE.md 初稿。
已有文件时它会提改进建议而不是直接覆盖。
第 2 步 · 人工精修
删掉它「自己能发现」的内容(如语言、框架),补上只有你知道的:
为什么这样设计、哪些是禁区、验证命令是什么。
第 3 步 · /memory 随时维护
会话中输入 /memory 可在编辑器里直接增改所有层级的记忆文件。
也可以直接说「记住:……」,Claude 会写入合适的文件。
3.4 进阶:导入与拆分
用 @路径 语法把现有文档导入记忆,避免重复维护。相对路径以引用它的那个文件为基准解析,
最多递归展开 4 层:
# 在 CLAUDE.md 中导入其他文档
@README.md
@docs/api-conventions.md
@~/.claude/personal-style.md
技巧:写在反引号或代码块里的
@路径不会被当作导入,可以用来展示字面量。
按主题拆分:把规则丢进 .claude/rules/*.md,与主 CLAUDE.md 同优先级、自动合并。
文件会被递归发现(rules/frontend/*.md 也能识别)。
如果某个规则只想在特定文件被打开时才生效,可以给它加 paths frontmatter:
---
paths:
- "src/driver/**/*.c"
- "src/driver/**/*.h"
---
# 驱动层特别约定
...
带 paths 的规则不常驻,只在 Claude 读取匹配文件时按需加载。
3.5 少即是多
模型能可靠遵循的指令是有限的。CLAUDE.md 建议控制在 200 行以内,只写「事实与规则」:
写得太长,遵守率反而下降。
四、Skill(技能):可复用的能力包
Skill 是封装了单一任务方法论的模块化能力包——一个装着 SKILL.md 的文件夹。
它把「提交代码」「代码审查」「生成发布日志」这类高频流程沉淀下来,
让 Claude 从「凭感觉干」变成「按规矩干」。
4.1 它和提示词有什么区别
普通提示词是「一次性口头指令」,聊完就失效;Skill 是可复用的工作手册,由三部分组成:
- 元数据 —— 什么时候用
- 行动指南 —— 具体怎么做
- 资源文件 —— 脚本与参考资料
一次封装,跨项目、跨会话复用,还能随仓库分发给团队。
4.2 两种安装位置
| 位置 | 路径 | 适用 |
|---|---|---|
| 个人级 | ~/.claude/skills/<name>/SKILL.md |
对你所有项目生效。放「提交信息规范」「个人写作风格」这类通用能力 |
| 项目级 | .claude/skills/<name>/SKILL.md |
随版本库提交、团队共享。放与项目强相关的流程,如「本仓库的发布流程」 |
4.3 目录结构
最小形态只有一个 SKILL.md;复杂技能可以带脚本和参考资料,Claude 会按需取用:
.claude/skills/
└── commit-message/ # 一个 Skill = 一个文件夹
├── SKILL.md # 必需:YAML 元数据 + 操作指令
├── scripts/ # 可选:可被调用的脚本
│ └── lint_msg.py
└── references/ # 可选:按需加载的参考资料
└── conventions.md
4.4 核心:SKILL.md 怎么写
文件分两段:YAML frontmatter 和 Markdown 正文。
---
name: commit-message
description: >
按 Conventional Commits 规范生成 Git 提交信息。
当用户要求"提交代码""写 commit message"时使用。
---
# Git 提交信息规范化
## 何时使用
- 用户要求提交代码、生成 commit 信息时
- 用户说"帮我 commit / 提交一下"时
## 执行步骤
1. 运行 `git status` 和 `git diff --staged` 查看变更
2. 判断变更类型:feat / fix / docs / refactor / test / chore
3. 生成一行式中文提交信息:`type(scope): 摘要`
4. 向用户确认后再执行 `git commit`
## 约束
- 摘要不超过 50 字,结尾不加句号
- 涉及多模块时用 scope 标注,如 `fix(driver): ...`
关于字段,有两点要注意:
- frontmatter 只在整个文件第一行就是
---时才会被解析,前面留空行或注释都会失效。 - 严格来说所有字段都是可选的(
name默认取目录名,description缺省时取第一行非空文本),
但强烈建议两个都写——尤其description。
💡
description是唯一的「触发广告位」。
反面教材:「一个 Git 工具」。
正面写法:说明动作(生成规范提交信息)+ 触发场景(用户要求提交代码时)。
4.5 渐进式披露:为什么 Skills 省 token
这就是 Skills 的精髓:不用的能力只占一行描述,用到的能力才展开细节。
| 层级 | 内容 | 开销 |
|---|---|---|
| 第 1 层 · 元数据 | name + description 始终驻留在系统提示中,供 Claude 判断「当前任务该不该用这个技能」 |
约 100 tokens · 常驻 (描述超过 1536 字符会被截断) |
| 第 2 层 · 指令正文 | 任务匹配 description 后,Claude 才读取 SKILL.md 正文,按其中步骤执行 |
建议 < 500 行 · 触发时加载 |
| 第 3 层 · 关联资源 | scripts/、references/ 里的脚本与文档,只有正文引用到时才被加载或执行 |
按需读取 · 不占上下文 |
所以你完全可以装几十个技能,上下文开销依然可控。
注意:正文一旦加载会留在本会话上下文中;脚本是被执行而不是被读入的,所以脚本写多长都不心疼。
4.6 三种创建方式
| 方式 | 适合 | 做法 |
|---|---|---|
| 手动创建 | 深度定制 / 学习原理 | 建 .claude/skills/<name>/ 目录 → 写 SKILL.md → 保存即用 |
| 官方脚手架 | 标准化团队开发 | 运行 anthropics/skills 仓库中的 init_skill.py,自动生成规范目录结构与模板 |
元技能 skill-creator |
快速原型 / 零代码 | 直接对 Claude 说:「帮我创建一个技能,功能是……」,由 skill-creator 自动生成 |
技能创建后即可使用:既会在任务匹配时自动触发,也可以在会话中输入
/commit-message 这样的斜杠命令手动调用。
五、Plugin(插件):把一整套配置打包分发
前面讲的 Skill 解决了「我会用」,但没解决「怎么给别人用」。
你写好了一套 Skills + Hooks + 子代理,同事想复刻,难道一个个文件夹拷贝?
Plugin 就是这个分发单位。
5.1 插件 vs 技能
| 技能 Skill | 插件 Plugin | |
|---|---|---|
| 粒度 | 单一能力 | 一套资产 |
| 内容 | 一个 SKILL.md + 资源 |
Skills + Commands + Agents + Hooks + MCP + LSP…… |
| 分发 | 拷贝文件夹 / 提交仓库 | 一条命令安装,带版本号、可更新、可卸载 |
| 命名 | /skill-name |
/plugin-name:skill-name(插件内技能带命名空间) |
同一个技能,装进插件后就多了命名空间前缀——这正是为了避免不同插件之间的命名冲突。
5.2 插件能装什么
一个插件目录可以包含以下任意组合:
my-plugin/
├── .claude-plugin/
│ └── plugin.json # 清单文件(唯一必须放在 .claude-plugin/ 里的东西)
├── skills/ # 技能,每个子目录一个 SKILL.md
├── commands/ # 斜杠命令(.md 文件平铺)
├── agents/ # 子代理定义
├── hooks/
│ └── hooks.json # 钩子配置
├── .mcp.json # 随插件一起提供的 MCP 服务器
├── .lsp.json # 语言服务器配置
└── output-styles/ # 输出风格
⚠️ 最容易踩的坑:只有
plugin.json放在.claude-plugin/里,
其余所有组件目录都必须放在插件根目录下。放错位置会静默不生效。
plugin.json 本身很轻,只有 name 是必填的:
{
"name": "conductor",
"version": "1.2.2",
"description": "Context-Driven Development plugin that transforms Claude Code into a project management tool",
"author": {
"name": "Seth Hobson"
},
"license": "Apache-2.0"
}
5.3 安装与管理
日常使用推荐在会话里用斜杠命令:
/plugin marketplace add anthropics/claude-code # 添加插件市场
/plugin install <插件名>@<市场名> # 安装插件
/plugin marketplace remove <市场名> # 移除市场
/plugin marketplace update <市场名> # 更新市场索引
脚本化 / CI 场景用命令行等价形式:
claude plugin marketplace add <URL、路径或 GitHub 仓库>
claude plugin marketplace list
claude plugin install <插件名> --scope user|project|local
claude plugin list # 查看已安装
claude plugin enable <插件名>
claude plugin disable <插件名>
claude plugin update <插件名> # 更新(重启后生效)
claude plugin uninstall <插件名>
claude plugin details <插件名> # 查看组件清单与预估 token 开销
作用域:--scope user 装到个人全局,project 随仓库共享,local 仅本机本仓库。
已安装的插件会被复制到插件缓存目录 ~/.claude/plugins/cache 下。
5.4 发布自己的插件
claude plugin init my-plugin --with skills agents hooks mcp
claude plugin validate ./my-plugin # 发布前校验清单
claude plugin tag ./my-plugin # 打一个 {name}--v{version} 的发布 tag
想建立一个市场,只需要一个仓库,根目录放 .claude-plugin/marketplace.json:
{
"name": "my-marketplace",
"owner": { "name": "Your Name" },
"plugins": [
{
"name": "my-plugin",
"source": "./plugins/my-plugin",
"description": "我的第一个插件"
}
]
}
其中 name、owner、plugins 三个字段必填。推上 GitHub 后,任何人一条命令就能装到你的插件。
💡 判断该不该做成插件:如果你发现自己在第三个项目里复制同一套
.claude/目录,
就该考虑把它打包成插件了。
六、Hook(钩子):事件驱动的确定性自动化
规则靠模型「自觉」,技能靠模型「判断」,而 Hooks 是确定性机制:
在 Claude Code 生命周期的固定节点上,必然执行你预先定义的 shell 命令——
格式化、拦截、通知,一次配置,永远生效。
6.1 生命周期与事件
一个会话的流转是:
启动 → 接收提示词 → (调用工具前 → 工具执行 → 工具完成) × N → 回复结束 → 会话终止
每个节点都有对应事件可挂载。常用事件:
| 事件 | 触发时机 | 能否阻止 |
|---|---|---|
SessionStart |
会话开始 / 恢复 | ❌ 仅通知 |
UserPromptSubmit |
你提交提示词后、Claude 处理前 | ✅ 可阻止 |
PreToolUse |
工具调用执行前(如 Bash/Edit) | ✅ 可阻止 |
PostToolUse |
工具调用成功后 | ❌ 仅通知 |
PostToolUseFailure |
工具调用失败后 | ❌ 仅通知 |
Notification |
Claude 发出通知时(如等待输入) | ❌ 仅通知 |
SubagentStart / SubagentStop |
子代理启动 / 结束时 | Stop 可阻止 |
Stop |
Claude 回复结束时 | ✅ 可阻止 |
PreCompact |
上下文压缩前 | ✅ 可阻止 |
SessionEnd |
会话终止时 | ❌ 仅通知 |
完整事件列表有 30 多个,此处只列日常最常用的。
能否阻止取决于事件本身——不是所有事件都支持用退出码否决。
6.2 配置文件
Hooks 写在 settings.json 的 hooks 块中。三层作用域:
~/.claude/settings.json—— 个人全局.claude/settings.json—— 项目共享,可提交进版本库.claude/settings.local.json—— 项目私有,不提交
配置结构为「事件 → 匹配器 → 命令」三层:
{
"hooks": {
"PostToolUse": [
{
"matcher": "Write|Edit",
"hooks": [
{
"type": "command",
"command": "npx prettier --write \"$CLAUDE_PROJECT_DIR/src/**/*.ts\""
}
]
}
]
}
}
不同层级的钩子是合并的,不是覆盖。
6.3 matcher 过滤语法
| matcher 写法 | 含义 |
|---|---|
"Bash" |
精确匹配 Bash 工具 |
"Write|Edit" |
匹配 Write 或 Edit(| 分隔) |
"mcp__memory__.*" |
匹配某个 MCP server 的全部工具(正则) |
"*" 或省略 |
匹配该事件下的所有工具 |
⚠️ 这里有个容易踩的细节:只由字母、数字、
_、-、空格、,、|组成的 matcher 走精确匹配;
一旦出现其他字符,整个字符串就被当作「非锚定」的 JavaScript 正则。
也就是说Edit.*会连NotebookEdit一起匹配上。
6.4 钩子的输入与输出约定
触发时,Claude Code 会把事件上下文以 JSON 从 stdin 传给钩子脚本,
内含 session_id、transcript_path、cwd、hook_event_name,工具类事件还会带
tool_name、tool_input、tool_use_id。
脚本的退出码决定结果:
| 退出码 | 含义 |
|---|---|
0 |
放行。stdout 内容在详细模式下可见;操作正常执行 |
2 |
阻止。stderr 内容作为错误反馈给 Claude,它会看到原因并调整行为(仅「可阻止」事件有效) |
| 其他非零 | 非阻塞错误。操作继续执行,错误只记进日志 |
⚠️
exit 1不会阻止任何操作——这是最常见的误解。
想否决一次工具调用,必须exit 2。
6.5 实战脚本:拦截危险命令
下面这个 PreToolUse 钩子挂在 Bash 上,用 jq 解析 stdin 的 JSON,
命中危险模式就 exit 2 阻止执行:
#!/bin/bash
# .claude/hooks/block-rm.sh — PreToolUse 钩子
# 从 stdin 读取 JSON,取出将要执行的命令
COMMAND=$(jq -r '.tool_input.command')
if echo "$COMMAND" | grep -qE 'rm\s+-rf|git\s+push\s+.*--force'; then
echo "禁止执行危险命令: $COMMAND" >&2
exit 2 # 退出码 2 = 阻止,stderr 会反馈给 Claude
fi
exit 0 # 退出码 0 = 放行
在 .claude/settings.json 里注册它:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{ "type": "command", "command": "$CLAUDE_PROJECT_DIR/.claude/hooks/block-rm.sh" }
]
}
]
}
}
Linux/macOS 下记得 chmod +x .claude/hooks/block-rm.sh;
Windows 环境建议改用 PowerShell 脚本或 node 脚本作为 command。
💡 钩子命令里可用变量
$CLAUDE_PROJECT_DIR指代项目根目录,插件里还可以用${CLAUDE_PLUGIN_ROOT}。
注意 PowerShell 下这个变量要写成${CLAUDE_PROJECT_DIR}或$env:CLAUDE_PROJECT_DIR,
裸写$CLAUDE_PROJECT_DIR会解析成$null。
6.6 三个开箱即用的场景
| 场景 | 事件 | 价值 |
|---|---|---|
| 拦截危险命令 | PreToolUse |
在 Bash 执行前检查命令,命中 rm -rf、强制推送等模式时以退出码 2 阻止,把「AI 手滑」变成不可能 · 安全护栏 |
| 编辑后自动格式化 | PostToolUse |
Claude 每次 Write/Edit 之后自动跑 prettier/black,再也不用叮嘱「记得格式化」 · 质量自动化 |
| 等待输入时桌面通知 | Notification |
Claude 需要确认时弹系统通知,切走窗口也不会错过 · 体验增强 |
桌面通知配置示例(Windows):
{
"hooks": {
"Notification": [
{
"matcher": "*",
"hooks": [
{
"type": "command",
"command": "powershell -c \"[reflection.assembly]::loadwithpartialname('System.Windows.Forms');[System.Windows.Forms.MessageBox]::Show('Claude 等待你的输入')\""
}
]
}
]
}
}
6.7 排查钩子问题
-
先手动执行验证脚本本身:
echo '{"tool_input":{"command":"ls"}}' | ./.claude/hooks/block-rm.sh -
再在会话里用
/hooks命令查看已注册的钩子。
七、MCP:给 Claude 接上外部世界
Skills 教 Claude「怎么做」,MCP 解决的是「用什么做」。
模型本身只能读写文件和跑命令;想让它查 Jira、搜内部知识库、操作数据库,
就需要 MCP(Model Context Protocol)——一个把外部系统标准化暴露成「工具 + 资源」的协议。
7.1 三种传输方式
| 传输 | 适用 | 命令 |
|---|---|---|
| stdio(默认) | 本地进程,最常用 | claude mcp add <名字> -- <命令> [参数...] |
| HTTP | 远程服务,推荐 | claude mcp add --transport http <名字> <URL> |
| SSE | 远程服务(旧) | claude mcp add --transport sse <名字> <URL> |
# stdio:本地 npx 起的服务,带环境变量
claude mcp add my-server -e API_KEY=xxx -- npx my-mcp-server
# stdio:本地可执行文件的写法,注意 -- 用于分隔
claude mcp add my-server -- my-command --some-flag arg1
# HTTP:远程服务,带认证头
claude mcp add --transport http corridor https://app.corridor.dev/api/mcp \
--header "Authorization: Bearer ..."
--之后的部分才是服务器自己的命令和参数,之前的是 Claude Code 的参数,别写反。
7.2 三种作用域
| 作用域 | 配置写入 | 适用 |
|---|---|---|
local(默认) |
~/.claude.json 中该项目的条目 |
只给「我 + 这个项目」用,最适合放密钥 |
project |
项目根目录 .mcp.json(可提交进版本库) |
团队共用一套配置 |
user |
~/.claude.json |
所有项目都能用 |
claude mcp add --scope project my-server -- npx my-mcp-server
⚠️ 注意:MCP 的
local作用域和一般设置的local不是一回事。
一般本地设置写在.claude/settings.local.json,而 MCP 的 local 写在~/.claude.json。
.mcp.json 提交进仓库后,队友首次打开项目会看到待批准提示,
批准前不会连接、也不会健康检查——这是防止别人塞给你一个恶意 MCP 服务的保护。
用 claude mcp reset-project-choices 可以重置所有批准/拒绝记录。
7.3 常用命令
claude mcp list # 列出所有已配置的服务器(含待批准状态)
claude mcp get <名字> # 查看某个服务器的详情
claude mcp remove <名字> # 移除
claude mcp add-json <名字> '<JSON>' # 直接以 JSON 添加(stdio/SSE/HTTP/ws 均可)
claude mcp login <名字> # 对需要 OAuth 的服务做认证
会话里用 /mcp 打开管理面板,可以看到每个服务器暴露了哪些工具、连接状态如何。
7.4 工具怎么被调用、资源怎么被引用
MCP 服务器暴露的工具会以固定命名出现:
mcp__<服务器名>__<工具名>
例如:mcp__github__search_repositories
插件自带的 MCP 服务器会用更长的形式,中间插入插件名:
mcp__plugin_<插件名>_<服务器名>__<工具名>
⚠️ 这意味着:给钩子写 matcher 时,用裸服务器名匹配不到插件带的服务器,得用上面这种长形式。
MCP 的资源可以在提示词里用 @ 直接引用,它们和文件一样出现在补全列表里:
@github:issue://123
@postgres:table://public/users
MCP 的提示词则是斜杠命令形式:/服务器名:提示词名。
7.5 相关设置与调优
settings.json 中的相关键:
enableAllProjectMcpServers:设为true则自动批准所有项目级.mcp.json服务器enabledMcpjsonServers/disabledMcpjsonServers:白名单 / 黑名单(拒绝优先于允许)
环境变量:
| 变量 | 作用 |
|---|---|
MCP_TIMEOUT |
服务器启动超时,默认 30 秒 |
MCP_TOOL_TIMEOUT |
单次工具调用超时 |
MAX_MCP_OUTPUT_TOKENS |
限制 MCP 返回内容的 token 量 |
7.6 什么时候该用 MCP
- 数据在外部系统里(Jira、Confluence、数据库、监控)→ 上 MCP
- 只是一段本地流程(怎么提交、怎么发版)→ 写 Skill 就够了
- 需要确定性拦截(不许改某个文件)→ 那是 Hook 的活
八、Agent(子代理):隔离上下文里分身干活
规则定规矩,技能定做法,钩子定时机——还差一个:
子代理定角色。
子代理(Subagent)是 Claude 在独立的上下文窗口里启动的一个「分身」,
带着自己的系统提示、自己的工具权限、自己的模型,干完活只把结论带回主会话。
8.1 为什么需要它
主会话的上下文是稀缺资源。让 Claude 去「在 200 个文件里找一段逻辑」,
搜索结果会塞满上下文窗口,把真正重要的对话挤出去。
子代理的价值就是上下文隔离:
主会话:帮我找一下错误处理的漏洞
├── 子代理 A → 扫描 api/ → "发现 2 处" ──┐
├── 子代理 B → 扫描 utils/ → "无问题" ──┼──→ 主会话只收到三行结论
└── 子代理 C → 扫描 cli/ → "发现 1 处" ──┘
三个子代理各自读了几十个文件,主会话的上下文里只多了三行。
它们还能真正并行跑。
8.2 定义文件
| 位置 | 作用域 | 优先级 |
|---|---|---|
| 企业托管设置 | 全组织 | 1(最高) |
--agents 命令行 JSON |
当前会话 | 2 |
.claude/agents/ |
项目级,可提交共享 | 3 |
~/.claude/agents/ |
个人全局 | 4 |
插件的 agents/ |
随插件分发 | 5 |
每个子代理是一个 Markdown 文件,只有 name 和 description 是必填的:
---
name: code-reviewer
description: >
审查代码变更,检查可读性、错误处理与安全隐患。
在写完或修改代码后主动使用。
tools: Read, Grep, Glob, Bash
model: sonnet
---
你是一位资深代码审查者。
审查时:
1. 先跑 `git diff` 看完整改动,不要只看最新一次提交
2. 按「安全 → 正确性 → 可维护性」的顺序检查
3. 每个问题给出 `文件:行号`、问题描述、以及具体的修复建议
输出格式:先列 CRITICAL/HIGH 问题,再列建议;没有问题就明说,不要为了凑数编造。
其他可用字段还有 disallowedTools、permissionMode、maxTurns、skills、
mcpServers、hooks、memory、effort、isolation、color 等。
8.3 怎么调用
自动委派——最常用的方式。description 写得好,Claude 会在合适的时机自己派活。
想让它更主动,在描述里加一句「主动使用 / use proactively」。
自然语言指定——「用 code-reviewer 子代理审查一下 driver 目录」。
@ 提及——在输入框里打 @ 补全,或直接输入 @agent-code-reviewer。
会话级绑定——启动时指定,整个会话都由它来当主角色:
claude --agent code-reviewer
8.4 模型与成本
子代理可以单独指定模型,这正是控制成本的关键:
主会话用强模型做决策,子代理用便宜快速的模型做「体力活」(搜索、批量读取、格式检查)——
反正它们只回传结论。
CLAUDE_CODE_SUBAGENT_MODEL 环境变量设置的是默认模型,
它会作用于没被单独指定模型的子代理、agent-team 队友和 workflow 代理。
可以用别名(haiku)或完整模型 ID,设为 inherit 等同于不设置。
⚠️ 优先级细节:子代理自己的
model字段和单次调用的模型参数会覆盖这个环境变量——
它只是一个「默认值」。想强制所有子代理都用同一个模型,
需要额外设置CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1。
📌 在第一节那份
settings.json里,
"CLAUDE_CODE_SUBAGENT_MODEL": "deepseek-v4-pro[1M]"就是在做这件事:
保证子代理也有 100 万 token 的上下文,不至于因为搜到大文件就爆窗口。
8.5 两个容易踩的点
-
/agents不再是交互式向导。在较新版本中它只会提示你去编辑.claude/agents/目录,
或者直接让 Claude 帮你创建。别等着它弹出一个配置界面。 -
子代理看不到你的对话历史。它启动时是全新的上下文,
所以委派时要把必要背景写进任务描述里——「审查刚才那个改动」它并不知道你指的是哪个改动。
唯一的例外是 fork:它会继承完整对话上下文,适合「基于我们刚聊的,去做 X」。
九、组合拳:一个真实项目的配置全景
真实项目里,几个机制存放在固定的目录结构中、各司其职。
下面是一份可以直接照搬的完整布局:
your-project/
├── CLAUDE.md # 【规则】项目记忆:架构、规范、红线
├── CLAUDE.local.md # 【规则】个人私有配置(不提交)
├── .mcp.json # 项目级 MCP 服务器(可选,可提交共享)
└── .claude/
├── rules/
│ ├── git.md # 【规则】提交规范(按需拆分)
│ └── driver.md # 【规则】驱动目录特别约定
├── skills/
│ ├── commit-message/
│ │ └── SKILL.md # 【技能】规范提交信息
│ └── reg-analyze/
│ ├── SKILL.md # 【技能】寄存器手册速查
│ └── references/
│ └── rtl8364_regs.md
├── agents/
│ └── code-reviewer.md # 【子代理】代码审查
├── settings.json # 【钩子】配置注册处
├── settings.local.json # 【钩子】个人私有钩子
├── hooks/
│ ├── protect.sh # 【钩子】拦截危险命令
│ └── format.sh # 【钩子】编辑后自动格式化
四者的分工:
- 规则:把上下文钉死 ——
CLAUDE.md说明架构与红线;rules/按主题拆分;
local 文件存个人临时偏好。会话一开始,Claude 就站在和你同一页纸上。 - 技能:把流程标准化 —— 高频流程封装进
skills/,Claude 自动匹配触发。
换个人、换个会话,产出质量依然稳定。 - 钩子:把底线焊死 ——
settings.json注册 hooks:危险命令必然被拦、
代码保存必然被格式化——与模型状态无关,永远在线。 - 子代理:把上下文隔开 —— 大范围搜索、批量审查交给分身,主会话只留结论。
实战:一份合格的 CLAUDE.md
以本项目(HC32L021 + RTL8364 光电转换器固件)为例,一份好的 CLAUDE.md 覆盖三类信息:
项目是什么、怎么构建验证、规范与红线:
# NEXC02-G1S-40R 光电转换器固件
## 项目概述
基于 HC32L021 的媒体转换器固件:通过 GPIO 模拟 SMI(I2C)总线配置
Realtek RTL8364 交换芯片,实现 EXT_PORT0(光口)与 UTP_PORT1(电口)
的链路联动。
## 构建与验证
- 构建:Keil MDK 打开 `example/MDK/HC32L021.uvprojx`,
输出到 `example/MDK/output/release`
- 版本控制:SVN(`svn://192.168.3.250/rsc/trunk/rtl8364`),**不是 Git**
- 本仓库用 SVN 提交,写明变更说明;不要用 git 命令
## 代码规范
- 应用层代码放 `example/source/`;`driver/`、`common/` 是 MCU 厂商 DDL,不要改
- 引脚定义只写在 `example/source/board_config.h`,不要在 .c 里散落魔数
- 日志统一用 `example/source/debug.h` 的 `debug_printf()` 宏
- SMI 读写统一走 `gpio_i2c.c` 的位操作宏(`STK_SDA_SET/RSET/READ`)
## 已知坑(改之前先读)
- `board_config.h` 里 `*_PRESSED()` 宏内的 `GPIO_PAx_READ()` 是按引脚写死的,
改 `GPIO_PIN_xx` 时**两处必须同步修改**
- SMI 的 `CLK_DURATION(DELAY)` 延时宏在编译后**并不存在**——
SCL 频率是代码生成后的副产物,改时序要在示波器上复测,
不要靠调延时数值「心算」
## 红线
- `Realtek_Unmanaged_Switch_API_V1.5.4_20250724/` 是原厂 API,只读参考,禁止修改
- HC32L021 是 Cortex-M0+,无 FPU,禁止使用浮点运算
注意最后那节「已知坑」——这些是 Claude 自己读代码读不出来的信息,
却往往是整个文件里最值钱的部分。判断标准依然是那句:
凡是你要对 Claude 重复第二遍的话,就该写进去。
十、速查表
收藏这一节,配置时随用随查。
规则
| 我要做什么 | 怎么做 |
|---|---|
| 生成项目记忆 | /init |
| 编辑记忆文件 | /memory |
| 全局个人规则 | ~/.claude/CLAUDE.md |
| 项目规则 | ./CLAUDE.md + .claude/rules/*.md |
| 按文件类型生效的规则 | 规则文件加 paths: frontmatter |
| 导入外部文档 | @docs/xxx.md(最多 4 层嵌套) |
技能
| 我要做什么 | 怎么做 |
|---|---|
| 技能目录(项目) | .claude/skills/<name>/SKILL.md |
| 技能目录(全局) | ~/.claude/skills/<name>/SKILL.md |
| 推荐元数据 | YAML 头:name + description |
| 手动调用 | /<skill-name> |
| 查看已安装技能 | /skills |
插件
| 我要做什么 | 怎么做 |
|---|---|
| 添加市场 | /plugin marketplace add <源> |
| 安装插件 | /plugin install <插件>@<市场> |
| 列出 / 启用 / 禁用 | claude plugin list / enable / disable |
| 查看组件与 token 开销 | claude plugin details <插件> |
| 脚手架 / 校验 / 发版 | claude plugin init / validate / tag |
钩子
| 我要做什么 | 怎么做 |
|---|---|
| 配置位置 | .claude/settings.json 的 hooks 块 |
| 放行 | exit 0 |
| 阻止并反馈 | exit 2(stderr 给 Claude,仅「可阻止」事件有效) |
| 项目根变量 | $CLAUDE_PROJECT_DIR |
| 查看已注册钩子 | /hooks |
| 手动测试钩子 | echo '<JSON>' | ./.claude/hooks/xxx.sh |
MCP
| 我要做什么 | 怎么做 |
|---|---|
| 添加(本地 stdio) | claude mcp add <名> -- <命令> [参数] |
| 添加(远程 HTTP) | claude mcp add --transport http <名> <URL> |
| 指定作用域 | --scope local|project|user |
| 查看 / 移除 | claude mcp list / claude mcp remove <名> |
| 会话内管理面板 | /mcp |
| 工具调用名格式 | mcp__<服务器>__<工具> |
| 引用资源 | @<服务器>:<协议>://<路径> |
子代理
| 我要做什么 | 怎么做 |
|---|---|
| 项目级定义 | .claude/agents/<name>.md |
| 个人全局定义 | ~/.claude/agents/<name>.md |
| 必填字段 | YAML 头:name + description |
| 默认模型 | 环境变量 CLAUDE_CODE_SUBAGENT_MODEL |
| 强制统一模型 | 追加 CLAUDE_CODE_SUBAGENT_MODEL_FORCE=1 |
| 会话级绑定 | claude --agent <名字> |
参考资料
- Anthropic 官方文档:https://code.claude.com/docs
- 社区实践指南与源码验证
本文中的配置示例均已在 Claude Code v2.1.258 上验证。
版本迭代较快,命令细节请以官方文档为准。

浙公网安备 33010602011771号