背 景
最近用 Claude Code 写了不少项目,发现很多人( 包括早期的我 )都搞不清楚:CLAUDE.md、Skills、MCP、Hooks 这几个东西到底是什么关系?什么时候用哪个?怎么把它们组合起来让 Agent 真正高效地工作?
这篇文章用最通俗的方式讲清楚它们的区别、使用场景,以及如何用它们编排一个完整的 Agent 工作流。
先说结论:四件套各司其职
想象你招了一个超级聪明的新员工。他学什么都快,但刚入职,对你的公司一无所知。
你需要给他四样东西:
员工手册( CLAUDE.md )— 告诉他公司做什么、团队规范、项目结构
标准操作流程 SOP( Skills )— 遇到特定任务该怎么一步步执行
工具箱接口( MCP )— 让他能操作外部工具,比如数据库、Slack、API
自动化脚本( Hooks )— 在特定事件自动执行固定流程
四者的定位完全不同:
| CLAUDE.md | Skills | MCP | Hooks | |
|---|---|---|---|---|
| 类比 | 员工手册 | SOP 流程 | 工具箱接口 | 流水线钩子 |
| 解决什么问题 | ” 这是什么项目 “ | ” 遇到 X 怎么做 “ | ” 能用什么工具 “ | ” 自动执行任务 “ |
| 表现形式 | Markdown 文件 | Markdown 文件 | Server 服务 | Shell 脚本 |
| 加载方式 | 自动加载 | 按需触发 | 按需连接 | 事件触发 |
| 执行方式 | LLM推理 | LLM推理 | LLM推理 | 确定性脚本 |
| 本质 | 静态上下文 | 可复用的流程 | 可执行的能力 | 自动化钩子 |
核心区别:
- CLAUDE.md + Skills = 知识层(告诉 Agent 怎么思考)
- MCP + Hooks = 能力层(让 Agent 能动手)
下面逐个展开。
一、CLAUDE.md:项目的自我介绍
1.1 它是什么
CLAUDE.md 是放在项目中的一个 Markdown 文件。Agent 启动时会自动读取它,作为理解你项目的 ” 背景知识 “。
你可以把它理解成新员工入职第一天拿到的那本手册 —— 公司做什么、团队用什么技术栈、代码怎么组织、有哪些潜规则。
关键特点:
- 自动加载,每次对话都生效
- 占用上下文窗口,所以要精简
- 适合放 ” 始终需要知道 ” 的信息
1.2 怎么写:WHY、WHAT、HOW 框架
一个好的 CLAUDE.md 应该回答三个问题:
- WHY( 为什么 )— 这个项目是做什么的?解决什么问题?
- WHAT( 是什么 )— 技术栈、目录结构、关键模块
- HOW( 怎么做 )— 用什么工具、怎么跑测试、怎么验证改动
# CLAUDE.md
## 项目概览( WHY )
这是一个面向 B2C 的电商项目,支持多语言、多币种。
## 技术栈与目录结构( WHAT )
Next.js + TypeScript + Tailwind CSS
src/
├── app/ # Next.js App Router 页面
├── components/ # 共享组件
├── lib/ # 工具函数
└── services/ # API 调用层
## 开发规范( HOW )
- 使用 pnpm 作为包管理器( 不要用 npm )
- 提交前运行 pnpm lint && pnpm test
- 不要修改 .env 文件
- API Key 绝对不能提交到代码里
1.3 关键原则:少即是多
这一点非常重要,很多人写 CLAUDE.md 会踩坑 —— 写太多了。
为什么?因为 CLAUDE.md 是每次对话都会自动加载的,它会占用宝贵的上下文窗口。研究表明,前沿 LLM 大约能稳定遵循 150-200 条指令,而 Claude Code 的系统提示已经占了约 50 条。留给你的空间其实不多。
几个实操建议:
- 控制在 300-500 行以内,越短越好。HumanLayer 团队的根目录 CLAUDE.md 只有不到 60 行
- 只放全局通用的信息。如果一条指令只在特定任务中有用( 比如 ” 如何设计数据库 schema ” ),就不要放在 CLAUDE.md 里,而应该放到 Skills 中按需加载
- 不要把代码风格写进 CLAUDE.md。格式化交给 ESLint、Prettier、Biome 这些工具,别让 Agent 浪费 token 在缩进和分号上
- 指向而非复制。引用具体文件路径( 如
src/lib/auth.ts:42)比直接粘贴代码片段更好,因为代码会变,CLAUDE.md 里的副本很快就过时了 - 不要把工作流写进 CLAUDE.md。” 怎么做代码审查 “、” 怎么部署 ” 这类流程应该用 Skills,不是 CLAUDE.md
1.4 渐进式信息披露
既然 CLAUDE.md 要保持精简,那详细的文档放哪?答案是单独的文档目录 + 在 CLAUDE.md 中列出索引:
# CLAUDE.md
## 详细文档
在开始任务前,根据需要阅读以下文档:
- `docs/api-guide.md` — API 规范和最佳实践
- `docs/testing.md` — 测试策略和命令
- `docs/deployment.md` — 部署流程说明
- `docs/architecture.md` — 服务架构设计
这样 CLAUDE.md 保持轻量,Agent 只在需要时才去读取具体文档。这个思路跟 Skills 的渐进式加载不谋而合。
1.5 层级机制:三层生效
CLAUDE.md 支持三个层级,从大到小依次覆盖:
比如你可以在全局配置里写 ” 我偏好 TypeScript “,在项目级写 ” 用 pnpm 不要用 npm “,在 src/components/ 下写 ” 组件必须导出 Props 类型 “。
~/.claude/CLAUDE.md ← 全局:所有项目通用的偏好
项目根目录/CLAUDE.md ← 项目级:团队共享的规范(会提交到 Git)
项目子目录/CLAUDE.md ← 模块级:特定目录的规则
加载规则:
- 所有层级的 CLAUDE.md 都会被加载到上下文中
- 当指令冲突时,Claude 会判断使用更具体的指令
- 更靠近工作目录的 CLAUDE.md 优先级更高
1.6 常见误区
❌ 误区1:把工作流写在 CLAUDE.md 正确做法:工作流用 Skills,CLAUDE.md 只放背景知识
❌ 误区2:把API文档全粘进来正确做法:放到单独文档,CLAUDE.md 只放索引
❌ 误区3:CLAUDE.md 写了 1000 行正确做法:精简到 500 行以内,详细内容放单独文档
❌ 误区4:把代码风格规则写进 CLAUDE.md 正确做法:交给 ESLint/Prettier/Biome,别浪费 token
1.7 核心定位
CLAUDE.md 是静态上下文。它解决的是 ” Agent 理解你的项目 ” 这个问题。
它不会教 Agent 怎么做事,只告诉它这是什么。