شکاف میان یک دمو جذاب از هوش مصنوعی و یک سیستم عملیاتی که ساعت ۲ صبح بدون دچار شدن به بحران به کار خود ادامه میدهد، بسیار عظیم است. اکثر کسانی که این دموها را میسازند، این موضوع را میدانند؛ آنها فقط وقتی نقشه راه را به شما میفروشند، همیشه در مورد آن صادق نیستند. در محیط عملیاتی، خط لوله (pipeline) شما به این دلیل شکست نمیخورد که مدل پایه (foundation model) اشتباهی انتخاب کردهاید؛ بلکه به این دلیل شکست میخورد که طراحی سیستم شما با یک نمونه اولیه (prototype) مانند یک محصول واقعی رفتار میکند.
در حال حاضر، همه هر چیزی را «عامل» (agent) مینامند. اسکریپتی که تا زمانی که یک شرط برقرار شود در یک حلقه میچرخد، ناگهان یک عامل است. چتباتی که سه پیام آخر را در حافظه خود نگه میدارد نیز یک عامل است. این واژهگزینی بیدقت، آسیبهای مهندسی واقعی ایجاد میکند. تیمها برای خودکارسازی یک گردش کار پنج مرحلهای که یک cron job ساده میتواند از پس آن بربیاید، به سراغ فریمورکهای سنگینِ عامل میروند. در عین حال، آنها روی پیچیدگیهای واقعی سرمایهگذاری نمیکنند، زیرا این برچسب باعث میشود تصور شود که مدل زبانی بزرگ (LLM) به شکلی جادویی موارد خاص (edge cases) را مدیریت خواهد کرد. اما این اتفاق نخواهد افتاد.
عامل واقعاً چیست
یک عامل، سیستمی با یک هدف مشخص است. عامل صرفاً دنبالهای از دستورالعملهای داده شده توسط انسان را اجرا نمیکند؛ بلکه بر اساس وضعیت جهان (state of the world)، تصمیم میگیرد که قدم بعدی چیست. عامل در صورت خرابی یک ابزار یا از دست رفتن دادهها، مدیریت خطا را بر عهده میگیرد. عامل میداند چه زمانی هدفش محقق شده و خودش را متوقف میکند.
برای قضاوت درباره هر چیزی که در حال ساخت آن هستید، از این سه قانون استفاده کنید:
- اگر یک انسان مجبور باشد هر مرحله را به آن بگوید، این فقط یک رابط چت است. در اینجا شما راننده هستید و سیستم فقط یک فرمان بسیار مودب است.
- اگر بتواند از یک فراخوانی ناموفق ابزار (tool call) بازیابی شود، در مسیر درستی هستید. تایماوت شدن یک Search API یا بازگشت خطای 500 نباید باعث پایان کار شود. سیستم باید دوباره تلاش کند، فاصله زمانی بین تلاشها را رعایت کند (back off)، به یک منبع جایگزین (fallback) سوئیچ کند یا درخواست کمک کند.
- اگر یک هدف را به زیروظایف تقسیم کرده و آنها را واگذار کند، یک عامل واقعی است. به آن دستوری مانند «گزارش انطباق فصل سوم را آماده کن» بدهید؛ عامل باید منابع داده را شناسایی کند، زمان استخراج را برنامهریزی کند، اعداد خام را به یک ماژول محاسباتی تحویل دهد، پیشنویس متن را برای بازبینی بفرستد و بداند چه زمانی کار تمام است.
اگر سیستم شما این کارها را انجام نمیدهد، مشکل شما مشکل «عامل» نیست؛ مشکل شما مشکل «اسکریپتنویسی» یا مشکل «گردش کار» است. پذیرش زودهنگام این موضوع، شما را از هفتهها درگیر کردن خود با تورم فریمورکها (framework bloat) نجات میدهد.
آنچه تیمهای موفق واقعاً اولویتبندی میکنند
تیمهایی که سیستمهای قابل اعتماد عرضه میکنند، روزهای خود را صرف جایگزین کردن آخرین مدلهای منتشر شده برای کسب چند امتیاز بیشتر در یک بنچمارک نمیکنند. آنها بر سه حوزه خستهکننده اما پربازده تمرکز میکنند.
طراحی ابزار (Tool design). عامل شما فقط به اندازه ابزارهایی که در اختیارش میگذارید خوب است. اگر یک تابع جستجو، یک JSON تو در تو با نام فیلدهای ناسازگار برگرداند، مدل به جای استدلال درباره محتوا، پنجره بافت (context window) ارزشمند خود را صرف تجزیه و تحلیل ساختار میکند. اگر توضیحات ابزار مبهم باشد، مدل آرگومانهای اشتباهی را توهم (hallucinate) میزند. با رابطهای ابزار مانند APIهایی رفتار کنید که برای یک توسعهدهنده جونیور (Junior Developer) بسیار دقیق طراحی شدهاند؛ کسی که به ورودیهای تمیز، خروجیهای قابل پیشبینی و وضعیتهای خطای صریح نیاز دارد.
مدیریت خطا (Failure handling). وقتی یک مرحله بازیابی (retrieval) چیزی برنمیگرداند، چه اتفاقی میافتد؟ بسیاری از خط لولهها به شکلی بیصدا، بافت خالی را به پرامپت تزریق میکنند و اجازه میدهند مدل پاسخی را از دادههای آموزشی خود توهم بزند. این یک ویژگی نیست؛ این یک حادثه در محیط تولید است که در انتظار وقوع است. یک سیستم مناسب، خلأ را تشخیص میدهد. با یک پرسوجوی گستردهتر دوباره تلاش میکند. به یک انسان ارجاع میدهد یا با یک توضیح شفاف متوقف میشود. سیستم هرگز وانمود نمیکند که چیزی پیدا کرده است، در حالی که پیدا نکرده است.
مشاهدهپذیری (Observability). شما باید ببینید چرا عامل یک تصمیم خاص را گرفته است. نه فقط خروجی نهایی، بلکه زنجیره تفکر (chain of thought)، انتخاب ابزار، بخشهای بازیابیشده (retrieved chunks) و لاگهای انتقال وظایف. بدون این ردپا (trace)، عیبیابی (debugging) حدس و گمان است. وقتی هفته آینده کاربری از یک پاسخ اشتباه شکایت کرد، باید بتوانید دقیقاً بازسازی کنید که کدام مرحله بازیابی دادههای بیارزش ارائه داده و چرا.
الگوهای معماری که فراتر از فریمورکها باقی میمانند
LangChain، CrewAI و فریمورکهای پرطرفدار بعدی که شش ماه دیگر معرفی میشوند، تنها داربست هستند. معماری، خودِ ساختمان است. اگر طراحی شما شکننده باشد، هیچ فریمورکی نجاتش نخواهد داد. به الگوهایی پایبند باشید که دوام خود را ثابت کردهاند:
- ابتدا برنامهریزی کنید، سپس اجرا کنید. اجازه ندهید مدل در یک لحظه هم استدلال کند و هم عمل کند. ابتدا یک برنامه ایجاد کنید، سپس مراحل را اجرا کنید. وقتی مشکلی پیش میآید، میتوانید برنامه را مستقل از اجرا بررسی کنید. با این کار، زمان بسیار کمتری را صرف باز کردن گرههای پیچیده فراخوانیهای ابزار درهمتنیده و استدلالهای جریان سیال ذهن (stream-of-consciousness) خواهید کرد.
- بازیابی (Retrieval) را از استدلال (Reasoning) جدا کنید. واکشیِ بافتار (Context) یک وظیفه I/O است. استفاده از بافتار یک وظیفه استدلالی است. ترکیب آنها به این معناست که بازیاب شما با محدودیتهای توکن مدل محدود میشود و مدل شما با نویزهای خامِ بازیابی آلوده میگردد. اجازه دهید لایه بازیابی بهصورت تهاجمی واکشی کند و لایه استدلال، آنچه را که دریافت کرده با دیدی شکاکانه ارزیابی کند.
- از تحویلهای صریح (Explicit handoffs) استفاده کنید. اگر چندین عامل (Agent) روی یک وظیفه کار میکنند، فرآیند انتقال را ساختارمند کنید. طرحهای خروجی (Output schemas)، مرزهای مالکیت و گزارشهای تحویل را بهوضوح تعریف کنید. چتهای غیررسمی و مبهم بین عاملها منجر به رها شدن وظایف، حلقههای تکراری یا کارهای تکراری میشود. با ارتباط عامل به عامل مانند یک قرارداد API تعریفشده رفتار کنید، نه یک چت گروهی.
دلیل واقعی اینکه چرا RAG شما خروجیهای بیارزش تولید میکند
اگر خط لوله (Pipeline) تولید تقویتشده با بازیابی (RAG) شما مدام نتایج بیفایده ارائه میدهد، از تنظیم کردن مدل embedding دست بردارید و به استراتژی تکهبندی (Chunking) خود نگاه کنید. این نادیدهگرفتهشدهترین نقطه شکست در سیستمهای RAG است.
وقتی اسناد را به تکههای (Chunks) با اندازه ثابت و صلب تقسیم میکنید، اغلب ایدهها را از معنا جدا میکنید. پاراگرافی که با «با این حال، این رویکرد نتوانست تغییرات مقرراتی را در نظر بگیرد» شروع میشود، بدون پاراگراف قبلی که نام آن رویکرد را برده است، هیچ معنایی ندارد. اگر آن قطعهی منزوی را به مدل بدهید، مدل هر بافتاری را که نیاز داشته باشد از خود میسازد. این بازیابی نیست؛ این یک کارخانه توهم (Hallucination) است.
این اصلاحات را امتحان کنید:
- پنجرههای همپوشان (Overlapping windows). اجازه دهید تکههای مجاور یک یا دو جمله را در مرزها با هم به اشتراک بگذارند تا مفاهیم در میانهی یک فکر، رها نشوند.
- تکهبندی معنایی (Semantic chunking). بهجای شمارش کاراکترها، در مرزهای طبیعی — پایان پاراگرافها، تیتر بخشها یا تغییر موضوعات — تقسیمبندی کنید.
- بازیابی سند والد (Parent-document retrieval). تکههای کوچک و دقیق را برای تطبیق معنایی بازیابی کنید، اما بخش والد یا سند کامل را به مدل زبانی بفرستید تا هنگام تولید، بافتار محیطی را در اختیار داشته باشد.
- بهجای متن خام، دادههای ساختاریافته ذخیره کنید. دادههای جدولی، جفتهای کلید-مقدار و روابط اغلب بهصورت متن ساده (Prose) بهخوبی جاسازی (Embed) نمیشوند. اگر منبع دادههای شما ساختاریافته است، آن را بهصورت ساختاریافته در یک پایگاه داده گراف یا ذخیرهساز رابطهای نگه دارید و اجازه دهید عامل بهجای حدس زدن از تکههای متن جاسازیشده، بهطور صریح از آن پرسوجو (Query) کند.
سیستمهایی بسازید که بتوانید به آنها اعتماد کنید
دست از دنبال کردن بنچمارکها بردارید. امتیاز جدول امتیازات (Leaderboard) یک شرایط آزمایشگاهی است. محیط عملیاتی (Production) آشفته، خصمانه و ناهمگام (Async) است. آنچه اهمیت دارد این است که آیا سیستم شما زمانی که خواب هستید، زمانی که API بالادستی ناپایدار است و زمانی که کاربر چیزی میپرسد که در دادههای آموزشی نبوده، بهدرستی رفتار میکند یا خیر.
بر طراحی سیستم تمرکز کنید. مرزهای مشخصی بین بازیابی و استدلال ایجاد کنید. ابزارهایی طراحی کنید که در صورت خطا، بهوضوح اعلام شوند (Fail loudly) و بهطور تمیز بازیابی شوند (Recover cleanly). تصمیمات را ثبت (Log) کنید تا بتوانید آنها را بازرسی کنید. اسناد خود را بهگونهای تکهبندی کنید که بافتار دستنخورده باقی بماند. با انجام این کار، خط لولههایی خواهید ساخت که نه تنها در نمایش (Demo) خوب عمل میکنند، بلکه در شرایط واقعی و سخت نیز قابل اعتماد باقی میمانند.
Source: The Overlooked Reason Your RAG Pipeline Keeps Returning Garbage
Join the learning community: GyaanSetu AI on Telegram
