سابایجنتها در SDK
سابایجنتها نمونههای ایجنتِ جداگانهای هستند که ایجنتِ اصلیِ تو میتواند برای انجامِ زیرکارهای متمرکز آنها را راهاندازی کند. از سابایجنتها استفاده کن تا کانتکست را برای زیرکارهای متمرکز ایزوله کنی، چند تحلیل را موازی اجرا کنی، و دستورهای تخصصی را بدون اضافهکردن به پرامپتِ ایجنت اصلی اعمال کنی.
این راهنما توضیح میدهد که چطور با استفاده از پارامتر agents سابایجنتها را در SDK تعریف و استفاده کنی.
مرور کلی
Section titled “مرور کلی”میتوانی سابایجنتها را به سه روش بسازی:
- بهصورت برنامهنویسیشده: از پارامتر
agentsدر گزینههایquery()استفاده کن (TypeScript، Python) - مبتنی بر فایلسیستم: ایجنتها را بهصورت فایلهای markdown در دایرکتوریهای
.claude/agents/تعریف کن (به تعریف سابایجنتها بهصورت فایل نگاه کن) - همهمنظورهی داخلی: Claude میتواند هر زمان سابایجنتِ داخلیِ
general-purposeرا از طریق ابزار Agent فراخوانی کند، بدون اینکه چیزی تعریف کنی
این راهنما روی رویکردِ برنامهنویسیشده تمرکز دارد که برای اپلیکیشنهای SDK توصیه میشود.
وقتی سابایجنتها را تعریف میکنی، Claude بر اساس فیلد descriptionِ هر سابایجنت تصمیم میگیرد آن را فراخوانی کند یا نه. توصیفهای روشنی بنویس که توضیح میدهند سابایجنت کِی باید استفاده شود، و Claude بهطور خودکار کارهای مناسب را واگذار میکند. همچنین میتوانی در پرامپتت صریحاً یک سابایجنت را با نام درخواست کنی (برای مثال، «از ایجنت code-reviewer استفاده کن تا…»).
مزایای استفاده از سابایجنتها
Section titled “مزایای استفاده از سابایجنتها”ایزولهسازی کانتکست
Section titled “ایزولهسازی کانتکست”هر سابایجنت در مکالمهی تازهی خودش اجرا میشود. فراخوانیها و نتایجِ میانیِ ابزار درون سابایجنت میمانند؛ فقط پیامِ نهاییاش به والد برمیگردد. برای اینکه دقیقاً ببینی چه چیزی در کانتکستِ سابایجنت هست، به سابایجنت چه چیزی به ارث میبرد نگاه کن.
مثال: یک سابایجنتِ research-assistant میتواند دهها فایل را بررسی کند بدون اینکه هیچکدام از آن محتوا در مکالمهی اصلی انباشته شود. والد یک خلاصهی فشرده دریافت میکند، نه هر فایلی که سابایجنت خوانده است.
موازیسازی
Section titled “موازیسازی”چند سابایجنت میتوانند همزمان اجرا شوند، پس زیرکارهای مستقل در زمانِ کندترین آنها تمام میشوند، نه در مجموعِ زمانِ همهشان.
مثال: در حین یک بازبینیِ کد، میتوانی سابایجنتهای style-checker، security-scanner و test-coverage را بهجای پشتسرهم، همزمان اجرا کنی.
دستورها و دانش تخصصی
Section titled “دستورها و دانش تخصصی”هر سابایجنت میتواند پرامپتهای سیستمیِ سفارشی با تخصص، بهترین شیوهها و قیدهای مشخص داشته باشد.
مثال: یک سابایجنتِ database-migration میتواند دانشِ مفصلی دربارهی بهترین شیوههای SQL، راهبردهای rollback و بررسیهای یکپارچگیِ داده داشته باشد که در دستورهای ایجنت اصلی صرفاً نویزِ غیرضروری خواهد بود.
محدودیتهای ابزار
Section titled “محدودیتهای ابزار”سابایجنتها را میتوان به ابزارهای مشخصی محدود کرد و این ریسکِ اقدامات ناخواسته را کاهش میدهد.
مثال: یک سابایجنتِ doc-reviewer ممکن است فقط به ابزارهای Read و Grep دسترسی داشته باشد، که تضمین میکند میتواند تحلیل کند اما هرگز بهطور تصادفی فایلهای مستنداتت را تغییر نمیدهد.
ساختن سابایجنتها
Section titled “ساختن سابایجنتها”تعریف برنامهنویسیشده (توصیهشده)
Section titled “تعریف برنامهنویسیشده (توصیهشده)”سابایجنتها را مستقیماً در کدت با استفاده از پارامتر agents تعریف کن. این مثال دو سابایجنت میسازد: یک بازبینِ کد با دسترسیِ فقطخواندنی و یک اجراکنندهی تست که میتواند دستورها را اجرا کند. Claude سابایجنتها را از طریق ابزار Agent فراخوانی میکند، پس Agent را در allowedTools بگنجان تا فراخوانیهای سابایجنت بدون درخواستِ مجوز خودکار تأیید شوند.
import asynciofrom 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);}پیکربندی AgentDefinition
Section titled “پیکربندی AgentDefinition”| فیلد | نوع | الزامی | توضیح |
|---|---|---|---|
description | string | بله | توصیفِ زبانِ طبیعی از اینکه این ایجنت کِی استفاده شود |
prompt | string | بله | پرامپتِ سیستمیِ ایجنت که نقش و رفتارش را تعریف میکند |
tools | string[] | خیر | آرایهای از نام ابزارهای مجاز. اگر حذف شود، همهی ابزارها را به ارث میبرد |
disallowedTools | string[] | خیر | آرایهای از نام ابزارهایی که باید از مجموعهی ابزارهای ایجنت حذف شوند |
model | string | خیر | بازنویسیِ مدل برای این ایجنت. یک alias مثل 'fable'، 'opus'، 'sonnet'، 'haiku'، 'inherit' یا یک شناسهی کاملِ مدل را میپذیرد. اگر حذف شود، پیشفرض مدلِ اصلی است |
skills | string[] | خیر | فهرستی از نام Skillها که هنگام شروع در کانتکستِ ایجنت پیشبارگذاری شوند. Skillهای فهرستنشده همچنان از طریق ابزار Skill قابلِ فراخوانیاند |
memory | 'user' | 'project' | 'local' | خیر | منبعِ حافظه برای این ایجنت |
mcpServers | (string | object)[] | خیر | سرورهای MCPِ در دسترسِ این ایجنت، با نام یا پیکربندیِ درونخطی |
initialPrompt | string | خیر | وقتی این ایجنت بهعنوان ایجنتِ نخِ اصلی اجرا شود، بهصورت خودکار بهعنوان اولین نوبتِ کاربر ارسال میشود. وقتی ایجنت بهعنوان سابایجنت فراخوانی شود نادیده گرفته میشود |
maxTurns | number | خیر | بیشینهی تعداد نوبتهای ایجنتیک پیش از توقفِ ایجنت |
background | boolean | خیر | هنگام فراخوانی، این ایجنت را بهعنوان یک تسکِ پسزمینهی غیرمسدودکننده اجرا کن |
effort | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | number | خیر | سطحِ تلاشِ استدلال (reasoning effort) برای این ایجنت |
permissionMode | PermissionMode | خیر | حالتِ مجوز برای اجرای ابزار درون این ایجنت |
در 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 “فراخوانی سابایجنتها”فراخوانی خودکار
Section titled “فراخوانی خودکار”Claude بهطور خودکار بر اساس کار و descriptionِ هر سابایجنت تصمیم میگیرد کِی آن را فراخوانی کند. برای مثال، اگر یک سابایجنتِ performance-optimizer با توصیفِ «متخصصِ بهینهسازیِ عملکرد برای تنظیمِ کوئری» تعریف کنی، Claude وقتی پرامپتت به بهینهسازیِ کوئریها اشاره کند آن را فراخوانی میکند.
توصیفهای روشن و مشخص بنویس تا Claude بتواند کارها را با سابایجنتِ درست تطبیق دهد.
فراخوانی صریح
Section titled “فراخوانی صریح”برای اینکه مطمئن شوی Claude از یک سابایجنتِ مشخص استفاده میکند، آن را با نام در پرامپتت ذکر کن:
"Use the code-reviewer agent to check the authentication module"این کار تطبیقِ خودکار را دور میزند و مستقیماً سابایجنتِ نامبرده را فراخوانی میکند.
پیکربندی پویای ایجنت
Section titled “پیکربندی پویای ایجنت”میتوانی تعاریفِ ایجنت را بهصورت پویا بر اساس شرایطِ زمانِ اجرا بسازی. این مثال یک بازبینِ امنیتی با سطوحِ سختگیریِ مختلف میسازد و برای بازبینیهای سختگیرانه از یک مدلِ قویتر استفاده میکند.
import asynciofrom claude_agent_sdk import query, ClaudeAgentOptions, AgentDefinition
# Factory function that returns an AgentDefinition# This pattern lets you customize agents based on runtime conditionsdef 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 conditionsfunction 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 settingsfor 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 asynciofrom 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 استفاده کن. برای ازسرگیریِ یک سابایجنت بهصورت برنامهنویسیشده:
- شناسهی نشست را بردار:
session_idرا از پیامهای اولین کوئری استخراج کن - شناسهی ایجنت را استخراج کن:
agentIdرا از متنِ نتیجهی ابزار Agent تجزیه کن - نشست را از سر بگیر: در گزینههای کوئریِ دوم
resume: sessionIdرا پاس بده و شناسهی ایجنت را در پرامپتت بگنجان
مثال زیر یک ایجنتِ سفارشیِ endpoint-finder تعریف میکند. کوئریِ اول آن را اجرا میکند و شناسهی نشست و شناسهی ایجنت را از نتیجهی ابزار Agent برمیدارد، سپس کوئریِ دوم نشست را از سر میگیرد تا سؤالِ پیگیریای بپرسد که به کانتکستِ تحلیلِ اول نیاز دارد.
import asyncioimport refrom 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 typesfunction 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 subagentfor 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-upif (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(پیشفرض: ۳۰ روز) پاک میشوند.
محدودیتهای ابزار
Section titled “محدودیتهای ابزار”سابایجنتها میتوانند از طریق فیلد tools دسترسیِ محدودی به ابزار داشته باشند:
- حذف فیلد: ایجنت همهی ابزارهای موجود را به ارث میبرد (پیشفرض)
- مشخصکردن ابزارها: ایجنت فقط میتواند از ابزارهای فهرستشده استفاده کند
این مثال یک ایجنتِ تحلیلِ فقطخواندنی میسازد که میتواند کد را بررسی کند اما نمیتواند فایلها را تغییر دهد یا دستورها را اجرا کند.
import asynciofrom 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);}ترکیبهای رایج ابزار
Section titled “ترکیبهای رایج ابزار”| کاربرد | ابزارها | توضیح |
|---|---|---|
| تحلیلِ فقطخواندنی | 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 فهرست شدهاند.
عیبیابی
Section titled “عیبیابی”Claude به سابایجنتها واگذار نمیکند
Section titled “Claude به سابایجنتها واگذار نمیکند”اگر Claude بهجای واگذاری به سابایجنتت، کارها را مستقیماً انجام میدهد:
- بررسی کن که فراخوانیهای Agent تأیید میشوند:
Agentرا درallowedToolsبگنجان تا فراخوانیهای سابایجنت خودکار تأیید شوند. بدون آن، فراخوانیهای Agent به callbackِcanUseToolت میرسند، یا در حالتdontAskرد میشوند - از پرامپتِ صریح استفاده کن: سابایجنت را با نام در پرامپتت ذکر کن (برای مثال، «از ایجنت code-reviewer استفاده کن تا…»)
- یک توصیفِ روشن بنویس: دقیقاً توضیح بده سابایجنت کِی باید استفاده شود تا Claude بتواند کارها را بهدرستی تطبیق دهد
ایجنتهای مبتنی بر فایلسیستم بارگذاری نمیشوند
Section titled “ایجنتهای مبتنی بر فایلسیستم بارگذاری نمیشوند”ایجنتهای تعریفشده در .claude/agents/ فقط هنگام شروع بارگذاری میشوند. اگر در حین اجرای Claude Code یک فایلِ ایجنتِ جدید بسازی، برای بارگذاریِ آن نشست را دوباره راهاندازی کن.
ویندوز: شکست پرامپتهای طولانی
Section titled “ویندوز: شکست پرامپتهای طولانی”در ویندوز، سابایجنتهایی با پرامپتهای بسیار طولانی ممکن است بهدلیلِ محدودیتِ طولِ خطِ فرمان (۸۱۹۱ کاراکتر) شکست بخورند. پرامپتها را مختصر نگه دار یا برای دستورهای پیچیده از ایجنتهای مبتنی بر فایلسیستم استفاده کن.
مستندات مرتبط
Section titled “مستندات مرتبط”- سابایجنتهای Claude Code: مستندات جامعِ سابایجنت شامل تعاریفِ مبتنی بر فایلسیستم
- ورکفلوهای پویا: دهها سابایجنت را از یک اسکریپت برای کارهای بزرگتر از یک مکالمه هماهنگ کن
- مرور کلی SDK: شروعِ کار با Claude Agent SDK