رفتن به محتوا

ساب‌ایجنت‌ها در SDK

ساب‌ایجنت‌ها نمونه‌های ایجنتِ جداگانه‌ای هستند که ایجنتِ اصلیِ تو می‌تواند برای انجامِ زیرکارهای متمرکز آن‌ها را راه‌اندازی کند. از ساب‌ایجنت‌ها استفاده کن تا کانتکست را برای زیرکارهای متمرکز ایزوله کنی، چند تحلیل را موازی اجرا کنی، و دستورهای تخصصی را بدون اضافه‌کردن به پرامپتِ ایجنت اصلی اعمال کنی.

این راهنما توضیح می‌دهد که چطور با استفاده از پارامتر agents ساب‌ایجنت‌ها را در SDK تعریف و استفاده کنی.

می‌توانی ساب‌ایجنت‌ها را به سه روش بسازی:

  • به‌صورت برنامه‌نویسی‌شده: از پارامتر agents در گزینه‌های query() استفاده کن (TypeScript، Python)
  • مبتنی بر فایل‌سیستم: ایجنت‌ها را به‌صورت فایل‌های markdown در دایرکتوری‌های .claude/agents/ تعریف کن (به تعریف ساب‌ایجنت‌ها به‌صورت فایل نگاه کن)
  • همه‌منظوره‌ی داخلی: Claude می‌تواند هر زمان ساب‌ایجنتِ داخلیِ general-purpose را از طریق ابزار Agent فراخوانی کند، بدون اینکه چیزی تعریف کنی

این راهنما روی رویکردِ برنامه‌نویسی‌شده تمرکز دارد که برای اپلیکیشن‌های SDK توصیه می‌شود.

وقتی ساب‌ایجنت‌ها را تعریف می‌کنی، Claude بر اساس فیلد descriptionِ هر ساب‌ایجنت تصمیم می‌گیرد آن را فراخوانی کند یا نه. توصیف‌های روشنی بنویس که توضیح می‌دهند ساب‌ایجنت کِی باید استفاده شود، و Claude به‌طور خودکار کارهای مناسب را واگذار می‌کند. همچنین می‌توانی در پرامپتت صریحاً یک ساب‌ایجنت را با نام درخواست کنی (برای مثال، «از ایجنت code-reviewer استفاده کن تا…»).

مزایای استفاده از ساب‌ایجنت‌ها

Section titled “مزایای استفاده از ساب‌ایجنت‌ها”

هر ساب‌ایجنت در مکالمه‌ی تازه‌ی خودش اجرا می‌شود. فراخوانی‌ها و نتایجِ میانیِ ابزار درون ساب‌ایجنت می‌مانند؛ فقط پیامِ نهایی‌اش به والد برمی‌گردد. برای اینکه دقیقاً ببینی چه چیزی در کانتکستِ ساب‌ایجنت هست، به ساب‌ایجنت چه چیزی به ارث می‌برد نگاه کن.

مثال: یک ساب‌ایجنتِ research-assistant می‌تواند ده‌ها فایل را بررسی کند بدون اینکه هیچ‌کدام از آن محتوا در مکالمه‌ی اصلی انباشته شود. والد یک خلاصه‌ی فشرده دریافت می‌کند، نه هر فایلی که ساب‌ایجنت خوانده است.

چند ساب‌ایجنت می‌توانند هم‌زمان اجرا شوند، پس زیرکارهای مستقل در زمانِ کندترین آن‌ها تمام می‌شوند، نه در مجموعِ زمانِ همه‌شان.

مثال: در حین یک بازبینیِ کد، می‌توانی ساب‌ایجنت‌های style-checker، security-scanner و test-coverage را به‌جای پشت‌سرهم، هم‌زمان اجرا کنی.

هر ساب‌ایجنت می‌تواند پرامپت‌های سیستمیِ سفارشی با تخصص، بهترین شیوه‌ها و قیدهای مشخص داشته باشد.

مثال: یک ساب‌ایجنتِ database-migration می‌تواند دانشِ مفصلی درباره‌ی بهترین شیوه‌های SQL، راهبردهای rollback و بررسی‌های یکپارچگیِ داده داشته باشد که در دستورهای ایجنت اصلی صرفاً نویزِ غیرضروری خواهد بود.

ساب‌ایجنت‌ها را می‌توان به ابزارهای مشخصی محدود کرد و این ریسکِ اقدامات ناخواسته را کاهش می‌دهد.

مثال: یک ساب‌ایجنتِ doc-reviewer ممکن است فقط به ابزارهای Read و Grep دسترسی داشته باشد، که تضمین می‌کند می‌تواند تحلیل کند اما هرگز به‌طور تصادفی فایل‌های مستنداتت را تغییر نمی‌دهد.

تعریف برنامه‌نویسی‌شده (توصیه‌شده)

Section titled “تعریف برنامه‌نویسی‌شده (توصیه‌شده)”

ساب‌ایجنت‌ها را مستقیماً در کدت با استفاده از پارامتر agents تعریف کن. این مثال دو ساب‌ایجنت می‌سازد: یک بازبینِ کد با دسترسیِ فقط‌خواندنی و یک اجراکننده‌ی تست که می‌تواند دستورها را اجرا کند. Claude ساب‌ایجنت‌ها را از طریق ابزار Agent فراخوانی می‌کند، پس Agent را در allowedTools بگنجان تا فراخوانی‌های ساب‌ایجنت بدون درخواستِ مجوز خودکار تأیید شوند.

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
async def main():
async for message in query(
prompt="Review the authentication module for security issues",
options=ClaudeAgentOptions(
# Auto-approve these tools, including Agent for subagent invocation
allowed_tools=["Read", "Grep", "Glob", "Agent"],
agents={
"code-reviewer": AgentDefinition(
# description tells Claude when to use this subagent
description="Expert code review specialist. Use for quality, security, and maintainability reviews.",
# prompt defines the subagent's behavior and expertise
prompt="""You are a code review specialist with expertise in security, performance, and best practices.
When reviewing code:
- Identify security vulnerabilities
- Check for performance issues
- Verify adherence to coding standards
- Suggest specific improvements
Be thorough but concise in your feedback.""",
# tools restricts what the subagent can do (read-only here)
tools=["Read", "Grep", "Glob"],
# model overrides the default model for this subagent
model="sonnet",
),
"test-runner": AgentDefinition(
description="Runs and analyzes test suites. Use for test execution and coverage analysis.",
prompt="""You are a test execution specialist. Run tests and provide clear analysis of results.
Focus on:
- Running test commands
- Analyzing test output
- Identifying failing tests
- Suggesting fixes for failures""",
# Bash access lets this subagent run test commands
tools=["Bash", "Read", "Grep"],
),
},
),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Review the authentication module for security issues",
options: {
// Auto-approve these tools, including Agent for subagent invocation
allowedTools: ["Read", "Grep", "Glob", "Agent"],
agents: {
"code-reviewer": {
// description tells Claude when to use this subagent
description:
"Expert code review specialist. Use for quality, security, and maintainability reviews.",
// prompt defines the subagent's behavior and expertise
prompt: `You are a code review specialist with expertise in security, performance, and best practices.
When reviewing code:
- Identify security vulnerabilities
- Check for performance issues
- Verify adherence to coding standards
- Suggest specific improvements
Be thorough but concise in your feedback.`,
// tools restricts what the subagent can do (read-only here)
tools: ["Read", "Grep", "Glob"],
// model overrides the default model for this subagent
model: "sonnet"
},
"test-runner": {
description:
"Runs and analyzes test suites. Use for test execution and coverage analysis.",
prompt: `You are a test execution specialist. Run tests and provide clear analysis of results.
Focus on:
- Running test commands
- Analyzing test output
- Identifying failing tests
- Suggesting fixes for failures`,
// Bash access lets this subagent run test commands
tools: ["Bash", "Read", "Grep"]
}
}
}
})) {
if ("result" in message) console.log(message.result);
}
فیلدنوعالزامیتوضیح
descriptionstringبلهتوصیفِ زبانِ طبیعی از اینکه این ایجنت کِی استفاده شود
promptstringبلهپرامپتِ سیستمیِ ایجنت که نقش و رفتارش را تعریف می‌کند
toolsstring[]خیرآرایه‌ای از نام ابزارهای مجاز. اگر حذف شود، همه‌ی ابزارها را به ارث می‌برد
disallowedToolsstring[]خیرآرایه‌ای از نام ابزارهایی که باید از مجموعه‌ی ابزارهای ایجنت حذف شوند
modelstringخیربازنویسیِ مدل برای این ایجنت. یک alias مثل 'fable'، 'opus'، 'sonnet'، 'haiku'، 'inherit' یا یک شناسه‌ی کاملِ مدل را می‌پذیرد. اگر حذف شود، پیش‌فرض مدلِ اصلی است
skillsstring[]خیرفهرستی از نام Skillها که هنگام شروع در کانتکستِ ایجنت پیش‌بارگذاری شوند. Skillهای فهرست‌نشده همچنان از طریق ابزار Skill قابلِ فراخوانی‌اند
memory'user' | 'project' | 'local'خیرمنبعِ حافظه برای این ایجنت
mcpServers(string | object)[]خیرسرورهای MCPِ در دسترسِ این ایجنت، با نام یا پیکربندیِ درون‌خطی
initialPromptstringخیروقتی این ایجنت به‌عنوان ایجنتِ نخِ اصلی اجرا شود، به‌صورت خودکار به‌عنوان اولین نوبتِ کاربر ارسال می‌شود. وقتی ایجنت به‌عنوان ساب‌ایجنت فراخوانی شود نادیده گرفته می‌شود
maxTurnsnumberخیربیشینه‌ی تعداد نوبت‌های ایجنتیک پیش از توقفِ ایجنت
backgroundbooleanخیرهنگام فراخوانی، این ایجنت را به‌عنوان یک تسکِ پس‌زمینه‌ی غیرمسدودکننده اجرا کن
effort'low' | 'medium' | 'high' | 'xhigh' | 'max' | numberخیرسطحِ تلاشِ استدلال (reasoning effort) برای این ایجنت
permissionModePermissionModeخیرحالتِ مجوز برای اجرای ابزار درون این ایجنت

در Python SDK، این نام‌های فیلد برای تطابق با قالبِ سیمی (wire format) از camelCase استفاده می‌کنند. برای جزئیات به مرجع AgentDefinition نگاه کن.

تعریف مبتنی بر فایل‌سیستم (روش جایگزین)

Section titled “تعریف مبتنی بر فایل‌سیستم (روش جایگزین)”

همچنین می‌توانی ساب‌ایجنت‌ها را به‌صورت فایل‌های markdown در دایرکتوری‌های .claude/agents/ تعریف کنی. برای جزئیاتِ این رویکرد به مستندات ساب‌ایجنت‌های Claude Code نگاه کن. ایجنت‌های تعریف‌شده به‌صورت برنامه‌نویسی‌شده بر ایجنت‌های مبتنی بر فایل‌سیستم با نام یکسان اولویت دارند.

ساب‌ایجنت چه چیزی به ارث می‌برد

Section titled “ساب‌ایجنت چه چیزی به ارث می‌برد”

پنجره‌ی کانتکستِ یک ساب‌ایجنت تازه شروع می‌شود (بدون مکالمه‌ی والد) اما خالی نیست. تنها کانالِ والد به ساب‌ایجنت، رشته‌ی پرامپتِ ابزار Agent است، پس هر مسیر فایل، پیام خطا یا تصمیمی را که ساب‌ایجنت نیاز دارد مستقیماً در همان پرامپت بگنجان.

ساب‌ایجنت دریافت می‌کندساب‌ایجنت دریافت نمی‌کند
پرامپتِ سیستمیِ خودش (AgentDefinition.prompt) و پرامپتِ ابزار Agentتاریخچه‌ی مکالمه یا نتایجِ ابزارِ والد
CLAUDE.mdِ پروژه (که از طریق settingSources بارگذاری می‌شود)محتوای Skillِ پیش‌بارگذاری‌شده، مگر اینکه در AgentDefinition.skills فهرست شده باشد
تعاریفِ ابزار (از والد به ارث‌رسیده، یا زیرمجموعه‌ی موجود در tools)پرامپتِ سیستمیِ والد

فراخوانی ساب‌ایجنت‌ها

Section titled “فراخوانی ساب‌ایجنت‌ها”

Claude به‌طور خودکار بر اساس کار و descriptionِ هر ساب‌ایجنت تصمیم می‌گیرد کِی آن را فراخوانی کند. برای مثال، اگر یک ساب‌ایجنتِ performance-optimizer با توصیفِ «متخصصِ بهینه‌سازیِ عملکرد برای تنظیمِ کوئری» تعریف کنی، Claude وقتی پرامپتت به بهینه‌سازیِ کوئری‌ها اشاره کند آن را فراخوانی می‌کند.

توصیف‌های روشن و مشخص بنویس تا Claude بتواند کارها را با ساب‌ایجنتِ درست تطبیق دهد.

برای اینکه مطمئن شوی Claude از یک ساب‌ایجنتِ مشخص استفاده می‌کند، آن را با نام در پرامپتت ذکر کن:

"Use the code-reviewer agent to check the authentication module"

این کار تطبیقِ خودکار را دور می‌زند و مستقیماً ساب‌ایجنتِ نام‌برده را فراخوانی می‌کند.

می‌توانی تعاریفِ ایجنت را به‌صورت پویا بر اساس شرایطِ زمانِ اجرا بسازی. این مثال یک بازبینِ امنیتی با سطوحِ سخت‌گیریِ مختلف می‌سازد و برای بازبینی‌های سخت‌گیرانه از یک مدلِ قوی‌تر استفاده می‌کند.

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
# Factory function that returns an AgentDefinition
# This pattern lets you customize agents based on runtime conditions
def create_security_agent(security_level: str) -> AgentDefinition:
is_strict = security_level == "strict"
return AgentDefinition(
description="Security code reviewer",
# Customize the prompt based on strictness level
prompt=f"You are a {'strict' if is_strict else 'balanced'} security reviewer...",
tools=["Read", "Grep", "Glob"],
# Key insight: use a more capable model for high-stakes reviews
model="opus" if is_strict else "sonnet",
)
async def main():
# The agent is created at query time, so each request can use different settings
async for message in query(
prompt="Review this PR for security issues",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "Glob", "Agent"],
agents={
# Call the factory with your desired configuration
"security-reviewer": create_security_agent("strict")
},
),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
import { query, type AgentDefinition } from "@anthropic-ai/claude-agent-sdk";
// Factory function that returns an AgentDefinition
// This pattern lets you customize agents based on runtime conditions
function createSecurityAgent(securityLevel: "basic" | "strict"): AgentDefinition {
const isStrict = securityLevel === "strict";
return {
description: "Security code reviewer",
// Customize the prompt based on strictness level
prompt: `You are a ${isStrict ? "strict" : "balanced"} security reviewer...`,
tools: ["Read", "Grep", "Glob"],
// Key insight: use a more capable model for high-stakes reviews
model: isStrict ? "opus" : "sonnet"
};
}
// The agent is created at query time, so each request can use different settings
for await (const message of query({
prompt: "Review this PR for security issues",
options: {
allowedTools: ["Read", "Grep", "Glob", "Agent"],
agents: {
// Call the factory with your desired configuration
"security-reviewer": createSecurityAgent("strict")
}
}
})) {
if ("result" in message) console.log(message.result);
}

تشخیص فراخوانی ساب‌ایجنت

Section titled “تشخیص فراخوانی ساب‌ایجنت”

ساب‌ایجنت‌ها از طریق ابزار Agent فراخوانی می‌شوند. برای تشخیصِ اینکه چه زمانی یک ساب‌ایجنت فراخوانی می‌شود، به‌دنبالِ بلاک‌های tool_use بگرد که در آن‌ها name برابرِ "Agent" است. پیام‌هایی که از درونِ کانتکستِ یک ساب‌ایجنت می‌آیند یک فیلد parent_tool_use_id دارند.

ساختارِ پیام بین SDKها متفاوت است. در Python، بلاک‌های محتوا مستقیماً از طریق message.content در دسترس‌اند. در TypeScript، SDKAssistantMessage پیامِ Claude API را در خود می‌پیچد، پس محتوا از طریق message.message.content در دسترس است.

این مثال روی پیام‌های استریم‌شده پیمایش می‌کند و زمانی که یک ساب‌ایجنت فراخوانی می‌شود و زمانی که پیام‌های بعدی از درونِ کانتکستِ اجرای آن ساب‌ایجنت می‌آیند، آن را لاگ می‌کند.

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ToolUseBlock
async def main():
async for message in query(
prompt="Use the code-reviewer agent to review this codebase",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Glob", "Grep", "Agent"],
agents={
"code-reviewer": AgentDefinition(
description="Expert code reviewer.",
prompt="Analyze code quality and suggest improvements.",
tools=["Read", "Glob", "Grep"],
)
},
),
):
# Check for subagent invocation. Match both names: older SDK
# versions emitted "Task", current versions emit "Agent".
if hasattr(message, "content") and message.content:
for block in message.content:
if isinstance(block, ToolUseBlock) and block.name in (
"Task",
"Agent",
):
print(f"Subagent invoked: {block.input.get('subagent_type')}")
# Check if this message is from within a subagent's context
if hasattr(message, "parent_tool_use_id") and message.parent_tool_use_id:
print(" (running inside subagent)")
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Use the code-reviewer agent to review this codebase",
options: {
allowedTools: ["Read", "Glob", "Grep", "Agent"],
agents: {
"code-reviewer": {
description: "Expert code reviewer.",
prompt: "Analyze code quality and suggest improvements.",
tools: ["Read", "Glob", "Grep"]
}
}
}
})) {
const msg = message as any;
// Check for subagent invocation. Match both names: older SDK versions
// emitted "Task", current versions emit "Agent".
for (const block of msg.message?.content ?? []) {
if (block.type === "tool_use" && (block.name === "Task" || block.name === "Agent")) {
console.log(`Subagent invoked: ${block.input.subagent_type}`);
}
}
// Check if this message is from within a subagent's context
if (msg.parent_tool_use_id) {
console.log(" (running inside subagent)");
}
if ("result" in message) {
console.log(message.result);
}
}

ازسرگیری ساب‌ایجنت‌ها

Section titled “ازسرگیری ساب‌ایجنت‌ها”

ساب‌ایجنت‌ها را می‌توان از سر گرفت تا از همان‌جایی که متوقف شدند ادامه بدهند. ساب‌ایجنت‌های ازسرگرفته‌شده کلِ تاریخچه‌ی مکالمه‌شان را، شامل همه‌ی فراخوانی‌های ابزار، نتایج و استدلال‌های قبلی، حفظ می‌کنند. ساب‌ایجنت دقیقاً از همان‌جایی که متوقف شد ادامه می‌دهد، نه از نو.

وقتی یک ساب‌ایجنت تمام می‌شود، نتیجه‌ی ابزار Agent شامل یک بلاکِ متنی است که agentId: <id> را در بر دارد. ایجنت‌های داخلیِ Explore و Plan تک‌مرحله‌ای (one-shot) هستند و agentId برنمی‌گردانند، پس وقتی نیاز به ازسرگیری داری از یک ایجنت سفارشی یا general-purpose استفاده کن. برای ازسرگیریِ یک ساب‌ایجنت به‌صورت برنامه‌نویسی‌شده:

  1. شناسه‌ی نشست را بردار: session_id را از پیام‌های اولین کوئری استخراج کن
  2. شناسه‌ی ایجنت را استخراج کن: agentId را از متنِ نتیجه‌ی ابزار Agent تجزیه کن
  3. نشست را از سر بگیر: در گزینه‌های کوئریِ دوم resume: sessionId را پاس بده و شناسه‌ی ایجنت را در پرامپتت بگنجان

مثال زیر یک ایجنتِ سفارشیِ endpoint-finder تعریف می‌کند. کوئریِ اول آن را اجرا می‌کند و شناسه‌ی نشست و شناسه‌ی ایجنت را از نتیجه‌ی ابزار Agent برمی‌دارد، سپس کوئریِ دوم نشست را از سر می‌گیرد تا سؤالِ پیگیری‌ای بپرسد که به کانتکستِ تحلیلِ اول نیاز دارد.

import asyncio
import re
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition, ToolResultBlock
AGENTS = {
"endpoint-finder": AgentDefinition(
description="Locates and catalogs API endpoints in a codebase.",
prompt="You find and document API endpoints. Report each endpoint's path, method, and handler.",
tools=["Read", "Grep", "Glob"],
)
}
def extract_agent_id(block: ToolResultBlock) -> str | None:
"""Extract agentId from an Agent tool result's text content."""
parts = block.content if isinstance(block.content, list) else [{"text": block.content}]
for part in parts:
if match := re.search(r"agentId:\s*([\w-]+)", part.get("text") or ""):
return match.group(1)
return None
async def main():
agent_id = None
session_id = None
# First invocation - run the endpoint-finder subagent
async for message in query(
prompt="Use the endpoint-finder agent to find all API endpoints in this codebase",
options=ClaudeAgentOptions(allowed_tools=["Read", "Grep", "Glob", "Agent"], agents=AGENTS),
):
# Capture session_id from ResultMessage (needed to resume this session)
if hasattr(message, "session_id"):
session_id = message.session_id
# Search tool results for the agentId trailer
for block in getattr(message, "content", None) or []:
if isinstance(block, ToolResultBlock):
agent_id = extract_agent_id(block) or agent_id
# Print the final result
if hasattr(message, "result"):
print(message.result)
# Second invocation - resume and ask follow-up
if agent_id and session_id:
async for message in query(
prompt=f"Resume agent {agent_id} and list the top 3 most complex endpoints",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "Glob", "Agent"], agents=AGENTS, resume=session_id
),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
import { query, type SDKMessage } from "@anthropic-ai/claude-agent-sdk";
const agents = {
"endpoint-finder": {
description: "Locates and catalogs API endpoints in a codebase.",
prompt: "You find and document API endpoints. Report each endpoint's path, method, and handler.",
tools: ["Read", "Grep", "Glob"]
}
};
// Stringify content to search for agentId without traversing nested block types
function extractAgentId(message: SDKMessage): string | undefined {
if (message.type !== "assistant" && message.type !== "user") return undefined;
const content = JSON.stringify(message.message.content);
const match = content.match(/agentId:\s*([\w-]+)/);
return match?.[1];
}
let agentId: string | undefined;
let sessionId: string | undefined;
// First invocation - run the endpoint-finder subagent
for await (const message of query({
prompt: "Use the endpoint-finder agent to find all API endpoints in this codebase",
options: { allowedTools: ["Read", "Grep", "Glob", "Agent"], agents }
})) {
// Capture session_id from ResultMessage (needed to resume this session)
if ("session_id" in message) sessionId = message.session_id;
// Search message content for the agentId (appears in Agent tool results)
const extractedId = extractAgentId(message);
if (extractedId) agentId = extractedId;
// Print the final result
if ("result" in message) console.log(message.result);
}
// Second invocation - resume and ask follow-up
if (agentId && sessionId) {
for await (const message of query({
prompt: `Resume agent ${agentId} and list the top 3 most complex endpoints`,
options: { allowedTools: ["Read", "Grep", "Glob", "Agent"], agents, resume: sessionId }
})) {
if ("result" in message) console.log(message.result);
}
}

رونوشت‌های ساب‌ایجنت مستقل از مکالمه‌ی اصلی پایدار می‌مانند:

  • فشرده‌سازیِ مکالمه‌ی اصلی: وقتی مکالمه‌ی اصلی فشرده می‌شود، رونوشت‌های ساب‌ایجنت تحت‌تأثیر قرار نمی‌گیرند. آن‌ها در فایل‌های جداگانه ذخیره می‌شوند.
  • پایداریِ نشست: رونوشت‌های ساب‌ایجنت در درون نشستشان پایدار می‌مانند. می‌توانی پس از راه‌اندازیِ مجددِ Claude Code با ازسرگیریِ همان نشست، یک ساب‌ایجنت را از سر بگیری.
  • پاک‌سازیِ خودکار: رونوشت‌ها بر اساس تنظیمِ cleanupPeriodDays (پیش‌فرض: ۳۰ روز) پاک می‌شوند.

ساب‌ایجنت‌ها می‌توانند از طریق فیلد tools دسترسیِ محدودی به ابزار داشته باشند:

  • حذف فیلد: ایجنت همه‌ی ابزارهای موجود را به ارث می‌برد (پیش‌فرض)
  • مشخص‌کردن ابزارها: ایجنت فقط می‌تواند از ابزارهای فهرست‌شده استفاده کند

این مثال یک ایجنتِ تحلیلِ فقط‌خواندنی می‌سازد که می‌تواند کد را بررسی کند اما نمی‌تواند فایل‌ها را تغییر دهد یا دستورها را اجرا کند.

import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
async def main():
async for message in query(
prompt="Analyze the architecture of this codebase",
options=ClaudeAgentOptions(
allowed_tools=["Read", "Grep", "Glob", "Agent"],
agents={
"code-analyzer": AgentDefinition(
description="Static code analysis and architecture review",
prompt="""You are a code architecture analyst. Analyze code structure,
identify patterns, and suggest improvements without making changes.""",
# Read-only tools: no Edit, Write, or Bash access
tools=["Read", "Grep", "Glob"],
)
},
),
):
if hasattr(message, "result"):
print(message.result)
asyncio.run(main())
import { query } from "@anthropic-ai/claude-agent-sdk";
for await (const message of query({
prompt: "Analyze the architecture of this codebase",
options: {
allowedTools: ["Read", "Grep", "Glob", "Agent"],
agents: {
"code-analyzer": {
description: "Static code analysis and architecture review",
prompt: `You are a code architecture analyst. Analyze code structure,
identify patterns, and suggest improvements without making changes.`,
// Read-only tools: no Edit, Write, or Bash access
tools: ["Read", "Grep", "Glob"]
}
}
}
})) {
if ("result" in message) console.log(message.result);
}
کاربردابزارهاتوضیح
تحلیلِ فقط‌خواندنیRead، Grep، Globمی‌تواند کد را بررسی کند اما تغییر یا اجرا نکند
اجرای تستBash، Read، Grepمی‌تواند دستورها را اجرا و خروجی را تحلیل کند
تغییر کدRead، Edit، Write، Grep، Globدسترسیِ کاملِ خواندن/نوشتن بدون اجرای دستور
دسترسیِ کاملهمه‌ی ابزارهاهمه‌ی ابزارها را از والد به ارث می‌برد (فیلد tools را حذف کن)

مقیاس‌پذیری با ورک‌فلوهای پویا

Section titled “مقیاس‌پذیری با ورک‌فلوهای پویا”

ساب‌ایجنت‌ها برای چند کارِ واگذارشده در هر نوبت خوب کار می‌کنند. برای اجراهایی که ده‌ها تا صدها ایجنت را هماهنگ می‌کنند، از ابزار Workflow استفاده کن که هماهنگی را به یک اسکریپت منتقل می‌کند که runtime آن را بیرون از کانتکستِ مکالمه اجرا می‌کند. برای اینکه ببینی ورک‌فلوها چه تفاوتی با واگذاریِ نوبت‌به‌نوبتِ ساب‌ایجنت دارند، به ورک‌فلوهای پویا نگاه کن.

ابزار Workflow در TypeScript Agent SDK نسخه‌ی v0.3.149 و بالاتر در دسترس است. Workflow را در allowedTools بگنجان تا اجراهای ورک‌فلو خودکار تأیید شوند. اسکیماهای ورودی و خروجیِ این ابزار در مرجع TypeScript فهرست شده‌اند.

Claude به ساب‌ایجنت‌ها واگذار نمی‌کند

Section titled “Claude به ساب‌ایجنت‌ها واگذار نمی‌کند”

اگر Claude به‌جای واگذاری به ساب‌ایجنتت، کارها را مستقیماً انجام می‌دهد:

  1. بررسی کن که فراخوانی‌های Agent تأیید می‌شوند: Agent را در allowedTools بگنجان تا فراخوانی‌های ساب‌ایجنت خودکار تأیید شوند. بدون آن، فراخوانی‌های Agent به callbackِ canUseToolت می‌رسند، یا در حالت dontAsk رد می‌شوند
  2. از پرامپتِ صریح استفاده کن: ساب‌ایجنت را با نام در پرامپتت ذکر کن (برای مثال، «از ایجنت code-reviewer استفاده کن تا…»)
  3. یک توصیفِ روشن بنویس: دقیقاً توضیح بده ساب‌ایجنت کِی باید استفاده شود تا Claude بتواند کارها را به‌درستی تطبیق دهد

ایجنت‌های مبتنی بر فایل‌سیستم بارگذاری نمی‌شوند

Section titled “ایجنت‌های مبتنی بر فایل‌سیستم بارگذاری نمی‌شوند”

ایجنت‌های تعریف‌شده در .claude/agents/ فقط هنگام شروع بارگذاری می‌شوند. اگر در حین اجرای Claude Code یک فایلِ ایجنتِ جدید بسازی، برای بارگذاریِ آن نشست را دوباره راه‌اندازی کن.

ویندوز: شکست پرامپت‌های طولانی

Section titled “ویندوز: شکست پرامپت‌های طولانی”

در ویندوز، ساب‌ایجنت‌هایی با پرامپت‌های بسیار طولانی ممکن است به‌دلیلِ محدودیتِ طولِ خطِ فرمان (۸۱۹۱ کاراکتر) شکست بخورند. پرامپت‌ها را مختصر نگه دار یا برای دستورهای پیچیده از ایجنت‌های مبتنی بر فایل‌سیستم استفاده کن.