اگر امروز کدنویسی را به یک عامل هوش مصنوعی میسپارید، احتمالاً با توهماتی مواجه شدهاید که معماری پروژه شما را به جای پیشرفت، به هر سو میکشاند. مشکل اصلی این نیست که مدلها نمیتوانند کد بنویسند، بلکه ناتوانی آنها در برنامهریزی نقشههای پیچیده بدون انحراف از مسیر است. این استدلال مرکزی توسعهدهندهای بود که در ۴ اکتبر ۲۰۲۶ در وبسایت dev.to چارچوبی مفصل برای مدیریت ریسک به اشتراک گذاشت. هشدار او بهویژه زمانی حیاتی میشود که کلیدبورد را برای نوشتن یک سیستم پیچیده مانند سیستم فایل Copy-on-Write (COW) به هوش مصنوعی میسپارید؛ کاری که همچنان یک قمار با ریسک بالا محسوب میشود.
با تکیه بر پوششهای قبلی ما درباره اینکه چگونه عاملها از SOPها و گیتها برای ساخت همین سیستم فایل استفاده میکنند، این فاز جدید از «چه چیزی» به «چگونه» حرکت میکند. مشکل بنیادین این است که عاملهای هوش مصنوعی مجریان فوقالعادهای هستند اما برنامهریزان ضعیفیاند. بدون یک نقشه صلب و سختگیرانه، یک عامل ممکن است سقف پروژه را پیش از آنکه حتی پی ساختمان کنده شود، به پایان برساند. این چالش با رویکردهای پیشین برای جلوگیری از حدسهای تصادفی دستیاران هوش مصنوعی در پروژههای کدنویسی همسو است که بر اهمیت داشتن یک نقشه راه دقیق تأکید داشت.
پیچیدگی نقشههای سیستم فایل
طراحی یک سیستم فایل نیازمند کوهی از دانش پیشنیاز است. یک نقشه درست بسیار فراتر از چند تصمیم ساده است. نویسنده اشاره میکند که بدون یک فرآیند ساختاریافته، یک عامل ممکن است در پاسخ به پرسشهای حیاتی معماری دچار سردرگمی شود، پرسشهایی مانند:
- ترکیب واحدها: چه چیزی در واحد خودکفا قرار میگیرد و این واحد چند اتاق دارد؟
- فرمت دادهها: فرمت دادهها چگونه تعریف میشود و اندازه هر اتاق چقدر است؟
- پارتیشنبندی: آیا استرایپها (Stripes) متغیر هستند و آیا پارتیشنها قابل جابجاییاند؟
- ژورنالینگ: ژورنال چگونه مدیریت میشود و آیا نیاز به نصب یک گیت داریم؟
- اولویتبندی: اولین هدف چیست؛ ابتدا اصلاح پی ساختمان یا ساخت سقف؟
حتی یک انسان که شب و روز در مراجع جستوجو میکند، ممکن است پنج سال زمان ببرد تا اولین طرح طراحی را تولید کند. در حالی که عاملهای هوش مصنوعی آموزش دیدهاند، اما مستعد این هستند که «به ته خط بروند»، بیش از حد اعتمادبهنفس پیدا کنند و با شتاب در یک مسیر واحد تا پایان پیش بروند. چون آنها میتوانند بدون قصد فریب دادن، دچار توهم شوند، توسعهدهنده به روشی نیاز دارد تا تایید کند آیا اطلاعات ارائه شده درست است یا غلط.
سامانه تخاصمی سه-عاملی
برای حل این بحران، نویسنده یک سامانه تخاصمی چند-عاملی بر اساس این ایده پیاده کرد که «سه راهب آب ندارند»؛ به این معنا که یک دیدگاه واحد کافی نیست. این سیستم از نقشهای زیر تشکیل شده است:
۱. عامل اصلی: این عامل برنامه را مدیریت میکند و پرسشهای مشخصی میپرسد. او درباره استدلالها قضاوت نمیکند، بلکه تایید میکند که آیا نتایج معتبر هستند یا خیر. او تضمین میکند که فرآیند طبق برنامه پیش برود (مثلاً: «امروز تصمیم میگیریم چند اتاق طراحی کنیم»).
۲. عامل قدرتمند (A): مسئول جمعآوری اطلاعات و پیشنهاد پاسخی است که بهظاهر درست به نظر میرسد.
۳. پشتیبان (B): به دنبال شواهد تاییدکننده غیرهمپوشان و استدلالهای دیگری میگردد که پاسخ را تقویت کنند. اگر موردی پیدا نشود، گزارش میدهد که نتوانسته است چیزی بیابد.
۴. مخالف (C): به دنبال شواهد قوی میگردد که نشان دهد پاسخ اصلاً درست نیست. شواهد ضعیف نادیده گرفته میشوند و فقط استدلالهای متقابل قوی گزارش میشوند.
این رویارویی سه-جانبه تا سه دور تکرار میشود. در دور دوم، عامل اصلی متریالهای دور اول، شامل هر دو دیدگاه تاییدکننده و مخالف را ارائه میدهد تا استدلال عمیقتری را تحمیل کند. اگر پس از سه دور نتیجهای حاصل نشد، فرآیند متوقف شده و سوال خلاصه شده و برای تصمیم نهایی به انسان ارجاع داده میشود.
حفاظها در برابر سوگیری هوش مصنوعی
برای جلوگیری از انحراف عاملها یا موافقت ساده با کاربر، نویسنده چهار محدودیت سختگیرانه اعمال کرد:
- تعیین هدف: عامل قدرتمند A باید پیش از شروع، هدفی را تعیین کند. اگر نتیجه منحرف شود (مثلاً هدف «سه اتاق» بود اما نتیجه شد «کفپوش بهتر است»)، نتیجه باطل است.
- دقت تجربی: هر برنامه آزمایشی باید شامل یک هدر فایل با یک معیار (سنگنوشت)، یک بند شکست (سنگنوشت)، یک بند پذیرش معکوس و لیستی از سوالاتی باشد که نمیتواند به آنها پاسخ دهد.
- حذف سوگیری کاربر: عاملها تمایل طبیعی به موافقت با کاربر دارند. برای متوقف کردن این روند، حتی پیشنهادات کاربر باید از فرآیند سه-جانبه عبور کنند. اگر کاربر اصرار به پذیرش داشته باشد، هوش مصنوعی آن را ثبت میکند اما شواهد را در قالب یک هشدار باقی میگذارد.
- تنوع مدلها: برای اجتناب از سوگیری «تفکر تک-منبعی»، نویسنده یک مدل محلی را در کنار هوشهای مصنوعی اصلی ادغام کرد. اگرچه مدل محلی اغلب توانایی کمتری دارد، اما گاهی در فاز حمله، «جرقههای الهام» ارائه میدهد.
علاوه بر این، منابع دادهی عامل اصلی غیرقابل اعتماد تلقی میشوند. هر عامل باید دادهها را بهطور مستقل اندازهگیری کند تا از توهم عامل اصلی در تزریق داده به کانتکست و سوگیری در قضاوتهای دیگران جلوگیری شود.
این امر نقش انسان را تغییر میدهد: بهجای بررسی اینکه آیا کد «واقعی» است یا توهم، انسان فقط چهار پرسش سطحبالای معماری را قضاوت میکند: آیا تست مورد نظر چیز درستی را اندازهگیری میکند؟ آیا ناوردا (Invariant) صحیح است؟ آیا مبنای تصمیم درست است؟ و آیا موازنه (Trade-off) پذیرفتنی است؟

بازتعریف «بهترین تجربیات» برای ماشینها
جنجالیترین ادعای این گزارش این است که «بهترین تجربیات» (Best Practices) سنتی کدنویسی، در واقع موانعی برای هوش مصنوعی هستند. اکثر استانداردهای انسانی — مانند نامهای کوتاه توابع، تودرتویی کم حلقهها و انتزاعهای سنگین — برای سازگاری با پهنای باند محدود مغز انسان طراحی شده بودند.
برای یک عامل هوش مصنوعی، این محدودیتها بیمعنی یا حتی مضرند. یک عامل میتواند ده سطح از حلقههای for را به عنوان یک پیمایش ساده مدیریت کند و تغییر دادن یک نقطه در کد، هزینهای برابر با تغییر ده نقطه دارد. انتزاع و کپسولهسازی، در حالی که برای نگهداری انسانی مفیدند، به عنوان بزرگترین منابع باگ در کدهای تولید شده توسط هوش مصنوعی ذکر شدهاند. وقتی یک عامل تابعی را تغییر میدهد، از grep استفاده میکند؛ بنابراین، نامهای توصیفی مختصاتی هستند که نرخ توهم را کاهش میدهند.
بازرسی قوانین قدیمی
نویسنده یک ممیزی چهار مرحلهای پیشنهاد میدهد تا تعیین کند آیا یک قانون کدنویسی باید حفظ شود یا خیر:
۱. شناسایی مشکل اصلی: این قانون در ابتدا قرار بود چه مشکلی را حل کند؟ اگر دلیل آن ناشناخته است، قانون فوراً حذف شود.
۲. بررسی تداوم مشکل: اگر قانون برای حل مشکلاتی مثل «انسانها نمیتوانند به خاطر بسپارند»، «انسانها نمیتوانند همه را بخوانند» یا «بازبینها بیش از حد مشغول هستند» بود، اکنون منسوخ شده است.
۳. جستوجوی دلیل غیرانسانی: اگر دلیلی وجود دارد که به محدودیتهای انسانی مربوط نمیشود، قانون حفظ شده و دلیل آن بازنویسی میشود.
۴. تبدیل دلیل به گیت: اگر دلیل نتواند به یک گیت مکانیکی تبدیل شود، به یک «پیشنهاد» تنزل مییابد.
بر اساس این منطق، استانداردهای زیر بهروزرسانی شدند:
- نامها: نامهای کوتاه لغو شدند. هیچ محدودیتی در طول وجود ندارد؛ نامها باید توصیفی باشند (مثلاً
stripe_indexبهجایi). - طول تابع: «محدودیت ۲۰ خطی» بازنویسی شد. توابع اکنون بر اساس این معیار که «آیا یک مورد را میتوان بهطور مستقل تایید کرد» برش میخورند، نه بر اساس تعداد خطوط.
- تودرتویی: محدودیتهای عمق کاهش یافت. هیچ محدودیتی برای عمق وجود ندارد؛ محدودیت اکنون روی تعداد مسیرهای اجراست.
- اصل DRY (خودت را تکرار نکن): تسهیل شد. تکرار مجاز است تا زمانی که توسط ماشین تولید شده باشد و نه با کپی دستی.
- پلیمورفیسم: جایگزینی شاخههای شرطی با پلیمورفیسم برای مجموعههای بسته لغو شد و به نفع Enumها و Matchهای جامع تغییر کرد.
- خروج واحد (Single Exit): لغو شد. بازگشتهای زودهنگام (Early returns) اکنون آزادانه مجاز هستند.
- محدودیت ستون: محدودیت ۸۰ ستونی به ابزارهایی مثل
rustfmtسپرده شد؛ نامها برای عرض خط کوتاه نمیشوند. - بهینهسازی: عبارت «از بهینهسازی زودهنگام اجتناب کنید» به یک پیشنهاد تنزل یافت.
استانداردهای جدید کدنویسی سازگار با AI در زبان Rust
برای کاهش نرخ توهم و افزایش قابلیت اطمینان، نویسنده چندین قانون سختگیرانه را در زبان Rust اجرا میکند:
- لغو اختصارات: نامهایی مانند
cnt،idx،bufیاtmpممنوع هستند. آنها با نامهای صریح مانندstripe_indexجایگزین میشوند. اختصارات دامنه (مانندlbaیاcrc) تنها در صورتی مجاز هستند که در یک جدول اختصارات معتبر ثبت شده باشند. حروف تککاراکتری ممنوعاند:iتبدیل بهstripe_indexمیشود، پارامتر جنریکTتبدیل بهKeyمیشود، لایفتایم'aتبدیل به'journalمیشود وErr(e)تبدیل بهErr(error)میگردد. - پیششرطها در نامها: نامها باید اقدام و وضعیت را بیان کنند. بهجای
write_node،نویسنده ازappend_verified_node_to_journalاستفاده میکند که مشخص میکند داده را اضافه میکند (نه جایگزین)، ورودی تایید شده است و مقصد ناحیه ژورنال است. نام تستها باید سناریو و انتظار را بیان کند، مانندcrash_between_data_write_and_commit_keeps_previous_generationبهجایtest_commit. - اولویت تایپ بر کامنت: معنا باید در سیستم تایپ زندگی کند. بهجای استفاده از کامنت برای توضیح یک بُعد (مثلاً
dim0: nationality) ،نویسنده از Enumهای خاص استفاده میکند (مثلاًnumber_of_people_in_japan[Nationality::USA][Gender::Woman][AgeBand::Teenager18To24]). این تضمین میکند که یک بُعد اشتباه منجر به خطای زمان کامپایل شود. - شاخهبندی جامع: استفاده از بازوهای Wildcard (
_ =>) در دستورات match ممنوع است. با نوشتن تکتک حالتها، توسعهدهنده کامپایلر Rust را مجبور میکند تا به عنوان بازبین اصلی عمل کند. اگر یک مورد جدید به Enum اضافه شود (مثلاً اضافه کردن نوع جدید بهMedium { Rotational, SolidState, Zoned { zone_size_in_bytes: u32 } }) ،کد تا زمانی که هر بازوی match بهروز نشود، کامپایل نخواهد شد.
شاخهبندی پیشرفته و ایمنی تایپ
برای انتقال بیشتر بررسیها از انسان به ماشین، نویسنده چندین الگوی خاص Rust را به کار میگیرد:
- تطبیق تاپل (Tuple Matching): برای تعامل بین دو مورد، نویسنده یک match جامع روی یک تاپل مینویسد. در
singlefs،تابعgeometryروی(Candidate, MapScope)تطبیق میدهد. حتی اگر دو ردیف مقادیر یکسانی داشته باشند، ادغام نمیشوند؛ این تضمین میکند که اضافه کردن چهارمین کاندیدا باعث خطای کامپایلر شود. - مجموعههای بسته: از Enumها برای مجموعههای بسته بهجای Trait Objectها استفاده میشود، زیرا متد پیشفرض یک Trait مانند یک بازوی Wildcard پنهان عمل میکند. Traitها اگر تنها یک پیادهسازی داشته باشند یا فقط برای «سهولت در تعویضهای آینده» باشند، انتزاع نمیشوند.
- غیرقابلنوشتن کردن حالتهای غیرقانونی: نویسنده از سیستم تایپ برای جلوگیری از خطاهای منطقی استفاده میکند. ایجاد تایپهای مجزا برای
LogicalAddress(pub u64)وPhysicalAddress(pub u64)مانع از آن میشود که عامل، نوع آدرس اشتباه را به تابعی مانندread_block(address: PhysicalAddress)ارسال کند. - گیتهای تایید: یک
RawNode(داده تایید نشده از دیسک) باید از طریق متدverifyکه چکسام را بررسی میکند، بهVerifiedNodeتبدیل شود. این باعث میشود «فراموش کردن تایید» در سطح کامپایل غیرممکن شود. - پارامترهای مبتنی بر تایپ: پارامترهای Boolean با Enumها جایگزین میشوند.
write(node, true)باwrite(node, Durability::Synced)جایگزین میشود تا وضوح در محل فراخوانی فراهم شود. - ساخت صریح: هنگام ساخت یک Struct، هر فیلد باید بهطور کامل نوشته شود. استفاده از
..Default::default()ممنوع است زیرا مانند یک بازوی Wildcard روی فیلدها عمل میکند. - تبدیلهای ایمن: کلمه کلیدی
asبرای تبدیلهای عددی با احتمال از دست رفتن داده ممنوع است؛try_fromبرای مدیریت شکستها بهجای بریدگی (Truncation) یا Wrap شدن بیصدا الزامی است.
مدیریت خطا و ناورداها
خطاهای قابل بازیابی (مانند شکستهای I/O، فساد دادههای روی دیسک یا اتمام فضای ذخیرهسازی) از طریق تایپهای Result مدیریت میشوند. این خطاها بر اساس تصمیمی که فراخواننده باید بگیرد (مثلاً «پیدا نشد» در مقابل «کمبود فضا») دستهبندی میشوند، نه بر اساس علت زمینهای. نویسنده از تایپهای خطای یکپارچه مانند anyhow در مرزهای عمومی اجتناب میکند زیرا آنها مانند یک «بازوی Wildcard» روی خطاها عمل میکنند.
نقض ناورداها (Invariant violations) به عنوان باگ تلقی شده و باعث اجرای فوری Assertionها میشوند. بهجای استفاده از unwrap() ،نویسنده expect() را با یک پیام مفصل که توضیح میدهد کدام ناوردا مورد استناد است، الزامی میکند. مثالها عبارتند از:
.expect("leaf number is not in the position table: the position table did not keep up after the split")u64::try_from(distinct_groups.len()).expect("the number of distinct nodes fits in u64")
هزینه قطعیت
این رویکرد هزینه بالایی در قالب توکنها و زمان «هدر رفته» دارد. فاز طراحی سه هفته به طول انجامید بدون اینکه حتی یک خط کد پیادهسازی نوشته شود. این فرآیند مقادیر عظیمی از توکنها را مصرف میکند — یک سوال میتواند سه عامل را در هشت دور گفتگو درگیر کند، در حالی که متریالهای پسزمینه از دو هزار خط فراتر میروند. کدهای آزمایشی ممکن است بسیار طولانی باشند بدون اینکه سهمی در پیادهسازی نهایی داشته باشند.
با این حال، دستاورد این است که سیستمی حاصل میشود که در آن هیچ نتیجه تاییدنشدهای هرگز وارد کدبیس نمیشود. توسعهدهنده دیگر زمان خود را صرف خواندن متریالها برای بررسی توهمات نمیکند؛ در عوض، بر منطق سطحبالا تمرکز میکند. این تغییر نشاندهنده یک تحول بنیادین در مدل ذهنی توسعهدهنده است: حرکت از نوشتن کد برای انسانهای دیگر به سمت نوشتن «پرامپتها» و «محدودیتها» برای ماشینها، در حالی که کامپایلر به عنوان داور نهایی حقیقت عمل میکند. این سطح از سختگیری در طراحی، برای جلوگیری از شکست پروژههای AI در بازبینیهای بودجه به دلیل نبود معیارهای پایه ضروری است، چرا که قطعیت فنی تنها راه توجیه هزینههای بالای توکن است.




گفتگو