ناوبری اصلی

از پوشش‌های مرورگر تا کار محدودشده با رایانه

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

خلاصه مدیریتی

  • کار با رایانه چیست و چرا اهمیت دارد؟ کار با رایانه ایده‌ای ساده با پیامدهایی گسترده است: به‌جای آنکه از مدل‌ها بخواهیم به پرسش‌ها پاسخ دهند، از آن‌ها می‌خواهیم با نرم‌افزار کار کنند؛ در وب‌سایت‌ها بگردند، فرم‌ها را پر کنند، مراحل گردش‌کار را با کلیک پیش ببرند و وظایف را به‌طور خودمختار از ابتدا تا انتها انجام دهند.

  • این رویکرد طیف بزرگی از وظایف دنیای واقعی را ممکن می‌کند که اکنون میان رابط‌های مختلف پراکنده‌اند؛ مانند رزرو کامل، تسویه‌حساب فروشگاه اینترنتی، برنامه‌ریزی چندمرحله‌ای سفر و گردش‌کارهای اداری که معادل API تمیزی ندارند. این مسائل تازه نیستند. آنچه تازگی دارد، امکان حل آن‌ها با مدل‌های همه‌منظوره است.

  • سیستم‌های اخیر Anthropic و OpenAI عامل‌هایی را به نمایش گذاشته‌اند که نه‌تنها اقدام می‌کنند، بلکه درباره وضعیت استدلال می‌کنند، خطاها را برطرف می‌سازند و همان لحظه راه‌حل‌های مختص هر وظیفه را می‌سازند. این امر مرورگر را به محیط اجرایی عمومی عامل‌ها تبدیل می‌کند، اما فوراً پرسشی در طراحی پدید می‌آورد: چه میزان از این محیط را باید در اختیار مدل بگذاریم؟

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

نموداری برای نمایش خلاصه مدیریتی.

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

پس مرورگر را در یک پوشش قرار می‌دهیم. ابزارهای ازپیش‌تعریف‌شده‌ای مانند click، type، scroll، select و read_text را در اختیار مدل می‌گذاریم. مدل شیء سند (DOM) را ساده می‌کنیم. فضای اقدامات را کاهش می‌دهیم. می‌کوشیم رفتار را با انتزاع‌هایی که طراحی کرده‌ایم، قابل‌درک و مهارپذیر کنیم.

این نقطه شروع معقولی است. اما هرچه می‌گذرد، بیشتر روشن می‌شود که این معماری بلندمدت نادرستی است.

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

این بده‌بستان هر روز جذابیت کمتری پیدا می‌کند.

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

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

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

چرا انتزاع‌ها از کار می‌افتند

مشکل این نیست که رابط‌های ثابت اقدامات از نظر مفهومی نادرست‌اند. مشکل این است که وب با آن‌ها سازگار نیست.

نموداری درباره دلایل از کار افتادن انتزاع‌ها.

رابط‌های مدرن با React، Vue و Angular ساخته می‌شوند و به‌روزرسانی ناهمگام وضعیت، سامانه‌های رویداد مصنوعی و ویجت‌های شخص ثالثی دارند که در iframeهای میان‌مبدأ با چرخه عمر مستقل خود اجرا می‌شوند. پوششی که می‌گوید «در این ورودی تایپ کن» تنها زمانی درست عمل می‌کند که تعریف صفحه از تایپ‌کردن با تعریف شما یکسان باشد. در بسیاری از صفحات چنین نیست. تنظیم مستقیم یک مقدار اغلب سازوکار تشخیص تغییر چارچوب را کاملاً دور می‌زند. ورودی پرشده به نظر می‌رسد. اعتبارسنجی هرگز فعال نمی‌شود. فرم همچنان خراب می‌ماند.

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

مسئله عمیق‌تر این است که فرضیات خود درباره نحوه تعامل را در لایه انتزاع کدنویسی می‌کنید و سپس درمی‌یابید که وب فرضیات دیگری دارد.

وقتی انتزاع با یک جریان واقعی روبه‌رو می‌شود چه اتفاقی می‌افتد؟

یک فرم پرداخت Stripe یا Adyen را در نظر بگیرید که درون یک iframe میان‌مبدأ جاسازی شده است. پوشش شما نمی‌تواند مستقیماً به آن دسترسی یابد، زیرا در مبدأیی جداگانه قرار دارد. ابزار read_text شما نمی‌تواند وضعیت داخلی آن را مشاهده کند. ابزار type شما نمی‌تواند ورودی‌های آن را هدف قرار دهد. عامل مبتنی بر پوشش در اینجا به بن‌بست می‌رسد. انتزاع برای سند اصلی طراحی شده بود. وظیفه واقعی جایی قرار دارد که انتزاع قادر به دیدنش نیست.

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

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

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

مدلی که در سطح پایین‌تری کار می‌کند—DOM زنده را بررسی می‌کند، درباره مرزهای فریم‌ها استدلال می‌کند و دنباله تعامل مختص آن سطح را می‌سازد—می‌تواند از این موقعیت‌ها عبور کند. موضوع این نیست که مدل ذاتاً هوشمندتر است. موضوع این است که به اطلاعات حذف‌شده دسترسی دارد.

گذار معماری

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

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

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

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

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

نکته مهم اینکه حذف لایه انتزاع، از انضباط سیستم نمی‌کاهد. بلکه محل اعمال این انضباط را تغییر می‌دهد.

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

پیامد غافلگیرکننده: کد محصول ساده‌تر، تعمیم‌پذیری گسترده‌تر

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

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

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

جزء قابل‌استفاده مجدد، فهرست اقدامات نیست؛ بلکه توانایی مدل برای بررسی وضعیت، اقدام ایمن و راستی‌آزمایی نتایج است.

محدود کنید، بیش از حد کمک نکنید

نموداری درباره محدودکردن به‌جای کمک بیش از حد.

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

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

در طراحی باید چهار ملاحظه را در نظر گرفت:

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

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

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

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

اصل زیربنایی ساده است: دادن قدرت بیشتر به مدل، مستلزم تقویت سیستم پیرامون آن است. خودمختاری بدون سیاست، آماده استفاده عملیاتی نیست.

بازنگری‌ای که طرز فکرمان را تغییر داد

دیگر نپرسیدیم: کدام اقدامات مرورگر را باید در اختیار مدل بگذاریم؟

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

این بازنگری اولویت‌ها را تغییر می‌دهد. رده‌بندی اقدامات و کامل‌بودن پوشش‌ها اهمیت کمتری پیدا می‌کند. سیاست محیط اجرا، مشاهده‌پذیری و ارزیابی هر مرحله مهم‌تر می‌شوند. توانمندی مدل و طراحی سیستم جایگزین یکدیگر نیستند. با پیشرفت مدل‌ها، نقش سیستم مهم‌تر می‌شود، نه کم‌اهمیت‌تر.

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

سخن پایانی

طراحی پوشش کمتر. مهندسی سیستم بیشتر.

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

نویسنده

Yuxi Huan،‏ Yuliyan Stefanov Savchev،‏ Sheah Wen Liaw