02-项目配置:CLAUDE.md、MCP、Skill与Hooks

项目配置:CLAUDE.md、MCP、Skill 与 Hooks

本文是 Claude Code AI 辅助编程系列的第 2 篇,深入讲解如何通过 CLAUDE.md 项目指令、MCP 外部服务、自定义 Skill 技能、Hooks 钩子和 Sub-Agent 子代理来配置和增强 Claude Code 的能力。


第三章:项目配置与最佳实践

3.1 CLAUDE.md 项目指令文件

3.1.1 CLAUDE.md 的作用与重要性

CLAUDE.md 是 Claude Code 的项目指令文件,相当于给 AI 的一份"员工手册"。每次启动 Claude Code 时,它会自动读取该文件内容作为背景知识,确保 AI 的所有操作都符合项目规范。

没有 CLAUDE.md 的情况

  • AI 不了解项目架构,可能把代码放错位置
  • AI 不了解编码规范,可能写出不符合团队标准的代码
  • AI 不了解数据库规范,可能设计出带外键、存储过程的表结构
  • AI 不知道项目已有哪些中间件和公共方法,会重复造轮子(如自己写日志方法、重新实现已有的工具类)
  • 每次对话都要重复说明项目约定,效率低下

有 CLAUDE.md 的情况

  • AI 自动知道项目是 .NET 6 分层架构,Model 放 OSModel、DAL 用 Dapper
  • AI 自动遵守编码规范:强类型、禁止 dynamic、模型类统一放置
  • AI 自动按数据库规范建表:utf8mb4、无外键、状态字段用 INT
  • AI 自动使用项目已有的中间件和公共方法(如 OperationLogHelper、全局过滤器等),而不是重复造轮子
  • 一次编写,全团队共享,所有人得到一致的 AI 行为

核心价值:CLAUDE.md 是团队用 AI 编程的质量底线,写得越完善,AI 输出的代码质量越高。

3.1.2 文件结构与编写规范

一个完善的 CLAUDE.md 通常包含以下模块:

# CLAUDE.md

## 项目概述
<!-- 一句话说明项目是什么、用什么技术栈 -->

## 架构结构
<!-- 项目分层、各层职责、目录说明 -->

### 代码规范
<!-- 命名规则、禁止事项、类放置规则等 -->

## 常用命令
<!-- 构建、运行、测试、部署命令 -->

## 关键配置
<!-- 依赖注入、数据库连接、路由规则等 -->

### 数据库设计规范
<!-- 建表规则、字段类型、字符集、约束规则 -->

### 字段规范
<!-- 状态字段、金额字段、数量字段的统一标准 -->

## 中间件与公共方法
<!-- 项目已有的中间件、工具类、公共方法,告诉 AI 优先复用 -->

## 主要业务模块
<!-- 核心业务逻辑的说明 -->

## 测试策略
<!-- 测试框架、目录结构、验证方式 -->

编写原则

  • 具体明确:不写"注意代码规范",而写"所有模型类必须放在 OSModel 项目中"
  • 给出示例:重要规则附带正确和错误的代码示例
  • 禁止项加粗:用 **禁止XXX** 标注红线规则,AI 会严格遵守
  • 保持更新:新增模块或规范变更时同步更新 CLAUDE.md

3.1.3 项目级 vs 用户级配置

Claude Code 的配置分为多个层级,从高到低依次加载:

层级 文件位置 作用范围 是否提交 Git
项目级 项目根目录/CLAUDE.md 整个项目,所有成员共享
项目本地级 项目根目录/.claude/settings.local.json 仅本地生效 否(加入 .gitignore)
用户级 ~/.claude/CLAUDE.md 该用户所有项目
用户设置 ~/.claude/settings.json 该用户全局设置

使用建议

  • 团队共享规范 → 写在项目根目录的 CLAUDE.md,提交到 Git
  • 个人偏好设置(如权限自动允许) → 写在 .claude/settings.local.json
  • 通用个人习惯(如"请用中文回复") → 写在用户级 ~/.claude/CLAUDE.md

3.1.4 实际案例:本项目的 CLAUDE.md 解析

我们项目的 CLAUDE.md 包含以下关键规则,AI 在每次对话中都会自动遵守:

规则类别 具体内容 AI 行为效果
架构规范 分层架构:OSAPI / OSBLL / OSDAL / OSModel AI 创建代码时自动放到正确的层
代码规范 模型类统一放 OSModel,禁止 dynamic AI 不会在 DAL 里定义 private class
数据库规范 禁止外键、禁止存储过程、utf8mb4 AI 建表时不会加 FOREIGN KEY
字段规范 状态用 INT(100/101)、金额 DECIMAL(15,4) AI 设计表时自动使用正确类型
中间件与公共方法 GlobalActionFilter、GlobalExceptionFilter、OperationLogHelper 等 AI 优先复用已有工具类,不重复造轮子
命令规范 dotnet build / dotnet test 等 AI 知道如何构建和测试项目
日志规范 使用 OperationLogHelper,复用数据库连接 AI 写日志代码时不会创建新连接

3.1.5 如何添加和维护规则

方法一:直接编辑文件

用任意文本编辑器打开项目根目录的 CLAUDE.md,按 Markdown 格式添加规则:

### 新增规范名称
- **规则描述**:具体要求说明
  - 详细条款 1
  - 详细条款 2
- **禁止事项**:不允许的做法

方法二:通过 Claude Code 命令添加

在 Claude Code 对话中使用 /init 命令,可以交互式初始化或更新 CLAUDE.md:

# 启动 Claude Code 后执行
/init

也可以直接让 AI 帮你添加规则:

请在 CLAUDE.md 中添加以下规范:
所有接口返回值统一使用 ResponseData<T> 包装类,禁止直接返回原始类型。

方法三:通过对话积累规则

在日常使用中发现 AI 的行为不符合预期时,可以当场要求它更新 CLAUDE.md:

你刚才生成的代码在 DAL 层定义了一个内部类,这不符合我们的规范。
请把"禁止在 DAL 层定义内部类"这条规则补充到 CLAUDE.md 的代码规范部分。

常见规则添加示例

# 示例 1:添加返回值规范
### 接口返回值规范
- 所有 API 接口统一返回 `ResponseData<T>` 类型
- 禁止直接返回 string、int 等原始类型
- 分页查询返回 `ResponseData<PagedResult<T>>`

# 示例 2:添加命名规范
### 命名规范
- Controller 类以 `Controller` 结尾
- BLL 类以 `BLL` 结尾
- DAL 类以 `DAL` 结尾
- 数据库表名使用下划线分隔小写命名(如 `goods_base_info`)

# 示例 3:添加禁止项
### 安全规范
- **禁止硬编码数据库密码**:所有敏感信息通过 Apollo 配置中心获取
- **禁止在日志中输出用户敏感信息**:如手机号、身份证号等

维护建议

  • 新模块上线后,补充该模块的业务说明和关键表结构
  • 团队 Code Review 中发现的共性问题,及时沉淀为 CLAUDE.md 规则
  • 定期清理过时的规则,保持文件的准确性和可读性

3.2 MCP 服务配置

3.2.1 MCP(Model Context Protocol)简介

MCP 是模型上下文协议,是 Anthropic 提出的开放标准,用于让 AI 模型连接外部工具和数据源。

通俗理解:默认情况下 Claude Code 只能读写本地文件和执行命令。通过 MCP,你可以给它"接上外设"——连数据库、调 API、访问第三方服务,就像给电脑插 U 盘一样即插即用。

在我们项目中的核心用途

  • 让 AI 直接查询开发数据库,验证代码是否正确写入了数据
  • 让 AI 查看表结构,辅助设计新表或排查字段问题
  • 让 AI 在编码过程中实时验证 SQL 语句的正确性

3.2.2 .mcp.json 配置文件详解

MCP 服务通过项目根目录的 .mcp.json 文件配置。Claude Code 启动时自动加载该文件并连接配置的服务。

文件结构

{
  "mcpServers": {
    "服务名称": {
      "type": "stdio",          // 通信方式,stdio 为标准输入输出
      "command": "npx",         // 启动命令
      "args": ["参数1", "参数2"], // 命令参数
      "env": {                  // 环境变量(连接信息等)
        "KEY": "VALUE"
      }
    }
  }
}

字段说明

字段 说明 示例
服务名称 自定义名称,用于标识服务 mysql-goods-service
type 通信协议类型 stdio(最常用)
command 启动 MCP 服务的命令 npxnodepython
args 命令参数,通常指定 MCP 包名 ["-y", "@benborla29/mcp-server-mysql"]
env 环境变量,传递连接信息 数据库主机、端口、用户名、密码等

3.2.3 数据库 MCP 服务配置(mysql-goods-service)

我们项目已配置了 MySQL MCP 服务,AI 可以直接查询开发环境数据库。

当前配置.mcp.json):

{
  "mcpServers": {
    "mysql-goods-service": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@benborla29/mcp-server-mysql"],
      "env": {
        "MYSQL_HOST": "192.168.85.73",
        "MYSQL_PORT": "3310",
        "MYSQL_USER": "os_user",
        "MYSQL_PASSWORD": "******",
        "MYSQL_DATABASE": "stt9900010001"
      }
    }
  }
}

前置条件:需要安装 Node.js(npx 命令依赖),首次运行时会自动下载 MCP 包。

检查 MCP 状态:在 Claude Code 中执行 /mcp 命令,可以查看所有 MCP 服务的连接状态。

实际使用场景举例

场景 1:验证数据写入
你:我刚写了一个创建商品的接口,帮我验证数据是否正确入库
AI:(自动通过 MCP 执行 SQL 查询,返回实际数据库记录)

场景 2:辅助表设计
你:帮我看一下 goods_base_info 表目前有哪些字段
AI:(通过 MCP 执行 DESCRIBE 查询,返回表结构)

场景 3:排查数据问题
你:库存扣减似乎不对,帮我查一下 SKU001 的库存流水
AI:(通过 MCP 查询 goods_inventory_transactions 表,分析流水记录)

安全注意事项

  • .mcp.json 中包含数据库密码,务必加入 .gitignore,不要提交到代码仓库
  • MCP 连接的数据库应该是开发/测试环境,禁止连接生产环境
  • AI 通过 MCP 执行的 SQL 默认只有查询权限,写操作需要根据 MCP 服务的配置决定

3.2.4 常用 MCP 服务推荐

除了 MySQL,还有许多实用的 MCP 服务可以提升开发效率:

MCP 服务 包名 用途 适用场景
MCP 服务 包名 用途 适用场景
--------- ------ ------ ---------
MySQL @benborla29/mcp-server-mysql 连接 MySQL 数据库 数据验证、表结构查询、SQL 调试
PostgreSQL @modelcontextprotocol/server-postgres 连接 PostgreSQL 数据库 同上(PostgreSQL 项目)
Redis @modelcontextprotocol/server-redis 连接 Redis 缓存数据查看、Key 排查
LSP 语言服务 mcp-language-server(Go 编写) 桥接 LSP 语言服务器 跳转定义、查找引用、代码诊断、重命名
LSP 多语言 lsp-mcp(jonrad/lsp-mcp) 多语言 LSP 代理 让 AI 获取语言级上下文(类型、符号、补全)
Filesystem @modelcontextprotocol/server-filesystem 扩展文件访问范围 需要访问项目目录外的文件时
Fetch @modelcontextprotocol/server-fetch HTTP 请求 调用外部 API、测试接口
GitHub @modelcontextprotocol/server-github GitHub API PR 管理、Issue 查看

LSP MCP 重点说明

LSP(Language Server Protocol)是编辑器实现代码智能提示的协议。通过 LSP MCP,AI 可以获得与 IDE 相同的代码语义理解能力:

能力 说明 实际效果
Go to Definition 跳转到符号定义 AI 能精确找到某个方法的实现位置,而非靠文本搜索猜测
Find References 查找所有引用 AI 能知道一个方法被哪些地方调用,重构时不会遗漏
Diagnostics 编译诊断 AI 能实时获取编译错误和警告,不用等 dotnet build
Hover Info 悬浮类型信息 AI 能查看变量的精确类型,减少类型推断错误
Rename 语义重命名 AI 重命名变量/方法时能准确修改所有引用点

LSP MCP 配置示例(以 mcp-language-server + C# 的 OmniSharp 为例):

{
  "mcpServers": {
    "csharp-lsp": {
      "type": "stdio",
      "command": "mcp-language-server",
      "args": [
        "--workspace", "E:/公司/GoodsService",
        "--lsp", "OmniSharp",
        "--lsp-args", "-lsp"
      ]
    }
  }
}

注意:LSP MCP 目前仍在快速发展中,各项目成熟度不同。推荐先在本地试用验证效果后再推广到团队。

相关项目地址:

添加新 MCP 服务的步骤

  1. 编辑项目根目录的 .mcp.json
  2. mcpServers 中新增一个服务配置
  3. 重启 Claude Code(或执行 /mcp 刷新)
  4. 验证服务状态是否正常

添加示例(增加 Redis 服务):

{
  "mcpServers": {
    "mysql-goods-service": {
      "...": "已有配置保持不变"
    },
    "redis-dev": {
      "type": "stdio",
      "command": "npx",
      "args": ["-y", "@modelcontextprotocol/server-redis"],
      "env": {
        "REDIS_URL": "redis://192.168.85.73:6379"
      }
    }
  }
}

方式二:通过 Claude Code 对话用提示词添加

直接用自然语言告诉 AI 你要添加什么 MCP 服务,AI 会自动编辑 .mcp.json 文件:

请帮我在 .mcp.json 中新增一个 Redis MCP 服务,地址是 192.168.85.73:6379

更多提示词示例

# 添加 MySQL MCP
帮我配置一个 MySQL 的 MCP 服务,连接信息如下:
- 主机:192.168.85.73
- 端口:3310
- 用户名:os_user
- 密码:xxx
- 数据库:stt9900010001

# 添加 Fetch MCP(用于调用外部 API)
帮我添加一个 Fetch MCP 服务,我需要让 AI 能发送 HTTP 请求测试接口

# 添加 Filesystem MCP(扩展文件访问范围)
帮我配置一个 Filesystem MCP,允许访问 D:/共享文档 目录

# 一次添加多个
帮我在 .mcp.json 中同时添加 Redis 和 Fetch 两个 MCP 服务,
Redis 地址 192.168.85.73:6379

方式三:通过 /mcp 命令管理

在 Claude Code 对话中执行 /mcp 命令,可以交互式查看和管理所有 MCP 服务的状态:

/mcp          # 查看所有 MCP 服务的连接状态

如果发现某个 MCP 服务状态异常,可以直接告诉 AI:

mysql-goods-service 连接失败了,帮我检查一下配置是否正确

3.3 自定义 Skill(技能)

3.3.1 Skill 的概念与用途

Skill(技能)是 Claude Code 的角色预设机制。通过一个 Markdown 文件定义 AI 的专业角色、能力边界、工作流程和输出标准,让 AI 在执行特定任务时像一个"专家"一样工作。

通俗理解:如果 CLAUDE.md 是给 AI 的"公司员工手册",那 Skill 就是给 AI 的"岗位说明书"——告诉它"你现在是产品经理/架构师/测试员,按这个标准干活"。

Skill 解决的问题

没有 Skill 有 Skill
每次需要写 PRD 时都要重复描述格式要求 一句 /erp-product-manager 自动切换为产品经理角色
AI 不知道项目已有哪些业务模块 Skill 内置了 17 个已有模块清单,AI 自动避免重复设计
AI 输出的文档格式不统一 Skill 定义了标准模板,每次输出格式一致
不同人使用 AI 的效果差异大 团队共享同一套 Skill,输出质量稳定

3.3.2 Skill 文件结构与创建方法

Skill 存放在项目的 .claude/skills/ 目录下,每个 Skill 一个文件夹,包含一个 SKILL.md 文件:

.claude/
└── skills/
    ├── erp-product-manager/
    │   └── SKILL.md
    ├── technical-architect/
    │   └── SKILL.md
    └── dev-pipeline-orchestrator/
        └── SKILL.md

SKILL.md 文件结构

---
name: skill-name                    # Skill 名称(英文,用 - 分隔)
description: 一句话描述用途           # 描述,会显示在 Skill 列表中
allowed-tools: Read, Glob, Grep     # 该 Skill 允许使用的工具
---

# Skill 标题

## 角色定义
[AI 扮演什么角色、具备什么能力]

## 工作流程
[按什么步骤执行任务]

## 输出标准
[输出物的格式模板]

## 禁止事项
[不允许做的事情]

创建新 Skill 的步骤

  1. .claude/skills/ 下新建文件夹(文件夹名即 Skill 名称)
  2. 在文件夹中创建 SKILL.md 文件
  3. 按上述结构编写内容
  4. 保存后立即生效,无需重启 Claude Code

也可以直接让 AI 帮你创建:

请帮我创建一个名为 code-reviewer 的 Skill,
角色是高级代码审查员,专注于审查 C# 代码的安全性和性能。

allowed-tools 常用配置

工具组合 适用场景 示例
Read, Glob, Grep 只读分析类(不修改代码) 产品经理、架构师
Read, Write, Edit, Glob, Grep, Bash 需要写代码和执行命令 代码生成器、开发者
Read, Write, Edit, Glob, Grep, Bash, Task 需要调度子代理 流水线编排器

3.3.3 本项目已有 Skill 介绍

本项目配置了 5 个 Skill,覆盖了从需求分析到代码交付、以及原型评审的完整链路:

产品需求 ──→ 产品经理(Skill1) ──→ PRD文档
                                      │
                         ┌────────────┼────────────┐
                         ▼            ▼            ▼
                   原型设计师      技术架构师     (团队评审)
                   (Skill5)      (Skill2)
                      │              │
                      ▼              ▼
                 HTML原型页面    技术分析文档
                 (浏览器预览)         │
                                      ▼
                                开发任务拆解
                                  (Skill3)
                                      │
                                      ▼
                                开发任务清单
                                      │
                                      ▼
                              开发流水线(Skill4)
                                      │
                                      ▼
                              代码 + 测试 + 质量报告

Skill 1:erp-product-manager(ERP 产品经理)

项目 内容
角色 拥有 15 年经验的 ERP 产品经理
输入 业务需求描述
输出 PRD 文档(含 Mermaid 流程图、时序图、状态图、数据流图)
核心能力 需求分析、业务流程设计、状态流转设计、业务规则梳理
内置知识 系统已有 17 个业务模块清单、已有产品文档索引、审批集成规范、状态码体系
调用方式 在对话中输入 /erp-product-manager

使用示例:

/erp-product-manager

请帮我设计一个商品盘点功能的 PRD,
需求:仓库管理员定期对仓库商品进行实物盘点,
系统记录盘盈盘亏并自动调整库存。

Skill 2:technical-architect(技术架构师)

项目 内容
角色 拥有 13 年经验的系统架构师
输入 产品经理产出的 PRD 文档
输出 技术分析文档(含技术流程图、时序图、数据流图,标注分层)
核心能力 PRD 技术转化、分层分析、复用评估、技术风险识别
内置知识 项目分层架构、17 个模块的 BLL/DAL 清单、4 种可复用技术模式
调用方式 在对话中输入 /technical-architect

使用示例:

/technical-architect

请根据 doc/产品文档/商品盘点/商品盘点功能PRD.md
生成技术分析文档。

Skill 3:dev-pipeline-orchestrator(开发流水线编排器)

项目 内容
角色 开发流水线编排器,协调 3 个子 Agent
输入 技术拆解文档
输出 完整的业务代码 + 测试报告 + 代码质量审查报告
工作流程 Agent1 生成代码 → Agent2 测试验证(≥95 分) → Agent3 质量审查(0 中高级问题)
核心特性 自动迭代修复、零 TODO 策略、MCP 数据库验证
调用方式 在对话中输入 /dev-pipeline-orchestrator

使用示例:

/dev-pipeline-orchestrator

请根据 doc/开发文档/商品盘点/商品盘点开发任务拆解.md
执行完整开发流水线。

Skill 4:prototype-ui-designer(前端原型设计师)

项目 内容
角色 拥有 10 年管理后台 UI 经验的前端原型设计师
输入 产品经理产出的 PRD 文档
输出 纯 HTML + CSS 静态原型页面(单文件,浏览器直接打开)
核心能力 PRD 页面提取、Ant Design Pro 风格还原、高信息密度布局
核心特性 10 条"AI 味"禁止清单、完整配色/字号/组件规范、自动自检机制
调用方式 在对话中输入 /prototype-ui-designer

使用示例:

/prototype-ui-designer

请根据 doc/产品文档/商品调价单/商品调价单功能说明书.md
生成 HTML 静态原型页面,包含列表页、新建页、审批页、历史查询页。
保存到 doc/prototype/price-adjustment.html

特别说明:这个 Skill 内置了严格的"去 AI 味"规范——禁止紫色、禁止渐变、禁止低信息密度。生成的页面参考 Ant Design Pro 管理后台风格,确保原型可直接用于正式团队评审,不会一眼看出是 AI 生成的。

3.3.4 Skill 编写技巧与最佳实践

1. 角色定义要具体

# 不好的定义
你是一个程序员。

# 好的定义
作为拥有 13 年企业级系统架构经验的资深技术架构师,
精通 .NET 分层架构、MySQL 数据库设计和 Dapper ORM,
负责将 PRD 文档转化为技术分析文档。

2. 内置项目上下文

把项目的关键信息写入 Skill,让 AI 不需要每次重新探索:

## 已实现业务模块
| 模块 | 核心 BLL | 核心 DAL |
|------|---------|---------|
| 商品基础信息 | GoodsBaseInfoBLL | GoodsBaseInfoDAL |
| 采购单 | PurchaseOrderBLL | PurchaseOrderDAL |
| ...  | ... | ... |

3. 定义明确的输出模板

给 AI 一个标准模板,它的输出格式就会高度一致:

## 文档模板
# [模块名称] 技术分析文档

## 1. PRD 需求概要
## 2. 技术分层分析
## 3. 核心流程技术分析
...

4. 设定禁止事项(红线规则)

明确告诉 AI 哪些事情不能做,防止越界:

## 禁止事项
- **不设计数据库表结构**:只描述业务实体
- **不编写代码**:只提供技术分析
- **不违反系统规范约束**

5. 团队维护建议

  • Skill 文件应提交到 Git,团队共享
  • 业务模块新增后及时更新 Skill 中的模块清单
  • 定期 Review Skill 内容,确保与项目现状一致
  • 每个 Skill 保持单一职责,不要一个 Skill 覆盖太多角色

3.4 Hooks 配置

3.4.1 Hook 的概念

Hooks(钩子)是 Claude Code 的自动化工作流机制,允许你在 AI 操作的特定时机自动执行 shell 命令或 LLM 提示。

通俗理解:如果 CLAUDE.md 是给 AI 的"规章制度"(靠 AI 自觉遵守),那 Hooks 就是"门禁系统"——在关键操作节点自动拦截检查,不符合条件就直接阻止。

Hooks 能做什么

  • 在 AI 执行命令前自动检查是否安全(如阻止 rm -rf
  • 在 AI 编辑文件后自动执行代码格式化
  • 在 AI 完成任务后自动运行测试
  • 在会话开始时自动加载额外上下文信息

3.4.2 Hook 事件类型

Claude Code 在生命周期的不同阶段提供了以下事件:

事件 触发时机 可阻止操作 典型用途
SessionStart 会话开始或恢复时 加载环境变量、初始化上下文
UserPromptSubmit 用户提交提示词后,AI 处理前 输入校验、敏感信息过滤
PreToolUse 工具调用执行前 阻止危险命令、权限控制
PostToolUse 工具调用成功后 代码格式化、自动测试
PostToolUseFailure 工具调用失败后 错误日志记录
Stop AI 完成响应时 检查任务是否完整
Notification 发送通知时 自定义通知渠道
SubagentStart 子代理启动时 子代理监控
SubagentStop 子代理完成时 子代理产出校验
PreCompact 上下文压缩前 保留关键信息
SessionEnd 会话终止时 清理资源、记录日志

其中 PreToolUse 是最常用的事件——在 AI 调用任何工具(读文件、写代码、执行命令等)之前都会触发,你可以在这里做安全拦截。

3.4.3 配置结构详解

Hooks 在 .claude/settings.json(或 settings.local.json)中配置:

{
  "hooks": {
    "事件名称": [
      {
        "matcher": "匹配模式(正则表达式,可选)",
        "hooks": [
          {
            "type": "command",
            "command": "要执行的脚本或命令",
            "timeout": 600,
            "async": false,
            "statusMessage": "执行中显示的提示文字"
          }
        ]
      }
    ]
  }
}

字段说明

字段 类型 必填 说明
matcher string 正则表达式,匹配工具名称(如 "Bash" 匹配 Bash 工具)
type string Hook 类型:command(执行命令)、prompt(LLM 提示)、agent(启动代理)
command string command 类型必填 要执行的 shell 命令或脚本路径
prompt string prompt 类型必填 发送给 LLM 的提示词
timeout number 超时时间(秒),command 默认 600,prompt 默认 30
async boolean 是否异步执行(不阻塞 AI 继续工作)
once boolean 是否每个会话只执行一次
statusMessage string 运行时显示的自定义状态消息

Hook 脚本可使用的环境变量

变量 说明
$CLAUDE_PROJECT_DIR 项目根目录路径
$CLAUDE_ENV_FILE 环境变量持久化文件路径(SessionStart 中使用)

Hook 脚本通过 stdin 接收 JSON 格式的上下文信息(包含 session_idtool_nametool_input 等字段),可以用 jq 解析。

Hook 脚本的返回值控制

返回方式 含义
exit 0 成功,允许继续
exit 2 阻塞操作,stderr 内容作为错误消息返回给 AI
JSON 输出 permissionDecision: "deny" 拒绝工具调用(更精细的控制)
JSON 输出 permissionDecision: "allow" 自动允许工具调用

3.4.4 常见使用场景与配置示例

场景 1:阻止危险的 Bash 命令

防止 AI 执行 rm -rfgit push --force 等破坏性命令:

配置(.claude/settings.local.json):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-dangerous-commands.sh"
          }
        ]
      }
    ]
  }
}

脚本(.claude/hooks/block-dangerous-commands.sh):

#!/bin/bash
COMMAND=$(cat | jq -r '.tool_input.command')

# 检查危险命令
if echo "$COMMAND" | grep -qE 'rm -rf|git push --force|git reset --hard'; then
  echo "危险命令被拦截: $COMMAND" >&2
  exit 2
fi

exit 0

场景 2:编辑文件后自动格式化

AI 每次编辑 C# 文件后自动执行 dotnet format

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "Write|Edit",
        "hooks": [
          {
            "type": "command",
            "command": "dotnet format --include \"$CLAUDE_PROJECT_DIR\"",
            "async": true,
            "timeout": 30,
            "statusMessage": "正在格式化代码..."
          }
        ]
      }
    ]
  }
}

场景 3:禁止 AI 自动提交代码

在 PreToolUse 中拦截所有 git commit 和 git push 操作(呼应我们团队的 Git 规范):

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Bash",
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/block-git-commit.sh"
          }
        ]
      }
    ]
  }
}

脚本(.claude/hooks/block-git-commit.sh):

#!/bin/bash
COMMAND=$(cat | jq -r '.tool_input.command')

if echo "$COMMAND" | grep -qE 'git (commit|push)'; then
  echo "Git 提交/推送操作已被 Hook 拦截,请手动执行或明确指示后再操作" >&2
  exit 2
fi

exit 0

场景 4:会话开始时自动加载项目状态

{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "\"$CLAUDE_PROJECT_DIR\"/.claude/hooks/load-project-status.sh",
            "once": true,
            "statusMessage": "正在加载项目状态..."
          }
        ]
      }
    ]
  }
}

场景 5:AI 完成任务时自动检查是否遗漏

使用 prompt 类型的 Hook,让 LLM 自动审查任务完成度:

{
  "hooks": {
    "Stop": [
      {
        "hooks": [
          {
            "type": "prompt",
            "prompt": "检查对话中的任务是否全部完成,是否有遗漏的步骤。如果全部完成返回 {\"ok\": true},否则返回 {\"ok\": false, \"reason\": \"遗漏说明\"}",
            "timeout": 30
          }
        ]
      }
    ]
  }
}

3.4.5 Hook 管理与调试

查看和管理 Hooks

  • 在 Claude Code 中执行 /hooks 命令,可以交互式查看、添加、删除 Hooks
  • Hooks 来源标记:[User](用户级)、[Project](项目级)、[Local](本地级)

调试 Hooks

  • 使用 claude --debug 启动,可以看到 Hook 的详细执行日志
  • 使用 Ctrl+O 切换 verbose 模式查看 Hook 输出

临时禁用所有 Hooks

{
  "disableAllHooks": true
}

安全注意事项

  • Hook 脚本以你的用户权限执行,拥有完整的系统访问权限
  • 脚本中 shell 变量务必用引号包裹("$VAR" 而非 $VAR
  • 不要在 Hook 中硬编码敏感信息(密码、Token 等)
  • Hook 脚本应提交到 Git(.claude/hooks/ 目录),但 settings.local.json 不提交

3.5 Sub-Agent(子代理)机制

3.5.1 什么是 Sub-Agent

Sub-Agent(子代理)是 Claude Code 将复杂任务拆分给专业"助手"执行的机制。主对话中的 AI 是"主管",Sub-Agent 是"下属"——主管把子任务分派给不同类型的下属,每个下属专注完成自己的工作后汇报结果。

为什么需要 Sub-Agent

问题 Sub-Agent 的解决方式
搜索代码时消耗大量上下文 Token 派 Explore 子代理去搜索,只返回精简结果,节省主对话上下文
复杂任务执行到一半上下文爆了 子代理有独立的上下文窗口,互不干扰
多个独立任务需要串行等待 多个子代理可以并行执行,效率翻倍
不同任务需要不同的模型能力 子代理可指定不同模型(简单任务用 haiku 省钱,复杂任务用 opus 保质量)

工作流程

用户提问 → 主 AI 分析任务
                │
                ├── 派出 Explore 子代理搜索代码 ──→ 返回搜索结果
                ├── 派出 Bash 子代理执行命令   ──→ 返回执行结果
                └── 派出 Plan 子代理设计方案   ──→ 返回方案文档
                │
          主 AI 汇总所有结果 → 回复用户

3.5.2 子代理类型详解

Claude Code 提供以下几种专用子代理类型:

1. Explore(探索代理)

项目 内容
擅长 快速搜索代码库、查找文件、理解代码结构
可用工具 Glob、Grep、Read、WebSearch、WebFetch 等(不能编辑文件)
典型场景 "这个功能在哪里实现的?"、"项目里哪些地方用到了 XXX?"
推荐模型 haiku(搜索任务简单,用轻量模型省 Token)

实际效果示例:

你:"帮我找一下项目中所有处理库存扣减的代码"

主 AI 内部操作:
  → 派出 Explore 子代理
  → 子代理执行 Grep 搜索 "库存扣减"、"SalesDeduction"、"inventory" 等关键词
  → 子代理阅读相关文件,整理出关键代码位置
  → 返回精简结果给主 AI

主 AI 回复:"库存扣减逻辑主要在以下位置:
  - OSBLL/SalesDeductionBLL.cs:45 - 批次扣减入口
  - OSDAL/InventoryBatchDAL.cs:120 - FIFO 扣减实现
  ..."

2. Plan(规划代理)

项目 内容
擅长 分析需求、设计实现方案、评估技术方案
可用工具 Glob、Grep、Read 等(不能编辑文件,只做分析)
典型场景 "帮我设计一下这个功能的实现方案"、"重构这个模块应该怎么做"
推荐模型 sonnet 或 opus(方案设计需要较强的推理能力)

3. Bash(命令执行代理)

项目 内容
擅长 执行终端命令、运行脚本、处理 git 操作
可用工具 仅 Bash 命令执行
典型场景 "运行一下测试"、"检查编译是否通过"
推荐模型 haiku(命令执行任务简单)

4. general-purpose(通用代理)

项目 内容
擅长 复杂多步骤任务,需要使用所有工具
可用工具 全部工具(Read、Write、Edit、Bash、Glob、Grep 等)
典型场景 代码生成、文件修改、复杂调查任务
推荐模型 sonnet(通用任务平衡质量与成本)或 opus(高质量要求)

3.5.3 子代理的触发方式

自动触发(AI 自主决策)

大多数情况下你不需要手动指定子代理。当你的提问涉及代码搜索、方案设计等场景时,AI 会自动判断是否需要派出子代理:

你:"项目中哪些地方用到了 OperationLogHelper?"
→ AI 自动派出 Explore 子代理搜索(你不需要做任何额外操作)

提示词引导

如果 AI 没有自动使用子代理,或者你想控制执行方式,可以在提示词中引导:

# 引导并行搜索
请同时搜索以下内容(并行执行):
1. 项目中所有 Controller 的路由定义
2. 项目中所有 DAL 的数据库连接方式
3. 项目中所有使用 RabbitMQ 的地方

# 引导使用 Plan 代理
请先分析一下实现方案(不要直接写代码),
评估几种不同的技术方案的优缺点。

# 引导后台执行
请在后台运行所有测试,我继续跟你讨论其他问题。

3.5.4 并行执行

子代理的一个核心优势是并行执行。当多个任务之间没有依赖关系时,AI 可以同时派出多个子代理:

串行 vs 并行对比

串行执行(慢):
  搜索文件A ──完成──→ 搜索文件B ──完成──→ 搜索文件C ──完成──→ 汇总结果

并行执行(快):
  搜索文件A ──┐
  搜索文件B ──┼──全部完成──→ 汇总结果
  搜索文件C ──┘

触发并行的提示词技巧

# 明确说"同时"或"并行"
请同时帮我做以下三件事:
1. 搜索所有入库相关的 BLL 代码
2. 搜索所有出库相关的 DAL 代码
3. 查看库存表的表结构

# 列出多个独立任务
帮我分别查一下:
- GoodsBaseInfoDAL 有多少行代码
- PurchaseOrderBLL 有哪些公开方法
- InboundOrderDAL 的 SQL 查询有没有 N+1 问题

3.5.5 子代理的模型选择策略

不同类型的子任务应选择不同的模型,平衡质量与成本:

任务类型 推荐模型 原因
文件搜索、关键词查找 haiku 简单任务,轻量模型即可,速度快、成本低
代码阅读理解 sonnet 需要一定理解力,但不需要深度推理
方案设计、架构分析 sonnet / opus 需要较强的推理和综合分析能力
代码生成(业务逻辑) sonnet 多数代码生成 sonnet 足够胜任
代码质量审查 opus 需要深度分析,发现潜在问题
命令执行 haiku 只是运行命令,不需要强推理

成本意识:opus 的 Token 价格远高于 haiku。简单的搜索任务用 opus 是浪费,复杂的架构分析用 haiku 可能质量不够。AI 通常会自动选择合适的模型,但你也可以在提示词中指定:

请用深度分析模式帮我审查这段代码的安全性(引导使用 opus)
请快速搜索一下项目中用到 Redis 的地方(引导使用 haiku)

3.5.6 子代理在本项目中的实际应用

应用 1:Skill 内部使用子代理

dev-pipeline-orchestrator Skill 就是通过子代理协调 3 个专业 Agent 工作的:

/dev-pipeline-orchestrator
│
├── Agent1(general-purpose, sonnet)── 代码生成
├── Agent2(general-purpose, sonnet)── 测试验证
└── Agent3(general-purpose, opus)  ── 质量审查

应用 2:日常开发中的搜索分析

你:"帮我梳理一下采购单从创建到入库的完整数据流转路径"

AI 内部:
  → Explore 子代理 1:搜索 PurchaseOrderBLL/DAL 的代码
  → Explore 子代理 2:搜索 InboundOrderBLL/DAL 的代码
  → Explore 子代理 3:搜索 CallbackBLL 中的审批回调处理
  → 主 AI 汇总三个子代理的结果,绘制完整数据流转路径

应用 3:批量代码分析

你:"帮我检查项目中所有 DAL 文件是否存在 SQL 注入风险"

AI 内部:
  → Explore 子代理:找到所有 *DAL.cs 文件
  → 多个 general-purpose 子代理并行审查每个文件
  → 主 AI 汇总审查结果,列出风险清单

3.5.7 Sub-Agent 与 Skill 的区别

新人经常混淆这两个概念。简单说:Skill 是"剧本",Sub-Agent 是"演员"。Skill 定义了角色应该怎么演,Sub-Agent 是实际上台表演的人。

本质区别

对比维度 Skill(技能) Sub-Agent(子代理)
是什么 一份 Markdown 文件(角色剧本) 一个运行中的 AI 进程(执行者)
存在形式 静态文件:.claude/skills/xxx/SKILL.md 动态进程:AI 运行时创建、执行完销毁
定义的内容 角色身份、专业知识、输出模板、禁止事项 无预定义内容,靠调用时的 prompt 指示
触发方式 用户主动调用 /skill-name AI 自动派出,或用户提示词引导
谁在使用它 主 AI 加载 Skill 后自己执行 主 AI 派出独立的子 AI 去执行
上下文 共享主对话的上下文 拥有独立的上下文窗口
适合的任务 需要深度专业角色、复杂模板、长期复用的任务 搜索、执行命令、并行处理等子任务

为什么有了 Sub-Agent 还需要 Skill?

原因 1:Sub-Agent 没有"记忆",Skill 有"知识库"

Sub-Agent 每次被派出时都是一张白纸,你需要在调用 prompt 中告诉它所有信息。而 Skill 是预先写好的知识库,包含了项目架构、业务模块清单、文档模板、审批规范等海量上下文——这些内容不可能每次都手写到 prompt 里。

没有 Skill 的情况:
  你:"帮我写一个商品盘点的 PRD"
  AI 派出 Sub-Agent → Sub-Agent 不知道项目有 17 个已有模块、
    不知道状态码规范、不知道审批集成模式、不知道 PRD 模板...
  → 输出质量不可控

有 Skill 的情况:
  你:"/erp-product-manager 帮我写一个商品盘点的 PRD"
  AI 加载 Skill → 自动获得 17 个模块清单、状态码体系、
    审批流程规范、标准 PRD 模板、Mermaid 图表规范...
  → 输出质量稳定、格式统一

原因 2:Sub-Agent 是"临时工",Skill 是"专职岗位"

Sub-Agent 适合一次性的子任务(搜索一下、跑个命令),任务完成后就消失了。Skill 定义的是一个持久的专业角色,可以被团队反复调用,每次都保持一致的专业水准。

Sub-Agent(临时工):
  "去搜一下项目里有哪些 Controller" → 搜完就结束

Skill(专职岗位):
  "/erp-product-manager" → 进入产品经理角色,
  持续在当前对话中以产品经理身份工作,
  遵循 PRD 模板、业务规则、审批规范...

原因 3:两者经常配合使用

Skill 和 Sub-Agent 不是替代关系,而是协作关系。我们的 dev-pipeline-orchestrator Skill 就是最好的例子:

/dev-pipeline-orchestrator (Skill 提供角色定义和流程规范)
│
│  Skill 定义了:
│  - 流水线三阶段流程
│  - 质量门禁标准(测试≥95分、0 中高级问题)
│  - 各 Agent 的调用模板和上下文传递规则
│  - 零 TODO 策略
│
│  Sub-Agent 负责执行:
├── Agent1(Sub-Agent)── 按 Skill 定义的规范生成代码
├── Agent2(Sub-Agent)── 按 Skill 定义的标准测试验证
└── Agent3(Sub-Agent)── 按 Skill 定义的标准审查质量

总结:什么时候用什么

场景 用 Skill 用 Sub-Agent 两者配合
写 PRD 文档 /erp-product-manager - -
搜索代码 - Explore 子代理 -
执行完整开发流水线 - - /dev-pipeline-orchestrator Skill + 3 个 Sub-Agent
技术方案分析 /technical-architect - -
并行搜索多个文件 - 多个 Explore 并行 -
代码审查(临时) - general-purpose 子代理 -
代码审查(团队标准) 自定义 code-reviewer Skill - -

系列文章导航

posted @ 2026-02-10 00:01  寒月萧风  阅读(967)  评论(0)    收藏  举报