Claude Code 完全指南:环境搭建 + 五大扩展机制

Claude Code 完全指南:环境搭建 + 五大扩展机制

一份可以直接照搬的实操手册。
上半篇解决「装得上、跑得起来」,下半篇解决「用得顺、管得住」——
Skill / Plugin / Hook / MCP / 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.md
Linux/WSL:/etc/claude-code/CLAUDE.md
Windows: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
  • 按文件类型的规则 → 下沉到 .claude/rules/ + paths
  • 需要连外部系统的能力 → 交给 MCP

写得太长,遵守率反而下降。


四、Skill(技能):可复用的能力包

Skill 是封装了单一任务方法论的模块化能力包——一个装着 SKILL.md 的文件夹。
它把「提交代码」「代码审查」「生成发布日志」这类高频流程沉淀下来,
让 Claude 从「凭感觉干」变成「按规矩干」。

4.1 它和提示词有什么区别

普通提示词是「一次性口头指令」,聊完就失效;Skill 是可复用的工作手册,由三部分组成:

  1. 元数据 —— 什么时候用
  2. 行动指南 —— 具体怎么做
  3. 资源文件 —— 脚本与参考资料

一次封装,跨项目、跨会话复用,还能随仓库分发给团队。

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 frontmatterMarkdown 正文

---
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": "我的第一个插件"
    }
  ]
}

其中 nameownerplugins 三个字段必填。推上 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.jsonhooks 块中。三层作用域:

  • ~/.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_idtranscript_pathcwdhook_event_name,工具类事件还会带
tool_nametool_inputtool_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 排查钩子问题

  1. 手动执行验证脚本本身:

    echo '{"tool_input":{"command":"ls"}}' | ./.claude/hooks/block-rm.sh
    
  2. 再在会话里用 /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 文件,只有 namedescription 是必填的

---
name: code-reviewer
description: >
  审查代码变更,检查可读性、错误处理与安全隐患。
  在写完或修改代码后主动使用。
tools: Read, Grep, Glob, Bash
model: sonnet
---

你是一位资深代码审查者。

审查时:
1. 先跑 `git diff` 看完整改动,不要只看最新一次提交
2. 按「安全 → 正确性 → 可维护性」的顺序检查
3. 每个问题给出 `文件:行号`、问题描述、以及具体的修复建议

输出格式:先列 CRITICAL/HIGH 问题,再列建议;没有问题就明说,不要为了凑数编造。

其他可用字段还有 disallowedToolspermissionModemaxTurnsskills
mcpServershooksmemoryeffortisolationcolor 等。

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 两个容易踩的点

  1. /agents 不再是交互式向导。在较新版本中它只会提示你去编辑 .claude/agents/ 目录,
    或者直接让 Claude 帮你创建。别等着它弹出一个配置界面。

  2. 子代理看不到你的对话历史。它启动时是全新的上下文,
    所以委派时要把必要背景写进任务描述里——「审查刚才那个改动」它并不知道你指的是哪个改动。

唯一的例外是 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.jsonhooks
放行 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 <名字>

参考资料

本文中的配置示例均已在 Claude Code v2.1.258 上验证。
版本迭代较快,命令细节请以官方文档为准。

posted @ 2026-09-21 16:27  放飞梦想C  阅读(16)  评论(0)    收藏  举报