CLAUDE.md、SKILL.md与MCP:哪一层负责存储哪些指令
为何一个庞大的 CLAUDE.md 会令编程智能体失效,规则、技能与 MCP 连接中应包含什么内容,作用域与路径的设定,决策树的作用,以及 AGENTS.md 命名中的陷阱。
来源: CLAUDE.md vs SKILL.md vs MCP: The Modern Agent Stack Explained
Claude Code及类似编程工具的新用户往往在第一个月会重复同一个错误:他们打开CLAUDE.md后不断输入内容,包括风格指南、部署步骤、审查清单、原始数据库结构等,直到文件行数达到600或900行。他们认为提前提供更多背景信息能让工具更智能。
但实际上恰恰相反。工作内存被占满后,回答的准确性会下降,原本有效的提示也会失效。总感觉有些不对劲,却又难以明确指出问题所在。对于每一个简单请求,模型都得先浏览数百行无关的指令,才能找到那一行代码。这既不是模型的问题,也不是提示的问题,只是让一个文本文件同时承担了三项不同的任务。
现代编码助手在指令被拆分为三个独立的层次时表现最佳:始终生效的项目规则、按需加载的任务技能,以及通过MCP建立的实时工具连接。通过将这些层次分开,模型能够在需要的时刻仅获取所需的信息。
为何要分为三层
有理由问为什么是三层,而不是一个大的文件或十个小的专用文件。每一层解决不同的问题,而且这些问题之间的重叠程度比预期要低。
- CLAUDE.md用于处理那些必须始终成立的规则。
- SKILL.md用于处理那些仅偶尔重要的内容。
- MCP用于处理一旦记录下来就会过时的数据。
这其实是三种不同的故障模式,而非同一种模式的三种变体。如果将各种技能都放入CLAUDE.md中,那么无论是否需要部署检查清单,每次会话时都会加载一个内容臃肿的完整文件。任何额外的层级其实都只是这三种模式中的某一种的细分,而非新的任务。
哪些内容应放在CLAUDE.md或AGENTS.md中
可以把CLAUDE.md视为给工程师入职第一天留下的提示。它并非完整的入门文档,只是记录了团队中每个人早已知晓的一些不成文规则,比如这里不允许使用类组件,或者绝不能直接操作数据库,而必须通过服务层来操作。
该文件位于项目根目录中,Claude Code会在每次会话开始时自动读取它。没人会主动调用或请求它,它就那样存在,就像人们开始编码时脑海中自然浮现的团队规范一样。
良好的候选内容包括编码规范、项目结构、严格限制条件、诸如绝不在代码中暴露API密钥之类的安全规则,以及智能体在审查工作时应遵循的角色定位。
较差的候选内容包括长达40步的部署指南、数据库结构,以及那些只有十天中一天才用得上的内容。大多数人都会犯错在选用这类内容。如果某些内容并非每次使用都必要,那它很可能就不该被包含其中。试图面面俱到的CLAUDE.md最终只会变成一个缓慢且臃肿、毫无实用价值的文件。
还有一个全局版本存在于~/.claude/CLAUDE.md中,适用于所有项目。人们通常会在其中记录个人习惯,比如偏好的提交信息格式或回复所用语言,而将特定于项目的规则放在项目文件中。
一个能正常完成任务的文件应如下所示,内容参考了一套广泛流传的行为准则。
# CLAUDE.md
Behavioral guidelines to reduce common LLM coding mistakes. Merge with project-specific instructions as needed.
**Tradeoff:** These guidelines bias toward caution over speed. For trivial tasks, use judgment.
## 1. Think Before Coding
**Don't assume. Don't hide confusion. Surface tradeoffs.**
Before implementing:
- State your assumptions explicitly. If uncertain, ask.
- If multiple interpretations exist, present them - don't pick silently.
- If a simpler approach exists, say so. Push back when warranted.
- If something is unclear, stop. Name what's confusing. Ask.
## 2. Simplicity First
**Minimum code that solves the problem. Nothing speculative.**
- No features beyond what was asked.
- No abstractions for single-use code.
- No "flexibility" or "configurability" that wasn't requested.
- No error handling for impossible scenarios.
- If you write 200 lines and it could be 50, rewrite it.
Ask yourself: "Would a senior engineer say this is overcomplicated?" If yes, simplify.
## 3. Surgical Changes
**Touch only what you must. Clean up only your own mess.**
When editing existing code:
- Don't "improve" adjacent code, comments, or formatting.
- Don't refactor things that aren't broken.
- Match existing style, even if you'd do it differently.
- If you notice unrelated dead code, mention it - don't delete it.
When your changes create orphans:
- Remove imports/variables/functions that YOUR changes made unused.
- Don't remove pre-existing dead code unless asked.
The test: Every changed line should trace directly to the user's request.
## 4. Goal-Driven Execution
**Define success criteria. Loop until verified.**
Transform tasks into verifiable goals:
- "Add validation" → "Write tests for invalid inputs, then make them pass"
- "Fix the bug" → "Write a test that reproduces it, then make it pass"
- "Refactor X" → "Ensure tests pass before and after"
For multi-step tasks, state a brief plan:
```
1. [Step] → verify: [check]
2. [Step] → verify: [check]
3. [Step] → verify: [check]
```
Strong success criteria let you loop independently. Weak criteria ("make it work") require constant clarification.
---
**These guidelines are working if:** fewer unnecessary changes in diffs, fewer rewrites due to overcomplication, and clarifying questions come before implementation rather than after mistakes.
它简短且具体,下周无需进行任何修改。这是出现错误时的样子,这是早期版本中常见的现象。
# Project Notes
Our database has these tables: users, orders, products, sessions,
audit_log (schema pasted below, 340 lines)...
To deploy, first SSH into staging, then run these 47 commands...
Here's our Slack webhook URL for notifications: hooks.slack.com/...
When reviewing PRs, check for: [12 paragraphs of instructions]
第二个示例中的每一项对CLAUDE.md来说都是错误的,原因各不相同。一旦有人添加了列,架构就会过时。部署步骤仅描述了一个有名称的任务。Webhook URL属于敏感信息,应存储在环境变量中,而非被提交到Markdown文件中。PR审核说明不过是披着CLAUDE.md外衣的技能描述罢了。
一个简单的测试方法:在三个月后的某个随机周二,当你正在做与此无关的事情时再次阅读这条内容,它仍然成立吗?如果不能,那就说明它不属于这个文件。
SKILL.md:仅在需要时显示的专业知识
Agent Skills于2025年10月由Anthropic推出,其设计理念是将特定任务的指令存储在文件夹中,需要时再加载使用,从而避免这些指令一直占用上下文空间。2025年12月,该格式被正式定为独立标准,其他工具也迅速采用了它。VS Code、Cursor、谷歌的Antigravity IDE、Gemini CLI、Goose以及若干其他编程助手现在都支持与Claude Code相同的SKILL.md格式。正是这一标准让MCP成为了工具连接的行业通用规范。
一旦理解了这个思路,就会发现它很有用:并非所有知识都需要一直存在于智能体的记忆中。工程师所掌握的知识大多只在处理特定任务时才有用处。在编写辅助函数时,没人会去回想部署检查清单。技能也是如此。一个存放着SKILL.md文件的文件夹会一直处于闲置状态,直到有“审查这个PR”之类的请求出现,此时Claude才会调出相应的审查检查清单。
技能文件以一段简短的描述开头,称为前置内容,用于说明该技能的功能以及触发时机。当有匹配的消息出现时,Claude才会加载其余内容;如果没有匹配,则这些内容不会出现在对话中。正因如此,使用技能会比将所有内容都放入CLAUDE.md中更为简洁。用于处理拉取请求审核的技能、用于数据库迁移的技能以及用于编写发布说明的技能,除非正在执行相应的任务,否则不会占用彼此的空间。
.claude/skills/
├── code-review/
│ └── SKILL.md
├── pr-description/
│ └── SKILL.md
└── anti-sycophancy/
└── SKILL.md
项目级技能存储在仓库中的 .claude/skills/ 目录下。而应随用户一同存在的个人技能则存储在 ~/.claude/skills/ 目录中。这种划分方式与 CLAUDE.md 中的项目级与全局级分类相对应。以下是经过简化的实际内容:
---
name: production-code-validation-checklist
description: "Run this checklist before pushing code to GitHub"
---
# Production Code Validation Checklist
**Run this checklist before pushing code to GitHub.**
This is not optional. This is how you prevent broken repositories.
## Secrets Audit
- [ ] Searched for: password, secret, token, key, api_key, credential
- [ ] All secrets are in environment variables or .env, not in code
- [ ] .env file is in .gitignore
## Failure Scenario Testing: Deliberately Break It
This is the most important step. Production code breaks. Can your code
handle it?
- [ ] Run without a required environment variable, does it fail with a
clear error?
- [ ] Simulate a timeout on any HTTP request, does the code handle it?
- [ ] Feed it empty input, null input, and malformed input, one at a time
## Final Production Readiness Assessment
Choose ONE:
- [ ] PROTOTYPE: concept proven, not production ready
- [ ] DEVELOPMENT READY: works for development, not production
- [ ] PRODUCTION CANDIDATE: ready for real-world testing
- [ ] PRODUCTION VERIFIED: tested in a real environment, known to work
**If you cannot check a box, you are not done.**
注意它避免了什么。它不遵循编码规范,也没有数据库架构。它只有一个有名称的任务,由某种特定情境触发,正因如此它才属于技能而非一个简化版的CLAUDE.md。简单的判断标准是:某事物是否仅在执行某个特定的、有名称的任务时才需要。如果是,那它就是技能而非规则。
MCP:不仅是知识,更是访问能力
CLAUDE.md和SKILL.md都是有人编写的Markdown文件。MCP则不同——它在Claude运行时将其与聊天界面之外的资源相连,无论是数据库、GitHub、Slack、文件系统,或是任何已连接的其它服务。
对于那些依赖RAG技术的项目来说,直接连接Chroma是一种常见做法。官方的chroma-mcp服务器会将各类数据集作为Claude可查询的工具提供出来。
{
"mcpServers": {
"chroma": {
"command": "uvx",
"args": [
"chroma-mcp",
"--client-type", "persistent",
"--data-dir", "/path/to/your/chroma/data"
]
}
}
}
在 Claude Code 中,配置只需一条命令即可完成,无需手动编辑 JSON 文件。
claude mcp add --scope project chroma \
-- uvx chroma-mcp --client-type persistent --data-dir ./chroma-data
它会注册服务器并将配置信息写入项目中的.mcp.json文件,该文件可被提交,这样整个团队无需手动配置即可使用相同的连接。Claude Code提供三种权限范围:本地,即一台机器上的一个用户;项目,即已存入仓库并可供共享的配置;以及用户,即某人参与的所有项目的配置。这种项目级与全局级的区分模式出现了第三次,一旦注意到便很容易记住。
该协议的发展速度极为迅速,其增长态势本身就已构成重要话题。根据 Anthropic 公布的数据,官方服务器注册表中列出的服务器数量已超过 9,000 台,而参考 SDK 的月度下载量在大约 16 个月内从约 200 万次上升至近 1 亿次。这已不再是一项小众功能。那些仍需将架构或 GitHub PR 内容手动粘贴到提示词中的人,其实是在用人工方式完成 MCP 连接原本能实时完成的操作,而且一旦上游有任何变动,这些手动粘贴的内容就会立刻过时。
决策树
- 无论任务是什么,这是否应在每个会话中都成立?如果是,请将其写入 CLAUDE.md;如果不是,则继续下一步。
- 这是否是一项具有明确名称、可重复执行且包含具体步骤的特定任务?如果是,请将其整理为 SKILL.md;如果不是,则继续下一步。
命名陷阱
任何在不同工具之间切换的用户最终都会遇到这个问题。Claude Code和Cursor读取CLAUDE.md,而Codex CLI及其他几款工具则读取AGENTS.md,二者其实功能相同只是名称不同。谷歌在2025年中期与Windsurf团队达成合作后由其开发的Antigravity也采用了自己的AGENTS.md规范。不过Claude Code、Cursor、Codex和Antigravity在处理技能时都使用相同的SKILL.md格式。因此规则层面因工具而异,但技能层面则保持一致。在认为为某个智能体编写的技能必须为另一个智能体重新编写之前,这一点很重要。
解决此问题的习惯
在将段落添加到 CLAUDE.md 之前,先确定它属于三个分类中的哪一个。很多塞进 CLAUDE.md 的内容其实都是那些尚未拥有独立文件夹的技能。这种做法实际上是通过不同的标签来进行上下文管理:选择让模型在何时看到哪些内容,而非将所有内容都放入第一个打开的文件中,寄希望于模型能自行分类。打开 CLAUDE.md 数一数有多少段落其实是使用了错误文件扩展名的技能,这个数字通常会比预期的要高。