Claude Code 插件装了不加载:依赖、提示与相关性三层各卡在哪

2026-08-18

「插件装了没反应」这句话没法直接回答。Claude Code 官方文档把这件事拆在三个不同页面上,三种现象长得很像,处置动作却完全不重叠:你自己装的插件功能不生效,跟平台组在 marketplace.json 里配了推荐但同事看不见,是两条链路。

先做分流:动手之前跑一条命令,把「装了但被禁用」和「压根没被推荐出来」分开

claude plugin list --json

官方文档在《Constrain plugin dependency versions》一页写明,有问题的插件在这个 JSON 输出里会带 errors 字段列出问题,干净加载的插件则省略该字段。成本极低,却能把下面三层里的第一层直接摘出来。

第一层:依赖没满足,插件被 Claude Code 主动禁用

现象:插件明明装过,claude plugin list 里也能看到,但它的 skill、agent、hook 一个都不生效。

判定动作:跑上面那条命令看目标插件有没有 errors 字段。文档特意提醒,依赖问题在 claude plugin list/plugin 中呈现为描述性的错误消息,而不是文档表格里那些字面错误码——别拿着 dependency-unsatisfied 这个词去搜输出,搜不到不代表没问题。文档同时写明,出现依赖错误时 Claude Code 会把受影响的插件禁用,直到你解决为止。

文档列出的常见错误有四个,含义和处置各不相同:

错误含义处置
dependency-unsatisfied依赖没装,或装了但被禁用跑错误消息里给出的 claude plugin install;依赖所在的 marketplace 还没配就先 claude plugin marketplace add,Claude Code 会自动解析;依赖被禁用的就启用它
range-conflict多个插件对同一依赖的版本要求无法合并错误消息会点名原因:没有版本满足全部范围、某个范围不是合法 semver、或范围复杂到无法求交。对应地卸载或更新冲突的一方、修正非法 version 字符串、简化过长的 || 链,或请上游放宽约束
dependency-version-unsatisfied已装依赖的版本落在本插件声明的范围之外claude plugin install <dependency>@<marketplace>,按当前所有约束重新解析
no-matching-tag依赖仓库上没有满足范围的 {name}--v* 标签确认上游按约定打了标签,或放宽范围

处置时几个容易踩空的前提,都写在同一页里:

  • 启用会连带启用依赖,但需要 Claude Code v2.1.143 或更高。更早的版本只启用你点名的那一个,然后在下一次加载时抛 dependency-unsatisfied。现象若是「我明明 enable 过了」,先看版本。
  • 启用被拒绝还有三类固定原因:依赖没装、依赖被组织的插件策略阻止(会点名被拦的那个)、依赖在优先级更高的 scope 上被显式设成了 false(要么在那个 scope 启用,要么用 --scope 写到那里去)。
  • 跨 marketplace 的依赖默认装不上。除非根 marketplace 的 marketplace.json 把目标名字加进 allowCrossMarketplaceDependenciesOn,否则安装以 cross-marketplace 错误失败。用户手动先装上那个依赖同样能满足约束。
  • 预发布版本默认被排除。像 2.0.0-beta.1 不会被匹配,除非范围用 ^2.0.0-0 这类带预发布后缀的写法主动 opt in。上游只打了 beta 标签而你写的是普通范围,表现就是 no-matching-tag
  • 非 git 源的依赖,版本约束根本不控制拉哪个版本。文档明确 npmarchivecommand 三类源不走标签解析,约束只在加载时检查,不满足就把依赖方插件以 dependency-version-unsatisfied 禁用。其中 command 源的依赖 Claude Code 从不自行安装plugin.json 里没写 version 的依赖满足不了任何约束
  • 本地文件夹形式的 marketplace 要按标签解析版本,需要 v2.1.196 或更高;更早版本不读它的标签,文件夹不是 git 仓库时也没标签可读,都退化成「按当前内容安装」。

上游打标签的约定是 {plugin-name}--v{version},插件目录下执行 claude plugin tag --push;文档写明它会先校验插件内容、检查 plugin.json 与 marketplace 条目版本是否一致、要求工作区干净。

处置后怎么验证:重跑 claude plugin list --json,确认 errors 字段消失。文档还提到,自动更新若因找不到满足所有范围的标签而跳过某个依赖,会把这次跳过列在 /plugin 的 Errors 标签页里并点名约束方,值得顺手看一眼。

什么情况说明不是这个原因:如果这个插件根本没有 errors 字段,依赖层就是干净的,再折腾 dependencies 也没用。先排掉两个纯结构问题:其一,commands/agents/skills/hooks/ 这些目录不能放进 .claude-plugin/,只有 plugin.json 在里面(文档还补了一句:插件根永远不是 ~/.claude/,放在 ~/.claude/.mcp.json 的文件不会被读)。其二,插件里的 skill 一律带命名空间,是 /plugin-name:skill-name 而不是裸的 /skill-name

还有个坑人的伪证据:文档写明 /reload-plugins 之后摘要里的 skills 计数只统计 commands/ 目录,所以哪怕 skill 已经重载,它也可能报 0 skills别把这个 0 当成「没加载」的证据。 agents 那侧则相反——项目和用户的 .claude/agents/ 定义会覆盖同名的插件 agent,从 .claude/ 迁移后原文件不删,插件版本就一直不生效。

第二层:你的 CLI 发了 hint,用户那边没弹安装提示

现象:你按《Recommend your plugin from your CLI》在自己的 CLI 里实现了 <claude-code-hint /> 标记,格式也照文档写了,但用户那边从没见过安装提示。

怎么确认:文档给的是一串顺序检查,按它逐条对:

  1. 环境变量是否被设。Claude Code 为它通过 Bash 和 PowerShell 工具运行的每条命令、以及 hook 命令设置 CLAUDECODE=1;从 v2.1.172 起在同样这些子进程里还设 CLAUDE_CODE_CHILD_SESSION=1只有 Bash 和 PowerShell 工具的输出会触发安装提示;hook 命令里的 hint 标记会被剥掉并忽略。Windows 侧走 PowerShell 不会掉链子,这两个工具的输出是同等对待的。
  2. 标记是否独占一行。这是文档明说会被强制的两条之一:嵌在某行中间(比如塞进一条日志语句里)的标记直接被忽略,行首行尾的空白则允许。
  3. 目标是否在官方 Anthropic marketplace。这是强制的第二条:value 必须指向 Anthropic 控制的 marketplace(例如 claude-plugins-official),指向别的 marketplace 的 hint 会被静默丢弃。文档还专门写明,站内提交表单加的是 community marketplace,而 hint 协议不检查 community。
  4. 属性是否合法。三个必需属性:v(唯一支持值是 1)、type(唯一支持值是 plugin)、valuename@marketplace 形式)。值可加双引号也可不加,不加引号时不能含空白,且不支持转义序列。
  5. 是否被提示频率挡掉。文档写了三档:同一插件只提示一次(提示过就记下,不管用户当时选了什么);每个会话最多一次,全机所有 CLI 合计;关闭了遥测的会话从不显示 hint 提示——包括设了 DISABLE_TELEMETRYCLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC 的会话,以及在 Amazon Bedrock、Google Cloud 的 Agent Platform 这类第三方 provider 上因自动遥测退出而适用的会话。

处置:文档给了带环境变量门控的示例,Shell 版原样如下:

if [ -n "$CLAUDECODE" ]; then
  printf '%s\n' '<claude-code-hint v="1" type="plugin" value="example-cli@claude-plugins-official" />' >&2
fi

同一页也给了 Node.js、Python、Go 三种写法,逻辑一致。门控选哪个变量文档给了取舍:CLAUDECODE 覆盖所有版本因而触达最广,但它在 tmux 会话、Claude Code 启动的 stdio MCP server 子进程、以及 IDE 扩展的集成终端里也会被设,而那里可能是真人在手敲你的 CLI;CLAUDE_CODE_CHILD_SESSION 只在 Claude Code 自己 spawn 的子进程里设(工具调用、hook 命令、状态行命令),代价是需要 v2.1.172 或更高。反直觉的一点:tmux server 这种长生命周期进程会把变量继承下来,之后从它启动的 shell 里仍会看到裸标记。

验证:文档说 hint 行总是在输出到达模型之前被移除,即使版本或 type 无法识别也一样。反过来说,「我在会话里没看到这个标记」并不能证明它没被发出来,验证只能靠提示本身是否出现,以及上面五条逐一排除。

什么情况说明不是这一层:插件根本不在 claude-plugins-official 里,那整条协议对你不成立,写得再对也不会弹——文档写明官方 marketplace 由 Anthropic 自行决定收录,站内提交表单加进去的是 community marketplace,而 hint 协议不检查 community;文档给的路径是:如果你有对接的 Anthropic 合作方联系人,通过对方协调官方 marketplace 上架。

第三层:marketplace 配了 relevance,但成员看不到建议

现象:平台组按《Recommend plugins for your org》给插件条目加了 relevance 块,成员那边没有任何建议出现。

判定动作,按依赖强度从硬到软:

  1. 客户端版本relevance 需要 Claude Code v2.1.152 或更高,更早的客户端直接忽略这个字段
  2. 管理员是否 allowlist 过这个 marketplace。光在 marketplace.json 里声明 relevance 不够,必须由管理员在 managed settings 的 pluginSuggestionMarketplaces 里加上该 marketplace 名字,官方 Anthropic marketplace 也不例外
  3. 非官方 marketplace 还要在同一份 managed settings 里声明来源:作为 extraKnownMarketplaces 中该名字的条目,或作为 strictKnownMarketplaces 的条目。文档强调,如果机器上以这个名字注册的 marketplace 来自另一个来源,allowlist 里的名字会被忽略。
  4. 是否被 spinner-tips 设置关掉了。spinner tip 和会话开始时的一行通知都属于 spinner-tips 体系,spinnerTipsEnabled 设成 false、或配了带 excludeDefaultspinnerTipsOverride 时两者都被禁用。/plugin Discover 标签页的置顶不受 tip 设置影响——这正好可以当判定动作:tip 看不到但 Discover 里置顶了,说明匹配成功,只是被 tip 开关挡住了。
  5. 信号本身是否匹配得上relevance.signals 下文档列了五个字段:cwdclihostsfilesReadmanifestDeps,至少要有一个才可能被建议。踩坑最多的是 cli:文档写明 Claude Code 每次 shell 工具调用只记录一个命令名——跳过前导环境变量赋值和 sudo 之后的第一个 token,而且复合命令只贡献前导命令,所以 cd infra && terraform plan 记下的是 cd 而不是 terraform,且是精确匹配。这条在每个平台都适用,Windows 上走 PowerShell 或 Git Bash 的记录方式相同。

Windows 侧要单独盯 manifestDeps 文档写明这个信号的路径不做分隔符归一化,Windows 路径就是反斜杠file 是对清单文件路径(通常是绝对路径)的正则,必须尾锚定,因为起始锚定的模式永远匹配不上绝对路径。官方写法是 JSON 转义形式的 [/\\\\]package\\.json$,用 [/\\\\] 同时吃两种斜杠,用 \\. 让点号变字面量;另外 file 大小写不敏感、pattern 大小写敏感。而 cwdfilesRead 是正斜杠归一化且大小写不敏感的,别混着记。

处置后怎么验证:发布前跑 claude plugin validate ./my-marketplace。它会把 relevancerelevance.signals 下的未知键报为警告,标记 relevance 值不是对象的情况,并拒绝 hosts 里带 scheme、端口或路径的条目(hosts 只接受裸的小写主机名)。注意这三条里只有 hosts 那条是拒绝,未知键只是警告——发布前扫一眼输出,别看到「通过」就以为字段名全拼对了。至于有没有办法把警告直接升级成错误,官方文档没有说明这一点,以 claude plugin validate --help 的实际输出为准。

什么情况说明不是这一层:allowlist 配了、版本够、信号也确实该命中,却只是「偶尔才看见」,那多半不是配置问题,而是文档写明的展示频率在起作用:同一插件的建议在 spinner tip 和会话开始通知合计最多每三个会话出现一次,插件一旦装上两者都不再出现;会话开始通知显示过两次后就不再出现;Discover 标签页对一个插件只置顶一次。这两个展示位还各有版本门槛——会话开始通知需要 v2.1.153 或更高,Discover 置顶需要 v2.1.154 或更高。看不到,不等于没配对。

最后一句边界:文档明确 Claude Code 从不自动安装插件,永远由用户确认,第二层和第三层做的都只是「建议」。真要全组织铺开,文档指的是把插件加进 managed settings 的 enabledPlugins


本文依据 Claude Code 官方文档(code.claude.com/docs)于 2026-08-17 的公开内容整理。 该产品闭源,本文只复述官方文档写明的机制,不推断其内部实现我们没有对文中涉及的功能做过实测,因此不涉及界面外观、操作手感与运行速度的任何描述。 该产品迭代频繁,文中涉及的命令、配置项与默认值随版本变动,请以官方文档最新内容为准。 本文不涉及价格、额度与限流的具体数值,相关信息请以官方定价与用量说明页为准。

安全与合规相关做法请结合自身环境评估,本文不构成安全方案建议。

想系统学会用 AI?报名体系课或加入会员,照着学、照着用。