وقتی اجزای مختلف یک سیستم خودکار مثل فرضیهساز، مجری آزمایش، اسکژولر، ناقد و نویسندهی مقاله را جداگانه میسازید، بزرگترین چالش زمان یکپارچهسازی آنها ظاهر میشود. معماری خوب جایی خودش را نشان میدهد که این قطعات بدون نیاز به فریمورکهای پیچیده یا کدهای واسط شکننده، صرفاً بر اساس قراردادهای مشخص دادهای در پایتون کنار هم بنشینند.
در این درس یاد میگیرید چطور یک حلقهی کامل پژوهش خودکار (auto-research loop) را بهصورت سرتاسری پیاده کنید. هدف این است که تمام خروجیها قطعی و قابل تست بمانند، هر مرحله در صورت دریافت دادهی نامعتبر با خطای صریح متوقف شود و سیستم گزارش نهایی شفافی از عملکرد تمام مراحل ارائه دهد.
دمو همان جایی است که تکتک قراردادهایی که قبلاً نوشتهاید باید کنار هم بنشینند و ترکیب شوند. اگر حتی یکی از آنها نشتی داشته باشد، دمو همان درسی است که مچش را میگیرد.
اهداف یادگیری
- سیمکشی حلقهی پژوهش خودکار (auto-research loop) بهصورت سرتاسری: فرضیهی اولیه (seed hypothesis)، مجری آزمایش (experiment runner)، اسکژولر، حلقهی ناقد، و نویسندهی مقاله (paper writer).
- ترکیب اجزای سازندهی چهار درس قبلی مسیر D تنها با ایمپورتهای سادهی Python، بدون استفاده از هیچ فریمورکی.
- اجرای حلقه تا رسیدن به پایان خودکار و ارائهی یک گزارش دموی یکپارچه شامل خروجی همهی مراحل.
- حفظ قطعیت (deterministic بودن) دمو تا مجموعهی تستها بتوانند ساختار خروجی نهایی را اعتبارسنجی (assert) کنند.
- نمایش شفاف حالتهای خطا (failure modes) در صورت نقض قرارداد هر مرحله، تا مرحلهی بعد با ورودی نامعتبر اجرا نشود.
چه چیزهایی در اینجا با هم ترکیب میشوند
شش مرحله داریم. نقطهی آغاز، فهرستی از سه فرضیه است. اسکژولر، شش آزمایش را روی آنها در سه اسلات موازی اجرا میکند. باس ارتباطی، یک یا چند تریگر مقاله (paper trigger) را گزارش میدهد. بخش انتخابگر (picker)، تکنتیجهی بهینه را گلچین میکند. حلقهی ناقد روی پیشنویسی که بر اساس همان نتیجه ساخته شده بازبینی انجام میدهد. در نهایت، نویسندهی مقاله خروجیهای LaTeX، BibTeX و مانیفست را تولید میکند.
چرا ایمپورت، نه کپی؟
هر کدام از درسهای قبلی یک main.py دارند که شامل دیتاکلاسها و توابع عمومی است. دمو با تنظیم sys.path روی دایرکتوری والد هر درس، آنها را ایمپورت میکند. این کار اتصال فریمورکی نیست؛ دقیقاً همان شیوهی ایمپورتی است که فایلهای تست درسهای قبل هم استفاده میکردند.
استاب (stub) درونکدی، نقش درسهای 50 تا 53 را ایفا میکند: یک مولد کوچک فرضیههای اولیه و یک تابع پاداش (reward function) همگام. میتوانید این استاب را صرفاً با تغییر دو ایمپورت، با اجزای سازندهی واقعی همان درسها جایگزین کنید.
تضمینهای قطعیت
دمو از پایه و در ذات خود قطعی است. مجری آزمایش با seed مشخص در numpy اجرا میشود. بخش بازبین (reviser) در حلقهی ناقد، ابعاد ثابت را با ترتیبی ثابت بررسی میکند. تولیدکنندهی متن در بخش نگارش مقاله، همان نسخهی شبیهسازیشدهی (mocked) درس 54 است. انتخابگر UCB در اسکژولر نیز هنگام تساوی، انتخاب را بر اساس ترتیب پیمایش انجام میدهد، نه تصادفی.
با seed یکسان، دمو گزارش یکسانی ارائه میدهد. تستهای ما هم این ویژگی را با دو بار اجرای دمو و مقایسهی مانیفست بررسی میکنند.
ساختار گزارش دمو
هر فیلد عیناً از مرحلهی بالادستی خود میآید. دمو خروجیها را دستکاری نمیکند؛ فقط آنها را کنار هم مینشاند. در واقع آزمون اصلی دمو در همین ترکیب نهفته است.
مدیریت حالتهای خطا
هر مرحله یا با موفقیت به پایان میرسد یا یک خطای تایپشده (typed error) صادر میکند.
Scheduler ........ returns SchedulerReport with stop_reason
in {queue_empty, max_experiments, deadline}
Best-result pick . raises NoTriggerError if no paper trigger fired
Critic loop ...... returns LoopResult with status converged or stopped
Paper writer ..... raises PaperValidationError on contract break
رخ دادن خطا در هر کدام از مراحل، اجرای دمو را بلافاصله با یک خطای مشخص متوقف میکند (short-circuit). تستها هم این قرارداد را کاملاً تثبیت کردهاند: تستهای test_no_triggers_raises_typed_error و test_best_picker_raises_when_no_triggers بررسی میکنند که اگر در هیچ branchای تریگری فعال نشود، انتخابگر خطای NoTriggerError یا BestResultError صادر کند و بخش نویسندهی مقاله اصلاً فراخوانی نشود.
انتخابگر بهترین نتیجه
اسکژولر تریگرهای مقاله را به ازای هر branch ارسال میکند. انتخابگر، branchای را که بالاترین میانگین پاداش را در همهی تریگرها داشته باشد گلچین میکند. در صورت تساوی، برای حفظ رفتار قطعی دمو، انتخاب بر اساس ترتیب الفبایی شناسهی branch انجام میشود. این انتخابگر یک تابع خالص کوچک است؛ تستها هم عملکرد آن را روی یک گزارش اسکژولرِ مشخص و ثابت میسنجند.
سیمکشی حلقهی ناقد
حلقهی ناقد در درس 55 روی یک MiniPaper کار میکند. دمو با قرار دادن شناسهی branch انتخابشده در چکیده، ایجاد دو بخش اولیه (مقدمه و نتایج) و تعیین برچسب اصالت (originality_tag) بر اساس میانگین پاداش branch (مقدار high اگر >= 0.8، مقدار medium اگر >= 0.6، و در غیر این صورت low)، یک MiniPaper میسازد.
سپس بازبین، پیشنویس را آنقدر اصلاح میکند تا به همگرایی برسد. خروجی این مرحله وارد نویسندهی مقاله میشود.
سیمکشی نویسندهی مقاله
نویسندهی مقاله در درس 54 روی ساختار کامل Paper همراه با تصاویر و کتابشناسی کار میکند. دمو پیشنویس همگراشدهی MiniPaper را از طریق تابع mini_to_full_paper ارتقا میدهد؛ این تابع یک تصویر مربوط به branch انتخابشده و یک کتابشناسی ساختگیِ کوچک برگرفته از اجتماع کلیدهای ارجاعی (cite keys) پیشنهادیِ ناقد را به آن ضمیمه میکند. هر ارجاعی که دمو اضافه میکند در فهرست کتابشناسی هم میآید تا اعتبارسنجی با موفقیت پاس شود.
راهنمای خواندن کد
فایل code/main.py این موارد را تعریف میکند: BestResultError، NoTriggerError، DemoReport، pick_best_branch، build_mini_paper، mini_to_full_paper و run_demo. ایمپورتهای بالای فایل یک بار sys.path را تنظیم کرده و PaperWriter، CriticLoop و IterationScheduler را از درسهای مربوطهشان لود میکنند.
فایل code/tests/test_e2e.py این موارد را پوشش میدهد: اجرای سرتاسری دمو و تولید گزارش با پر شدن هر پنج فیلد، قطعیت خروجی در دو بار اجرا، صدور NoTriggerError وقتی هیچ branchای از آستانه عبور نمیکند، رخ دادن PaperValidationError هنگام نقض قرارداد نویسنده، وجود تصویر branch انتخابشده در مانیفست مقاله، و قرار داشتن دلیل توقف اسکژولر در میان مقادیر مورد انتظار.
گامهای بعدی
وقتی تستهای دمو همگی سبز شدند، پیادهسازی این سه مورد ارزش ادامه دادن دارد: اول، ماندگارسازی وضعیت (persistent state): ذخیرهی نتیجهی هر مرحله در یک فایل JSON کوچک تا در صورت اجرای مجدد، سیستم بدون تکرار مراحل کمهزینه از همانجا ادامه یابد. دوم، داشبورد: نمایش رویدادهای ردگیری محاسبات (trace events) ثبتشده در اسکژولر و حلقهی ناقد در قالب یک خط زمانی واحد. سوم، فراخوانی مدلهای واقعی: جایگزین کردن تولیدکنندهی متنِ شبیهسازیشده و ناقد قطعی با مدلهای زبانی واقعی؛ منطق سیمکشی سیستم کوچکترین تغییری نخواهد کرد.
رسالت این دمو اثبات این نکته است که خودِ ترکیب، معماری اصلی است. پنج درس، چهار ایمپورت، یک گزارش. دفعات بعد با افزودن هر مرحلهی تازه، سیمکشی کد دقیقاً یک خط بیشتر میشود.
