اولین بار که یک قطعه کد تولیدشده توسط مدل زبانی را در pipeline تولیدی مستقر کردم، دو هفته بعد با یک memory leak مواجه شدم که در هیچ تست خودکاری دیده نشده بود. آن کد کامپایل می‌شد، تست واحد را پاس می‌کرد و در review انسانی بی‌عیب به نظر می‌رسید، اما در بار واقعی شکست می‌خورد. آن تجربه، نقطهٔ شروع وسواس من شد روی پرسشی که امروز به یکی از جدی‌ترین سؤالات مهندسان ارشد تبدیل شده است: کد تولیدشده با AI واقعاً چقدر قابل اعتماد است؟

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

قابل اعتماد بودن یعنی چه؟ تعریف عملیاتی

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

این چهار شرط، در ادبیات فعلی کمتر به‌طور همزمان بررسی می‌شوند. بنچمارک‌های رایج مثل HumanEval که توسط Mark Chen و همکارانش در OpenAI معرفی شد، فقط شرط اول را می‌سنجند — آن هم در مسائل الگوریتمی کوتاه که با تست‌های واحد مشخص قابل ارزیابی هستند. اما کد تولیدی، به‌ندرت شکل مسئلهٔ الگوریتمی دارد. اگر می‌خواهید بفهمید چگونه هوش مصنوعی به برنامه‌نویسی کمک می‌کند، نقش هوش مصنوعی در برنامه‌نویسی را ببینید.

تعریف عملیاتی که در پروژه‌های خودم استفاده می‌کنم، سه لایه دارد. لایهٔ اول، syntactic validity است: کد کامپایل یا اجرا می‌شود. لایهٔ دوم، semantic correctness است: کد در تست‌های نمونه درست عمل می‌کند. لایهٔ سوم، production readiness است: کد در شرایط واقعی، شامل ورودی‌های نامعتبر، حجم بالا، خطای شبکه، و حالت‌های مرزی، رفتار قابل‌قبول دارد. بیشتر بحث‌های عمومی دربارهٔ اعتبار کد مولد، در لایهٔ دوم متوقف می‌شوند؛ اما شکست‌های واقعی، عمدتاً در لایهٔ سوم رخ می‌دهند.

کد مولد در لایهٔ نحو و معنای سطحی، امروز از میانگین کد انسانی جلوتر است؛ در لایهٔ آمادگی تولید، همچنان چند پله عقب است.

آنچه بنچمارک‌ها دربارهٔ اعتبار کد می‌گویند

در سال‌های اخیر، چند بنچمارک تلاش کرده‌اند تصویر واقع‌بینانه‌تری از توانایی مدل‌ها در کدنویسی ارائه دهند. HumanEval که در سال ۲۰۲۱ منتشر شد، ۱۶۴ مسئلهٔ کوتاه الگوریتمی دارد. مدل‌های اولیهٔ GPT-3 در این بنچمارک حدود ۲۸ درصد موفقیت داشتند. امروز بهترین مدل‌ها به بالای ۹۰ درصد رسیده‌اند. اما این عدد، در عمل گمراه‌کننده است؛ چون مسئله‌های HumanEval به‌طور معمول چند خطی هستند و کیفیت ساختاری کد در آن‌ها سنجیده نمی‌شود.

SWE-bench که توسط Carlos Jimenez و همکارانش در Princeton در سال ۲۰۲۳ معرفی شد، یک تصویر بسیار واقع‌بینانه‌تر ارائه می‌دهد. در این بنچمارک، مدل باید issueهای واقعی GitHub را در پروژه‌های بزرگ پایتون حل کند. از آنجا که این issues نیازمند درک کدبیس، اجرای تست‌ها و اصلاح چندفایلی هستند، نرخ موفقیت به‌مراتب پایین‌تر است. در سال ۲۰۲۴، بهترین مدل‌ها حدود ۲۰ درصد موفقیت داشتند و در سال ۲۰۲۶، این عدد در مدل‌های frontier به بالای ۷۰ درصد رسیده. اما این آمار نیز باید با احتیاط خوانده شود؛ چون SWE-bench روی پروژه‌هایی اجرا می‌شود که در دادهٔ آموزشی مدل‌ها حضور داشته‌اند.

بنچمارک‌های تکمیلی مثل MBPP، CodeContests و LiveCodeBench تصویر را کامل‌تر می‌کنند. LiveCodeBench که برای جلوگیری از data contamination طراحی شده، سؤالاتی از مسابقات برنامه‌نویسی بعد از تاریخ قطع آموزش مدل‌ها انتخاب می‌کند. نتایج این بنچمارک نشان می‌دهد که افت عملکرد در داده‌های تازه، معمولاً ۱۰ تا ۲۰ واحد درصد است. این اختلاف، تفاوت بین حفظ کردن الگو و توانایی استدلال واقعی را نشان می‌دهد. برای آشنایی با ابزارهای فعلی این حوزه، بهترین ابزارهای هوش مصنوعی برای کدنویسی را ببینید.

بنچمارکنوع مسئلهسطح دشواریمیزان واقع‌نمایی
HumanEvalالگوریتمی کوتاهپایینمحدود
MBPPالگوریتمی متوسطمتوسطمتوسط
SWE-benchissueهای واقعی GitHubبالازیاد
LiveCodeBenchمسابقات تازهبالازیاد

الگوهای واقعی شکست در کد مولد

در تجربهٔ کار با مدل‌های زبانی برای کدنویسی، الگوهای شکست تکرارشونده‌ای دیده‌ام که در بنچمارک‌ها کمتر نمایان می‌شوند. اولین و شایع‌ترین الگو، hallucination API است: مدل تابعی را فراخوانی می‌کند که وجود ندارد، یا با پارامترهای اشتباه. این مشکل به‌ویژه در کتابخانه‌هایی که نسخه‌های متعددی دارند، شایع است. مدلی که در ژانویه با نسخهٔ ۳ کتابخانه آموزش دیده، در مارس نسخهٔ ۴ را به‌عنوان موجود فرض می‌کند و APIای اختراع می‌کند که هرگز وجود نداشته.

الگوی دوم، off-by-one و مرزهای پنهان است. کد مولد در مسائل الگوریتمی معمولاً درست است، اما در مرزها — اندیس صفر، آخرین عنصر، آرایهٔ خالی، ورودی null — خطا می‌کند. این خطاها در تست‌های واحد معمولاً پوشش داده نمی‌شوند چون تست‌ها هم توسط مدل نوشته شده‌اند و همان blind spot را دارند.

الگوی سوم، concurrency و race condition است. مدل‌ها در نوشتن کد async، مدیریت lock، و همگام‌سازی منابع ضعیف عمل می‌کنند. اگر مدل به‌طور صریح به race condition توجه نشود، احتمالاً کدی بدون synchronisation لازم تولید می‌کند که در بار پایین درست کار می‌کند و در بار بالا شکست می‌خورد. برای درک این دسته از خطاها، اشتباهات رایج در کدنویسی وردپرس را ببینید که برخی از این الگوها را در context وردپرس باز کرده است.

الگوی چهارم، error handling سطحی است. مدل‌ها معمولاً try-except ساده می‌نویسند که خطا را catch می‌کند اما آن را یا silent می‌کند یا به‌درستی مدیریت نمی‌کند. در کد تولیدی، این منجر به failure خاموش می‌شود که debugging آن بسیار دشوار است. الگوی پنجم، dependency injection ضعیف است؛ مدل‌ها به‌طور پیش‌فرض از global state و hard-coded dependency استفاده می‌کنند که تست‌پذیری و maintainability را کاهش می‌دهد.

مشکل اصلی کد مولد، خطاهای ساده نیست؛ خطاهای خاموشی است که در تست واحد پاس می‌شوند و در بار واقعی شکست می‌خورند.

شکاف امنیتی: پاشنهٔ آشیل کد مولد

مهم‌ترین ضعف کد مولد که در بحث‌های سطحی نادیده می‌ماند، بعد امنیتی است. پژوهشی که توسط Hammond Pearce و همکارانش در NYU در سال ۲۰۲۱ منتشر شد، نشان داد که ۴۰ درصد از کدهای تولیدشده توسط GitHub Copilot در سناریوهای حساس، حاوی آسیب‌پذیری‌های امنیتی بودند. این آسیب‌پذیری‌ها شامل SQL injection، XSS، path traversal و buffer overflow می‌شد.

مطالعهٔ دیگری در سال ۲۰۲۴ نشان داد که مدل‌های زبانی بزرگ در تولید کد رمزنگاری، به‌طور نظام‌مند از الگوریتم‌های منسوخ مثل MD5 یا ECB mode استفاده می‌کنند. علت ریشه‌ای این است که دادهٔ آموزشی مدل‌ها شامل میلیون‌ها نمونه کد از سال‌های مختلف است و مدل تفاوت بین کد قدیمی و به‌روز را درک نمی‌کند. برای درک الگوهای مشابه در کد امن، نوشتن کد PHP امن برای وردپرس را ببینید.

چالش عمیق‌تر این است که مدل‌ها در تشخیص آسیب‌پذیری ضعیف عمل می‌کنند. اگر از مدل بخواهید کد امن بنویسد، معمولاً کد بهتری تولید می‌کند؛ اما اگر از آن بخواهید کد را برای آسیب‌پذیری بررسی کند، نرخ خطا بالا است. یک مطالعه در سال ۲۰۲۵ نشان داد که مدل‌ها در شناسایی آسیب‌پذیری‌های subtle مثل TOCTOU (Time-of-Check to Time-of-Use) و race conditions امنیتی، نرخ false negative بالای ۵۰ درصد دارند.

راه‌حل عملی این است که کد مولد هرگز جایگزین ابزارهای تحلیل استاتیک و پویا نشود. ابزارهایی مثل Snyk، Semgrep و SonarQube همچنان ضروری‌اند. اما نکتهٔ مهم‌تر: مدل‌ها می‌توانند این ابزارها را در pipeline تقویت کنند. اگر یک مدل، خروجی ابزار تحلیل استاتیک را به‌عنوان context بگیرد و از آن خواسته شود که الگوهای مشابه در بقیهٔ کد جستجو کند، نرخ تشخیص بهبود چشمگیری می‌یابد. برای درک بیشتر از نحوهٔ کار مدل‌ها در دیباگ، چگونه هوش مصنوعی باگ‌های کد را پیدا می‌کند را ببینید.

استراتژی‌های اعتبارسنجی کد مولد

اعتبارسنجی کد مولد، نیازمند یک pipeline چندلایه است که هر لایه یک نوع خطا را هدف می‌گیرد. لایهٔ اول، static analysis است: کامپایل، lint و type check. این لایه ارزان‌ترین و سریع‌ترین است و خطاهای نحوی و type mismatch را می‌گیرد. لایهٔ دوم، unit testing است که توسط انسان نوشته شود، نه توسط همان مدل. اگر مدل هم کد و هم تست را بنویسد، همان blind spot در هر دو تکرار می‌شود. لایهٔ سوم، property-based testing است که به‌جای بررسی نمونه‌های خاص، invariants را بررسی می‌کند. لایهٔ چهارم، static security analysis است که آسیب‌پذیری‌های شناخته‌شده را شناسایی می‌کند. لایهٔ پنجم، code review انسانی با تمرکز بر مرزها و concurrency است.

یک رویکرد مؤثر که در پروژه‌های خودم استفاده می‌کنم، adversarial verification است. به‌جای اینکه از مدل بپرسیم آیا این کد درست است، از یک نمونهٔ دیگر مدل می‌خواهیم که سعی کند کد را بشکند: ورودی‌های نامعتبر بدهد، حالت‌های مرزی را تست کند، و فرض‌های پنهان را به چالش بکشد. این رویکرد، نرخ detection را به‌طور محسوسی بالا می‌برد و از تأیید تعصبی جلوگیری می‌کند.

رویکرد دیگر، mutation testing است. در این روش، تغییرات کوچک در کد ایجاد می‌شود و بررسی می‌شود که آیا تست‌ها این تغییرات را تشخیص می‌دهند. اگر تست‌ها نتوانند mutation را detect کنند، احتمالاً در پوشش نقاط بحرانی ضعیف هستند. این تکنیک برای کد مولد به‌ویژه مفید است، چون نشان می‌دهد کدام بخش‌های کد واقعاً تست نشده‌اند. اگر به بهبود مهارت دیباگ علاقه دارید، دیباگ کردن کد سفارشی وردپرس مسیر عملی مناسبی است.

تفاوت اعتبار در پروژهٔ solo و تیمی

در یک پروژهٔ solo یا prototype، کد مولد می‌تواند شتاب قابل‌توجهی بدهد. اگر کد فقط برای خودتان است و هدف بررسی ایده است، حتی کدی که ۷۰ درصد درست است ارزشمند است؛ چون ۳۰ درصد باقی‌مانده سریع‌تر از نوشتن از صفر اصلاح می‌شود. اما در پروژهٔ تیمی و تولیدی، همان کد می‌تواند منبع بدهی فنی سنگین شود.

سه تفاوت بنیادی وجود دارد. اول، در پروژهٔ تیمی، کد باید توسط اعضای دیگر خوانده، تغییر و نگهداری شود. کد مولد معمولاً از conventions تیم پیروی نمی‌کند، نام‌گذاری غیراستاندارد دارد و به الگوهای معماری موجود پروژه احترام نمی‌گذارد. نتیجه، افزایش پیچیدگی cognitive برای اعضای تیم است.

دوم، در پروژهٔ تیمی، کد در طول زمان تکامل می‌یابد. کد مولد در لحظهٔ تولید ممکن است کار کند، اما وقتی context تغییر کند، اگر ساختار درستی نداشته باشد، تغییر آن دشوار است. برای درک الگوهای ساختاری، اصول کدنویسی تمیز در پروژه‌های وردپرس را ببینید. سوم، در پروژهٔ تیمی، review انسانی یک bottleneck است. اگر حجم کد مولد زیاد باشد، reviewerها نمی‌توانند همه را با دقت بررسی کنند و به مرور از review سطحی استفاده می‌کنند. اینجاست که الگوهای شکست پنهان وارد production می‌شوند.

راه‌حل عملی، تعریف یک policy صریح برای استفاده از کد مولد در تیم است. این policy باید مشخص کند: در چه بخش‌هایی از کدبیس استفاده از کد مولد مجاز است، در چه بخش‌هایی ممنوع است، و چه سطحی از review انسانی لازم است. برای مثال، در کد مربوط به احراز هویت، پرداخت و رمزنگاری، کد مولد باید یا ممنوع باشد یا حتماً توسط متخصص امنیت review شود. برای آشنایی با چالش‌های همکاری تیمی در این حوزه، ساختاربندی پروژهٔ توسعه وردپرس را ببینید.

نکتهٔ آماری مهم: یک مطالعه در سال ۲۰۲۵ نشان داد که تیم‌هایی که از دستیارهای کدنویسی استفاده می‌کنند، در تکمیل تکالیف سرعت بالاتری دارند، اما نرخ defect density در آن‌ها در ابتدا بالاتر است. این اختلاف پس از ۶ ماه و با یادگیری الگوهای استفاده، به تعادل می‌رسد. یعنی برای تیم‌ها، منحنی یادگیری استفادهٔ درست از کد مولد، حداقل چند ماه است. بحث کامل‌تر این موضوع در چالش‌های AI در برنامه‌نویسی تیمی بررسی شده است.

پرسش‌های پرتکرار مهندسان دربارهٔ اعتبار کد مولد

آیا کد مولد می‌تواند جایگزین code review انسانی شود؟ نه. کد مولد می‌تواند لایه‌ای از بررسی خودکار باشد، اما نمی‌تواند جایگزین قضاوت انسانی شود. دلیل این است که مدل‌ها در تشخیص آسیب‌پذیری‌های subtle، نقض invariants و مسائل معماری ضعیف عمل می‌کنند. بهترین حالت، ترکیب کد مولد به‌عنوان draft، ابزارهای تحلیل خودکار و review انسانی متمرکز است.

کدام زبان‌های برنامه‌نویسی بیشترین اعتبار را در کد مولد دارند؟ زبان‌هایی که دادهٔ آموزشی بیشتری دارند، عملکرد بهتری نشان می‌دهند. پایتون، JavaScript، TypeScript و Java در صدر هستند. زبان‌هایی مثل Rust، Haskell و زبان‌های دامنه‌محور، کد ضعیف‌تری تولید می‌کنند، چون دادهٔ آموزشی محدودتری دارند. برای زبان‌های خاص مثل PHP در context وردپرس، عملکرد متوسط است و نیاز به review انسانی بالاتری دارد.

آیا مدل‌های بزرگ‌تر همیشه کد بهتری تولید می‌کنند؟ نه به‌طور خطی. در برخی taskهای کوتاه، مدل‌های متوسط با prompt engineering بهتر می‌توانند عمل کنند. اما در taskهای پیچیده که نیاز به درک context بزرگ دارند، مدل‌های بزرگ‌تر به‌طور محسوسی بهتر هستند. نکتهٔ مهم: مدل بزرگ‌تر با prompt بد، می‌تواند از مدل کوچک با prompt خوب بدتر عمل کند.

چگونه می‌توان نرخ اعتبار کد مولد را در پروژه افزایش داد؟ سه اقدام مؤثر: اول، ارائهٔ context غنی به مدل — شامل فایل‌های مرتبط، conventions پروژه و مستندات API. دوم، درخواست تست‌های جامع از مدل و سپس بازبینی آن‌ها توسط انسان. سوم، استفاده از تکنیک‌های self-consistency که در آن چند نمونه از مدل گرفته می‌شود و بهترین انتخاب می‌شود.

آیا کد مولد در محیط‌های regulated قابل استفاده است؟ بله، اما با محدودیت‌های سختگیرانه. در محیط‌هایی مثل healthcare و finance، هر خط کد مولد باید traceable باشد، یعنی مشخص باشد که توسط چه مدلی، با چه promptی و در چه تاریخی تولید شده. همچنین باید در pipeline review قرار گیرد که لاگ کامل داشته باشد. این الزامات، هزینهٔ استفاده را بالا می‌برد اما ریسک را به‌شدت کاهش می‌دهد.

آیا مدل‌ها می‌توانند کد خودشان را debug کنند؟ در سطح محدود، بله. مدل‌ها می‌توانند خطاهای واضح را تشخیص و اصلاح کنند، به‌ویژه اگر پیام خطا و context کد در اختیارشان باشد. اما در خطاهای مربوط به state خارجی، race condition و منطق کسب‌وکار پیچیده، عملکرد ضعیف است. توانایی دیباگ مستقل مدل‌ها یک حوزهٔ تحقیقاتی فعال است و ممکن است در آینده بهبود یابد.

مسیری که تیم‌های مهندسی باید ترسیم کنند

پس از چند سال کار عملی با مدل‌های زبانی برای کدنویسی، سه نتیجه‌گیری برای من روشن است. اول، اعتبار کد مولد یک ویژگی ثابت نیست؛ تابعی از بستر، نوع مسئله و سطح review است. کد مولد در یک prototype با ۸۰ درصد اعتبار مفید است، اما همان کد در یک سیستم پرداخت با همان نرخ، یک ریسک جدی است. بنابراین پرسش درست این نیست که آیا کد مولد قابل اعتماد است، بلکه این است که در چه سطحی از risk tolerance برای چه کاربردی.

دوم، مسیر پیشرفت مدل‌ها خطی نیست و به موازات آن، ابزارهای verification هم در حال بلوغ هستند. امروز تکنیک‌هایی مثل property-based testing، mutation testing و adversarial verification به‌طور مؤثر نرخ detection را بالا می‌برند. تیم‌هایی که این ابزارها را در pipeline خود ادغام می‌کنند، تجربهٔ بسیار بهتری از کد مولد دارند. اگر به مسیر کلی این حوزه علاقه دارید، مزایا و معایب تولید کد با هوش مصنوعی را ببینید.

سوم، مسئولیت نهایی بر دوش مهندس انسانی است. مدل، ابزار است؛ تصمیم‌گیری با مهندس است. اگر کد مولد در production شکست بخورد، پاسخگویی به کاربر نهایی با تیم است، نه با مدل. این مسئولیت، ما را ملزم می‌کند که استانداردهای verification را بالاتر از آنچه برای کد انسانی داریم، نگه داریم — نه به‌خاطر ضعف مدل، بلکه به‌خاطر تفاوت شناخت ما از کد مولد. برای مطالعهٔ پایه‌های مفهومی این حوزه، هوش مصنوعی مولد را در ویکی‌پدیا دنبال کنید.

اگر در پروژه‌ای تجربه‌ای داشته‌اید که در آن کد مولد به‌طور غیرمنتظره‌ای شکست خورد یا برعکس، موفقیتی بالاتر از انتظار داشت، تجربه‌تان را بنویسید. جزئیات آن سناریو — نوع کد، نوع ورودی، نوع شکست — برای مهندس بعدی که همین مسیر را طی می‌کند، از هر benchmarkی ارزشمندتر است.