ربات هوشمند اسلک با Laravel AI SDK
خلاصهٔ کاملتر
تیم Tighten تو این مقاله یه ربات هوشمند اسلک رو با Laravel AI SDK از صفر میسازه. نویسنده میگه Claude Tag آنتروپیک همین کار رو میکنه و خوبم کار میکنه، ولی دو تا ایراد داره: اول vendor lock-in، یعنی گیر افتادن تو اکوسیستم یه فروشنده، چون عوض کردن مدل به OpenAI یا Gemini بهسادگی تغییر یه مقدار تنظیمات نیست. دوم حافظه: تاریخچهٔ گفتوگو و هر چیزی که ربات یادش میمونه روی سرورهای آنتروپیک میمونه و تو نمیتونی مستقیم بخونیش یا جای دیگه استفادهش کنی.
نقطهٔ شروع، ساختن یه ایجنت با php artisan make:agent هست. مدل و فروشنده با اتریبیوتهای #[Provider] و #[Model] روی خود کلاس تعیین میشن، پس عوض کردن مدل واقعاً یه خط تغییره. متد instructions هم دستور پایهٔ ایجنت رو برمیگردونه.
#[Provider(Lab::OpenAI)]
#[Model('gpt-5.4')]
class SlackBot implements Agent, Conversational, HasTools
{
use Promptable, RemembersConversations;
}بقیهٔ اسکلت کار هم سادهست: یه روت POST عمومی که اسلک رویدادها رو روش میفرسته، و یه کنترلر invokable که اول درخواست url_verification اسلک رو با برگردوندن رشتهٔ challenge جواب میده. چون اسلک تا سه ثانیه منتظر جوابه و بعدش درخواست رو دوباره میفرسته، جواب دادن ایجنت به یه جاب صف منتقل میشه. جاب هم منشن ربات رو از متن پاک میکنه، پرامپت میزنه و با chat.postMessage جواب میفرسته.
یه نکتهٔ ریز که به گفتهٔ نویسنده رفتار ربات رو طبیعیتر میکنه، پارامتر thread_ts هست: اگه اسلک این مقدار رو فرستاده باشه یعنی کاربر داخل یه ترد ربات رو صدا زده و همونجا جواب میگیره، وگرنه تایماستمپ پیام اصلی بهکار میره و یه ترد تازه ساخته میشه. برای حافظهٔ گفتوگو هم تریت RemembersConversations اضافه میشه، بهعلاوهٔ دو مدل کوچیک: SlackUser بهعنوان مالک گفتوگو و SlackConversation که thread_ts اسلک رو به conversation_id این SDK وصل میکنه.
چون اپ به رویداد message.channels گوش میده، همهٔ پیامهای کانال به کنترلر میرسن و فیلتر کردن سمت خودته. نویسنده از همین استفاده میکنه تا رفتار Claude Tag رو تقلید کنه: جواب بده وقتی ربات منشن شده یا وقتی پیام تو تردیه که قبلاً توش جواب داده. تشخیص دومی فقط یه کوئری ایندکسشده روی thread_ts هست، پس همچنان داخل پنجرهٔ سه ثانیهای اسلک جا میشه.
بخش آخر حافظهٔ بینتردیه که با RAG ساخته میشه، یعنی هر پیام به یه vector (لیستی از اعداد که معنای متن رو نشون میده) تبدیل و کنار متن اصلی ذخیره میشه تا بعداً نزدیکترینهاش پیدا بشن. این به PostgreSQL با افزونهٔ pgvector نیاز داره و ستون امبدینگ ۱۵۳۶ بُعد داره، چون مدل پیشفرض امبدینگ OpenAI یعنی text-embedding-3-small همین اندازهست. ابزار SimilaritySearch هم به ایجنت داده میشه و ایجنت خودش تصمیم میگیره کِی سرچ کنه.
SimilaritySearch::usingModel(
SlackMessage::class,
'embedding',
minSimilarity: 0.3,
limit: 5,
)نکات کلیدی:
- کل ربات از یه کنترلر، یه جاب صف و مدلهای SlackUser، SlackConversation و SlackMessage تشکیل شده
- عوض کردن مدل یا فروشنده فقط تغییر اتریبیوتهای #[Provider] و #[Model] روی کلاس ایجنته
- اسلک تا سه ثانیه منتظر جواب میمونه، پس پاسخ ایجنت باید تو صف پردازش بشه
- حافظهٔ بلندمدت با pgvector و امبدینگ ۱۵۳۶ بُعدی text-embedding-3-small ذخیره میشه
- نویسنده هشدار میده سرچ شباهت پیشفرض همهٔ پیامها رو میگرده؛ برای پروداکشن با ستون کانال محدودش کن




