Skip to content

Latest commit

 

History

History
158 lines (109 loc) · 6.72 KB

File metadata and controls

158 lines (109 loc) · 6.72 KB

理解大型 Monorepo 中的 Claude Skills 发现机制

在使用 Claude Code 处理 monorepo 时,理解 skills 是如何被发现并加载到上下文中的,对于有效地组织项目特定的能力至关重要。

← 返回 Claude Code 最佳实践 Claude

与 CLAUDE.md 的重要区别

Skills 的加载行为与 CLAUDE.md 文件不同。 虽然 CLAUDE.md 文件会向上遍历目录树(祖先加载),但 skills 使用一种不同的发现机制,专注于项目内的嵌套目录。

Skills 的发现方式

1. 标准 Skill 位置

Skills 根据作用域从这些固定位置加载:

位置 路径 适用范围
Enterprise 托管设置 组织内所有用户
Personal ~/.claude/skills/<skill-name>/SKILL.md 你的所有项目
Project .claude/skills/<skill-name>/SKILL.md 仅当前项目
Plugin <plugin>/skills/<skill-name>/SKILL.md 启用 plugin 的位置

2. 嵌套目录的自动发现

当你处理子目录中的文件时,Claude Code 会自动发现嵌套的 .claude/skills/ 目录中的 skills。例如,如果你在编辑 packages/frontend/ 中的文件,Claude Code 也会查找 packages/frontend/.claude/skills/ 中的 skills。

这支持 monorepo 设置,其中各个包可以拥有自己的 skills。

Monorepo 结构示例

考虑一个典型的包含多个独立包的 monorepo:

/mymonorepo/
├── .claude/
│   └── skills/
│       └── shared-conventions/SKILL.md    # 项目级 skill
├── packages/
│   ├── frontend/
│   │   ├── .claude/
│   │   │   └── skills/
│   │   │       └── react-patterns/SKILL.md  # 前端专用 skill
│   │   └── src/
│   │       └── App.tsx
│   ├── backend/
│   │   ├── .claude/
│   │   │   └── skills/
│   │   │       └── api-design/SKILL.md      # 后端专用 skill
│   │   └── src/
│   └── shared/
│       ├── .claude/
│       │   └── skills/
│       │       └── utils-patterns/SKILL.md  # 共享工具 skill
│       └── src/

场景 1:刚在根目录启动 Claude(尚未编辑任何文件)

当你在 /mymonorepo/ 运行 Claude Code 且尚未编辑任何文件时:

cd /mymonorepo
claude
# 刚启动 - 尚未编辑任何文件
Skill 是否在上下文中? 原因
shared-conventions 根目录 .claude/skills/ 中的项目级 skill
react-patterns 未发现 - 尚未处理 packages/frontend/ 中的文件
api-design 未发现 - 尚未处理 packages/backend/ 中的文件
utils-patterns 未发现 - 尚未处理 packages/shared/ 中的文件

场景 2:编辑包内文件后

在你要求 Claude 编辑 packages/frontend/src/App.tsx 后:

Skill 是否在上下文中? 原因
shared-conventions 根目录 .claude/skills/ 中的项目级 skill
react-patterns 处理 packages/frontend/ 中文件时发现
api-design 仍未发现 - 尚未处理 packages/backend/ 中的文件
utils-patterns 仍未发现 - 尚未处理 packages/shared/ 中的文件

关键洞察:嵌套 skills 是按需发现的,当你处理这些目录中的文件时才会加载。它们不会在会话开始时预加载。

关键行为:描述 vs 完整内容

Skill 描述会被加载到上下文中,让 Claude 知道有哪些可用技能,但 完整 skill 内容只在调用时加载。这是一个重要的优化:

  • 描述:始终在上下文中(在字符预算范围内)
  • 完整内容:skill 被调用时按需加载

注意:预加载 skills 的子代理工作方式不同 - 完整 skill 内容会在启动时注入。

优先级顺序(当 Skills 同名时)

当 skills 在不同层级共享相同名称时,高优先级位置优先:

优先级 位置 作用域
1 (最高) Enterprise 组织范围
2 Personal (~/.claude/skills/) 你的所有项目
3 (最低) Project (.claude/skills/) 仅当前项目

Plugin skills 使用 plugin-name:skill-name 命名空间,因此不会与其他层级冲突。

为什么这种设计适用于 Monorepos

  • 包特定的 skills 保持隔离 - 在 packages/frontend/ 工作的前端开发者可以获得前端专用 skills,而不会让后端 skills 干扰上下文。

  • 自动发现减少配置 - 无需显式注册包级 skills;它们会在你处理这些目录时被发现。

  • 上下文经过优化 - 只有 skill 描述会在初始加载,嵌套 skills 按需发现。

  • 团队可以维护自己的 skills - 每个包团队可以定义自己领域的 skills,无需与其他团队协调。

字符预算考虑

Skill 描述会被加载到上下文中,直到达到字符预算限制(默认 15,000 字符)。在拥有多个包和 skills 的大型 monorepo 中,你可能会达到这个限制。

  • 运行 /context 检查关于被排除 skills 的警告
  • 设置 SLASH_COMMAND_TOOL_CHAR_BUDGET 环境变量来增加限制

最佳实践

  1. 将共享工作流放在根目录 .claude/skills/ - 仓库范围的约定、提交工作流和共享模式。

  2. 将包特定的 skills 放在包的 .claude/skills/ - 框架特定的模式、组件约定、该包独有的测试工具。

  3. 对危险的 skills 使用 disable-model-invocation: true - 部署或破坏性 skills 应需要显式用户调用。

  4. 保持 skill 描述简洁 - 描述始终在上下文中(直到字符预算),因此冗长的描述会浪费上下文空间。

  5. 在 skill 名称中使用命名空间 - 考虑使用包名前缀(例如 frontend-reviewbackend-deploy)以避免混淆。

对比:Skills vs CLAUDE.md 加载

行为 CLAUDE.md Skills
祖先加载(向上遍历目录树)
嵌套/后代发现(向下遍历目录树) 是(惰性) 是(自动发现)
全局位置 ~/.claude/CLAUDE.md ~/.claude/skills/
项目位置 .claude/ 或仓库根目录 .claude/skills/
内容加载 完整内容 仅描述(调用时加载完整内容)

来源