תיעוד 184
תוספים ב-SDK
טען תוספים מותאמים אישית כדי להרחיב את Claude Code עם skills, agents, hooks ושרתי MCP דרך Agent SDK
תוספים מאפשרים להרחיב את Claude Code עם פונקציונליות מותאמת אישית שאפשר לשתף בין פרויקטים. דרך Agent SDK אפשר לטעון תוספים באופן תכנותי מתיקיות מקומיות כדי להוסיף יכולות לסשנים של הסוכן. תוסף יכול לכלול:
- Skills: יכולות ש-Claude מפעיל באופן עצמאי כשהן רלוונטיות. אפשר גם להפעיל skill של תוסף ישירות עם
/plugin-name:skill-name. - Agents: תת-סוכנים מתמחים למשימות מסוימות
- Hooks: מטפלי אירועים שמגיבים לשימוש בכלים ולאירועים אחרים
- שרתי MCP: שילובי כלים חיצוניים דרך Model Context Protocol
למידע מלא על מבנה תוסף ואיך ליצור תוספים, ראה תוספים.
#טעינת תוספים
טען תוספים על ידי אספקת נתיבי מערכת הקבצים המקומית שלהם בהגדרות האפשרויות. השדה type חייב להיות "local", הערך היחיד שה-SDK מקבל. ה-SDK תומך בטעינת כמה תוספים ממיקומים שונים.
כדי להשתמש בתוסף שמופץ דרך marketplace או מאגר מרוחק, הורד אותו קודם וספק את נתיב התיקייה המקומית. למבנה התיקיות שתוסף צריך, ראה את הפניה למבנה תוסף למטה.
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
}import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions
async def main():
async for message in query(
prompt="Hello",
options=ClaudeAgentOptions(
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())#מפרטי נתיב
נתיבי תוספים יכולים להיות:
- נתיבים יחסיים: נפתרים יחסית לאפשרות
cwd(לדוגמה,"./plugins/my-plugin") - נתיבים מוחלטים: נתיבי מערכת קבצים מלאים (לדוגמה,
"/home/user/plugins/my-plugin")
הערה
הנתיב צריך להצביע לתיקיית השורש של התוסף: ההורה של
skills/,agents/,hooks/,commands/או.claude-plugin/.
#טעינה מחדש של תוספים בסשן פעיל
כדי להחיל שינוי על skills, commands, agents או hooks של תוסף בלי להתחיל סשן חדש, קרא ל-reloadPlugins() על אובייקט Query של TypeScript SDK. Python SDK לא חושף מתודה מקבילה. שלח /reload-plugins כ-prompt בסשן במקום זאת.
#הוספת תוספים לסשן פעיל
ב-TypeScript SDK, קרא ל-reloadPlugins() על אובייקט Query ש-query() החזיר, וציין את תיקיית התוסף באפשרות addPlugins של אותה קריאה. כל רשומה ב-addPlugins היא אובייקט { type: "local", path } עם path מוחלט. נדרש TypeScript Agent SDK מגרסה v0.3.301 ואילך.
בדוגמה הזו, q הוא אובייקט Query ש-query() החזיר. הדוגמה מוסיפה תיקיית תוסף אחת לסשן הפעיל, ואחרי ש-reloadPlugins() חוזר, מדפיסה את הנתיב של כל תוסף בסשן:
const result = await q.reloadPlugins({
addPlugins: [{ type: "local", path: "/home/user/plugins/another-plugin" }]
});
console.log(result.plugins.map((plugin) => plugin.path));אם התוסף נטען, הרשימה המודפסת כוללת את /home/user/plugins/another-plugin. אם הנתיב הזה חסר מהרשימה, או ש-reloadPlugins() נדחה, ראה כש-reloadPlugins() לא טוען את תיקיות addPlugins לסיבות.
#אימות התקנת תוסף
כשתוספים נטענים בהצלחה, הם מופיעים בהודעת האתחול של המערכת. אפשר לוודא שהתוספים זמינים:
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: "/absolute/path/to/my-plugin" }]
// Plugin skills appear with the plugin name as a prefix
console.log("Skills:", message.skills);
// Example: ["my-plugin:greet"]
// Plugin commands use the same prefix, and skills appear here too
console.log("Commands:", message.slash_commands);
// Example: ["compact", "context", "my-plugin:custom-command", "my-plugin:greet"]
}
}import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, SystemMessage
async def main():
async for message in query(
prompt="Hello",
options=ClaudeAgentOptions(
plugins=[{"type": "local", "path": "./my-plugin"}]
),
):
if isinstance(message, SystemMessage) and message.subtype == "init":
# Check loaded plugins
print("Plugins:", message.data.get("plugins"))
# Example: [{"name": "my-plugin", "path": "/absolute/path/to/my-plugin"}]
# Plugin skills appear with the plugin name as a prefix
print("Skills:", message.data.get("skills"))
# Example: ["my-plugin:greet"]
# Plugin commands use the same prefix, and skills appear here too
print("Commands:", message.data.get("slash_commands"))
# Example: ["compact", "context", "my-plugin:custom-command", "my-plugin:greet"]
asyncio.run(main())#שימוש ב-skills של תוסף
Skills מתוספים מקבלים אוטומטית namespace עם שם התוסף כדי למנוע התנגשויות. כדי להפעיל אחד ישירות, שלח /plugin-name:skill-name כ-prompt.
import { query } from "@anthropic-ai/claude-agent-sdk";
// Load a plugin with a custom /greet skill
for await (const message of query({
prompt: "/my-plugin:greet", // Use plugin skill with namespace
options: {
plugins: [{ type: "local", path: "./my-plugin" }]
}
})) {
// Claude executes the custom greeting skill from the plugin
if (message.type === "assistant") {
console.log(message.message.content);
}
}import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock
async def main():
# Load a plugin with a custom /greet skill
async for message in query(
prompt="/my-plugin:greet", # Use plugin skill with namespace
options=ClaudeAgentOptions(
plugins=[{"type": "local", "path": "./my-plugin"}]
),
):
# Claude executes the custom greeting skill from the plugin
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(f"Claude: {block.text}")
asyncio.run(main())הערה
אם התקנת תוסף דרך ה-CLI (לדוגמה,
/plugin install my-plugin@marketplace), עדיין אפשר להשתמש בו ב-SDK על ידי אספקת נתיב ההתקנה שלו. בדוק את~/.claude/plugins/לתוספים שהותקנו דרך CLI.
#דוגמה מלאה
הנה דוגמה מלאה שמדגימה טעינת תוסף ושימוש בו:
import { query } from "@anthropic-ai/claude-agent-sdk";
import { fileURLToPath } from "node:url";
async function runWithPlugin() {
const pluginPath = fileURLToPath(new URL("./plugins/my-plugin", import.meta.url));
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 skills:", message.skills);
console.log("Available commands:", message.slash_commands);
}
if (message.type === "assistant") {
console.log("Assistant:", message.message.content);
}
}
}
runWithPlugin().catch(console.error);#!/usr/bin/env python3
"""Example demonstrating how to use plugins with the Agent SDK."""
import asyncio
from pathlib import Path
from claude_agent_sdk import (
AssistantMessage,
ClaudeAgentOptions,
SystemMessage,
TextBlock,
query,
)
async def run_with_plugin():
"""Example using a custom plugin."""
plugin_path = Path(__file__).parent / "plugins" / "my-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 isinstance(message, SystemMessage) and message.subtype == "init":
print(f"Loaded plugins: {message.data.get('plugins')}")
print(f"Available skills: {message.data.get('skills')}")
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__":
asyncio.run(run_with_plugin())#הפניה למבנה תוסף
תיקיית תוסף מכילה בדרך כלל קובץ מניפסט .claude-plugin/plugin.json. המניפסט אופציונלי. כשהוא מושמט, Claude Code מגלה רכיבים אוטומטית ממבנה התיקיות. התיקייה יכולה לכלול:
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Plugin manifest (optional, components auto-discovered without it)
├── skills/ # Agent Skills (invoked autonomously or via /plugin-name:skill-name)
│ └── my-skill/
│ └── SKILL.md
├── commands/ # Skills as flat .md files
│ └── custom-cmd.md
├── agents/ # Custom agents
│ └── specialist.md
├── hooks/ # Event handlers
│ └── hooks.json
└── .mcp.json # MCP server definitionsהערה
התיקייה
commands/מחזיקה skills כקבצי Markdown שטוחים. השתמש ב-skills/לתוספים חדשים. Claude Code תומך בשני המיקומים.
#מקורות מרובים לתוספים
שלב תוספים ממיקומים שונים:
import * as os from "node:os";
import * as path from "node:path";
plugins: [
{ type: "local", path: "./local-plugin" },
{
type: "local",
path: path.join(os.homedir(), ".claude", "custom-plugins", "shared-plugin")
}
];הערה
ה-SDK לא מרחיב נתיבי tilde כמו
~/plugins. אם נתיב תוסף לא קיים, ה-SDK מדלג על התוסף והסשן ממשיך, אז בדוק את רשימתpluginsבהודעת init כדי לאשר שכל תוסף נטען.
#פתרון בעיות
#תוסף לא נטען
אם התוסף לא מופיע ברשימת plugins של הודעת init, בדוק את השדה plugin_errors שלו לסיבה, ואז עבור על הבדיקות האלה:
- בדוק את הנתיב: ודא שהנתיב מצביע לתיקיית השורש של התוסף, ההורה של
skills/,agents/,hooks/,commands/או.claude-plugin/ - אמת את plugin.json: אם התוסף כולל מניפסט, ודא שיש לו תחביר JSON תקין
- בדוק הרשאות קבצים: ודא שתיקיית התוסף ניתנת לקריאה
- אשר שהתיקייה קיימת: ה-SDK מדלג על נתיב שלא קיים, והתוסף לא מופיע ברשימת
pluginsשל הודעת init
#Skills לא מופיעים
אם skills של תוסף לא עובדים:
- השתמש ב-namespace: הפעל skills של תוסף כ-
/plugin-name:skill-name - בדוק את הודעת init: ודא שה-skill מופיע ברשימת
skillsעם ה-namespace הנכון - אמת קבצי skill: ודא שלכל skill יש קובץ
SKILL.mdבתת-תיקייה משלו תחתskills/, לדוגמהskills/my-skill/SKILL.md
#ראה גם
- תוספים: מדריך מלא לפיתוח תוספים
- הפניה לתוספים: מפרטים טכניים
- פקודות: שיגור פקודות ב-SDK
- תת-סוכנים: עבודה עם סוכנים מתמחים
- Skills: שימוש ב-Agent Skills