اگر برنامهنویس باشید یا اخبار AI را دنبال کرده باشید، احتمالا نام Cursor یا Claude رو شنیدید. از این قسمتها میگذرم چون با یه سرچ ساده میتونید اطلاعاتی که دنبالش هستید رو در مورد این ابزارها پیدا بکنید.
اینجا میخوام از تجربه خودم از Claude Code بنویسم و اینکه چرا در حال حاضر گزینه خیلی بهتری هست نسبت به Cursor.
کمی بعد از استفاده از Claude Code متوجه شدم خروجی کار خیلی مطلوبتر هست و بعد از بررسی مهمترین نکتهای که دیدم نوع نگاه این دو ابزار به موضوع Context هست جایی که Cursor از RAG کردن فایلها استفاده میکنه و Claude از جستجو بین فایلها.
اول بیایم یه نگاه خیلی ساده به RAG بندازم که چرا هست و معایب مزایاش چیه:
وقتی که ChatGPT و LLMها معرفی شدند محدودیتی رو به عنوان توکن معرفی کردند مثلا در اون ابتدا مدل GPT-3.5 مقدار ۴۰۹۶ توکن رو پشتیبانی میکرد و به مرور این مقدار در حال بیشتر و بیشتر شدن هست. هرچقدر این مقدار بیشتر باشد، شما میتوانید پرامپت بزرگتر یا Context بزرگتری به LLM بدهید. معمولا این تو گفتگوهای ساده در ChatGPT خیلی خودش رو نشون نمیده اما وقتی بخواهید بطور مثال داکیومنتهای برنامتون که کلی صفحه هست رو و یا کد پروژتون که خطهای زیادی داره رو بدید، اونجاست که مشکل خودش رو نشون می ده.
برای حل این مشکل تو دنیا از روشی به نام Retrieval-Augmented Generation یا به اختصار RAG استفاده شد (و میشه).
ایده اصلی ساده هست: اگر همه چیز رو نمیشه به عنوان Context به LLM داد، اون قسمتی که مرتبطترین هست رو استفاده میکنیم.
در این روش کل محتوا به تکههای کوچکتری تقسیم میشوند و براساس نیاز قطعه(های) مورد نیاز انتخاب و به عنوان Context در اختیار LLM قرار میگیرد.
قطعه قطعه کردن محتوا
برای حل این مشکل، محتوای بزرگ به تکههای کوچک تبدیل میشوند (۴۰۰-۱۰۰۰ توکن که حدودا میشه ۳۰۰-۷۰۰ کلمه).
حالا مشکل چیه؟ راهکار سادهای برای خورد کردن ۵۰۰ کلمهای وجود نداره. فرض کنید یک داکیومنت بزرگ دارید که بخشها و صفحات مختلفی داره. وقتی این خورد کردن انجام میشه احتمال اینکه بخشی مهمی در چند بخش تقسیم بشه و یا توضیحی در وسط جمله قطع بشه ویا دادهها از بخش توضیحی خود جدا شوند و امثال این موارد، وجود دارد.
مثلا اگر شما کلمهای را جستجو کنید ممکن است به قطعه برسید که در آن فقط عنوان این کلمه وجود دارد و محتوای اصلی آن در بخش دیگری است.
البته راهکارهایی برای بهبود Chunk کردن وجود دارد که میتواند برخی از مشکلات را برطرف کند اما در نهایت مشکل، یعنی کار کردن با بخشی از یک داکیومنت به جای کل آن، وجود دارد.
نحوه دسترسی به قطعهها
هر قطعه به وکتورهایی با ابعاد زیاد تبدیل میشوند. وقتی کاربر سوالی میپرسد، اون سوال هم تبدیل به یک وکتور میشود و حالا سیستم شروع به پیدا کردن شبیهترین وکتورها به سوال میشود.
بزارید با یک مثال ساده بریم جلو:
فرض کنید میخواهید کاربر از مستندات نرمافزار شما سؤال بپرسد و بر اساس همان مستندات جواب بگیرد. ابتدا محتوای مستندات را به قطعات منطقی تقسیم میکنید. هر قطعه را به یک مدل امبدینگ میدهید تا آن را به یک بردار عددی تبدیل کند و این بردارها را همراه متادیتا در یک دیتابیس مناسب ذخیره میکنید.
وقتی کاربر سؤال میپرسد، سؤال هم به بردار تبدیل میشود و با بردارهای ذخیرهشده مقایسه میگردد تا شبیهترین قطعات پیدا شوند. چند قطعهٔ برتر را برمیدارید و بهعنوان زمینه به مدل زبانی میدهید، همراه با دستورالعمل لازم و خودِ سؤال کاربر. مدل با تکیه بر همین زمینه پاسخ میدهد و نتیجه بر اساس محتوای شما تولید میشود.
در کل این روش در تئوری خوبه اما در حالتهای خاص میتونه بسیار اذیت کننده بشه. برای مثال یک مشکل این هست که مدلهای embedding مبتنی بر متنهای عمومی توسعه داده شدن و اگر محتوای شما تخصصی باشه احتمالا مشکلات زیادی خواهید داشت. همچنین این مدلها مشابهها رو پیدا میکنند و این کار بدون در نظر گرفتن Context معنایی رخ میده (کلمهها و مفاهیمی که در شرایط مختلف، معانی متفاوتی دارند).
و حالا این رو بگذارید که شما باید یک ساز و کار بروزرسانی قطعات رو هم داشته باشید و هر قسمت از سیستم که تغییر میکند باید Chunkهای مرتبط با آن نیز تغییر کند (اگر با Cursor کار کرده باشید میدونید که همین موضوع ممکنه باعث چالشهای مختلفی بشه و خیلی موقعها برای جلوگیری از این مشکلات بعد از هر تغییر نیاز دارید تا کدبیس خودتان را مجدد سینک کنید تا embedding بروزرسانی شود).
نوع نگاه Claude Code
وقتی که شروع به کار با Claude Code کردم متوجه شدم که خیلی بهتر و سریعتر داره عمل میکنه و این بخاطر مدل RAGش نبود، بخاطر این بود که اصلا چیزی به نام RAG نداشت و براساس نیاز عملیات جستجو را انجام میداد.
- با استفاده از regex داخل فایلها رو جستجو میکنه.
- نیاز به indexing نداره و به لحظه جستجو رو انجام میده.
- جستجو براساس نوع فایل (پسوند) را هم انجام میده.
- نتیجه را همراه با شماره خطها برمیگردونه.
- باری روی سیستم نمیاره.
و جالبتر اینکه جستجو را خیلی هوشمند و ساختارمند انجام میده، یعنی در چند مرحله، ادغام چند نوع سرچ با هم، اصلاح خودش براساس موارد یافت شده و…
با این روش دیگر نیازی به RAG و بروزرسانیهای اون نیست و در هر مرحله و لحظه سیستم آمادگی پیدا کردن جواب مورد نظرش رو داره و میتونه:
- کل فایل یا ساختار رو بخونه.
- ارتباطات و ساختار رو درک کنه.
- و در نهایت یک Context خوب با بررسی کامل بدست بیاره.
و قشنگتر اینکه روی هر متنی میتونه کار کنه و این امکان رو میده که برای هر کارکردی ازش استفاده بشه (و sub agentهای متنوعتری رو براش تعریف کرد – که خارج از موضوع این نوشته هست).
پینوشت۱: اخیرا متوجه شدم که Cursor هم ابزار CLI خودش رو معرفی کرده اما نمیدونم آیا داره از این مدل و بدون RAG استفاده میکنه یا نه.
پینوشت۲: برای دسترسی به Claude Code باید اکانت Claude Pro or Max داشته باشید که ماهانه ۲۰ و ۱۰۰ دلار هزینه داره (نسخه ارزونتر محدودیت بیشتری داره).
پینوشت۳: بهترین نمونه مشابه Claude Code که تقریبا رایگان هم هست (حداقل چیزی که من میدونم)، Qwen Code هست.
پینوشت۴: در کنار Claude Code میتوانید از VS Code استفاده بکنید تا هم ویو بهتری داشته باشید و هم اینکه یک اکستنشن خیلی خوب هم خود Claude براش توسعه داده.