Claude Code 插件与 Skill 加载机制 (Claude Code Plugin and Skill Loading)
一句话
给自建 agent 挂自己的方法论技能,正确姿势是 plugins(显式目录) + 环境变量 CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1。skills 过滤器不可靠,managedSettings.disableBundledSkills 无效。以下全部实测。
目录结构
my-plugin/
.claude-plugin/plugin.json 清单:name / version / description / author
skills/<技能名>/SKILL.md 技能本体,YAML frontmatter + Markdown 正文
commands/ 可选:自定义斜杠命令
agents/ 可选:子 agent
hooks/hooks.json 可选:事件钩子
.mcp.json 可选:MCP 配置(可以用 skipMcpDiscovery 忽略)SKILL.md 文件名必须全大写;技能目录名用 kebab-case;插件名小写短横线。
SKILL.md 格式
---
name: recon
description: 什么时候该用它 —— 这句话是模型唯一常驻能看到的内容,写好
---
正文。只在技能被触发时才读进上下文,可以写长。引用插件内部路径时用 ${CLAUDE_PLUGIN_ROOT}。
成本:渐进式加载
claude --plugin-dir ./my-plugin plugin details <插件名> 会报预估 token:
Projected token cost
Always-on: ~75 tok added to every session
component always-on on-invoke
code-audit ~30 ~660
recon < 20 ~380
report < 20 ~460
web-check < 20 ~530常驻只有技能名 + 一句描述(合计 ~75 tok),正文按需加载。这就是 skills 相对"把方法论全塞进系统提示词"的全部价值。
注意 --plugin-dir 是顶层参数(claude --plugin-dir <路径> plugin details <名字>),写在 plugin details 后面会报 unknown option。
三个开关的实测结论
| 做法 | 结果 |
|---|---|
skills: 'all' | ❌ 把 Claude Code 自带的 16 个 skill 一起打开(deep-research/dataviz/code-review/claude-api ...) |
skills: ['my-plugin:recon'] | ❌ 内置的照样在。显式列表只增不减 |
skills: [] | ❌ 依然无效,连自己插件的技能都还列着 |
managedSettings: { disableBundledSkills: true } | ❌ 实测无效 |
环境变量 CLAUDE_CODE_DISABLE_BUNDLED_SKILLS=1 | ✅ 有效。16 个 → 只剩自己的 |
disableBundledSkills 定义在 SDK 的 Settings 接口(settings.json schema)里,不是 Options,文档说它等价于那个环境变量 —— 但只有环境变量这条实际生效。
代码里的做法:配置里仍写 claudeSettings.disableBundledSkills,由拼环境变量的那一层翻译成 env。
关掉前后对比:
关之前: skills = [deep-research, dataviz, update-config, verify, debug, code-review,
simplify, batch, fewer-permission-prompts, doctor, loop, claude-api,
workflow-authoring, run, run-skill-generator, sec-guard:recon]
关之后: skills = [sec-guard:recon, doctor](doctor 是内置斜杠命令,不是 skill,关不掉;slash_commands 里还留着 typable 但模型看不见的那些。)
为什么用 plugins 而不是 settingSources
plugin.path 是显式路径,所以不需要打开 settingSources。
一旦打开 settingSources: ['project'|'user'],宿主机的 CLAUDE.md、settings.json、用户自己的 MCP server 全会渗进来
(见 Claude Agent SDK 配置渗漏与隔离 (Claude Agent SDK Config Bleed and settingSources Isolation))。
skipMcpDiscovery: true 让插件不读自己的 .mcp.json,MCP 连接仍由宿主代码掌握。
技能会不会被触发:不一定
技能是概率性的。列表在上下文里,用不用由模型决定。
同一句"帮我摸一下 10.20.0.1 这台机器":
- 加了提示词点名之前:2 次里 1 次触发
- 在系统提示词里加了一张"什么任务加载什么技能"的表之后:连测 3/3 触发
光靠 frontmatter 的 description 不够,系统提示词里点名才稳。
另外:技能是通过 Skill 工具加载的,不是去 Read SKILL.md。检测是否触发要看 tool_use.name === 'Skill',不要找文件读取。
安全提示
官方文档原话:
This is a context filter, not a sandbox: unlisted skills are hidden from the model's listing and rejected by
the Skill tool, but their files remain on disk and are reachable via Read/Bash. Do not store secrets in skill files.
推论:第三方 SKILL.md 是不可信的指令。它不是代码,是注入到模型上下文里的自然语言。
一个来路不明的技能可以在权限范围内指挥模型做过度操作,或试图引导它忽略既有的门禁。
代码层写的门禁绕不过去(见 Agent 权限门禁做在代码层 (Enforcing Permission Gates in Code for LLM Agents)),
但模型行为会被带偏。第三方技能要读一遍再用,别整包拖进来。
相关
- Claude Agent SDK 配置渗漏与隔离 (Claude Agent SDK Config Bleed and settingSources Isolation)
- Agent 权限门禁做在代码层 (Enforcing Permission Gates in Code for LLM Agents)
- MCP (Model Context Protocol)
出现场景
C:\Users\18086\.workspace\git-workspace\mini-agent,2026-09-11。为网安检查助手挂 recon / web-check / code-audit / report 四个方法论技能时验证。
本文归档于个人知识库 · 领域:CS & AI · 模块:04 Project_CS_AI/AI apps