یک فشار ساده روی کلید Enter در Claude Code، موتور پیچیدهای از بازیابی خطاها را فعال میکند تا کاربر هرگز با پیامهای خطای زیرساختی مواجه نشود. در ۱۷ اکتبر ۲۰۲۶، بررسیهای فنی فاش کرد که این عامل به جای یک حلقهٔ ساده برای تلاش مجدد، از یک پشتهٔ ۸ لایه از مکانیزمهای تابآوری استفاده میکند.
همانطور که در تحلیل قبلی ما دربارهی تأثیر باورهای شخصی بر توصیههای مدلها اشاره کردیم، این معماری نشان میدهد که عاملهای در سطح تولید (Production-grade) به چیزی فراتر از یک مدل باهوش نیاز دارند. آنها به یک پوشش (Wrapper) مستحکم نیاز دارند که خطاهای API را نه به عنوان پایان مسیر یا خطاهای ترمینال، بلکه به عنوان موانعی موقت ببیند. این رویکرد در واقع پاسخی به شکستهای عملیاتی رایجی است که مدلهای هوشمند را در محیطهای واقعی ناکام میگذارد. برای یک برنامهنویس، این یعنی تفاوت بین ابزاری که هنگام نوسانات شبکه کرش میکند و ابزاری که در سکوت، خودش را تعمیر میکند.
اولین خط دفاعی: withRetry
هر فراخوانی منطقی به مدل زبانی بزرگ (LLM) در تابعی به نام withRetry محصور شده است. طبق گزارش وبسایت dev.to، Claude Code هرگز یک درخواست لخت و بدون پوشش به مدل نمیفرستد. هر call_llm کپسولهسازی شده است؛ به این معنا که یک درخواست ظاهری از دید کاربر، ممکن است در پشت صحنه به یک تا ده درخواست HTTP واقعی تبدیل شود.
سیستم به طور پیشفرض تا ۱۰ تلاش مجدد را برای هر درخواست مجاز میداند که توسط متغیر DEFAULT_MAX_RETRIES = 10 تعریف شده است. این مقدار میتواند توسط CLAUDE_CODE_MAX_RETRIES تغییر کند. منطق اصلی ساده است: اگر یک خطا «قابل تلاش مجدد» (Retryable) باشد، سیستم طبق سیاست عقبنشینی منتظر میماند و دوباره تلاش میکند؛ در غیر این صورت، شکست را بلافاصله به حلقه بیرونی بازمیگرداند. این سازوکار تضمین میکند که حلقه اصلی تنها نتیجه نهایی (موفقیت یا شکست قطعی) را ببیند، در حالی که تلاشهای گذرا پنهان میمانند.
این عامل به جای استفاده از حدسهای سمت کلاینت، به سیگنالهای هدایتشده توسط سرور اولویت میدهد. سیستم به دنبال هدر x-should-retry از سرورهای Anthropic میگردد. اگر سرور مقدار x-should-retry: true یا x-should-retry: false را ارسال کند، این دستور بر کد وضعیت HTTP اولویت دارد.
heuristicهای سمت کلاینت — مانند بررسی وجود overloaded_error در بدنه پاسخ — تنها به عنوان راهکار جایگزین (Fallback) در زمانی که هدر مذکور غایب است، استفاده میشوند. این الگوی سازگار با محیط تولید به سرویس اجازه میدهد تا معنای تلاشهای مجدد را بر اساس وضعیت خوشه (Cluster) تغییر دهد، بدون اینکه نیاز باشد هر کلاینت یک بهروزرسانی نرمافزاری دریافت کند.
عقبنشینی هوشمند و مدیریت فشار بیش از حد
وقتی یک تلاش مجدد فعال میشود، عامل ابتدا هدر Retry-After را بررسی میکند تا زمان دقیق انتظار را تعیین کند. این مقدار میتواند یک مقدار نسبی باشد (مثلاً Retry-After: 30 برای ۳۰ ثانیه) یا یک تاریخ HTTP-date. برای برخی محدودیتهای نرخ (Rate limits)، سیستم مستقیماً تا زمان بازنشینی پنجره محدودیت منتظر میماند، زیرا این دقیقترین زمانبندی برای سهمیههای تمامشده است.
اگر سرور ساکت باشد، سیستم به جدول «عقبنشینی نمایی» (Exponential Backoff) روی میآورد: ۱ ثانیه، ۲ ثانیه، ۴ ثانیه، ۸ ثانیه، ۱۶ ثانیه، ۳۲ ثانیه و به همین ترتیب. این کار مانع از «کوری» سیستم در زمانبندیهای ثابت میشود؛ وضعیتی که در آن ممکن است در حالی که محدودیت هنوز فعال است خیلی زود تلاش مجدد کند، یا پس از بازیابی سرویس، بیش از حد منتظر بماند.
منطق ویژهای برای مدیریت خطاهای HTTP 529 وجود دارد که نشاندهنده فشار بیش از حد به خوشه است، جایی که منابع در دسترس نیستند. این خطا با خطای ۴۲۹ متفاوت است؛ ۴۲۹ نشان میدهد که فراخواننده ترافیک زیادی میفرستد. برای جلوگیری از ایجاد «طوفان تلاش مجدد» (Retry Storm) — جایی که فشار کلی به دلیل تلاش همزمان همه کاربران افزایش مییابد — Claude Code بین انواع کار تفاوت قائل میشود:
- وظایف پسزمینه: کارهای غیر-پیشزمینه، مانند فشردهسازی (Compaction) یا کوئریهای حافظه جلسه، بلافاصله شکست میخورند. این کارها ارزش تشدید فشار روی خوشه را ندارند.
- وظایف پیشزمینه: کارهایی که کاربر فعالانه منتظر جواب آنهاست ممکن است تلاش مجدد کنند، اما تنها تا سقف مشخصی از
MAX_529_RETRIES.
جایگزینی مدل و حذف امضاها
اگر مدل اصلی — مانند claude-opus-4-6 — به دلیل خطاهای ۵۲۹ یا سایر مشکلات بحرانی مکرراً شکست بخورد، سیستم خطای FallbackTriggeredError را صادر میکند. این اتفاق باعث جابهجایی مدل به یک جایگزین پیکربندیشده، مانند claude-sonnet-4-6، و ارسال مجدد همان تاریخچه پیامها میشود. در این مرحله، مدیریت دقیق اتصالها حیاتی است، چرا که برخی نقاط شکست بحرانی در هنگام اتصال مدلهای مختلف به Claude Code میتواند کل فرآیند بازیابی را مختل کند.
نکته حیاتی این است که این جابهجایی به عنوان یک نوبت (Turn) جدید محاسبه نمیشود. این اتفاق در حلقه داخلی بازیابی ماشین وضعیت رخ میدهد، نه در حلقه بیرونی که مقدار turnCount را افزایش میدهد. این امر تضمین میکند که یک بار فشار دادن Enter به معنای یک تعامل است و از سهمیه maxTurns کاربر کم نمیکند.
از آنجا که مدلهای مختلف از امضاهای «تفکر» (Thinking signatures) متفاوتی استفاده میکنند، عامل یک مرحله پاکسازی حیاتی انجام میدهد. یک پیام قدیمی دستیار ممکن است ساختاری مانند { type: 'thinking', signature: '...', thinking: '...' } داشته باشد. ارسال امضایی که توسط یک مدل تولید شده به مدلی دیگر میتواند باعث رد درخواست توسط سرور شود. قبل از درخواست جایگزین، Claude Code تاریخچه را اسکن کرده و فیلدهای signature را حذف میکند در حالی که محتوای thinking را حفظ میکند تا گفتگو قابلفهم باقی بماند اما متادیتا با مدل جدید سازگار شود.
بازیابی مرحلهبندی شده برای زمینه و توکنها
وقتی API خطای prompt_too_long (طولانی بودن متن) را برمیگرداند، عامل یک مسیر بازیابی سه مرحلهای را اجرا میکند تا از کرش سخت جلوگیری کند:
- تخلیه متمرکز زمینه (Context-collapse drain): حذف تهاجمی حجم زیادی از تاریخچه قدیمی. این مکانیزم دارای Feature-flag است و بسیار شدیدتر از فشردهسازی معمولی عمل میکند.
- فشردهسازی واکنشی (Reactive compaction): سیستم یک فرآیند استاندارد مشابه
/compactرا اجرا میکند، زیرا API پیش از این پرامپت را رد کرده است. - نمایش خطا: تنها پس از شکست هر دو تلاش قبلی، خطای
{ reason: 'prompt_too_long' }به لایه SDK بازگردانده میشود.
به همین ترتیب، دلایل توقف مربوط به max_tokens از طریق یک توالی تصاعدی با حد بازیابی MAX_OUTPUT_TOKENS_RECOVERY_LIMIT = 3 مدیریت میشوند:
- مرحله ۱: افزایش سقف
max_tokensو تلاش مجدد. - مرحله ۲: اگر سقف افزایشیافته دوباره لمس شود، پیام کاربر
[Output token limit hit, continue]به تاریخچه اضافه میشود تا مدل صراحتاً ترغیب شود کار ناتمام را ادامه دهد. - مرحله ۳: اگر برای بار سوم محدودیت رخ دهد، بازیابی متوقف شده و خطا نمایش داده میشود.
پشته ۸ لایه بازیابی
از نزدیکترین مکانیزم در سطح درخواست تا بیرونیترین حفاظ، یک فراخوانی شکستخورده مدل میتواند از ۸ لایه متمایز تابآوری عبور کند:
۱. withRetry: مدیریت خطاهای شبکه، خطاهای ۵۰۰ و خطاهای واجد شرایط ۵۲۹ با عقبنشینی (تا ۱۰ تلاش).
۲. جابهجایی مدل جایگزین: تغییر مدل زمانی که مدل اصلی قادر به بازیابی نیست.
۳. حذف امضا: تضمین سازگاری درخواستهای جایگزین با فرمتهای مختلف تفکر.
۴. بازیابی سه مرحلهای prompt_too_long: پیشروی از تخلیه به فشردهسازی و سپس نمایش خطا.
۵. بازیابی سه مرحلهای max_tokens: افزایش سقفها، تزریق دستور ادامه و سپس نمایش خطا.
۶. انتقالات ماشین وضعیت: مسیریابی کار از طریق فشردهسازی واکنشی، مسدودسازی Stop-hook و بازیابی خروجی. این لایه دقیقاً همان جایی است که مسیریابی ماشینحالت برای مقابله با توهمات و لوپهای شکننده در محیط تولید به کار گرفته میشود.
۷. پنهانسازی خطا: جلوگیری از مشاهده خطاهای گذرا توسط فراخوانندگان SDK؛ تنها خطاهای ترمینال به کاربر میرسند.
۸. maxTurns: قطعکننده سخت (Circuit Breaker) که فرآیند را زمانی که تمام تلاشهای دیگر شکست خوردند، متوقف میکند.
این اصل «پنهانسازی خطا» تضمین میکند که کاربر تنها یک موفقیت نهایی یا یک شکست ترمینال واقعاً غیرقابل بازیابی را ببیند. به هر فشار روی Enter، تا جای ممکن مسیرهای بازیابی ایمن و معنادار داده میشود پیش از آنکه نیاز به دخالت انسانی باشد.
این تغییر در معماری، فرض بنیادی در طراحی عاملهای هوش مصنوعی را تغییر میدهد. تمرکز از «مهندسی پرامپت» به «مهندسی بازیابی» منتقل شده است. Anthropic با نگاه به LLM به عنوان یک قطعه غیرقابلاعتماد در یک ماشین وضعیت بزرگتر، سیستمی ساخته است که در آن تابآوری عامل به اندازه هوش آن اهمیت دارد.
برای توسعهدهندگانی که عاملهای خود را میسازند، درس آشکار است: فقط روی خطاهای ۵۰۰ تلاش مجدد نکنید. یک پشته لایهبندی شده بسازید که تفاوت بین محدودیت نرخ (Rate limit)، فشار خوشه (Cluster overload) و سرریز زمینه (Context overflow) را درک کند.
برای اینکه ببینید این سیستم چگونه دیگر سوی طیف را مدیریت میکند، منتظر جزئیات آینده درباره نحوه مدیریت توقفهای کاربر توسط Ctrl-C در Claude Code بدون تخریب تاریخچه پیامها باشید.




گفتگو