Plugins ใน SDK
โหลด custom plugins เพื่อขยาย Claude Code ด้วย skills, agents, hooks และ MCP servers ผ่าน Agent SDK
Plugins ช่วยให้คุณสามารถขยาย Claude Code ด้วยฟังก์ชันการทำงาน custom ที่สามารถแชร์ข้าม projects ได้ ผ่าน Agent SDK คุณสามารถโหลด plugins จาก local directories แบบ programmatic เพื่อเพิ่ม skills, agents, hooks และ MCP servers เข้าใน agent sessions ของคุณ
Plugins คืออะไร?
Plugins เป็น packages ของ Claude Code extensions ที่สามารถรวมถึง:
- Skills: ความสามารถที่ model invoke ซึ่ง Claude ใช้งานโดยอัตโนมัติ (สามารถ invoke ด้วย
/skill-nameได้เช่นกัน) - Agents: Subagents เฉพาะทางสำหรับงานเฉพาะ
- Hooks: Event handlers ที่ตอบสนองต่อการใช้ tool และ events อื่นๆ
- MCP servers: การ integrate เครื่องมือภายนอกผ่าน Model Context Protocol
directory commands/ เป็น format เก่า ให้ใช้ skills/ สำหรับ plugins ใหม่ Claude Code ยังคง support ทั้งสอง formats สำหรับความเข้ากันได้ย้อนหลัง
สำหรับข้อมูลครบถ้วนเกี่ยวกับโครงสร้าง plugin และวิธีสร้าง plugins ดู Plugins
การโหลด Plugins
โหลด plugins โดยให้ local file system paths ในการกำหนด options ของคุณ field type ต้องเป็น "local" ซึ่งเป็นค่าเดียวที่ SDK ยอมรับ เพื่อใช้ plugin ที่แจกจ่ายผ่าน marketplace หรือ remote repository ให้ดาวน์โหลดก่อนและให้ local directory path SDK รองรับการโหลด plugins หลายตัวจาก locations ต่างกัน
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 และ features อื่นๆ พร้อมใช้งานแล้ว
}
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 และ features อื่นๆ พร้อมใช้งานแล้ว
pass
asyncio.run(main())
การระบุ Path
Plugin paths สามารถเป็น:
- Relative paths: Resolved เทียบกับ current working directory ของคุณ (เช่น
"./plugins/my-plugin") - Absolute paths: File system paths แบบเต็ม (เช่น
"/home/user/plugins/my-plugin")
path ควรชี้ไปยัง root directory ของ plugin: parent ของ skills/, agents/, hooks/, commands/ (legacy) หรือ .claude-plugin/ ไม่ใช่ subdirectory
การตรวจสอบการติดตั้ง Plugin
เมื่อ plugins โหลดสำเร็จ จะปรากฏใน system initialization message คุณสามารถตรวจสอบว่า plugins ของคุณพร้อมใช้งาน:
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") {
// ตรวจสอบ plugins ที่โหลด
console.log("Plugins:", message.plugins);
// ตัวอย่าง: [{ name: "my-plugin", path: "./my-plugin" }]
// Plugin skills ปรากฏพร้อม plugin name เป็น prefix
console.log("Skills:", message.skills);
// ตัวอย่าง: ["my-plugin:greet"]
// Plugin commands ใช้ prefix เดียวกัน และ skills ปรากฏที่นี่ด้วย
console.log("Commands:", message.slash_commands);
// ตัวอย่าง: ["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":
# ตรวจสอบ plugins ที่โหลด
print("Plugins:", message.data.get("plugins"))
# ตัวอย่าง: [{"name": "my-plugin", "path": "./my-plugin"}]
# Plugin skills ปรากฏพร้อม plugin name เป็น prefix
print("Skills:", message.data.get("skills"))
# ตัวอย่าง: ["my-plugin:greet"]
# Plugin commands ใช้ prefix เดียวกัน และ skills ปรากฏที่นี่ด้วย
print("Commands:", message.data.get("slash_commands"))
# ตัวอย่าง: ["compact", "context", "my-plugin:custom-command", "my-plugin:greet"]
asyncio.run(main())
การใช้ Plugin Skills
Skills จาก plugins จะถูก namespace โดยอัตโนมัติด้วยชื่อ plugin เพื่อหลีกเลี่ยงการชนกัน เพื่อ invoke โดยตรง ให้ส่ง /plugin-name:skill-name เป็น prompt
import { query } from "@anthropic-ai/claude-agent-sdk";
// โหลด plugin ที่มี custom /greet skill
for await (const message of query({
prompt: "/my-plugin:greet", // ใช้ plugin skill พร้อม namespace
options: {
plugins: [{ type: "local", path: "./my-plugin" }]
}
})) {
// Claude รัน custom greeting skill จาก plugin
if (message.type === "assistant") {
console.log(message.message.content);
}
}
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock
async def main():
# โหลด plugin ที่มี custom /greet skill
async for message in query(
prompt="/demo-plugin:greet", # ใช้ plugin skill พร้อม namespace
options=ClaudeAgentOptions(
plugins=[{"type": "local", "path": "./plugins/demo-plugin"}]
),
):
# Claude รัน custom greeting skill จาก plugin
if isinstance(message, AssistantMessage):
for block in message.content:
if isinstance(block, TextBlock):
print(f"Claude: {block.text}")
asyncio.run(main())
หากคุณติดตั้ง plugin ผ่าน CLI (เช่น /plugin install my-plugin@marketplace) คุณยังคงใช้งานได้ใน SDK โดยให้ installation path ของมัน ตรวจสอบ ~/.claude/plugins/ สำหรับ CLI-installed plugins
ตัวอย่างครบถ้วน
นี่คือตัวอย่างเต็มที่แสดงการโหลดและใช้งาน plugin:
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 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
"""ตัวอย่างแสดงวิธีใช้ plugins กับ Agent SDK"""
from pathlib import Path
import anyio
from claude_agent_sdk import (
AssistantMessage,
ClaudeAgentOptions,
SystemMessage,
TextBlock,
query,
)
async def run_with_plugin():
"""ตัวอย่างการใช้ 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 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__":
anyio.run(run_with_plugin)
Plugin Structure Reference
Plugin directory มักประกอบด้วยไฟล์ manifest .claude-plugin/plugin.json manifest เป็น optional เมื่อไม่ระบุ Claude Code จะค้นพบ components โดยอัตโนมัติจาก directory layout:
my-plugin/
├── .claude-plugin/
│ └── plugin.json # Plugin manifest (optional)
├── skills/ # Agent Skills
│ └── my-skill/
│ └── SKILL.md
├── commands/ # Legacy: ใช้ skills/ แทน
│ └── custom-cmd.md
├── agents/ # Custom agents
│ └── specialist.md
├── hooks/ # Event handlers
│ └── hooks.json
└── .mcp.json # MCP server definitions
สำหรับข้อมูลรายละเอียดในการสร้าง plugins ดู:
- Plugins - คู่มือพัฒนา plugin ครบถ้วน
- Plugins reference - ข้อกำหนดทางเทคนิคและ schemas
Use Cases ทั่วไป
การพัฒนาและทดสอบ
โหลด plugins ระหว่างการพัฒนาโดยไม่ต้องติดตั้ง globally:
plugins: [{ type: "local", path: "./dev-plugins/my-plugin" }];
Extensions เฉพาะ Project
รวม plugins ใน project repository ของคุณเพื่อความสอดคล้องทั่วทีม:
plugins: [{ type: "local", path: "./project-plugins/team-workflows" }];
หลาย Plugin Sources
รวม plugins จาก locations ต่างกัน:
plugins: [
{ type: "local", path: "./local-plugin" },
{ type: "local", path: "~/.claude/custom-plugins/shared-plugin" }
];
การแก้ไขปัญหา
Plugin ไม่โหลด
หาก plugin ของคุณไม่ปรากฏใน init message:
- ตรวจสอบ path: ให้แน่ใจว่า path ชี้ไปยัง root directory ของ plugin ซึ่งเป็น parent ของ
skills/,agents/,hooks/,commands/(legacy) หรือ.claude-plugin/ - Validate plugin.json: หาก plugin ของคุณมี manifest ให้ตรวจสอบว่ามี JSON syntax ที่ถูกต้อง
- ตรวจสอบ file permissions: ให้แน่ใจว่า plugin directory อ่านได้
Skills ไม่ปรากฏ
หาก plugin skills ไม่ทำงาน:
- ใช้ namespace: invoke plugin skills เป็น
/plugin-name:skill-name - ตรวจสอบ init message: ยืนยันว่า skill ปรากฏใน list
skillsพร้อม namespace ที่ถูกต้อง - Validate skill files: ให้แน่ใจว่า skill แต่ละอันมีไฟล์
SKILL.mdใน subdirectory ของตัวเองภายใต้skills/เช่นskills/my-skill/SKILL.md
ปัญหา Path Resolution
หาก relative paths ไม่ทำงาน:
- ตรวจสอบ working directory: Relative paths ถูก resolved จาก current working directory ของคุณ
- ใช้ absolute paths: เพื่อความน่าเชื่อถือ ให้พิจารณาใช้ absolute paths
- Normalize paths: ใช้ path utilities เพื่อสร้าง paths อย่างถูกต้อง
ดูเพิ่มเติม
- Plugins - คู่มือพัฒนา plugin ครบถ้วน
- Plugins reference - ข้อกำหนดทางเทคนิค
- Commands - การใช้ commands ใน SDK
- Subagents - การทำงานกับ specialized agents
- Skills - การใช้ Agent Skills