هر عامل کدنویسی هوش مصنوعی می‌تواند یک diff تولید کند. مشکل واقعی این است که بدانید آیا آن diff حاصل یک فرآیند متمرکز و حساب‌شده بوده است یا یک جست‌وجوی سراسری و بی‌هدف در مخزن (repository) شما که از روی شانس به نتیجه درست رسیده است. در حال حاضر، اکثر تیم‌ها نمی‌توانند این تفاوت را تشخیص دهند.

این یک محدودیت فنی نیست؛ بلکه یک مشکل در زمینه شفافیت (visibility) است.

وقتی یک عامل سه خط کد عملیاتی (production code) می‌نویسد، ممکن است سه فایل را خوانده و تست‌ها را اجرا کرده باشد. یا ممکن است چهل فایل بی‌ربط را لمس کرده، ده‌ها دستور ناموفق را اجرا کرده، مجموعه تست‌های شما را به دلیل خرابی نصب وابستگی‌ها (dependency install) نادیده گرفته و هزینه آن را هم از شما گرفته باشد. در هر دو حالت، diff ظاهراً یکسان است. بدون داشتن گزارشی از این مسیر، شما در حدس زدن کیفیت نتیجه نهایی رها می‌شوید.

چرا لاگ‌های چت، رسید (Receipt) نیستند

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

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

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

یک رسید خوب چگونه است

یک رسید قابل بازبینی باید بدون نیاز به جست‌وجوی عمیق، به سوالات مشخصی پاسخ دهد:

  • وظیفه چه بود؟ توصیفی شفاف از تغییر مورد نظر، نه صرفاً تکرار مبهم یک پرامپت.
  • کدام فایل‌ها خوانده شدند؟ تا بتوانید قضاوت کنید که آیا عامل بافتار (context) را از منابع درستی ساخته است یا خیر.
  • کدام فایل‌ها ویرایش شدند؟ ردپای نهایی تغییرات.
  • کدام دستورات اجرا شدند؟ مراحل ساخت (build)، لینترها (linters)، فرمت‌کننده‌ها یا اسکریپت‌های سفارشی که عامل فراخوانی کرده است.
  • کدام دستورات با شکست مواجه شدند؟ نه فقط موارد موفق. شکست‌ها نشان می‌دهند که عامل کجا مجبور به بداهه‌پردازی شده یا کجا تسلیم شده است.
  • کدام تست‌ها با موفقیت اجرا شدند یا نادیده گرفته شدند؟ تست‌های نادیده گرفته شده یک زنگ خطر هستند. رسید باید بگوید چرا آن‌ها نادیده گرفته شده‌اند.
  • هزینه کل چقدر بود؟ توکن‌ها، فراخوانی‌های API و زمان محاسباتی. این شامل هزینه معماری شما نیز می‌شود، نه فقط مدل.

این قالب، بازبینی را از یک حفاری باستان‌شناسی به یک بررسی سلامت (sanity check) سریع تبدیل می‌کند. یک مهندس ارشد باید بتواند رسید را در کمتر از یک دقیقه مرور کند و بگوید «این منطقی است» یا «این مشکوک به نظر می‌رسد».

ردپا را بخوانید، نه فقط تاریخچه را

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

ردپا همچنین تکرار را آشکار می‌کند. عاملی که مدام به یک بن‌بست برخورد می‌کند — مثلاً سه بار یک فایل تنظیمات (config file) را می‌خواند یا یک تست ناموفق را بارها و بارها اجرا می‌کند — در حال هدر دادن منابع محاسباتی و پنجره بافتار (context window) است. این الگو باید قابل مشاهده باشد. اگر یک عامل برای اجرای یک اسکریپت مهاجرت (migration script) ۹ بار تلاش کرده است، رسید باید این را اعلام کند. این اطلاعات نحوه ارزیابی خروجی شما را تغییر می‌دهد. یک diff «درست» که از طریق روش زورگویانه (brute-force) و هرج‌ومرج تولید شده، با یک diff درست که به شکلی تمیز تولید شده است، متفاوت است.

هزینه پنهان طراحی ضعیف

هزینه فقط قیمت هر توکن نیست. یک گردش کار با طراحی ضعیف، باعث می‌شود عامل حتی قبل از تولید اولین کاراکتر، گران تمام شود. طرح‌های ابزار (tool schemas) حجیم، ایندکس کردن غیرضروری فایل‌ها و پرامپت‌های سیستم بیش از حد گسترده، همگی باعث تورم پنجره بافتار می‌شوند. رسید باید این هزینه‌های اضافی را فاش کند.

اگر تولید ارزان‌تر شود اما بازبینی سخت‌تر گردد، شما چیزی به دست نیاورده‌اید؛ بلکه فقط گلوگاه را جابه‌جا کرده‌اید. زمان مهندسان معمولاً کمیاب‌ترین منبع در یک تیم است. صرفه‌جویی در ۵ دلار هزینه API در ازای اضافه شدن ۳۰ دقیقه زمان بازبینی به هر pull request، معامله بسیار بدی است. رسید به شما کمک می‌کند تا مستقیماً این معامله را حسابرسی کنید.

صداقت یک ویژگی است

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

مثال‌ها اهمیت دارند:

  • «۳۷ فایل را برای یک تغییر تک‌خطی خواند.»
  • «تست‌ها نادیده گرفته شدند زیرا npm install با تداخل وابستگی همتا (peer dependency) شکست خورد.»
  • «فایل utils.py را خارج از محدوده درخواستی ویرایش کرد تا یک import را که توسط عامل ایجاد شده بود، اصلاح کند.»
  • «لینتر (linter) را ۴ بار اجرا کرد؛ سه بار اول به دلیل پیکربندی اشتباه مسیر شکست خوردند.»

این‌ها باگ‌هایی در گزارش (receipt) نیستند؛ بلکه سیگنال هستند. آن‌ها به بازبین می‌گویند که کجا باید با تردید بیشتری نگاه کند. همچنین به تیم پلتفرم می‌گویند که در کجای گردش کار (workflow) نیاز به اصلاح و محدودسازی وجود دارد.

اجراهای کوچک‌تر، نظارت شفاف‌تر

این وسوسه طبیعی وجود دارد که اجازه دهیم عامل‌ها در سطوح گسترده‌ای آزادانه عمل کنند. استفاده از یک پرامپت غول‌آسا برای بازنویسی (refactor) یک سرویس کامل، سریع به نظر می‌رسد، اما این‌طور نیست. این کار یک توده کاری غیرقابل بازبینی ایجاد می‌کند. بعدازظهر شما صرف ردیابی این می‌شود که کدام‌یک از هشتاد فایل تغییر یافته، عمدی بوده‌اند.

اجراهای کوچک و قابل بررسی بهتر هستند. مرزهای مشخصی برای وظیفه تعریف کنید. لیست فایل‌هایی که عامل می‌تواند بخواند را از لیست فایل‌هایی که می‌تواند بنویسد، جدا کنید. تاریخچه‌ای از دستورات شکست‌خورده را ثبت کنید تا بن‌بست‌ها قابل مشاهده باشند. تاییدیه های نادیده گرفته شده را به‌طور صریح علامت‌گذاری کنید. هرگونه استفاده از ابزارهای خارجی، از APIهای جستجو گرفته تا اجراکننده‌های تست (test runners) را یادداشت کنید.

هدف، خودمختاری کامل نیست. خودمختاری کاملی که هیچ انسانی نتواند آن را تایید کند، صرفاً اتوماسیونی همراه با مسئولیت‌پذیری (liability) است. هدف واقعی، قابلیت بازبینی (reviewability) است. هر خروجیِ عامل باید به‌راحتی قابل تایید یا رد باشد. نباید هیچ منطقه خاکستری و مبهمی وجود داشته باشد که در آن، صرفاً چون از بررسی کردن خسته شده‌اید، کد را می‌پذیرید.

آزمونی برای هر عامل کدنویسی

قبل از به‌کارگیری هر عامل یا پلتفرمی، یک سوال بپرسید: آیا می‌تواند شواهد کافی برای این باقی بگذارد که یک انسان بتواند مرحله بعدی را با اطمینان تایید کند؟

اگر پاسخ مثبت است، آن ابزار با یک گردش کار حرفه‌ای سازگار است. اگر پاسخ منفی است، شما در حال خرید بهره‌وری نیستید؛ بلکه در حال خرید معمایی هستید که گهگاه کامپایل می‌شود. این برای یک پروژه جانبی در آخر هفته مشکلی ندارد، اما برای مهندسی تولید (production engineering) غیرقابل قبول است.

تیم‌هایی که با خروجی‌های عامل مانند هدایای بررسی‌نشده برخورد می‌کنند، در نهایت با باگی ظریف مواجه خواهند شد که ناشی از گسترش کنترل‌نشده محدوده (scope creep) بوده است. تفاوت کدها (diff) بی‌گناه به نظر خواهد رسید، اما گزارش (receipt) حقیقت را می‌گفت.

گزارش‌ها را الزامی کنید. برای بازبینی طراحی کنید. اعتماد یک استراتژی نیست؛ شواهد است.


برای بحث‌های عملی بیشتر در مورد ابزارهای هوش مصنوعی و گردش کارهای توسعه‌دهندگان، می‌توانید به انجمن GyaanSetu در تلگرام بپیوندید.