Claude Agent SDK 插件 - 加载自定义命令、Agents、Skills、Hooks
通过 Agent SDK 加载自定义 plugins,使用命令、agents、skills 和 hooks 扩展 Claude Code。
SDK 中的 Plugins
通过 Agent SDK 加载自定义 plugins,使用命令、agents、skills 和 hooks 扩展 Claude Code
Plugins 允许你使用可在项目间共享的自定义功能来扩展 Claude Code。通过 Agent SDK,你可以以编程方式从本地目录加载 plugins,以便向 agent 会话添加自定义 slash commands、agents、skills、hooks 和 MCP servers。
什么是 plugins?
Plugins 是 Claude Code 扩展的包,可以包括:
- Skills:Claude 自主使用的模型调用功能(也可以使用
/skill-name调用) - Agents:用于特定任务的专门子 agents
- Hooks:响应工具使用和其他事件的事件处理程序
- MCP servers:通过 Model Context Protocol 的外部工具集成
ℹ️
commands/目录是旧版格式。对于新 plugins,请使用skills/。Claude Code 继续支持两种格式以实现向后兼容性。
有关 plugin 结构和如何创建 plugins 的完整信息,请参阅 Plugins。
加载 plugins
通过在选项配置中提供本地文件系统路径来加载 plugins。type 字段必须是 "local",这是 SDK 接受的唯一值。要使用通过 marketplace 或远程存储库分发的 plugin,请先下载它并提供本地目录路径。SDK 支持从不同位置加载多个 plugins。
TypeScript:
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Hello",
options: {
plugins: [
{ type: "local", path: "./my-plugin" },
{ type: "local", path: "/absolute/path/to/another-plugin" }
]
}
})) {
// Plugin commands, agents, and other features are now available
}
Python:
import asyncio
from claude_agent_sdk import query
async def main():
async for message in query(
prompt="Hello",
options={
"plugins": [
{"type": "local", "path": "./my-plugin"},
{"type": "local", "path": "/absolute/path/to/another-plugin"},
]
},
):
# Plugin commands, agents, and other features are now available
pass
asyncio.run(main())
路径规范
Plugin 路径可以是:
- 相对路径:相对于你的当前工作目录解析(例如,
"./plugins/my-plugin") - 绝对路径:完整文件系统路径(例如,
"/home/user/plugins/my-plugin")
ℹ️ 路径应指向 plugin 的根目录(包含
.claude-plugin/plugin.json的目录)。
验证 plugin 安装
当 plugins 成功加载时,它们会出现在系统初始化消息中。你可以验证你的 plugins 是否可用:
TypeScript:
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Hello",
options: {
plugins: [{ type: "local", path: "./my-plugin" }]
}
})) {
if (message.type === "system" && message.subtype === "init") {
// Check loaded plugins
console.log("Plugins:", message.plugins);
// Example: [{ name: "my-plugin", path: "./my-plugin" }]
// Check available commands from plugins
console.log("Commands:", message.slash_commands);
// Example: ["/help", "/compact", "my-plugin:custom-command"]
}
}
Python:
import asyncio
from claude_agent_sdk import query
async def main():
async for message in query(
prompt="Hello", options={"plugins": [{"type": "local", "path": "./my-plugin"}]}
):
if message.type == "system" and message.subtype == "init":
# Check loaded plugins
print("Plugins:", message.data.get("plugins"))
# Example: [{"name": "my-plugin", "path": "./my-plugin"}]
# Check available commands from plugins
print("Commands:", message.data.get("slash_commands"))
# Example: ["/help", "/compact", "my-plugin:custom-command"]
asyncio.run(main())
使用 plugin skills
来自 plugins 的 skills 会自动使用 plugin 名称进行命名空间划分,以避免冲突。当作为 slash commands 调用时,格式为 plugin-name:skill-name。
TypeScript:
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "/my-plugin:greet", // Use plugin skill with namespace
options: {
plugins: [{ type: "local", path: "./my-plugin" }]
}
})) {
if (message.type === "assistant") {
console.log(message.message.content);
}
}
Python:
import asyncio
from claude_agent_sdk import query, AssistantMessage, TextBlock
async def main():
async for message in query(
prompt="/demo-plugin:greet",
options={"plugins": [{"type": "local", "path": "./plugins/demo-plugin"}]},
):
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(f"Claude: {block.text}")
asyncio.run(main())
ℹ️ 如果你通过 CLI 安装了 plugin(例如,
/plugin install my-plugin@marketplace),你仍然可以通过提供其安装路径在 SDK 中使用它。检查~/.claude/plugins/以查找 CLI 安装的 plugins。
完整示例
这是一个演示 plugin 加载和使用的完整示例:
TypeScript:
import { query } from "@anthropic-ai/claude-agent-sdk";
import * as path from "path";
async function runWithPlugin() {
const pluginPath = path.join(__dirname, "plugins", "my-plugin");
console.log("Loading plugin from:", pluginPath);
for await (const message of query({
prompt: "What custom commands do you have available?",
options: {
plugins: [{ type: "local", path: pluginPath }],
maxTurns: 3
}
})) {
if (message.type === "system" && message.subtype === "init") {
console.log("Loaded plugins:", message.plugins);
console.log("Available commands:", message.slash_commands);
}
if (message.type === "assistant") {
console.log("Assistant:", message.message.content);
}
}
}
runWithPlugin().catch(console.error);
Python:
#!/usr/bin/env python3
"""Example demonstrating how to use plugins with the Agent SDK."""
from pathlib import Path
import anyio
from claude_agent_sdk import (
AssistantMessage,
ClaudeAgentOptions,
TextBlock,
query,
)
async def run_with_plugin():
"""Example using a custom plugin."""
plugin_path = Path(__file__).parent / "plugins" / "demo-plugin"
print(f"Loading plugin from: {plugin_path}")
options = ClaudeAgentOptions(
plugins=[{"type": "local", "path": str(plugin_path)}],
max_turns=3,
)
async for message in query(
prompt="What custom commands do you have available?", options=options
):
if message.type == "system" and message.subtype == "init":
print(f"Loaded plugins: {message.data.get('plugins')}")
print(f"Available commands: {message.data.get('slash_commands')}")
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(f"Assistant: {block.text}")
if __name__ == "__main__":
anyio.run(run_with_plugin)
Plugin 结构参考
Plugin 目录必须包含 .claude-plugin/plugin.json 清单文件。它可以选择性地包括:
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Required: plugin manifest
├── skills/ # Agent Skills (invoked autonomously or via /skill-name)
│ └── my-skill/
│ └── SKILL.md
├── commands/ # Legacy: use skills/ instead
│ └── custom-cmd.md
├── agents/ # Custom agents
│ └── specialist.md
├── hooks/ # Event handlers
│ └── hooks.json
└── .mcp.json # MCP server definitions
有关创建 plugins 的详细信息,请参阅:
- Plugins - 完整的 plugin 开发指南
- Plugins reference - 技术规范和架构
常见用例
开发和测试
在开发期间加载 plugins,无需全局安装它们:
plugins: [{ type: "local", path: "./dev-plugins/my-plugin" }];
项目特定的扩展
在你的项目存储库中包含 plugins,以实现团队范围的一致性:
plugins: [{ type: "local", path: "./project-plugins/team-workflows" }];
多个 plugin 源
组合来自不同位置的 plugins:
plugins: [
{ type: "local", path: "./local-plugin" },
{ type: "local", path: "~/.claude/custom-plugins/shared-plugin" }
];
故障排除
Plugin 未加载
如果你的 plugin 未出现在初始化消息中:
- 检查路径:确保路径指向 plugin 根目录(包含
.claude-plugin/) - 验证 plugin.json:确保你的清单文件具有有效的 JSON 语法
- 检查文件权限:确保 plugin 目录可读
Skills 未出现
如果 plugin skills 不起作用:
- 使用命名空间:作为 slash commands 调用时,plugin skills 需要
plugin-name:skill-name格式 - 检查初始化消息:验证 skill 是否以正确的命名空间出现在
slash_commands中 - 验证 skill 文件:确保每个 skill 在
skills/下的自己的子目录中都有一个SKILL.md文件(例如,skills/my-skill/SKILL.md)
路径解析问题
如果相对路径不起作用:
- 检查工作目录:相对路径从你的当前工作目录解析
- 使用绝对路径:为了可靠性,考虑使用绝对路径
- 规范化路径:使用路径实用程序正确构造路径
另请参阅
- Plugins - 完整的 plugin 开发指南
- Plugins reference - 技术规范
- Slash Commands - 在 SDK 中使用 slash commands
- Subagents - 使用专门的 agents
- Skills - 使用 Agent Skills
本文翻译自 Anthropic Claude Code 官方文档,最近一次同步:2025-05-01。