تصور کنید برای هر بخش از پروژهتان یک متخصص استخدام کردهاید، اما متوجه میشوید ۸۰ درصد آنها یک ماه است که حتی یک ساعت هم کار نکردهاند، ولی همچنان حقوقشان را میگیرند. این دقیقاً همان اتفاقی است که در محیطهای توسعهی Claude Code میافتد؛ جایی که تعریف کردن یک عامل (Agent) — شبیه به استخدام یک کارمند متخصص برای یک وظیفه خاص — لزوماً به معنای استفادهی مدل از آن نیست. در واقع، این یک مغالطه رایج در میان توسعهدهندگان است که تصور میکنند «تعریف شده یعنی در حال کار».
بر اساس بررسیهای یک توسعهدهنده، ۷ مورد از ۸ عامل سفارشی در یک محیط عملیاتی طی یک دوره ۳۰ روزه هیچ فراخوانیای نداشتند. همانطور که در تحلیل قبلی ما دربارهی بازسازی زیرساختهای امنیتی Anthropic اشاره کردیم، شکنندگی سیستمها همیشه در لایههای امنیتی نیست، بلکه گاهی در انباشت «بدهی فنی هوش مصنوعی» (AI Technical Debt) از طریق پرامپتهای سیستمی متورم نهفته است. وقتی عاملها را از طریق فایلهای .md در دایرکتوری ~/.claude/agents/ تعریف میکنید، تمام تعاریف آنها در هر درخواست به پرامپت سیستمی (System Prompt) — همان دستورالعملهای بنیادینی که مدل در هر لحظه در ذهن دارد تا بداند چه کسی است و چه میکند — تزریق میشوند.
این یعنی شما برای عاملهایی که هرگز فعال نمیشوند، «مالیات توکن» میپردازید. این موضوع یادآور چالشهای بهینهسازی است که در بررسی اثرات کشینگ API بر کاهش مصرف توکنها به آن پرداختیم. در این مورد خاص، هفت عامل بلااستفاده — شامل متخصصان معماری، امنیت و بررسی پایگاهداده — بدون اینکه کاری انجام دهند، توکنها را میسوزاندند و کیفیت استنتاج (Inference) — لحظهای که مدل واقعاً جواب تولید میکند، شبیه به خودِ آشپزی و نه دورهی آموزش آشپز — را در هر فراخوانی به طور نامحسوس کاهش میدادند. حجم این اضافات قابل توجه بود: ۸ فایل اولیه در مجموع حدود ۱۰۷ کیلوبایت (۱۰۹,۸۵۲ بایت) فضا و ۱۲۲۱ خط متن را اشغال کرده بودند. تعاریف بزرگی مانند code-reviewer.md (۳۲۳ خط)، planner.md (۲۲۱ خط) و architect.md (۲۲۰ خط) فارغ از اینکه هرگز فراخوانی شوند یا نه، به طور دائمی بخشی از حافظه فعال مدل را اشغال کرده بودند.
مکانیزم اندازهگیری
این توسعهدهنده برای عبور از حدس و گمان به دادههای واقعی، یک چرخه عملیاتی سه لایه طراحی کرد تا از احساسات به سمت دادههای اندازهگیری شده حرکت کند. این سامانه از stop hook در Claude Code استفاده میکند که پس از تکمیل هر فراخوانی عامل، یک اسکریپت را اجرا میکند. این رویکرد به او اجازه داد محیط اتوماسیونی با هزینه ۱.۲ میلیون ین در ماه را مدیریت کند، آن هم با سرمایهگذاری روی مکانیزمهایی که متوجه میشوند چه زمانی هوش مصنوعی در مسیر اشتباه حرکت میکند.
- لایه اول (ثبت): یک stop hook تمام فراخوانیهای عامل را در یک فایل JSONL در مسیر
~/.claude/logs/agent-invocations.jsonlذخیره میکند. هر رکورد شامل برچسب زمانی (ts)، شناسه جلسه (Session ID)، نوع زیر-عامل و وضعیت است. برای مثال، یک رکورد ممکن است نشان دهد که یک عاملgeneral-purposeبرای یافتن دادههای کلیک ریدایرکت CTA به ۳۴۰۷ میلیثانیه زمان نیاز داشته است. - لایه دوم (تجمیع): یک اسکریپت ترکیبی Bash و پایتون به نام
agent-usage-summary.shاین لاگها را پردازش میکند. این اسکریپت رکوردها را بر اساس یک پنجره زمانی مشخص (مثلاً ۷ یا ۳۰ روز) فیلتر کرده و آنها را با استفاده از یک الگوی glob با فایلهای .md موجود در دایرکتوری عاملها تطبیق میدهد. - لایه سوم (خروجی): سامانه یک رتبهبندی از ۱۰ عامل پرکاربرد و لیستی صریح از «عاملهای صفر-فراخوانی» برای هرس کردن فوری تولید میکند. این خروجی دادههای خام لازم برای تصمیمگیری در مورد حذف، آرشیو یا ساخت یک فراخوان (Caller) خاص برای یک عامل را فراهم میکند.
جزئیات فنی پیادهسازی
به نقل از مستندات این پروژه، فرآیند ثبت نیاز به اسکن دو مرحلهای فایل transcript.jsonl دارد؛ زیرا Claude Code فراخوانی ابزار (tool_use) و نتیجه آن (tool_result) را در دو خط مجزا ثبت میکند. با تطبیق این دو از طریق tool_use_id است که توسعهدهنده میتواند مدت زمان دقیق اجرای هر عامل (duration_ms) و وضعیت موفقیت یا خطا («ok» یا «error») را محاسبه کند.
دادههای استخراج شده از لاگها، که بازه زمانی ۲۸ مه تا ۳۰ اوت ۲۰۲۶ را پوشش میداد، در ۶۸۲ رکورد تفاوت فاحشی را در عملکرد نشان داد:
- عامل Explore: میانگین زمان ۲۳۶ میلیثانیه. این عامل داخلی در جستوجوی فایلها و بررسی کد تخصص دارد.
- عامل General-Purpose: زمانی بین ۳۴۰۷ تا ۶۸۳۰ میلیثانیه را به خود اختصاص داد.
این شکاف به عنوان معیاری برای هزینه توکن و بار شناختی مرتبط با انواع مختلف عاملها عمل میکند. اسکریپت تجمیعکننده در ۱۰۳ خط نوشته شده است و از یک پوسته Bash برای تجزیه آرگومانها و یک heredoc پایتونی برای منطق اصلی استفاده میکند تا از پیچیدگیهای تجزیه JSONL در Bash خالص اجتناب شود.
تحلیل عمیق منطق ثبت
اسکریپت stop_agent_tracker.sh برای تضمین سلامت دادهها از یک ساختار دو-پاسه (Two-pass) خاص استفاده میکند. در پاس اول، تمام ورودیهای tool_use و tool_result را در دیکشنریهای مجزا ایندکس میکند. در پاس دوم، روی موارد استفاده پیمایش کرده و نتیجه متناظر را جستوجو میکند.
این طراحی اجازه میدهد سیستم وضعیتهای «در انتظار» (pending) را مدیریت کند. اگر یک جلسه به طور اجباری بسته شود یا قبل از اینکه tool_result نوشته شود قطع شود، رکورد با وضعیت status: "pending" علامتگذاری میشود. این کار باعث تمایز بین یک عامل شکستخورده و یک جلسه کرش کرده میشود. برای جلوگیری از فساد دادهها ناشی از اجرای چندین hook در یک جلسه، اسکریپت از یک مجموعه seen_ids برای حذف تکراریهای tool_use_id استفاده میکند. این واقعیت که در ۶۸۲ رکورد حتی یک مورد تکراری وجود نداشت، گواه کارآمدی این سیستم حذف تکرار است.
غلبه بر چالشهای اجرایی
در مسیر ساخت، چندین مانع فنی شناسایی شد. نخست اینکه توسعهدهنده متوجه شد نام ابزار داخلی «Agent» است، نه «Task» (آنطور که در برخی مستندات پیشنهاد شده بود). فیلتر کردن برای «Task» باعث شد به مدت دو روز هیچ رکوردی ثبت نشود تا اینکه یک دستور grep مستقیم روی ترنسکریپت، حقیقت را آشکار کرد. راه حل، یک تغییر تکخطی از b.get("name") == "Task" به b.get("name") == "Agent" بود.
دوم اینکه subagent_type در داخل یک شیء input تو در تو قرار داشت (b.get("input", {}).get("subagent_type"))، به این معنی که کوئریهای ساده در سطح اول هیچ نتیجهای نمیدادند. برای عیبیابی این موضوع، توسعهدهنده از متغیر محیطی CC_AGENT_TRACKER_DEBUG=1 برای فعالسازی لاگهای دقیق استفاده کرد. زمانی که مشکل رخ داد، لاگی که باید ۶۸۲ رکورد میداشت، صفر بود زیرا شرط حفاظتی if "subagent_type" not in inp: continue تمام رکوردها را رد میکرد.
خطاهای عملیاتی در زمان اجرای سیستم از طریق cron نیز رخ داد:
- مشکلات PATH: محیط cron فاقد
PATHلازم برای یافتنpython3یاnodeتحت nvm بود. راه حل، سختافزاری کردن مسیرها به صورتPATH=/usr/local/bin:/usr/bin:/binو استفاده از مسیرهای مطلق برای دایرکتوری خانگی (مثلاً/Users/youraccount/) به جای~/بود. - خطاهای Bash: استفاده از
set -uo pipefailباعث میشد اسکریپت در صورت عدم ارسال آرگومان کرش کند، زیرا سعی میکرد به یک آرایه خالیWINDOWSارجاع دهد. برای جلوگیری از این اتفاق، مقدار پیشفرض7dپیاده شد. این مشکل فقط در اجراهای cron ظاهر میشد، زیرا اجراهای دستی همیشه شامل آرگومان بودند. - فساد دادهها: برای جلوگیری از اینکه یک خط خراب در JSONL باعث توقف کل فرآیند تجمیع شود، اسکریپت از یک بلوک
try/exceptهمراه باcontinueبرای نادیده گرفتن رکوردهای فاسد استفاده میکند. این موضوع حیاتی است زیرا جلساتی که هنگام اجرای hook قطع میشوند، ممکن است خطوط نیمهکاره به جا بگذارند.
توهم «باید استفاده شود»
یکی از تکاندهندهترین یافتهها این بود که استفاده از لحن دستوری و شدید در تعریف یک عامل، مدل را مجبور به استفاده از آن نمیکند. عامل code-reviewer.md صراحتاً ذکر کرده بود که «باید برای تمام تغییرات کد استفاده شود» (MUST BE USED)، اما در ۳۰ روز تنها یک بار فراخوانی شد — و آن یک بار هم به دلیل درخواست دستی کاربر بود.
طبق این گزارش، توصیفات عاملها صرفاً «راهنماییهایی» (Hints) برای LLM هستند تا تصمیم بگیرد کدام عامل را انتخاب کند. آنها دستوراتی نیستند که فعالسازی را از بیرون اجباری کنند. مگر اینکه یک پرامپت خاص یا یک stop hook صراحتاً عامل را فراخوانی کند، Claude معمولاً مسیر عمومی (Generic) را انتخاب میکند. این موضوع یک حس کاذب از دستاورد ایجاد میکند؛ جایی که توسعهدهنده باور دارد کدهایش به طور خودکار بررسی میشوند، در حالی که در واقعیت، عامل مربوطه صرفاً در پرامپت سیستمی در حال استراحت است. این عدم تطابق بین تعریف و اجرا، مشابه همان نقص در مدیریت اجراست که باعث کاهش نرخ موفقیت عاملهای کدنویس در LoopArena شد.
هرس کردن و نگهداری
با دسترسی به دادهها، توسعهدهنده استراتژی هرس سختگیرانهای را بر اساس اعداد اندازهگیری شده جایگزین حدس و گمان کرد. عاملهایی با صفر فراخوانی در ۳۰ روز به سه روش مدیریت شدند:
- حذف: اگر عامل بلااستفاده بود و هیچ مکانیزم فراخوانی برای آن وجود نداشت، برای صرفهجویی در توکنها حذف شد. این کار بلافاصله حجم پرامپت سیستمی را کاهش میدهد.
- آرشیو: اگر احتمال میرفت در آینده مفید باشد، به مسیر
~/.claude/agents/archive/منتقل شد. چون اسکریپت از یک glob غیر-بازگشتی (*.md) استفاده میکند، انتقال فایل به یک زیرپوشه به طور خودکار آن را از لیست فعال خارج میکند. این کار اجازه میدهد محیط پاک بماند بدون اینکه کارهای انجام شده برای همیشه از دست بروند. - ساخت فراخوان: اگر قابلیت عامل ارزشمند بود، مکانیزمی (مانند stop hook یا قالب پرامپت) برای فراخوانی صریح آن اضافه شد. حتی در اینجا، توسعهدهنده توصیه میکند پس از پیادهسازی، دوباره آمار را بررسی کنید تا اثر آن تأیید شود.
این فرآیند باعث کاهش چشمگیر تورم پرامپت سیستمی شد. حذف تعاریف بلااستفاده منجر به افزایش محسوس در سرعت پاسخدهی و ایجاد محیطی تمیزتر برای استدلال هوش مصنوعی شد. این رویکرد با استراتژی حذف دورهای دستورالعملهای قدیمی همسو است تا مدلها از خطاهای قدیمی عبور کنند. توصیه میشود این آمارگیری به صورت هفتگی یا ماهانه از طریق cron اجرا شود تا وضعیتی حفظ شود که در آن «فقط چیزهایی که استفاده میشوند، وجود داشته باشند».
تحلیل: هزینه انباشت در هوش مصنوعی
این مورد ثابت میکند که گلوگاه اصلی در محیطهای هوش مصنوعی خودمختار، هوش مدل نیست، بلکه «بهداشت محیطی» است. اکثر توسعهدهندگان تعریف عامل را یک کار «تنظیم کن و فراموش کن» میبینند و کتابخانهای از متخصصان میسازند که مدل به ندرت انتخاب میکند از آنها استفاده کند.
برای متخصصان، این یعنی هر عامل جدید که بدون مکانیزم فراخوانی متناظر اضافه شود، در واقع یک جریمه برای عملکرد سیستم است. اثر ثانویه آن، تخریب پنجره زمینه (Context Window) است؛ هرچه پرامپت سیستمی با تعاریف بلااستفاده رشد کند، فضای کمتری برای دادههای واقعی مرتبط با تسک باقی میماند. علاوه بر این، انباشت تعاریفی که بازتابدهنده واقعیت نیستند، اعتماد به سیستم خودمختار را از بین میبرد. لحظهای که کاربر بپرسد «آیا این عامل اصلاً در حال اجراست؟»، اعتماد به کل سیستم لرزان میشود.
بهترین شیوهها برای محیطهای Claude Code
برای جلوگیری از این دامها، عادتهای عملیاتی زیر توصیه میشود:
- تأیید لاگهای خام: همیشه قبل از نوشتن اسکریپتها، دستور
grep '"name"' ~/.claude/projects/*/transcript.jsonl | head -5را اجرا کنید تا مطمئن شوید نام ابزارها را درست هدف قرار دادهاید. حقیقت در فایل است، نه در مستندات. - مقایسه پنجرههای زمانی: استفادهی ۷ روزه و ۳۰ روزه را به طور همزمان مقایسه کنید. عاملی که در ۳۰ روز یک بار استفاده شده اما در ۷ روز اخیر صفر است، احتمالاً یک استفاده اتفاقی و یکباره بوده است.
- نظارت بر نرخ خطا: از ستون
errorsدر رتبهبندی Top 10 برای شناسایی عاملهایی که فراخوانی میشوند اما شکست میخورند استفاده کنید. این موارد را از طریقgrep '"status":"error"'استخراج کرده و شناسه جلسه را ردیابی کنید. - ردیابی وضعیت Pending: به طور دورهای رکوردهای
"status":"pending"را بررسی کنید. درصد بالای فراخوانیهای در انتظار، نشانه جلسات ناپایدار یا خروجهای اجباری است. نرخ اتلاف زیر ۱۰٪ عموماً قابل قبول است. - طراحی «اول فراخوان»: هرگز عاملی را تعریف نکنید مگر اینکه ابتدا منطق فراخوانی آن را ساخته باشید. در لحظه خلق، دقیقاً تصمیم بگیرید که چگونه تحریک شود (hook، قالب یا دستور).
- آمارگیری قبل از افزودن: قبل از اضافه کردن هر عامل جدید،
agent-usage-summary.sh 30dرا اجرا کنید. اگر لیست صفر-فراخوانی از قبل طولانی است، ابتدا محیط را مرتب کنید تا فرآیند انتخاب عامل برای مدل شفاف بماند. - استفاده از مدت زمان برای بهینهسازی: از
duration_msبرای شناسایی عاملهای سنگین استفاده کنید. اگر یک عامل سنگین زیاد فراخوانی میشود، بررسی کنید آیا عامل داخلیExploreمیتواند آن مورد را به طور بهینهتری پوشش دهد. - مدیریت فایلهای غیر-عامل: آگاه باشید که فایلهایی مانند
INDEX.mdممکن است توسط الگوهای glob به اشتباه به عنوان عامل شناسایی شوند. این فایلها را به زیرپوشهها منتقل کنید یا از یک لیست استثنائات استفاده کنید تا در لیست صفر-فراخوانی نویز ایجاد نکنند. - تنظیم محیط Cron: متغیرهای
HOMEوPATHرا در تعاریف cron صراحتاً ذکر کنید. برای مثال:0 9 * * 1 HOME=/Users/user/ PATH=/usr/local/bin:/usr/bin:/bin bash ~/scripts/agent-usage-summary.sh 7d 30d >> ~/agent-weekly.log 2>&1.
گام بعدی شما
توسعهدهندگانی که از Claude Code استفاده میکنند باید همین امروز پوشه ~/.claude/agents/ خود را بازرسی کنند و یک hook ثبت ساده را پیاده کنند تا ببینند کدام متخصصان واقعاً در جریان کار آنها مشارکت میکنند. بدون اعداد، شما بر اساس امید پیش میروید؛ با اعداد، میتوانید اضافات را حذف کنید و اجازه دهید هوش مصنوعی روی کار واقعیاش تمرکز کند.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو