صفحه ۱۰ از ۴۹، درس‌ها

درس 09. جلوگیری از اعلام پیروزی زودهنگام توسط ایجنت‌ها

متنی ۱۰ دقیقه به‌روز شده در ۱۰ آبان ۱۴۰۵

در این صفحه
  1. سراشیبی لغزنده
  2. بررسی سه‌لایه‌ای خاتمه
  3. مفاهیم اصلی
  4. قبولی در آزمون‌های واحد ≠ اتمام وظیفه
  5. چگونه از اعلام زودهنگام اتمام جلوگیری کنیم
  6. موردی از دنیای واقعی
  7. نکات کلیدی
  8. منابع بیشتر
  9. تمرین‌ها

Code examples for this lecture: code/ Hands-on practice: Project 05. Let the agent verify its own work

شما از یک ایجنت (agent) می‌خواهید قابلیت «بازیابی رمز عبور» را پیاده‌سازی کند. ایجنت طرح پایگاه داده را تغییر می‌دهد، اندپوینت API را می‌نویسد، قالب ایمیل را اضافه می‌کند، آزمون‌های واحد را اجرا می‌نماید (همه پاس می‌شوند)، و سپس با اطمینان کامل به شما می‌گوید «انجام شد». اما وقتی واقعاً تلاش می‌کنید آن را اجرا کنید — پیوند بازیابی رمز عبور ارسال نمی‌شود زیرا پیکربندی سرویس ایمیل وجود ندارد؛ فرایند مایگریشن پایگاه داده در نیمهٔ راه با شکست مواجه می‌شود و طرح را در وضعیتی ناسازگار باقی می‌گذارد؛ و جریان سرتاسری (end-to-end) حتی یک‌بار هم اجرا نشده است.

این یک حادثهٔ منفرد نیست. مقالهٔ کلاسیک سال 2017 در کنفرانس ICML توسط گوئو و همکاران اثبات کرد: شبکه‌های عصبی مدرن به‌طور سیستماتیک بیش از حد مطمئن هستند — اطمینانی که توسط مدل‌ها گزارش می‌شود به‌مراتب بالاتر از دقت واقعی آن‌هاست. ایجنت‌های کدنویسی هوش مصنوعی نیز تفاوتی ندارند. آن‌ها «احساس» می‌کنند کار تمام شده است، اما در واقعیت فرسنگ‌ها با اتمام فاصله دارند. هارنس (harness) شما باید «احساسات» ایجنت را با راستی‌آزمایی (verification) بیرونی‌سازی‌شده و مبتنی بر اجرا جایگزین کند.

سراشیبی لغزنده#

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

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

بررسی سه‌لایه‌ای خاتمه#

flowchart LR
    Claim["Agent says: done"] --> L1["First run<br/>lint / typecheck"]
    L1 --> L2["Then run<br/>tests and startup checks"]
    L2 --> L3["Finally run<br/>complete user flow"]
    L3 --> Done["Pass all three to be done"]
flowchart LR
    A["Code is written<br/>unit tests are green"] --> B["But app didn't really start<br/>full flow never ran"]
    B --> C["Config, DB, external service issues<br/>all remain hidden"]
    C --> D["So agent declares victory too early"]

مفاهیم اصلی#

  • اعلام زودهنگام اتمام (Premature Completion Declaration): ایجنت ادعا می‌کند وظیفه تمام شده است، اما مشخصات درستی برآورده‌نشده باقی مانده‌اند. مشکل اصلی این است که ایجنت بر اساس اطمینان محلی در سطح کد قضاوت می‌کند، در حالی که درستی در سطح سیستم نیازمند راستی‌آزمایی سراسری است.
  • سوگیری کالیبراسیون اطمینان (Confidence Calibration Bias): فاصله‌ای سیستماتیک میان اطمینان خوداظهاری‌شدهٔ ایجنت از اتمام کار و کیفیت واقعی اتمام. برای وظایف پیچیدهٔ چندفایلی، این سوگیری به‌طرز چشمگیری مثبت است — یعنی ایجنت همواره بسیار مطمئن‌تر از عملکرد واقعی خود ظاهر می‌شود.
  • معیارهای خاتمه (Termination Criteria): مجموعه‌ای شفاف و قابل‌اجرا از شرایط قضاوت که در هارنس تعریف شده است. ایجنت باید تمام شرایط را پیش از اعلام اتمام برآورده سازد. «تمام شد» از یک قضاوت ذهنی به یک تصمیم‌گیری عینی تغییر می‌یابد.
  • دروازهٔ دوگانهٔ راستی‌آزمایی-اعتبارسنجی (Verification-Validation Dual Gate): لایهٔ اول (راستی‌آزمایی) بررسی می‌کند که آیا کد رفتار مشخص‌شده را به‌درستی پیاده کرده است؛ لایهٔ دوم (اعتبارسنجی) بررسی می‌کند که آیا رفتار سطح سیستم نیازمندی‌های سرتاسری را برآورده می‌سازد یا خیر. هر دو باید پیش از اتمام وظیفه پاس شوند.
  • سیگنال‌های بازخورد زمان اجرا: گزارش‌ها، وضعیت‌های فرایند، و بررسی‌های سلامت ناشی از اجرای برنامه — این‌ها مبنای عینی هارنس برای قضاوت دربارهٔ کیفیت اتمام کار را تشکیل می‌دهند.
  • قید اولویت اتمام: ابتدا درستی عملکردی را راستی‌آزمایی کنید، سپس به کارایی بپردازید، و در نهایت سبک کد را مدیریت نمایید. هیچ بازآرایی کدی تا زمانی که کارکرد اصلی راستی‌آزمایی نشده باشد مجاز نیست.

قبولی در آزمون‌های واحد ≠ اتمام وظیفه#

این رایج‌ترین و خطرناک‌ترین دام است. ایجنت کد را می‌نویسد، آزمون‌های واحد را اجرا می‌کند، چراغ‌های سبز را می‌بیند، و می‌گوید «تمام شد». اما فلسفهٔ طراحی آزمون‌های واحد — جداسازی واحد مورد آزمون و ماک کردن (mocking) وابستگی‌ها — دقیقاً همان چیزی است که آن‌ها را در شناسایی مشکلات میان مؤلفه‌ها ناتوان می‌سازد:

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

خطاهای انتشار وضعیت: یک مایگریشن پایگاه داده طرح جدول را تغییر می‌دهد، اما لایهٔ کش ORM همچنان مدخل‌های کش را برای طرح قدیمی نگه می‌دارد. آزمون‌های واحد هر بار در یک محیط ماک تازه اجرا می‌شوند، بنابراین این نوع ناسازگاری وضعیت میان‌لایه‌ای هرگز خود را نشان نمی‌دهد.

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

«بازآرایی هم‌زمان» سم قضاوت دربارهٔ اتمام کار است#

مدل Claude Code یک الگوی رفتاری رایج دارد: پیش از آنکه کارکرد اصلی راستی‌آزمایی را پاس کند، شروع به بازآرایی کد، بهینه‌سازی کارایی، و بهبود سبک کدنویسی می‌نماید. جملهٔ معروف دانلد کنوث که «بهینه‌سازی زودهنگام ریشهٔ تمام بدی‌هاست» در سناریوی ایجنت معنای تازه‌ای می‌یابد — بازآرایی مرز میان کدهای راستی‌آزمایی‌شده و راستی‌آزمایی‌نشده را تغییر می‌دهد و ممکن است مسیرهایی را بشکند که پیش‌تر به‌طور ضمنی درست بودند.

سوگیری سیستماتیک در خودارزیابی#

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

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

راه‌حل این نیست که ایجنت را «عینی‌تر» کنیم. همان مدلی که تولید می‌کند، ارزیابی نیز می‌نماید، بنابراین ذاتاً تمایل دارد نسبت به خود دست‌ودلباز باشد. راه‌حل تفکیک «سازنده» از «بازرس» (maker-checker) است.

یک ایجنت ارزیاب (evaluator) مستقل که مشخصاً برای «سخت‌گیری و ایرادگیری» تنظیم شده است، بسیار کارآمدتر از این است که ایجنت تولیدکننده (generator) کار خودش را ارزیابی کند. داده‌های تجربی Anthropic:

معماری زمان اجرا هزینه آیا ویژگی‌های اصلی کار می‌کنند؟
تک‌ایجنتی (اجرای برهنه) 20 دقیقه $9 خیر (موجودیت‌های بازی به ورودی‌ها پاسخ نمی‌دادند)
سه ایجنتی (برنامه‌ریز + تولیدکننده + ارزیاب) 6 ساعت $200 هستهٔ بازی کار می‌کرد؛ مشکلات فیزیک و مراحل باقی مانده بود

این دقیقاً همان مدل (Opus 4.5) با همان پرامپت یکسان («یک ویرایشگر بازی دو‌بعدی رترو بسازید») است. تنها تفاوت در هارنس است: از «اجرای برهنه» به «برنامه‌ریز نیازمندی‌ها را بسط می‌دهد → تولیدکننده ویژگی به ویژگی پیاده‌سازی می‌کند → ارزیاب آزمون‌های کلیک واقعی را با Playwright اجرا می‌کند».

منبع: Anthropic: Harness design for long-running application development

چگونه از اعلام زودهنگام اتمام جلوگیری کنیم#

1. بیرونی‌سازی قضاوت دربارهٔ اتمام#

قضاوت دربارهٔ اتمام کار نباید توسط خود ایجنت انجام شود. هارنس باید اعتبارسنجی خاتمه را به‌طور مستقل اجرا کند، و به‌جای اطمینان ایجنت، سیگنال‌های زمان اجرا را به‌عنوان ورودی مبنا قرار دهد. در CLAUDE.md می‌توانید این را به‌روشنی قید کنید:

## Definition of Done
- Feature complete = end-to-end verification passed, not "code is written"
- Required verification levels:
  1. Unit tests pass
  2. Integration tests pass
  3. End-to-end flow verification passes
- Do not proceed to level 2 if level 1 fails
- Do not proceed to level 3 if level 2 fails

2. ساخت اعتبارسنجی سه‌لایه‌ای خاتمه#

  • لایهٔ 1: نحو و تحلیل ایستا. کمترین هزینه، کمترین اطلاعات، اما گذر از آن الزامی است. این حداقل ضرورت است — باید پیش از خواندن ادامهٔ متن، کلمات را درست بنویسید.
  • لایهٔ 2: راستی‌آزمایی رفتار زمان اجرا. اجرای آزمون‌ها، بررسی‌های راه‌اندازی برنامه، و اعتبارسنجی مسیرهای بحرانی. این شواهد اصلی اتمام کار است — نه فقط نوشته‌شده، بلکه قابل‌اجرا.
  • لایهٔ 3: تأییدیه در سطح سیستم. آزمون‌های سرتاسری، اعتبارسنجی ادغام، و شبیه‌سازی سناریوی کاربر. واپسین خط دفاعی در برابر اعلام زودهنگام — نه فقط قابل‌اجرا، بلکه درست و دقیق.

3. ارائهٔ بازخورد خطای کارآمد به ایجنت#

شرکت OpenAI در تجارب Codex خود الگویی بسیار مؤثر را معرفی کرد: پیام‌های خطایی که برای ایجنت‌ها نوشته می‌شوند باید حاوی دستورالعمل‌های اصلاح باشند. فقط به ایجنت نگویید «اشتباه است» — دقیقاً اشاره کنید چه چیزی اشتباه است و چگونه باید اصلاح شود. از پیام "Test failed" استفاده نکنید؛ بنویسید: "Test failed: POST /api/reset-password returned 500. Check that the email service config exists in environment variables. The template file should be at templates/reset-email.html." این نوع بازخورد دقیق و کارآمد به ایجنت اجازه می‌دهد بدون دخالت انسان خود را تصحیح کند.

4. ثبت سیگنال‌های زمان اجرا#

سیگنال‌های مؤثر زمان اجرا شامل این مواردند: - آیا برنامه با موفقیت شروع به کار کرد و به وضعیت آماده رسید؟ - آیا مسیرهای بحرانی قابلیت‌ها در زمان اجرا با موفقیت اجرا شدند؟ - آیا نوشتن در پایگاه داده، عملیات فایل‌ها، و سایر اثرات جانبی درست بودند؟ - آیا منابع موقت پاک‌سازی شدند؟

موردی از دنیای واقعی#

وظیفه: پیاده‌سازی قابلیت بازیابی رمز عبور کاربر. شامل عملیات پایگاه داده، ارسال ایمیل، و تغییرات اندپوینت‌های API.

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

موارد از قلم افتادهٔ واقعی: (1) جریان سرتاسری آزمون نشده است — ارسال واقعی و راستی‌آزمایی پیوند بازیابی هرگز تأیید نشد. (2) مایگریشن پایگاه داده پس از اجرای ناقص شکست خورد و طرح را ناسازگار باقی گذاشت. (3) پیکربندی سرویس ایمیل در محیط هدف مفقود بود.

مداخلهٔ هارنس: اعتبارسنجی خاتمه اجباری می‌شود — (1) کل برنامه را راه‌اندازی کنید تا اطمینان حاصل شود اندپوینت بازیابی در دسترس است؛ (2) جریان کامل بازیابی را اجرا کنید؛ (3) سازگاری وضعیت پایگاه داده را راستی‌آزمایی نمایید. هر سه نقص درون همان نشست آشکار می‌شوند، در حالی که هزینهٔ اصلاح هنوز محلی است.

نکات کلیدی#

  • ایجنت‌ها به‌طور سیستماتیک بیش از حد مطمئن هستند — سوگیری کالیبراسیون اطمینان یک واقعیت عینی است. نوشته شدن کد به‌معنای درست نوشته شدن آن نیست.
  • قضاوت دربارهٔ اتمام کار باید بیرونی‌سازی شود — هارنس به‌طور مستقل راستی‌آزمایی می‌کند. به «احساسات» ایجنت اعتماد نکنید.
  • هر سه لایهٔ اعتبارسنجی ضروری هستند: نحو پاس شود، رفتار پاس شود، سیستم پاس شود — لایه‌به‌لایه، بدون میان‌بر.
  • پیام‌های خطا باید شامل گام‌های اصلاحی مشخص باشند، تا ایجنت بتواند خود را تصحیح کند نه اینکه صرفاً به آن گفته شود «اشتباه است».
  • عدم بازآرایی تا پیش از راستی‌آزمایی عملکرد اصلی — قید اولویت اتمام کلید جلوگیری از بهینه‌سازی زودهنگام است.

منابع بیشتر#

تمرین‌ها#

  1. طراحی تابع اعتبارسنجی خاتمه: یک اعتبارسنجی کامل خاتمه برای وظیفه‌ای که شامل مایگریشن پایگاه داده و تغییرات API است طراحی کنید. سیگنال‌های زمان اجرای لازم و معیارهای قبولی/رد را برای هرکدام فهرست نمایید. آن را روی یک وظیفهٔ واقعی اجرا کنید و مواردی را که پنهان مانده بود ثبت نمایید.

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

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