SSD Nodes Learn 🎉 VPS از $5.50/ماه
راهنماها Matt Connorتوسط Matt Connor · به‌روزرسانی شده 2026-08-13

چرا ایجنت‌های برنامه‌نویسی دستورات را نادیده می‌گیرند؟

ایجنت‌ها به دلیل محدودیت context window یا تضاد در دستورات، قوانین شما را اجرا نمی‌کنند. با بررسی دقیق harness و اولویت‌بندی فایل‌ها، علت نادیده گرفتن دستورات را تشخیص دهید.

چرا ایجنت‌های برنامه‌نویسی دستورات شما را نادیده می‌گیرند

ایجنت‌های برنامه‌نویسی به چهار دلیل دستورات شما را نادیده می‌گیرند و هیچ‌کدام از این دلایل به دلیل مؤدب بودن بیش از حد شما نیست. قانون مورد نظر هرگز در context window قرار نگرفته است. قانون بیش از حد مبهم بوده و امکان بررسی یک اقدام بر اساس آن وجود نداشته است. مورد دیگری در context با آن در تضاد بوده که معمولاً کدی است که ایجنت به‌تازگی خوانده است. یا اینکه قانون همچنان بارگذاری شده اما در فاصله‌ای دور از نوبت فعلی قرار دارد و ایجنت بر اساس اطلاعات نزدیک به خود عمل می‌کند.

هر علت راه‌حل خاص خود را دارد، بنابراین اولین کار تشخیص آن‌ها از یکدیگر است. حروف بزرگ و کلمه IMPORTANT تشخیص فنی محسوب نمی‌شوند. مکانیسم‌های زیر از Claude Code به‌عنوان نمونه استفاده می‌کنند، زیرا رفتار بارگذاری و فشرده‌سازی آن تا اوت 2026 به‌طور دقیق مستند شده است. سایر ابزارها در جزئیات متفاوت هستند اما در کلیات به همین شکل عمل می‌کنند.

ابتدا دو اصطلاح را تعریف می‌کنیم. context window بلوکی از متن است که مدل در یک نوبت خاص می‌بیند: system prompt، فایل‌های دستورالعمل شما، گفتگو و هر فایلی که ایجنت خوانده است. harness برنامه‌ای است که مدل را احاطه کرده و وظیفه خواندن فایل‌ها از دیسک و جمع‌آوری آن بلوک را بر عهده دارد. تقریباً تمام شکایات در این مطلب در واقع شکایتی از harness هستند، نه مدل.

فایل دستورالعمل شما یک پیام است، نه یک تنظیمات

فایل دستورالعمل، پیکربندی (configuration) نیست. هیچ بخشی از runtime فایل CLAUDE.md را نمی‌خواند و آن را اعمال نمی‌کند. ابزار اجراکننده (harness)، فایل را از روی دیسک می‌خواند و متن آن را در گفتگو جای‌گذاری می‌کند. در Claude Code، این محتوا به عنوان یک پیام کاربر پس از system prompt ارسال می‌شود؛ این یعنی مدل، قوانین شما را همان‌طور می‌بیند که هر متن دیگری که تایپ کرده‌اید را می‌بیند.

این موضوع یک نتیجهٔ ناخوشایند دارد. قوانین شما با هر متن دیگری در پنجره، در شرایطی برابر رقابت می‌کنند. یک قانون، صرفاً یک ادعاست. فایلی که عامل (agent) به‌تازگی باز کرده است، شواهد محسوب می‌شود. وقتی این دو با هم اختلاف داشته باشند، شواهد اغلب پیروز می‌شوند و هیچ خطایی هم رخ نمی‌دهد، زیرا از دیدگاه مدل، هیچ اتفاق اشتباهی نیفتاده است.

مستندات رسمی این موضوع را به‌وضوح بیان کرده‌اند: فایل‌های دستورالعمل به عنوان زمینه (context) در نظر گرفته می‌شوند، نه پیکربندیِ اعمال‌شده. برای مسدود کردن یک اقدام، صرف‌نظر از اینکه مدل چه تصمیمی می‌گیرد، شما به یک hook نیاز دارید، نه یک جمله. این اصل را به خاطر بسپارید. بیشتر اصلاحاتی که در انتهای این مطلب آمده‌اند، در واقع پیاده‌سازی همین اصل برای موارد خاص هستند.

کدام فایل‌های دستورالعمل و چه زمانی بارگذاری می‌شوند

Claude Code مسیر دایرکتوری را از جایی که آن را اجرا کرده‌اید به سمت بالا (root) طی می‌کند. هر CLAUDE.md و CLAUDE.local.md از ریشه سیستم فایل تا دایرکتوری کاری شما، هنگام راه‌اندازی به‌طور کامل بارگذاری می‌شوند. این فایل‌ها به همان ترتیب به یکدیگر متصل (concatenate) می‌شوند، بنابراین فایلی که به محل اجرای شما نزدیک‌تر است در آخرین مرحله خوانده می‌شود و در یک دایرکتوری واحد، فایل .local پس از فایل اصلی ضمیمه می‌گردد.

فایل‌های موجود در زیردایرکتوری‌های پایین‌تر از دایرکتوری کاری شما رفتار متفاوتی دارند. این فایل‌ها هنگام راه‌اندازی بارگذاری نمی‌شوند، بلکه زمانی بارگذاری می‌شوند که عامل (agent) فایلی را در آن دایرکتوری بخواند. همین موضوع در مورد قوانین با دامنه مسیر (path scoped) در .claude/rules/ که دارای فیلد frontmatter با عنوان paths: هستند نیز صدق می‌کند: آن‌ها هنگام خوانده شدن یک فایل منطبق وارد context می‌شوند، نه در هر نوبت از گفتگو.

همین یک تفاوت، بخش بزرگی از شکست‌های گزارش‌شده را توضیح می‌دهد. شما قانونی را در packages/api/CLAUDE.md قرار می‌دهید، درباره API سوال می‌پرسید و عامل بدون باز کردن هیچ فایلی در packages/api/ پاسخ می‌دهد. قانون نادیده گرفته نشده است؛ بلکه اصلاً در آن لحظه وجود نداشته است. اگر مخزن شما دستورالعمل‌ها را در فایل‌های دستورالعمل هر بسته در یک monorepo تقسیم کرده است، این اولین موردی است که باید همیشه بررسی کنید.

یک تله دیگر در بارگذاری وجود دارد که رایج‌ترین نسخه از «عامل دستورات مرا نادیده گرفت» است: Claude Code فایل CLAUDE.md را می‌خواند، نه AGENTS.md. مخزنی که بر اساس AGENTS.md استانداردسازی شده و فاقد CLAUDE.md باشد، هیچ چیزی برای بارگذاری به Claude Code نمی‌دهد. پل ارتباطی پشتیبانی‌شده، یک CLAUDE.md است که خط اول آن @AGENTS.md باشد؛ این خط فایل را هنگام راه‌اندازی وارد می‌کند و هرگونه یادداشت خاص مربوط به Claude می‌تواند در زیر آن قرار گیرد. اگر محتوای اضافه‌ای برای افزودن ندارید، استفاده از symlink نیز کارساز است. تصمیم‌گیری درباره اینکه چه چیزی در وهله اول به آن فایل تعلق دارد، موضوع جداگانه‌ای است که در تفکیک دستورالعمل‌های عامل از مستندات انسانی به آن پرداخته شده است.

تأیید بارگذاری فایل پیش از بازنویسی آن

تا زمانی که از مشاهده فایل توسط عامل (agent) اطمینان حاصل نکرده‌اید، محتوا را تغییر ندهید. دو روش برای بررسی وجود دارد که روش ساده‌تر در اولویت است.

دستور /context را در نشست (session) اجرا کنید. این دستور پنجره فعلی را بر اساس دسته‌بندی نمایش می‌دهد و لیست Memory files نام تمام فایل‌های دستورالعملی که واقعاً بارگذاری شده‌اند را ذکر می‌کند. فایلی که در این لیست نباشد، در گفتگو وجود ندارد؛ بنابراین هر تغییری که در آن اعمال کنید بی‌اثر خواهد بود. دستور /memory مسیر فایل‌ها را فهرست کرده و آن‌ها را برای ویرایش باز می‌کند، حتی فایل‌هایی که هنوز وجود ندارند.

برای بررسی دقیق‌تر، بارگذاری‌ها را لاگ کنید. رویداد hook در InstructionsLoaded هر بار که یک CLAUDE.md یا یک فایل قوانین وارد context می‌شود فعال می‌گردد و matcher آن دلیل بارگذاری را مشخص می‌کند: session_start، nested_traversal، path_glob_match، include یا compact. این کد را در .claude/settings.json قرار دهید:

{
  "hooks": {
    "InstructionsLoaded": [
      {
        "matcher": "nested_traversal",
        "hooks": [
          {
            "type": "command",
            "command": "cat >> /tmp/instructions-loaded.log"
          }
        ]
      }
    ]
  }
}

این hook داده‌های خود را به صورت JSON در ورودی استاندارد دریافت می‌کند، بنابراین cat کل رکورد را به فایل ضمیمه می‌کند. هنگام کار، آن را با tail -f /tmp/instructions-loaded.log مانیتور کنید. وضعیت خروج (exit status) این رویداد نادیده گرفته می‌شود، بنابراین hook فقط می‌تواند مشاهده کند و هرگز قادر به مسدودسازی نیست. اگر فایل تو در توی شما در طول نشستی که انتظار بارگذاری آن را داشتید در لاگ ظاهر نشد، بازنویسی را متوقف کنید. مشکل در محل قرارگیری فایل است.

تأثیر نشست‌های طولانی بر قوانین شما

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

فاصله. قانونی که در نوبت 1 بیان شده، در نوبت 90 همچنان در پنجره متن حضور دارد، اما اکنون با 90 نوبت متن جدیدتر که به آنچه در حال حاضر انجام می‌دهید مرتبط‌تر است، رقابت می‌کند. شما نمی‌توانید این موضوع را با پیکربندی تغییر دهید، اما می‌توانید آن را اندازه‌گیری کنید. همان وظیفه را در یک نشست تازه اجرا کنید. اگر قانون در آنجا برقرار است اما در عمق یک نشست طولانی شکست می‌خورد، پاسخ شما «فاصله» است.

فشرده‌سازی. هنگامی که پنجره پر می‌شود، سیستم مکالمه تا آن لحظه را خلاصه کرده و از آن خلاصه ادامه می‌دهد. آنچه باقی می‌ماند، مواردی است که خلاصه‌ساز آن‌ها را مهم تشخیص داده است، که لزوماً با آنچه شما مهم می‌دانید یکی نیست. Claude Code نتیجه را بر اساس هر مکانیزم مستند می‌کند و تفاوت‌ها بسیار زیاد است. ریشه پروژه CLAUDE.md و قوانین بدون دامنه (unscoped)، پس از هر فشرده‌سازی مجدداً از روی دیسک تزریق می‌شوند. حافظه خودکار (Auto memory) نیز از روی دیسک بازخوانی می‌شود. قوانینی که دارای فراداده (frontmatter) paths: هستند، تا زمانی که فایل مربوطه دوباره خوانده نشود، از دست می‌روند. فایل‌های تو در توی CLAUDE.md در زیرشاخه‌ها نیز تا زمانی که فایلی در آن زیرشاخه دوباره خوانده نشود، از دست می‌روند.

دستورالعمل‌های خود را بر اساس آن جدول رتبه‌بندی کنید تا ترتیب شکنندگی آن‌ها مشخص شود. قانونی که فقط در چت تایپ کرده‌اید، شکننده‌ترین مورد در نشست است: این قانون تنها در صورتی باقی می‌ماند که خلاصه‌ساز آن را حفظ کرده باشد. قانون موجود در packages/api/CLAUDE.md در رتبه بعدی قرار دارد، زیرا یک بار بارگذاری شده، در خلاصه حذف شده و تنها با خواندن مجدد در آن دایرکتوری بازمی‌گردد. قانون موجود در فایل ریشه پروژه، بادوام‌ترین است، زیرا هر بار از روی دیسک بازخوانی می‌شود.

بنابراین، اگر یک دستورالعمل باید برای کل نشست معتبر بماند، باید در فایل ریشه پروژه و بدون فراداده paths: قرار گیرد. هر چیز دیگری یک بده‌بستان (tradeoff) است که باید آگاهانه انجام دهید. مدیریت آنچه در پنجره متن باقی می‌ماند به /compact با تمرکز بر آرگومان و /clear بین وظایف نامرتبط می‌پردازد؛ هر دوی این موارد نحوه تصمیم‌گیری خلاصه‌ساز درباره قوانین شما را تغییر می‌دهند.

چرا کد موجود بر قانون غلبه می‌کند

این همان شکستی است که افراد بیش از همه توصیف می‌کنند و کمتر از همه آن را عیب‌یابی می‌کنند. فایل شما می‌گوید دسترسی به پایگاه داده باید از طریق لایه repository انجام شود. اما agent یک handler می‌نویسد که مستقیماً ORM (نگاشت‌گر شیء-رابطه‌ای) را فراخوانی می‌کند. نادیده گرفته شدن شما به دلیل سبک کدنویسی نیست؛ بلکه شواهد، رأی شما را شکست داده‌اند.

یک قانون، بیانگر یک ترجیح است. اما کد، یک واقعیت را نشان می‌دهد. وقتی agent سه فایلی را که قصد ویرایش آن‌ها را دارد باز می‌کند و هر سه مستقیماً ORM را فراخوانی می‌کنند، زمینه (context) شامل یک جمله انتزاعی در یک سو و سه نمونه عینی، جدید و متناسب با وظیفه در سوی دیگر است. کپی کردن الگوی محلی معمولاً رفتار درستی است. این کار تنها در اینجا اشتباه است، زیرا شما چیزی را می‌دانید که زمینه از آن بی‌خبر است: آن فایل‌ها legacy هستند.

پس این موضوع را در قانون بنویسید. قوانینی که شواهد نقض خود را نام می‌برند، در مواجهه با یک مخزن واقعی دوام می‌آورند. قوانینی که فقط یک ترجیح ساده را بیان می‌کنند، چنین نیستند.

دسترسی جدید به پایگاه داده باید از طریق app/repositories/ انجام شود. فایل‌های موجود در app/legacy/ همچنان مستقیماً ORM را فراخوانی می‌کنند. آن کدها قدیمی هستند و الگو محسوب نمی‌شوند. از آن‌ها کپی نکنید.

جمله دوم کار اصلی را انجام می‌دهد. این جمله به agent می‌گوید که قرار است با چه چیزی مواجه شود و پیش از آنکه آن را پیدا کند، چگونه باید آن را تفسیر کند. همین اصلاح برای هر قانونی که مخزن شما به‌طور مشهود با آن در تضاد است، کاربرد دارد: سبکی در commit که تاریخچه شما از آن پیروی نمی‌کند، ساختار تستی که نیمی از مجموعه شما آن را نادیده می‌گیرد، یا قرارداد import که فقط در کدهای جدید رعایت می‌شود. هر جا که کد با فایل قوانین اختلاف دارد، آن اختلاف را در همان فایل ذکر کنید.

یک قانون مبهم قابل بررسی نیست، بنابراین قابل اجرا هم نیست

«کد تمیز بنویسید.» «بیش از حد مهندسی نکنید.» «ساده نگه دارید.» «در مهاجرت‌ها دقت کنید.» هیچ‌کدام از این موارد را نمی‌توان با یک اقدام مشخص، چه توسط عامل (agent) و چه توسط شما، تست کرد. عاملی که قانونی به او داده شود که نتواند خروجی خود را با آن بسنجد، در حال حدس زدن است و شما هم آن حدس را بر اساس حس شخصی نمره می‌دهید.

این تستی است که باید روی تک‌تک خطوط فایل خود اعمال کنید. دستور shellای را بنویسید که در صورت نقض قانون، با کد خروجی غیر صفر (non-zero) متوقف شود. اگر نمی‌توانید چنین دستوری بنویسید، آن قانون قابل بررسی نیست. این جفت‌ها را مقایسه کنید:

  • غیرقابل بررسی: «توابع را کوچک نگه دارید.» قابل بررسی: «هر تابعی که بیش از 60 خط باشد، باید در بالای آن توضیحی درباره دلیل این طولانی بودن وجود داشته باشد.»
  • غیرقابل بررسی: «تغییرات خود را تست کنید.» قابل بررسی: «دستور npm test را اجرا کنید و قبل از اعلام پایان کار، تعداد خطاها را درج کنید.»
  • غیرقابل بررسی: «فایل‌ها را سازمان‌دهی کنید.» قابل بررسی: «هندلرهای HTTP باید در src/api/handlers/ قرار بگیرند. هیچ فایل دیگری نباید در آن دایرکتوری باشد.»
  • غیرقابل بررسی: «کد را به‌درستی فرمت کنید.» قابل بررسی: «در فایل‌های .ts از تورفتگی 2 اسپیسی استفاده کنید.»

«بیش از حد مهندسی نکنید» اولین قانونی است که افراد از آن دست می‌کشند، زیرا اصلاح آن نه با یک جمله کوتاه‌تر، بلکه با جمله‌ای طولانی‌تر ممکن است: توضیح دقیق اینکه کوچک‌ترین تغییرِ کارآمد واقعاً به چه معناست معیارهایی به عامل می‌دهد که می‌تواند diff خود را با آن بسنجد.

حجم فایل نیز همان مشکل را با ظاهری متفاوت دارد. راهنمای Claude Code توصیه می‌کند هر فایل دستورالعمل زیر 200 خط باشد و مستقیماً بیان می‌کند که فایل‌های طولانی‌تر، پایبندی به دستورات را کاهش می‌دهند. یک فایل 700 خطی، دستورالعمل محکم‌تری نیست. این فایل شامل 700 خط ادعا با احتمال تناقض بیشتر است و در هر نوبت از مکالمه، از سهمیه پنجره متنی شما کسر می‌شود که مستقیماً در میزان مصرف توکن‌های شما نمایان می‌شود. ساختاردهی به فایل به‌گونه‌ای که هر قانون زیر یک عنوان قابل اسکن قرار گیرد، در نوشتن فایل دستورالعملی که عامل بتواند بر اساس آن عمل کند پوشش داده شده است.

نحوه عیب‌یابی در ده دقیقه

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

  1. بارگذاری را تأیید کنید. دستور /context را اجرا کرده و لیست فایل‌های Memory را بخوانید. اگر فایل در آنجا نیست، مسیر را اصلاح کنید و متوقف شوید. هیچ‌کدام از مراحل بعدی این لیست هنوز کاربردی ندارند.
  2. در یک نشست جدید بازتولید کنید. یک نشست جدید شروع کنید و کوچک‌ترین وظیفه‌ای که باید قانون را فعال کند، به آن بدهید. اگر در اینجا کار می‌کند اما در یک نشست طولانی شکست می‌خورد، مشکل از فاصله (distance) یا فشرده‌سازی (compaction) است. اگر در اینجا هم شکست می‌خورد، یعنی خودِ قانون مشکل دارد.
  3. رقابت را حذف کنید. همان تغییر را در دایرکتوری درخواست کنید که کد موجود در آن، از قبل از قانون پیروی می‌کند. اگر انطباق (compliance) بازگشت، کد اطراف در حال خنثی کردن دستور شما بوده است.
  4. به دنبال تداخل بگردید. دو فایل که برای یک رفتار مشابه، دستورالعمل‌های متفاوتی ارائه می‌دهند، یک خطای مستند محسوب می‌شوند: مدل ممکن است یکی را به دلخواه انتخاب کند و به شما اطلاع نخواهد داد.
  5. آن را قابل بررسی کنید و دوباره تست کنید. قانون را با یک مسیر مشخص و یک شرط بازنویسی کنید. جهش بزرگ در میزان انطباق به این معنی است که نحوه نگارش، عامل مشکل بوده است.

مرحله 4 تنها یک دستور است. تمام منابع دستورالعمل را برای آن موضوع جستجو کنید، نه فقط فایلی که در حال ویرایش آن بودید:

grep -rni "migration" --include="CLAUDE.md" --include="CLAUDE.local.md" .
grep -rni "migration" .claude/rules/ ~/.claude/CLAUDE.md ~/.claude/rules/ 2>/dev/null

وجود یک مورد مشابه در دو فایل که چیزهای متفاوتی می‌گویند، همان باگ شماست. یکی را حذف کنید. سعی نکنید با استفاده از کلمات قوی‌تر به آن‌ها اولویت بدهید، زیرا هیچ موتور رتبه‌بندی برای رسیدگی به این اولویت‌بندی وجود ندارد.

اصلاحات، به ترتیب میزان تأثیرگذاری

هر گام در زیر، نسبت به گام پیشین تأثیرگذاری بیشتری دارد و پیاده‌سازی آن هزینه‌برتر است. زمانی که بازنویسی یک قانون کم‌هزینه است، از بالا شروع کنید. به محض اینکه یک قانون اهمیت پیدا کرد و نادیده گرفتن گاه‌به‌گاه آن غیرقابل‌قبول شد، به سمت پایین حرکت کنید.

  1. قانون را مشخص و عینی کنید. یک مسیر، یک دستور یا یک شرط را نام ببرید. همان‌طور که پیش‌تر نشان داده شد، شواهد نقض‌کننده (counter-evidence) که عامل (agent) در مخزن پیدا خواهد کرد را اضافه کنید. این کار رایگان است و بخش قابل‌توجهی از موارد را اصلاح می‌کند.
  2. قانون را به موضوع تحت نظارتش نزدیک‌تر کنید. یک CLAUDE.md تو در تو، قانونی با دامنه محدود در .claude/rules/، یا یک کامنت در بالای خود فایل. به این ترتیب، قانون همزمان با کدی که بر آن اعمال می‌شود، خوانده می‌شود. این بده‌بستان را بپذیرید: هر چیزی که به این شکل بارگذاری شود، در فشرده‌سازی بعدی حذف شده و در خواندن منطبق بعدی بازمی‌گردد.
  3. اجرای قانون را به یک hook منتقل کنید. متنِ نوشتاری درخواست می‌کند، اما یک hook تصمیم می‌گیرد. hookها به عنوان کد در رویدادهای مشخصی از چرخه حیات اجرا می‌شوند و صرف‌نظر از نتیجه‌گیری مدل، اعمال می‌گردند.
  4. قانون را به یک ابزار قطعی (deterministic) بسپارید و متن نوشتاری را حذف کنید. قالب‌بندی، ترتیب importها، طول خط، importهای ممنوع، ساختار پیام commit. ruff format، prettier --write، eslint، یک hook در pre-commit. فرمت‌کننده همیشه درست عمل می‌کند و هزینه توکن آن صفر است. جمله نوشتاری بیشتر اوقات درست است اما در هر نوبت هزینه توکن دارد.

گام 3 به طور کامل. فرض کنید فایل‌های migration هرگز نباید توسط عامل ویرایش شوند. این را در .claude/settings.json قرار دهید:

{
  "hooks": {
    "PreToolUse": [
      {
        "matcher": "Edit|Write",
        "hooks": [
          {
            "type": "command",
            "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/guard-migrations.sh"
          }
        ]
      }
    ]
  }
}

و این را در .claude/hooks/guard-migrations.sh:

#!/usr/bin/env bash
set -euo pipefail

path=$(jq -r '.tool_input.file_path // empty')

case "$path" in
  */migrations/*)
    echo "Files under migrations/ are written by hand. Stop and ask first." >&2
    exit 2
    ;;
esac

exit 0

دستور chmod +x .claude/hooks/guard-migrations.sh را اجرا کنید، سپس یک نشست جدید شروع کرده و از عامل بخواهید فایلی را در مسیر migrations/ ویرایش کند. ویرایش رد می‌شود و پیام شما به عنوان دلیل بازگردانده می‌شود. خروجی وضعیت 2 در PreToolUse، فراخوانی ابزار را پیش از اجرا مسدود می‌کند و متن stderr شما به عنوان پیام مسدودکننده به مدل تحویل داده می‌شود. ${CLAUDE_PROJECT_DIR} به ریشه پروژه اشاره می‌کند، بنابراین hook در هر دایرکتوری که عامل در آن باشد، کار می‌کند. عامل نیازی ندارد با قانون موافقت کند، آن را به خاطر بسپارد یا همچنان آن را در context داشته باشد. ویرایش انجام نمی‌شود.

برای یک ممنوعیت کلی بدون هیچ منطق پیچیده‌ای، permissions.deny در تنظیمات شما همان کار را بدون نیاز به نگهداری اسکریپت انجام می‌دهد و حالت‌های دسترسی تعیین می‌کنند چه چیزی بدون پرسش از شما اجرا شود. اگر یک دستور واقعاً باید در سطح system prompt قرار بگیرد و نه در پیام کاربر، --append-system-prompt آن را در آنجا قرار می‌دهد؛ هرچند باید در هر فراخوانی ارسال شود که این برای اسکریپت‌ها مناسب‌تر از کار تعاملی است.

مواردی که نمی‌توان با دستورالعمل اصلاح کرد

شفاف باشید که کدام بخش از این موارد در حیطه مسئولیت شماست. جای‌گذاری، جمله‌بندی، تداخل بین فایل‌ها و حجم فایل، مشکلاتی هستند که نویسنده باید آن‌ها را برطرف کند. باقی موارد، رفتار ذاتی مدل است و با تغییر جمله‌بندی اصلاح نمی‌شوند.

توافق به معنای تبعیت نیست. یک عامل (agent) ممکن است قانونی را تأیید کند، آن را به‌درستی برای شما بازگو کند و دو فراخوانی ابزار بعد، آن را نقض نماید. این تأیید هیچ هزینه‌ای برای مدل ندارد و هیچ‌چیز را پیش‌بینی نمی‌کند. آن را به عنوان یک راهکار در نظر نگیرید و به عنوان یک تست روی آن حساب نکنید.

برخی عادت‌ها پایدار هستند. افزودن توضیحات (comments)، افزودن مدیریت خطای تدافعی، نوشتن خلاصه پایانی، یا اجرای دستور بعدی که بدیهی است. این رفتارها حتی تحت قانونی که آن‌ها را منع می‌کند، بازمی‌گردند؛ البته با نرخ کمتر، نه صفر. شما می‌توانید نرخ خطای خود را اندازه‌گیری کنید: یک تسک مشابه را ده بار در نشست‌های (sessions) جدید اجرا کنید و تعداد تخلفات را بشمارید. در مواردی که این عدد باید صفر باشد، آن قانون باید از پرامپت حذف شود.

نشست شما به یک الگو تبدیل می‌شود. اگر عامل در مرحله 12 قانون را شکست و شما از آن گذشتید، آن تخلف اکنون به عنوان یک نمونه در کانتکست (context) باقی می‌ماند و نسبت به خودِ قانون، تازگی بیشتری دارد. هر تخلفی را در همان لحظه که مشاهده کردید، اصلاح کنید. یک تخلف اصلاح‌نشده، به باقی نشست آموزش می‌دهد که آن رفتار مجاز است.

فایل دستورالعمل یک مرز امنیتی نیست. این فایل رفتار را شکل می‌دهد اما آن را تحمیل نمی‌کند. هر موردی که خطای آن هزینه‌بر باشد، مانند اعتبارنامه‌ها (credentials) یا دستورات مخرب، باید در سطح مجوزها (permissions) یا هوک‌ها (hooks) مدیریت شود. دور نگه داشتن اسرار از دسترس عامل همین اصل را در مورد داده‌ها اعمال می‌کند: از عامل نخواهید که فایلی را نخواند، بلکه دسترسی به آن فایل را محدود کنید تا قابل خواندن نباشد.

خلاصه مطلب: بارگذاری فایل را اثبات کنید، قانون را قابل بررسی کنید، آن را در کنار موردی که کنترل می‌کند قرار دهید، و زمانی که نرخ خطا همچنان اهمیت دارد، آن را از متن دستورالعمل خارج کنید. قانونی که عامل نتواند آن را نادیده بگیرد، قانونی است که هرگز از عامل درخواست نشده است.

FAQ

چرا Claude Code فایل CLAUDE.md مرا نادیده می‌گیرد؟

پیش از آنکه فرض کنید فایل نادیده گرفته شده است، بررسی کنید که آیا بارگذاری شده است یا خیر. دستور /context را اجرا کنید و لیست Memory files را ببینید؛ فایلی که در آن لیست نباشد، در گفتگو وجود ندارد. فایل‌های دستورالعمل به عنوان یک پیام کاربر پس از system prompt ارسال می‌شوند و به جای پیکربندی اجباری، به عنوان متن زمینه (context) در نظر گرفته می‌شوند، بنابراین تضمین قطعی برای رعایت آن‌ها وجود ندارد. اکثر موارد واقعی به یکی از چهار دلیل زیر رخ می‌دهند: فایل در زیرشاخه‌ای قرار دارد که agent هرگز آن را نخوانده است، دو فایل با هم تضاد دارند و مدل یکی را به دلخواه انتخاب کرده است، قانون برای بررسی یک عمل بیش از حد مبهم است، یا کدهای اطراف، خلاف آنچه قانون می‌گوید را نشان می‌دهند.

آیا ویرایش فایل دستورالعمل در میانه نشست، تغییری ایجاد می‌کند؟

برای نسخه‌ای که در حال حاضر در گفتگو وجود دارد، خیر. فایل‌های موجود در دایرکتوری کاری شما در زمان شروع نشست به‌طور کامل بارگذاری می‌شوند، بنابراین متنی که مدل در اختیار دارد، همان متن زمان شروع است. برای اعمال ویرایش، یک نشست جدید شروع کنید یا از agent بخواهید فایل را با ابزارهای فایل معمولی خود بخواند؛ این کار نسخه فعلی را به عنوان یک پیام جدید وارد گفتگو می‌کند. پس از عملیات compaction، فایل ریشه پروژه دوباره از دیسک خوانده می‌شود، بنابراین نسخه جدید در آن نقطه نیز اعمال خواهد شد.

وقتی یک CLAUDE.md در ریشه و یک فایل تو در تو با هم تضاد دارند، کدام پیروز است؟

هیچ‌کدام به‌طور قابل‌اطمینان. فایل‌های کشف‌شده به جای جایگزینی یکدیگر، به متن زمینه الحاق (concatenate) می‌شوند و ترتیب آن‌ها از ریشه سیستم فایل تا دایرکتوری کاری شماست، بنابراین فایلی که نزدیک‌تر است، صرفاً در آخر خوانده می‌شود. هیچ موتور اولویتی برای حل تضادها وجود ندارد و مستندات Claude Code بیان می‌کند که قوانین متناقض ممکن است به صورت تصادفی حل شوند. فایل‌های تو در تو را به عنوان مکمل‌هایی بنویسید که مسیر تحت پوشش خود را مشخص می‌کنند و به جای تلاش برای اولویت‌بندی، تضاد را حذف کنید.

آیا دستورالعمل‌های من پس از /compact باقی می‌مانند؟

بستگی به نحوه بارگذاری آن‌ها دارد. فایل CLAUDE.md ریشه پروژه، قوانین بدون دامنه (unscoped) و حافظه خودکار پس از compaction دوباره از دیسک تزریق می‌شوند. قوانین دارای frontmatter در paths: و فایل‌های CLAUDE.md تو در تو در زیرشاخه‌ها تا زمانی که فایل مربوطه دوباره خوانده نشود، از دست می‌روند. هر چیزی که فقط در چت تایپ کرده‌اید، تنها در صورتی باقی می‌ماند که summariser به‌طور اتفاقی آن را حفظ کرده باشد. اگر قانونی باید در کل نشست معتبر بماند، آن را در فایل ریشه پروژه بدون frontmatter در paths: قرار دهید.

چه زمانی یک قانون باید به جای متن، به یک hook تبدیل شود؟

زمانی که بررسی آن قطعی (deterministic) باشد و هزینه نادیده گرفته شدن آن، بیشتر از هزینه نوشتن یک اسکریپت کوچک باشد. محدودیت‌های مسیر فایل، دستورات الزامی پیش از commit و فراخوانی‌های ممنوعه ابزار، همگی شامل این مورد می‌شوند. یک hook در PreToolUse که با وضعیت 2 خارج شود، فراخوانی ابزار را کاملاً مسدود کرده و متن stderr شما را به عنوان دلیل به مدل بازمی‌گرداند، بنابراین فارغ از اینکه قانون در کجای متن زمینه باشد، اعمال خواهد شد. هر چیزی که یک formatter یا linter بتواند در مورد آن تصمیم بگیرد، باید توسط همان ابزار مدیریت شود و به‌طور کامل از فایل دستورالعمل حذف گردد.