进阶武器库
五件套 + Agent SDK。前两章讲的是「怎么和 Claude Code 对话」;这一章讲的是「怎么让它越用越懂你」。学完你会从「能用」跨到「会架构它」。
先把五件套摆一起看
到第二章为止,你已经会用 Claude Code 完成单次任务了。但每开一次新会话,它都是「刚上班的新人」——不知道你项目的规矩、不知道你喜欢的风格、不知道上次做到哪里。
进阶的五件套就是用来解决「怎么让它越用越顺手」这件事的。每一件都在回答一个不同的问题:
| 名字 | 回答的问题 | 比喻 | 生效时机 |
|---|---|---|---|
| CLAUDE.md | 我的项目有什么规矩? | 员工手册 | 每次会话启动 |
| Skills | 有什么「招式」可以按需调用? | 武功秘籍 | 被 /xxx 或自然语言触发时 |
| Hooks | 某些时刻自动发生什么? | 红外感应器 | 事件触发(如 PreToolUse) |
| Subagents | 能不能派几个人同时干活? | 分身 | 主 Claude 自己决定派出去时 |
| MCP | 怎么连外部服务(GitHub、Slack)? | 对外接线板 | 服务器启动时连上,之后常驻 |
加上 Agent SDK(第 3.7 节),你就能把 Claude 作为一个库嵌进自己的 Python / TypeScript 程序里——彻底摆脱「必须有个终端坐在前面」的限制。下面一个一个拆开讲。
CLAUDE.md — 员工手册
CLAUDE.md 是一个普通的 Markdown 文件,放在项目的根目录。每次 Claude Code 在这个项目里启动,它都会自动读这个文件,把内容作为「永久指令」加进上下文。每一轮对话它都带着这份手册。
你在里面写什么?写那些每次都要告诉它、但每次都懒得重复的东西。
# 我的项目
包管理器用 pnpm,不要用 npm/yarn。
测试用 vitest,测试文件和源文件放一起,命名 *.test.ts。
所有 API 响应用 zod 校验,不要用手写的类型守卫。
## 常用命令
- 启动:pnpm dev
- 测试:pnpm test
- 类型检查:pnpm tsc
- 构建:pnpm build
## 风格
- 使用 2 空格缩进
- 导出用 named export,不用 default export
- 错误信息写中文,代码注释写英文
## 不要做
- 不要加任何 any 类型
- 不要写 if/else 嵌套超过 3 层,拆函数
- 不要动 src/legacy/ 下的文件,那是遗产代码
- 不要 @ts-ignore 绕过类型错误,测试失败要修代码不要改测试
一键生成
不用从零写,打 /init,Claude 会自己扫项目、读 package.json、看目录结构,生成一份初版 CLAUDE.md。你再改几笔就行。
分层:CLAUDE.md 的四种放法
CLAUDE.md 可以放在多个地方,作用域不一样,层层叠加:
| 位置 | 作用域 | 会被 git 提交吗 |
|---|---|---|
~/.claude/CLAUDE.md | 你所有项目(个人偏好) | 不会 |
./CLAUDE.md | 当前项目(团队共享) | 会 |
./CLAUDE.local.md | 当前项目(只给你自己) | 不会(自动加到 .gitignore) |
./src/subdir/CLAUDE.md | 子目录 | 会,只在读这个目录下的文件时生效 |
这个分层设计很聪明:「所有 Go 项目都用 gofumpt 格式化」 放 ~/.claude/;「这个项目的 API 必须先过 zod」 放项目根;「我这台机器上 Python 解释器在 /opt/…」 放 .local.md。各司其职,不串味。
写好 CLAUDE.md 的几个经验
- 具体 > 抽象。「请写优雅的代码」没用;「所有 public 函数要有 JSDoc」有用。
- 可验证 > 不可验证。「缩进 2 空格」可以在 review 时直接检查;「代码可读性高」没法检查。
- 否定式 > 宽泛建议。「不要 @ts-ignore」比「注意类型安全」管用十倍。
- 短 > 长。超过 200 行开始稀释关键规则——会被淹没。关键的放前面。
- 常用命令必写。你的
pnpm test、cargo run --example foo、docker compose up db——Claude 不会猜,你一次写清楚,它每次都记得。
不要把 CLAUDE.md 写成小说
每一句都占你的上下文预算。写 300 行的背景介绍、商业逻辑考虑——不如抽成项目文档,CLAUDE.md 里只留「规则」和「命令」这两类硬货。
auto memory:CLAUDE.md 之外的另一层记忆
Claude Code 还维护一套自动记忆系统,存在 ~/.claude/projects/<proj-hash>/memory/。它会从你的历史交互中提炼三类信息:
- user:你是谁(「科大学生、主力写 Python」)
- feedback:你的偏好(「不要 mock 数据库,上次 mock 过出过事」)
- project:项目当前的状态(「这周在做 auth 重构」)
- reference:外部资源位置(「PR 讨论在 Linear 的 INGEST 项目」)
每条存成一个单独的 md 文件,配一份索引 MEMORY.md。/memory 命令打开这个目录的可视化面板。和 CLAUDE.md 的区别:CLAUDE.md 是你主动写的规则,auto memory 是 Claude 自己记的观察——你可以删、可以改,但不用每次亲自写。
Skills — 武功秘籍
CLAUDE.md 是「常驻背景」,每次都加载。但有些指令很复杂、又不是每次都用——比如「发布一个新版本」的完整流程,可能要跑七八步命令、检查十几个条件。把这些全塞进 CLAUDE.md,每次会话都占上下文,不划算。
Skill 就是为这种情况设计的:一段「按需召唤」的指令包。你想用的时候打 /skill-name,或者用自然语言描述需求触发它;不用的时候它就安静地待在文件系统里,不占空间。
一个最小 Skill
新建 ~/.claude/skills/summarize-changes/SKILL.md:
---
description: 总结我未提交的改动,并点出潜在风险
allowed-tools: Bash(git *) Read
---
## 当前未提交的改动
!`git diff HEAD`
## 任务
用 2-3 个要点总结上面的 diff,然后列出你注意到的任何风险:
- 缺少错误处理
- 有硬编码的值
- 测试需要更新但还没更新
- 有 console.log 或调试代码忘了删
如果 diff 是空的,就说"没有未提交的改动",然后停。
保存完,在 Claude Code 里输入 /summarize-changes,它就跑这个流程。注意文件顶部的 !`git diff HEAD`——那个反引号 + 感叹号不是装饰,是告诉 Claude Code「加载 Skill 之前,先把这条命令跑一遍,把结果注入进来」。动态内容就这么来的。
SKILL.md 的完整 frontmatter
Bash(git *) Read Grep。不写 = 继承会话权限。model: haiku 能省钱。main(默认,在当前会话跑)或 fork(开子会话跑,结果汇报回来——不污染主上下文)。参数和占位符
你可以让 skill 接参数:
---
description: 给一个分支名,把它 rebase 到 main 上
---
## 任务
把分支 $1 rebase 到 main。如果有冲突,逐个分析、给出解决建议,不要自作主张解决。
完整参数:$ARGUMENTS
使用时:/my-rebase feature-auth——$1 会被替换成 feature-auth,$ARGUMENTS 保存完整参数串。
Skill 和斜杠命令的关系
你在第二章里见到的 /review、/security-review、/simplify、/less-permission-prompts——它们都是 Anthropic 官方内置的 Skill。不神秘,你也能自己写。内置 skill 只是目录在 Claude Code 自己的安装路径下。
Skill 几个实战模板
把这些当样板改,很快能凑出一套自己的 Skill 库:
- commit:读
git diff --staged,生成一条符合团队约定(Conventional Commits 之类)的提交信息。 - deploy:按发布清单逐项检查——版本号、changelog、测试、文档,缺哪项就补哪项。
- hotfix:专门的紧急修复流程——切 hotfix 分支、最小改动、加回归测试、禁止碰其他文件。
- pr-review-self:用你偏好的清单给自己的 PR 先过一遍。
- explain-this-file:读当前
@file,按「外部契约 / 内部结构 / 可疑之处」三段写解读。
Hooks — 红外感应器
Skills 是「你主动喊它来」。Hooks 相反——它们在特定事件发生时自动触发,不需要你喊。
你可以把 Hook 理解成「事件监听器」。Claude Code 在生命周期里会发出各种事件,你可以绑脚本到这些事件上,系统自动帮你跑。
完整的事件清单
| 事件 | 什么时候触发 | 能阻止这次操作吗 |
|---|---|---|
SessionStart | 会话启动时 | 不能 |
SessionEnd | 会话完全结束 | 不能 |
UserPromptSubmit | 你按下回车把消息发出去之前 | 能 |
PreToolUse | Claude 要调用一个工具之前 | 能 |
PostToolUse | 工具调用成功之后 | 不能(但可改输出) |
PostToolUseFailure | 工具调用失败时 | 不能 |
PermissionRequest | 权限弹窗要显示之前 | 能 |
Stop | Claude 说「我做完了」要结束时 | 能(可强制继续) |
PreCompact | 上下文压缩前 | 不能 |
SubagentStart / SubagentStop | 子代理启停 | 不能 |
WorktreeCreate / WorktreeRemove | worktree 创建/销毁 | 不能 |
四种 hook 处理器
command:跑一条 shell 命令。最常见。prompt:发一条额外 prompt 给 Claude(比如「记得跑 lint」)。agent:启动一个子代理去处理。http:POST JSON 到指定 URL(对接监控、通知)。
一个具体例子:禁止跑 rm -rf
在 .claude/settings.json:
{
"hooks": {
"PreToolUse": [
{
"matcher": "Bash",
"hooks": [
{
"type": "command",
"if": "Bash(rm -rf *)",
"command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/block-rm.sh"
}
]
}
]
}
}
然后 .claude/hooks/block-rm.sh:
#!/bin/bash
echo "Nope." >&2
exit 2 # 退出码 2 表示阻止这次工具调用
退出码约定:0 放行、2 阻止、其他按一般错误处理。从此 Claude 再想跑 rm -rf,钩子直接挡掉。
实用 hook 套路
Edit / Write,改完自动跑 prettier --write / gofumpt -w。.env、credentials.json、*.pem 的写操作。notify-send / osascript / PowerShell Toast。长任务跑着你去干别的,做完提醒你。Bash(git commit *),先跑 pnpm lint,挂了 exit 2 阻止提交。Hook 是有执行代价的
钩子在每次匹配事件时都会跑。别在高频事件(PreToolUse / PostToolUse)上绑慢脚本——每次多 2 秒,一小时跑下来整个会话会发粘。慢脚本放 Stop 或单独的 cron。
Subagents — 分身
有时候你会遇到这种场景:主任务正在进行,中间卡了一个「先调研一下这个库怎么用」的子任务。让主 Claude 自己去调研?它会读一堆文档、主对话上下文被灌满。让你手动开一个新会话?麻烦。
Subagent就是主 Claude 派出去的「分身」。主 Claude 说:「去,帮我调研一下 Drizzle 怎么建 migration,结果回来告诉我。」分身在独立上下文里跑,读完十几个文档、写完一份报告,把总结返回主会话。主会话只看到那份简洁的总结。
内置几种 Subagent
用 /agents 命令打开面板,看当前运行的子代理和可用代理库。
自己写一个
新建 .claude/agents/my-researcher/AGENT.md:
---
name: my-researcher
description: 深度研究一个特定主题,读大量文档/代码,生成详细报告。用于需要读很多东西才能回答的问题。
tools: Glob Grep Read WebFetch WebSearch
model: sonnet
---
你是一个技术研究员。给你一个主题:
1. 用 Glob/Grep 找出项目里所有和这个主题相关的文件
2. 读透它们,必要时上网搜外部资料
3. 生成一份结构化报告:背景 / 现状 / 选项 / 建议
不修改任何文件。报告要能让没看过代码的人看懂。
主 Claude 看到这个 agent 的 description,在合适的场景里自己决定派出去。或者你直接说「用 my-researcher 帮我研究 X」。
并行的力量
多个 subagent 可以并行跑。主 Claude 同时派三个分身查三件事,总耗时是最慢那个的时间。这是 Claude Code 做大任务时「变快」的主要手段。
> 我要调研三件事(可以并行):
> 1. 我们项目里所有用到 WebSocket 的地方
> 2. Node 22 在 Docker Alpine 上的已知坑
> 3. Redis 7.4 新增的命令对我们 cache 层有哪些影响
> 做完汇总成一份报告。
心智模型
Claude Code 本身是一个 agent。Subagent 是 agent 套 agent。一个管理者把子任务分给几个下属,下属只汇报结论,不带回所有原材料——和真实世界的团队一样。
MCP — 对外接线板
到目前为止,Claude Code 的工具都是「本地」的:读本地文件、跑本地命令。但现实工作里你常常要碰外部系统——GitHub issue、Slack 消息、Notion、Jira、线上数据库……
MCP(Model Context Protocol)是一个标准化的办法:把「第三方服务」封装成 Claude 能直接调用的工具集。你不用关心协议细节,只要知道:有一堆现成的 MCP 服务器,连进来以后 Claude 就多一批新工具。
连一个 GitHub MCP 服务器
在项目根的 .mcp.json:
{
"mcpServers": {
"github": {
"command": "npx",
"args": ["@anthropic-ai/github-mcp"],
"env": {
"GITHUB_TOKEN": "${GITHUB_TOKEN}"
}
}
}
}
重启 Claude Code,现在你可以说:
> 帮我看看 #42 这个 issue,然后开一个 PR 修它
Claude 调用 MCP 工具读 issue 原文、理解需求,按正常流程改代码、最后调 MCP 工具开 PR。全程你不用离开终端。
常见的 MCP 服务器
三种传输方式
$ claude mcp add github npx @anthropic-ai/github-mcp
$ claude mcp add --transport sse remote-tool https://api.example.com/mcp
$ claude mcp add --transport http my-api https://api.example.com/mcp
MCP 权限要上心
MCP 工具一旦连上就是一等公民,和本地工具同级。一个能发 Slack 消息的 MCP,意味着 Claude 理论上能替你发消息。在 permissions 里明确允许/禁止:
{
"permissions": {
"allow": ["mcp__github__*"],
"deny": ["mcp__slack__send_message", "mcp__postgres__execute_write"]
}
}
Agent SDK — 把 Claude 嵌进你自己的程序
前六节都在讲「在终端里怎么用好 Claude Code」。第七节讲一个完全不同的方向:把 Claude 作为一个库嵌进你自己写的 Python / TypeScript 程序里。这就是 Agent SDK。
SDK 给你和 Claude Code 同一个 agent 引擎,但你自己决定「在什么环境下跑、接什么工具、吃什么 prompt」。核心类是 query(TS)或 ClaudeSDKClient(Python):
from claude_agent_sdk import query, ClaudeAgentOptions
options = ClaudeAgentOptions(
system_prompt="你是一个代码审查者。只看安全问题。",
allowed_tools=["Read", "Grep", "Glob"],
permission_mode="plan",
max_turns=10,
model="claude-opus-4-7",
)
async for msg in query(
prompt="审一下 src/auth/ 下所有文件,找 SQL 注入和鉴权 bypass。",
options=options,
):
print(msg)
值得记的特性:
- 流式输出:每轮工具调用和文字输出实时拿到,做进度展示很自然。
- 自定义工具:注册你自己的 Python/TS 函数作为 Claude 的工具。
- Prompt caching:SDK 自动做 5 分钟 TTL 的 prompt cache,重复调用大幅省钱。
- Managed Agents / Batch API:Anthropic 托管的 agent 和批处理 API 都能从 SDK 调。
一个实际场景
你想做一个「新同事入职 checklist 机器人」:拿到同事的 GitHub 用户名,自动查他们最近 5 个 PR、生成技能画像、给 onboarding 路径。这种事情交互式跑也行,但你希望它长期挂在公司内网的 web 服务后面——SDK 就是这个场景。
from fastapi import FastAPI
from claude_agent_sdk import query, ClaudeAgentOptions
app = FastAPI()
@app.post("/onboard/{username}")
async def onboard(username: str):
prompt = f"查看 GitHub 用户 {username} 最近 5 个 PR,生成技能画像和 onboarding 路径。"
result = []
async for msg in query(
prompt=prompt,
options=ClaudeAgentOptions(
allowed_tools=["WebFetch", "Bash(gh pr *)"],
max_turns=6,
max_budget_usd=0.30,
),
):
result.append(msg)
return {"report": result}
该不该学 SDK
大一大二如果你只是用 Claude 帮自己写作业、做项目——前六节够了。SDK 是给「想把 Claude 变成自己产品里一部分」的人准备的。等你真的有 idea 了,回来看这一节即可。
组合拳:一个成熟项目的 Claude Code 配置
想象你在一个中等规模的项目里工作几个月了。你的 Claude Code 设置可能长这样:
~/.claude/
├── CLAUDE.md # 个人偏好:包管理器、命名风格...
├── skills/
│ ├── commit/ # 我自己写的智能提交流程
│ └── my-pr-review/ # 我喜欢的 PR 审查清单
├── agents/
│ └── researcher/ # 个人研究员
├── memory/ # 自动记忆
│ ├── MEMORY.md
│ └── *.md
└── keybindings.json # 自定义快捷键
my-project/
├── CLAUDE.md # 团队规范:架构、禁区、测试要求
├── CLAUDE.local.md # 我这台机器的特殊路径 (.gitignore)
├── .mcp.json # MCP 服务器配置
└── .claude/
├── settings.json # Hook + 权限 + 策略
├── agents/
│ └── migration-bot/ # 项目共享的数据库迁移代理
├── hooks/
│ ├── block-env.sh
│ ├── auto-format.sh
│ └── notify-done.sh
├── skills/
│ ├── deploy/ # 团队发布流程
│ └── hotfix/ # 紧急修复流程
└── plans/ # 历史 /plan 产出归档
这时候你的 Claude Code 已经「长」出一个完整的工作台:
- 它知道项目规矩(CLAUDE.md + auto memory);
- 它会各种常用招式(Skills);
- 某些事情会自动发生,不用每次叮嘱(Hooks);
- 大任务可以分头并进(Subagents);
- 它能触达外部系统(MCP);
- 你甚至能把它做成产品(Agent SDK)。
五件套不是「非学不可」——一个大一学生完全可以只用 claude + 自然语言跑很多东西。但当你发现自己每天都在告诉 Claude 同样的事,就是引入这些的信号。它们是你用得越久越值得投资的东西。
建议的学习顺序
从 CLAUDE.md 开始——收益最大、成本最低。然后写 2–3 个你天天用的 Skills。权限弹窗多到烦了,配 permissions 白名单。再久一点,写一两个 Hook。Subagents 和 MCP 是锦上添花,不急。SDK 等你有真实产品需求再学。