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

درس 07. ترسیم مرزهای شفاف وظایف برای ایجنت‌ها

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

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

Code examples: code/ Practice project: Project 04. Use runtime feedback to correct agent behavior

شما به Claude Code می‌گویید «احراز هویت کاربر را به این پروژه اضافه کن»، و ایجنت شروع به ویرایش طرح پایگاه داده، نوشتن مسیرها، تغییر مؤلفه‌های فرانت‌اند، و — در حین انجام این کارها — بازآرایی میان‌افزار مدیریت خطا می‌کند. دو ساعت بعد بررسی می‌کنید: 12 فایل تغییر یافته، 800 خط کد جدید، و حتی یک قابلیت هم به‌صورت سرتاسری (end-to-end) کار نمی‌کند.

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

پست وبلاگ مهندسی Anthropic تحت عنوان «Effective harnesses for long-running agents» به‌روشنی بیان می‌کند: وقتی پرامپت‌ها (prompt) بیش از حد گسترده باشند، ایجنت‌ها تمایل دارند «چندین کار را هم‌زمان آغاز کنند» به‌جای اینکه «ابتدا یک کار را تمام کنند». تجارب مهندسی Codex در OpenAI نیز همین را نشان داد — وظایفی که فاقد کنترل‌های صریح دامنه (scope) هستند با افت شدید نرخ تکمیل مواجه می‌شوند. این مشکل مدل نیست — مشکل هارنس (harness) است. شما مرز را ترسیم نکرده‌اید.

توجه یک منبع محدود است#

این یک استعاره نیست — این ریاضیات است. فرض کنید ظرفیت زمینهٔ (context) ایجنت برابر با C باشد و k وظیفه را به‌طور هم‌زمان فعال کند. هر وظیفه به‌طور میانگین C/k منابع استدلال دریافت می‌کند. هنگامی که C/k به زیر آستانهٔ حداقلی لازم برای تکمیل یک وظیفه سقوط کند، هیچ‌یک از آن‌ها به پایان نمی‌رسند.

رفتار واقعی Claude Code گویای همه‌چیز است. از آن بخواهید «ثبت‌نام کاربر را اضافه کن»، و ممکن است:

  1. مدل User را ایجاد کند
  2. مسیر ثبت‌نام را بنویسد
  3. متوجه شود به تأیید ایمیل نیاز است، پس یک سرویس ایمیل اضافه کند
  4. ببیند رمزهای عبور نیاز به هش دارند، پس bcrypt را بیاورد
  5. ببیند مدیریت خطاها ناسازگار است، پس میان‌افزار خطای سراسری را بازآرایی کند
  6. ببیند ساختار فایل‌های آزمون نامرتب است، پس دایرکتوری را سازماندهی مجدد کند

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

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

جریان کاری WIP=1#

flowchart LR
    Queue["Feature queue"] --> Pick["Pick exactly one task"]
    Pick --> Active["Only one active item"]
    Active --> Verify["Run end-to-end verification"]
    Verify -->|pass| Commit["Commit and unlock next task"]
    Verify -->|fail| Active
    Commit --> Queue
flowchart TB
    Budget["Available reasoning budget = C"] --> One["WIP = 1<br/>C / 1 per task"]
    Budget --> Many["WIP = 5<br/>C / 5 per task"]

    One --> Finish["One feature reaches passing state"]
    Many --> Partial["Five partial implementations"]
    Partial --> VCR["Low verified completion rate<br/>high rework next session"]

مفاهیم اصلی#

  • فرارَوی (Overreach): وضعیتی که ایجنت در یک نشست واحد، وظایفی بیش از حد بهینه را فعال می‌کند. این موضوع ذهنی نیست — کمّی و قابل‌اندازه‌گیری است: انجام 5 ویژگی با 0 مورد قبولی سرتاسری، فراروی است.
  • ناتمام‌گذاری (Under-finish): نسبتی از وظایف فعال‌شده که راستی‌آزمایی سرتاسری را پاس می‌کنند، به زیر آستانه می‌رسد. کد نوشته شده اما آزمون‌ها پاس نشده‌اند، این ناتمام‌گذاری است.
  • حد کار در جریان (WIP Limit): برگرفته از روش‌شناسی کانبان (Kanban). ایدهٔ اصلی: محدود کردن تعداد کارهای در حال انجام به‌طور هم‌زمان. برای ایجنت‌ها، WIP=1 امن‌ترین حالت پیش‌فرض است — پیش از شروع بعدی، کار فعلی را تمام کنید.
  • شواهد اتمام (Completion Evidence): شرایط قابل‌راستی‌آزمایی که یک وظیفه باید برآورده کند تا از وضعیت «در جریان» به «انجام‌شده» برود. بدون این شواهد، ایجنت گزارهٔ «کد خوب به‌نظر می‌رسد» را جایگزین «رفتار برنامه آزمون‌ها را پاس می‌کند» خواهد کرد.
  • سطح دامنه (Scope Surface): ساختاری از گراف جهت‌دار بدون دور (DAG) که در آن هر گره (node) یک واحد کاری و یال‌ها (edges) وابستگی‌ها هستند. وضعیت‌ها به چهار مورد محدود می‌شوند: not_started، active، blocked، و passing.
  • فشار اتمام (Completion Pressure): نیروی بازدارنده‌ای که هارنس از طریق حدود WIP و الزامات شواهد اتمام اعمال می‌کند، و ایجنت را وادار می‌سازد پیش از شروع وظیفه‌ای تازه، وظیفهٔ کنونی را تمام کند.

فراروی و ناتمام‌گذاری دو روی یک سکه‌اند#

این دو مشکل از یکدیگر مستقل نیستند — بلکه یکدیگر را تشدید می‌کنند. فراروی توجه را رقیق می‌کند، توجه رقیق‌شده باعث ناتمام‌گذاری می‌شود، و کدهای نیمه‌کارهٔ به‌جامانده پیچیدگی سیستم را افزایش می‌دهند، که به نوبهٔ خود فراروی بیشتری را در وظیفهٔ بعدی رقم می‌زند. یک چرخهٔ معیوب.

به تعبیر کانبان: قانون لیتل به ما می‌گوید L = lambda * W. اگر کار در جریان L بیش از حد بالا باشد (انجام هم‌زمان کارهای بیش از حد)، زمان سپری‌شده W برای هر وظیفه به‌طور اجتناب‌ناپذیری افزایش می‌یابد. برای ایجنت‌ها، این بدان معناست که هر قابلیت از شروع تا راستی‌آزمایی کامل زمان بیشتری می‌برد، و احتمال شکست بالا می‌رود.

این مشکلی دیرینه در دنیای انسان‌ها نیز هست. استیو مک‌کانل در کتاب Rapid Development مستند کرده است که خزش دامنه (scope creep) مهم‌ترین دلیل شکست پروژه‌هاست. اما انسان‌ها دست‌کم این درک شهودی را دارند که «دیگر به اندازهٔ کافی انجام داده‌ام». ایجنت‌ها چنین درکی ندارند. تولید ایدهٔ بعدی برای مدل تقریباً هیچ هزینه‌ای ندارد — نوشتن این جمله که «بگذار تا اینجا هستم این را هم درست کنم» توکن اضافی چندانی نمی‌برد، اما هر تغییر اضافی، توجه ایجنت را رقیق‌تر می‌سازد.

چگونه این کار را درست انجام دهیم#

1. اعمال شرط WIP=1#

این مستقیم‌ترین و کارآمدترین روش است. در هارنس خود، به‌طور صریح به ایجنت بگویید: در هر زمان تنها یک وظیفه مجاز است در وضعیت «active» باشد. در فایل CLAUDE.md در Claude Code یا AGENTS.md در Codex بنویسید:

## Work Rules
- Work on one feature at a time
- Only start the next feature after the current one passes end-to-end verification
- Don't "also refactor" feature B while implementing feature A

2. تعریف شواهد اتمام صریح برای هر وظیفه#

اتمام به‌معنای «کد نوشته شده است» نیست — بلکه به‌معنای «راستی‌آزمایی رفتار پاس می‌شود» است. در فهرست ویژگی‌های شما، هر ورودی نیاز به یک دستور راستی‌آزمایی دارد:

F01: User Registration
  Verification: curl -X POST /api/register -d '{"email":"test@example.com","password":"123456"}' | jq .status == 201
  State: passing

3. بیرونی‌سازی سطح دامنه#

از یک فایل ماشین‌خوان (JSON یا Markdown) برای ثبت تمام وضعیت‌های وظایف بهره ببرید. هر نشست تازه می‌تواند این فایل را بخواند و بی‌درنگ بداند: کدام وظیفه فعال است؟ چه رفتاری به‌منزلهٔ اتمام است؟ چه راستی‌آزمایی‌هایی پاس شده‌اند؟

4. پایش نرخ تکمیل راستی‌آزمایی‌شده#

هارنس باید به‌طور مداوم سنجهٔ VCR (Verified Completion Rate) = وظایف راستی‌آزمایی‌شده / وظایف فعال‌شده را ردیابی کند. وقتی VCR < 1.0 است، فعال‌سازی وظایف تازه را مسدود نمایید.

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

یک پروژهٔ REST API با 8 قابلیت، مقایسهٔ دو راهبرد:

حالت بدون قیدوبند: ایجنت 5 قابلیت را به‌طور هم‌زمان در نشست 1 فعال می‌کند. حدود 800 خط کد در 12 فایل تولید می‌نماید. نرخ قبولی آزمون‌های سرتاسری: 20% — تنها ثبت‌نام کاربر کار می‌کند. 4 قابلیت دیگر: طرح پایگاه داده ایجاد شده اما فاقد منطق اعتبارسنجی است، مسیرها تعریف شده‌اند اما قالب‌های پاسخ نادرستی برمی‌گردانند. تا پایان نشست 3، تنها 3 مورد از 8 قابلیت کامل شده‌اند.

حالت WIP=1: ایجنت در نشست 1 تنها روی ثبت‌نام کاربر کار می‌کند. حدود 200 خط در 4 فایل تولید می‌نماید. آزمون‌های سرتاسری: 100% قبولی. یک پیاده‌سازی تمیز و راستی‌آزمایی‌شده را کامیت می‌کند. تا پایان نشست 4، 7 مورد از 8 قابلیت کامل شده‌اند (مورد هشتم به‌دلیل وابستگی خارجی مسدود شد).

نتیجه: کد کلی کمتر (800 خط در برابر 1200 خط) اما کد مؤثر بیشتر. نرخ تکمیل: 87.5% در برابر 37.5%.

نکات کلیدی#

  • قاعدهٔ WIP=1 تنظیمات پیش‌فرض امن برای هارنس‌های ایجنت است — یکی را تمام کنید، سپس بعدی را شروع کنید؛ تلاش نکنید کارها را موازی پیش ببرید.
  • شواهد اتمام باید قابل‌اجرا باشند — «کد خوب به‌نظر می‌رسد» اعتباری ندارد؛ «دستور curl مقدار 201 برمی‌گرداند» معتبر است.
  • سطح دامنه باید به‌صورت یک فایل بیرونی‌سازی شود — نه اینکه صرفاً در گفتگو بیان شود، بلکه در قالبی ماشین‌خوان در مخزن ثبت گردد.
  • فراروی و ناتمام‌گذاری پیوند همزیستی دارند — حل یکی، دیگری را برطرف می‌کند.
  • «کمتر انجام دادن اما به اتمام رساندن» همواره بر «بیشتر انجام دادن و نیمه‌کاره رها کردن» پیروز است — تعداد خطوط کد ایجنت و نرخ تکمیل قابلیت‌ها همبستگی منفی دارند. کیفیت همیشه بر کمیت برتری دارد.

منابع بیشتر#

تمرین‌ها#

  1. ریزسازی وظایف: یک نیازمندی کلی را بردارید (مانند «پیاده‌سازی سامانهٔ مدیریت کاربران») و آن را به دست‌کم 5 واحد کاری اتمام‌پذیر خرد کنید. برای هر واحد، این موارد را مشخص نمایید: (الف) شرح تک‌رفتار، (ب) یک دستور راستی‌آزمایی قابل‌اجرا، (ج) وابستگی‌ها. بررسی کنید آیا این تفکیک قید WIP=1 را برآورده می‌سازد یا خیر.

  2. آزمایش مقایسه‌ای: یک پروژه را دو بار اجرا کنید — یک‌بار بدون قیدوبند، و یک‌بار با اعمال اجباری WIP=1. نرخ تکمیل راستی‌آزمایی‌شده، مجموع خطوط کد، و نسبت کد مؤثر را مقایسه کنید.

  3. بازبینی شواهد اتمام: خروجی یکی از اجراهای اخیر ایجنت را مرور کرده و هر تغییر کد را در یکی از دسته‌های «رفتار کامل‌شده»، «رفتار ناقص»، یا «داربست» طبقه‌بندی نمایید. برای هر رفتار ناقص، دستورات راستی‌آزمایی مفقود را اضافه کنید.