پرش به مطلب اصلی

6 پست با برچسب "معماری نرم‌افزار بهشتی"

مرورها و تمرین‌های درس معماری نرم‌افزار دانشگاه شهید بهشتی

مشاهده تمام برچسب‌ها

وقتی دمو تمام می‌شود؛ داستان معماری یک سرویس RAG قابل اعتماد

· ۲۴ دقیقه مطالعه
مهدی مالوردی
مهندس نرم‌افزار و نویسندهٔ این سایت

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

این نوشته از همین جا شروع می کند. نه از این پرسش که کدام مدل بهتر است، بلکه از این پرسش که اگر پاسخ درست بود اما دیر رسید، به سند اشتباه تکیه کرد یا چیزی را افشا کرد، کجای سامانه باید جوابگو باشد؟

چرخه کنترل یک سرویس بازیابی افزوده: اسناد، مجوز، مسیریابی، مدل، اعتبارسنجی و پایش

ساعت ۹:۱۷ صبح

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

«پاسخ درست بود، ولی چرا ۲۸ ثانیه طول کشید؟»

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

مهندس تیم صفحه پایش را باز می‌کند: API پاسخ 200 داده، GPU از پا نیفتاده و هیچ exception واضحی دیده نمی‌شود. از نگاه نمودارهای معمول، سامانه سالم است. از نگاه کاربران، نه.

این صحنه گزارش یک رخداد واقعی در شرکت مشخصی نیست؛ سناریویی ترکیبی و فرضی است که failure modeهای گزارش‌شده در پژوهش‌های RAG را کنار هم می‌گذارد. بااین‌حال پرسش آن کاملا واقعی است: وقتی مدل «جواب می‌دهد» اما نمی‌توان به سرویس اعتماد کرد، باید دنبال ایراد کجا بگردیم؟

این رخداد ساختگی است، اما از مسئله هایی ساخته شده که در پژوهش های RAG بارها گزارش شده اند.

پلتفرم داخلی، محصول است یا صف تیکت؟

· ۱۳ دقیقه مطالعه
مهدی مالوردی
مهندس نرم‌افزار و نویسندهٔ این سایت

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

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

همان‌جا بود که به نظرم رسید شاید ما پلتفرم نساخته‌ایم؛ فقط صف درخواست‌های زیرساخت را مرتب‌تر کرده‌ایم.

این روایت، ترکیبی از چند تجربه‌ی مشابه با Kubernetes، سامانه‌های داده و ابزارهای مشترک است و برای کنارگذاشتن جزئیات سازمانی ساده شده است.

صف درخواست‌های دستی در برابر مسیرهای روان خودخدمت از یک پلتفرم داخلی

مرز سرویس، مسیر رشد کسب‌وکار را مشخص می‌کند

· ۱۷ دقیقه مطالعه
مهدی مالوردی
مهندس نرم‌افزار و نویسندهٔ این سایت

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

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

ما سامانه را به چند سرویس تقسیم کرده بودیم، اما قابلیت کسب‌وکار را از جای اشتباهی بریده بودیم.

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

مرز فنی نامناسب که مسیر رشد قابلیت‌های کسب‌وکار را پیچیده و محدود می‌کند

معمار یا گلوگاه؟

· ۱۱ دقیقه مطالعه
مهدی مالوردی
مهندس نرم‌افزار و نویسندهٔ این سایت

یکی از سؤال‌هایی که بارها در نقش لید از من پرسیده شده، چیزی شبیه این بوده است:

برای این بخش از کدام راه برویم؟

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

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

در ظاهر داشتم به تیم کمک می‌کردم؛ در عمل داشتم تیمی می‌ساختم که برای جلو رفتن به حضور من نیاز داشت.

اگر برای هر تصمیم معماری باید منتظر تأیید یک نفر بمانیم، احتمالاً با یک معمار قدرتمند طرف نیستیم؛ با یک گلوگاه طرفیم. گلوگاهی که شاید خودش هم آن را آگاهانه نساخته باشد.

تفاوت معماری متمرکز بر یک تصمیم‌گیرنده با تصمیم‌گیری توزیع‌شده میان تیم‌ها

آیا با عوض‌کردن وسایل، خانه هم نو می‌شود؟

· ۷ دقیقه مطالعه
مهدی مالوردی
مهندس نرم‌افزار و نویسندهٔ این سایت

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

آیا می‌توانیم بگوییم خانه را نوسازی کرده‌ایم؟

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

خانه‌ای با وسایل و نمای تازه که زیر آن، ساختار فرسوده و لوله‌کشی پیچیده همچنان باقی مانده است

رویداد یا آشوب؟

· ۱۳ دقیقه مطالعه
مهدی مالوردی
مهندس نرم‌افزار و نویسندهٔ این سایت

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

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

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

قرار بود سرویس‌ها مستقل شوند؛ اما حالا وابستگی‌ها فقط از جلوی چشممان ناپدید شده بودند.

تبدیل جریان ساده‌ی رویدادها به شبکه‌ای پیچیده از مصرف‌کننده‌ها و وابستگی‌های پنهان