یک مسئله، یک‌ ابزار، سه سطح نگاه!

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

موجی که هیجان ناشی از توسعه PoCها یا حتی گاها MVPهایی که به سرعت با سرویس‌های AI توسعه داده می‌شن؛ خیلی‌ها رو از صرافت «یادگیری اصولی» غافل کرده؛ باعث شکل‌گیری یک نوع توهم خطرناک شده: اینکه چون تونستم یه چیزی بسازم، پس اون رو می‌فهمم. این ابتلا به توهم دانایی، خصوصا وقتی فرد به چیزهایی دست یافته که پیشتر، یا قادر به توسعه‌شون نبوده، یا زمان و انرژی و استرس خیلی بالایی بابت توسعه متحمل می‌شده؛ خیلی خطرناکه!

بله، شما می‌تونید با نوشتن پرامپت و مدل‌هایی که روز به روز هم بهتر می‌شن؛ نرم‌افزارهایی رو توسعه بدید؛ ولی این برای یک «شرکت یا تیم نرم‌افزاری» و برای ساختن «مسیر و آینده شغلی» کافی نیست. اما برای یک شرکت نرم‌افزاری، یک تیم مهندسی، یا حتی برای ساختن یک مسیر شغلی جدی، «کار کردن در ظاهر» کافی نیست.

مسئله فقط این نیست که آیا کد اجرا می‌شه یا نه. مسئله اینه که آیا این کد امنه؟ قابل نگهداریه؟ قابل تسته؟ قابل مشاهده و مانیتور کردنه؟ با معماری سیستم سازگاره؟ با استانداردهای تیم و سازمان هم‌خوانه؟ و آیا فردی که اون رو تولید کرده، واقعاً می‌فهمه چه چیزی وارد سیستم کرده؟

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

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

مثال: پیاده‌سازی قابلیت احراز هویت و سطح دسترسی در یک REST API:

سطح اول: توسعه‌دهنده‌ای که کار می‌کنه

پرامپت:

«Authentication و Authorization رو به API اضافه کن»

خروجی؟ کدی که کامپایل می‌شه، تست می‌شه، merge می‌شه.

ولی پشت این چند کلمه، ده‌ها تصمیم فنی پنهانه که هیچ‌کدوم پرسیده نشده:

  • JWT یا Session-based؟ با چه دلیلی؟
  • توکن کجا ذخیره می‌شه؟ در localStorage؟ cookie؟ memory؟عمرش چقدره؟ آیا refresh token داریم؟
  • اگر refresh token دزدیده شد چه می‌شود؟
  • پسورد با چه الگوریتمی hash می‌شه؟
  • اگر کاربری هزار بار اشتباه وارد کنه چه اتفاقی می‌افته؟
  • این کد چطور تست می‌شه؟ اصلاً می‌شه تستش کرد؟
  • آیا logout واقعاً token رو بی‌اعتبار می‌کنه یا فقط از سمت UI کاربر رو بیرون می‌اندازه؟
  • آیا authorization در سطح business rule هم رعایت شده یا فقط endpointها محافظت شدن؟
  • آیا اطلاعات حساس داخل logها نشت می‌کنه؟
  • آیا تستی برای مسیرهای شکست داریم؟
  • آیا کسی می‌تونه با تغییر claim یا دستکاری token به داده‌ای دسترسی پیدا کنه که نباید؟

هیچ‌کدوم بیان نشده، پس مدل از default‌های خودش استفاده می‌کنه. default‌هایی که لزوماً با context سرویس، threat model اون، یا استانداردهای تیم، یا نیاز اون پروژه هماهنگ نیستن. مشکل این فرد این نیست که از AI استفاده کرده. مشکل اینه که نمی‌دونه باید چه چیزهایی رو از AI بخواد، چه چیزهایی رو بررسی کنه، و کجاها خروجی AI می‌تونه خطرناک باشه.

این نوع استفاده از AI، بیشتر از اینکه نشونه‌ی بهره‌وری باشه، نشونه‌ی واگذاری تصمیم‌های مهندسی به ابزاریه که context کامل، مسئولیت production، و پاسخ‌گویی سازمانی نداره.

در چنین حالتی، AI فقط سرعت تولید کد رو بالا نمی‌بره؛ سرعت تولید ریسک رو هم بالا می‌بره.

این توسعه‌دهنده کد ننوشته، به مدل اجازه داده تصمیم بگیره و کد بنویسه. همچنین این توسعه‌دهنده عموما متوجه برخی یا حتی اغلب تصمیماتی که مدل می‌گیره نخواهد شد.


سطح دوم: توسعه‌دهنده‌ای که «با دانش قبلی» فکر می‌کنه

پرامپت:

«می‌خوام Authentication و Authorization رو به صورت امن به یه REST API با Go اضافه کنم.

روش احراز هویت: JWT با الگوریتم RS256. کلیدهای private/public جدا باشن. HS256, MD5, SHA, یا هر الگوریتم reversibleای قابل قبول نیست. Access token با TTL پانزده دقیقه، Refresh token هفت روز، با قابلیت بی‌اعتبار کردن که فقط در httpOnly Secure Cookie ذخیره بشه. هیچ token‌ای نباید در localStorage ذخیره بشه.

ذخیره‌سازی: پسورد با Argon2id هش بشه. Refresh tokenها در Redis باشن با امکان revoke.

مکانیزمAuthorization: به‌صورت RBAC ساده با سه نقش. Middleware جداگانه برای بررسی دسترسی. Permission‌ها از یه config map بیان، hardcode نشن.

آسیب‌پذیری‌هایی که باید جلوگیری بشه: JWT Algorithm Confusion، brute force روی login endpoint با rate limiting دو لایه، timing attack روی مقایسه‌ی token.

امکان Observability: هر login موفق و ناموفق با IP، timestamp و user agent لاگ بشه. Metric های Prometheus برای موفقیت و شکست احراز هویت.

امکان Testability: با auth middleware و باید بدون HTTP server واقعی قابل تست باشه. یه test helper برای تولید token معتبر و نامعتبر.

هر تصمیم طراحی که می‌گیری رو با دلیل توضیح بده. لایبری‌ها و ورژن مورد استفاده رو از منظر آسیب‌پذیری‌های شناخته شده چک کن.»

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

مهندس خوب وقتی از AI استفاده می‌کنه، فقط نمی‌گه چه چیزی بساز. می‌گه با چه روشی و با چه محدودیت‌هایی بساز، چه ریسک‌هایی رو در نظر بگیر، چه چیزهایی ممنوعه، چه چیزهایی باید تست بشه، و قبل از تولید کد، تصمیم‌های طراحی رو توضیح بده.

اینجا AI هنوز ابزاره، نه تصمیم‌گیرنده نهایی.

مهندس می‌تونه خروجی رو نقد کنه، ازش سؤال بپرهد، trade-offها رو بررسی کنه، و اجازه نده یک پیاده‌سازی ظاهراً درست، بدون فهم و کنترل وارد codebase بشه.

در این سطح، AI می‌تونه واقعاً بهره‌وری ایجاد کند. چون روی یک پایه‌ی مهندسی سوار شده.
اما اینجا هم یک مشکل باقی می‌مونه. اگر هر مهندس در هر تیم، برای خودش یک پرامپت خوب بنویسه، آیا خروجی کل سازمان یکدست و قابل کنترل خواهد بود؟ احتمالاً نه.


سطح سوم: نگاه سازمانی، Skill، Agent و استاندارد قابل بررسی و تکرار

در یک سازمان جدی، مسئله فقط این نیست که یک مهندس بتونه یک پرامپت خوب بنویسه. مسئله اینه که دانش و استاندارد مهندسی نباید در ذهن چند نفر، چند فایل پراکنده، یا چند مکالمه‌ی اتفاقی با AI دفن بشه.

اگر یک شرکت ده تا تیم داشته باشه و هر تیم Authentication و Authorization رو با تفسیر خودش پیاده کنه، خروجی احتمالاً چیزی شبیه این می‌شه:

یک تیم از JWT استفاده می‌کنه.
یک تیم session-based جلو می‌ره.
یک تیم refresh token داره، یکی نداره.
یک تیم role-based authorization می‌نویسه، یکی policy-based.
یک تیم token رو در localStorage ذخیره می‌کنه، یکی در cookie.
یک تیم structured logging داره، یکی token رو هم داخل log می‌ریزه.
یک تیم تست مسیرهای امنیتی داره، یکی فقط happy path رو تست کرده.
یک تیم تصمیم‌های امنیتی رو مستند کرده، یکی هیچ چیزی ننوشته.

نتیجه چی می‌شه؟ در ظاهر، همه از AI استفاده کردن. ولی در عمل، سازمان دچار پراکندگی، بدهی فنی و ریسک امنیتی شده. و اینجاست که بحث Skill و Agent و البته مدیریت، سیاست‌گذاری و نظارت سازمانی معنا پیدا می‌کنه.

به جای اینکه هر کس از صفر به AI توضیح بده Authentication و Authorization در شرکت ما یعنی چی، سازمان باید دانش مهندسی خودش رو تبدیل به یک دارایی قابل استفاده کنه.اینجا دیگه پرامپت نیست. Skill است، یه agent مشترک که دانش و استانداردهای فنی سازمان رو توی خودش داره؛ اونم با مستندات، مثال، ورژن و…
مثلاً یک Authentication & Authorization Skill سازمانی می‌تونه شامل این چیزها باشه:

[استانداردهای امنیتی شرکت؛ نسخه ۲.۳]

استاندارد رسمی احراز هویت در شرکت
الگوی مورد قبول برای access token و refresh token
قوانین مربوط به token lifetime، rotation و revocation
محل‌های مجاز و غیرمجاز برای ذخیره‌سازی token
سیاست password hashing
استاندارد claims و permissionها
الگوی رسمی authorization
قوانین logging و masking اطلاعات حساس
الزامات audit trail
الگوی correlation ID
تست‌های الزامی امنیتی و عملیاتی
چک‌لیست code review
نمونه کدهای تأییدشده
ضدالگوهای ممنوع
معیارهای production readiness
لینک به مستندات امنیتی، معماری و platform داخلی

این Skill دقیقن نقش code generation agent مطابق استانداردهای فنی و امنیتی این سازمان رو داره که کدها رو تولید می‌کنه.
به عنوان مثال:
ثابت‌های غیرقابل تغییر سازمان رو می‌دونه:
— الگوریتم: RS256 باید باشه و کلید رو از Vaultبگیره
— هش پسورد: Argon2id
— لاگ: ساختار JSON با فیلدهای trace_id، user_id، ip، action
— پوشش تست برای auth layer: حداقل ۸۰٪ باید باشه
— هر endpoint باید rate limit داشته باشه
— مقادیر فقط باید از config بیان
— هیچ secret در کد نباید باشه و مقادیر باید فقط از vault یا infisical خونده بشه و environment لحاظ بشه
— localStorage برای هیچ token‌ای استفاده نشه
— inline SQL (بدون parameterized query نوشته نشه)infisical خونده بشه و environment لحاظ بشه
— localStorage برای هیچ token‌ای استفاده نشه
— inline SQL (بدون parameterized query نوشته نشه)

و مدل باید برای هر قابلیتی که پیاده‌سازی می‌کنه:
۱. یه threat model کوتاه بنویسه
۲. تصمیم‌های طراحی رو با دلیل توضیح بده
۳. test skeleton رو همراه کد تولید کنه
۴. هر جایی که از استاندارد انحراف داره، صریح بگه

این agent برای تیم یا حتی سازمان (اگر کوچیک باشه) یا دامنه (اگر متوسط باشه) یکسانه. Junior و Senior با یه baseline کار می‌کنن. هر کسی برای خودش پرامپت (ولو پرامپت خوب و از سر دانش و تجربه) نمی‌نویسه. توی Skill مثال و مستندات و رفرنس و اسامی لایبری‌ها و ورژن‌ها اومده. دانش سازمانی داخل ابزاره؛ نه داخل ذهن یه نفر که شاید فردا نباشه. این Skill ها همراه با مستندات و تاریخچه و… نگهداری می‌شن و هر تیمی چه از Claude code استفاده کنه چه GitHub Copilot یا هر ابزار استاندارد دیگه، به راحتی ازش استفاده خواهد کرد.


مشکل واقعی وایب‌کدینگ:

به نظر من مشکل وایب‌کدینگ این نیست که کسی با AI یه چیزی می‌سازه. این خودش اتفاق بدی نیست.

مشکل وقتی شروع می‌شه که فرد یا سازمان، تفاوت بین «ساختن چیزی که اجرا می‌شه» و «ساختن چیزی که قابل اعتماده» رو فراموش می‌کنه.

توی نرم‌افزارهای واقعی، مخصوصاً سیستم‌های سازمانی، مالی، منابع انسانی، سلامت، حمل‌ونقل، زیرساخت یا هر جایی که داده و تصمیم مهم وجود داره، اجرای موفق برنامه، فقط نقطه‌ی شروعه.

ما به چیزهای بیشتری نیاز داریم:

امنیت
قابلیت نگهداری
تست‌پذیری
مشاهده‌پذیری
قابلیت audit
هماهنگی با معماری
مدیریت خطا
پایداری در production
مستندات
و ownership واقعی

AI می‌تونه در همه‌ی این‌ها کمک کنه. اما فقط زمانی که کسی بدونه باید چه چیزی رو مطالبه کنه. و این یعنی باید اول خودش بیاموزه. اگر مهندس ندونه authorization فقط چک کردن role نیست، AI هم لزوماً اون رو نجات نمی‌ده. اگر تیم ندونه observability فقط چند log تصادفی نیست، AI هم ممکنه همون logهای بد رو بیشتر کنه. اگر سازمان استاندارد نداشته باشه، AI فقط آشفتگی رو سریع‌تر و شیک‌تر تولید می‌کنه.


جمع‌بندی

AI قرار نیست جایگزین دانش مهندسی بشه. فعلا هم نوآور نیست!
AI بیشتر شبیه amplifier است.

اگر پشتش دانش، استاندارد، معماری، تست، امنیت و discipline باشه، می‌تونه بهره‌وری واقعی ایجاد کنه. اما اگه پشتش فقط هیجان، عجله، ندونستن و اعتماد بیش از حد باشه، خروجیش می‌شه کدی که ظاهراً کار می‌کنه، ولی در عمل ریسک می‌سازه.

برای همین، آینده متعلق به کسانیه که فقط بلدند پرامپت بنویسن نیست. آینده متعلق به مهندس‌ها و سازمان‌هاییه که می‌تونن دانش مهندسی رو به شکل استاندارد، قابل تکرار، قابل تست و قابل کنترل وارد workflowهای AI کنن. (فعلا؛ و تا روزی که AI نوآوری، تکامل نهادینه و شعور نداره)

و شاید خلاصه‌ی بحث همین باشه:

AI می‌تونه سرعت بده؛ اما جهت رو هنوز دانش مهندسی تعیین می‌کنه.

AI یه ضریبه.
اگر دانش داری، ضریبی که سرعتت رو بالا می‌بره. اگر دانش نداری، ضریبی که اشتباهاتت رو سریع‌تر تولید می‌کنه.
ابزار فرقی نکرده، فقط سرعت فرق کرده.

مطالبی که پیشتر در این رابطه نوشتم:
- استفاده از GenAI در توسعه نرم‌افزار، خوب، بد، زشت! (قسمت اول، دوم، سوم)
- مقدمه‌ای بر Skills، مهارت‌آموزی AI برای توسعه نرم‌افزار (لینک)
- داستان وایب‌کدینک (لینک)

دیدگاهتان را بنویسید