پرش به محتوای اصلی
پرش به محتوای مقاله

چطور بازطراحی گراف استنتاج سرعت ایندکس CodeSage را ۵ برابر کرد؟

·۱۰ مهر ۱۴۰۵۹ دقیقه مطالعه
لوگوی CodeSage: هوش کد برای عامل‌های هوش مصنوعی
لوگوی CodeSage: هوش کد برای عامل‌های هوش مصنوعی
اشتراک‌گذاری
واقعاً چه چیز جدید است؟

کاهش ۸۰ درصدی زمان ایندکس نه از طریق مدل، بلکه با ادغام عملیات (Operator Fusion) در گراف ONNX و رفع یک باگ اسکن در SQLite حاصل شده است.

تصور کنید برای شروع کار با یک پروژه عظیم، باید نیم ساعت منتظر بمانید تا عامل هوش مصنوعی شما کدها را تحلیل کند؛ این تأخیر یعنی یا کار با داده‌های قدیمی و یا توقف کامل جریان توسعه. CodeSage در نسخه ۰.۳۸ این بن‌بست را شکست و طبق گزارش فنی منتشر شده در ۲ اکتبر ۲۰۲۶، زمان ایندکس کامل مخزن php-src را از ۱۷۸۲ ثانیه به تنها ۳۷۳ ثانیه کاهش داد.

بسیاری از عامل‌های کدنویسی تنها به پنجره زمینه (Context Window) — مثل میز کاری که جا برای چند ورق دارد، نه برای کل کتابخانه — تکیه می‌کنند که منجر به حدس زدن به‌جای دانستن می‌شود. CodeSage با ارائه یک گراف ساختاری از نمادها و وابستگی‌ها در کنار جست‌وجوی معنایی (Semantic Search) — شبیه به سیستمی که مفهوم کلمات را می‌فهمد نه فقط حروف آن‌ها را — این مشکل را حل می‌کند. این ابزار که به صورت یک فایل باینری Rust عرضه شده، اجازه می‌دهد عامل‌ها به‌جای جست‌وجوی ساده با دستوراتی مثل grep، سوالات دقیقی مثل «چه کلاس‌هایی به این تابع وابسته هستند» یا «مدیریت نشست‌ها (session handling) در کجا اتفاق می‌افتد» بپرسند.

زمینه و معماری

CodeSage به عنوان یک موتور هوش کد برای عامل‌های کدنویسی عمل می‌کند. این سیستم یک گراف ساختاری (شامل نمادها، ارجاعات و وابستگی‌ها) را با جست‌وجوی معنایی ترکیب می‌کند که از بازیابی بردار (Embedding Retrieval) و بازرتبه‌بندی با استفاده از cross-encoder بهره می‌برد. برای تجزیه کدها از tree-sitter استفاده شده که زبان‌های PHP، پایتون، C، C++، جاوا، Rust، جاوااسکریپت، تایپ‌اسکریپت و گو (Go) را پوشش می‌دهد.

هر پروژه از طریق یک پایگاه‌داده SQLite واحد که در مسیر .codesage/index.db قرار دارد مدیریت می‌شود. این سیستم برای جست‌وجوی K-Nearest Neighbor (KNN) از sqlite-vec و برای تطبیق‌های تحت‌اللفظی از FTS5 استفاده می‌کند.

در بخش پروتکل زمینه مدل (MCP)، سیستم از یک shim stdio استفاده می‌کند که یک دیمون (Daemon) مخصوص هر کاربر را روی یک سوکت یونیکس (Unix socket) اجرا یا بازنشانی می‌کند. این معماری اجازه می‌دهد جلسات هم‌زمانِ عامل‌ها، یک حافظه پنهان (Cache) پروژه، یک استخر مدل (Model Pool) و یک محیط CUDA مشترک داشته باشند، که در نتیجه نیاز به شنونده HTTP کاملاً حذف می‌شود.

مجموعه ابزار MCP و قابلیت‌ها

سرور MCP این ابزار ۲۲ ابزار مختلف را در اختیار عامل قرار می‌دهد. حیاتی‌ترین این ابزارها عبارتند از:

  • find_symbol، find_references و trace_call_path: این ابزارها محل تعریف یک نماد، کسانی که آن را فراخوانی می‌کنند و کوتاه‌ترین زنجیره فراخوانی بین دو نماد را شناسایی می‌کنند.
  • impact_analysis و assess_risk: این‌ها تعیین می‌کنند که تغییر در یک فایل خاص چه بخش‌هایی را ممکن است خراب کند. این کار با استفاده از امتیازی استخراج شده از گراف ساختاری و تاریخچه git انجام می‌شود.
  • search: بازیابی زبان طبیعی را روی تکه‌هایی از کد با طول تقریبی ۵۰ خط فراهم می‌کند که سپس بازرتبه‌بندی می‌شوند.
  • from_trace: گزارش‌های خطای چسبانده شده (Stack Traces) یا گزارش‌های ASan را روی نمادهای ایندکس شده نگاشت می‌کند. این قابلیت از پایتون، PHP (با Xdebug)، Rust، جاوا، گو، Node و gdb پشتیبانی می‌کند.
  • edit_check: پیش از آنکه عامل فایل را روی دیسک بنویسد، تعریف پیشنهادی را با آخرین کامیت (HEAD) مقایسه (Diff) می‌کند.

گلوگاه استنتاج (Inference Bottleneck)

به نقل از مستندات فنی این پروژه، جهش عملکردی ناشی از تغییر وزن‌های مدل نبود، بلکه نتیجه بازسازی گراف استنتاج (Inference) بود. پیش از این، CodeSage دو مدل خود را دقیقاً همان‌طور که در Hugging Face عرضه شده بودند اجرا می‌کرد: مدل جاسازی کد Jina و بازرتبه‌بند ms-marco MiniLM. خروجی ONNX اصلی Jina v2 از یک ساختار decomposed opset-11 استفاده می‌کرد که بهینه‌ساز transformer در ONNX Runtime قادر به شناسایی آن نبود. این موضوع سیستم را مجبور می‌کرد تا تانسورهای امتیاز کامل [batch, 12, seq, seq] را چندین بار ایجاد کند و تانسورهای [batch, seq, 768] را برای هر دسته از GPU به میزبان (Host) کپی کند تا فقط بتواند میانگین آن‌ها را بگیرد.

برای رفع این مشکل، توسعه‌دهنده دو گراف جدید را در Hugging Face تحت عنوان IA0x00/jina-embeddings-v2-base-code-codesage منتشر کرد:

۱. گراف Pooled fp32 (onnx/model.onnx): این گراف عملیات masked mean pooling و نرمال‌سازی L2 را مستقیماً در خود ادغام می‌کند تا اطمینان حاصل شود که فقط بردار نهایی ۷۶۸ بعدی به میزبان بازمی‌گردد. این نسخه روی تمامی ارائه‌دهندگان اجرا (Execution Providers) کار می‌کند.
۲. گراف Fused fp16 (onnx/model_cuda_fp16.onnx): این نسخه مخصوص CUDA است و مکانیزم توجه (Attention) را در com.microsoft MultiHeadAttention ادغام کرده و از وزن‌های fp16 استفاده می‌کند. در اینجا ALiBi و ماسک پدینگ کلید به عنوان attention_bias پاس داده می‌شوند. برای جلوگیری از سرریز (Overflow) در fp16، ماسک توجه اکنون موقعیت‌های پد شده را با مقدار -10000.0 پر می‌کند، به جای استفاده از -FLT_MAX.

این تغییرات منجر به افزایش شدید توان عملیاتی شد. در اندازه‌گیری روی GPU مدل RTX 4080 Laptop با ONNX Runtime 1.24.4 و استفاده از ۲۰۴۸ تکه واقعی (تا ۵۱۲ توکن برای هر تکه)، نتایج به شرح زیر بود:

  • php-src (C): از ۵۹.۷ تکه در ثانیه (Upstream fp32) به ۲۴۹-۲۵۷ تکه در ثانیه (Fused fp16) جهش کرد.
  • اپلیکیشن Laravel (PHP): از ۶۷.۲ تکه در ثانیه به ۳۰۱-۳۱۷ تکه در ثانیه رسید.
  • اپلیکیشن React (TS/JS): از ۶۹.۸ تکه در ثانیه به ۲۹۶-۳۱۷ تکه در ثانیه رسید.

بردارها تقریباً یکسان باقی ماندند، به طوری که حداقل شباهت کسینوسی ۰.۹۹۹۹۹ و هم‌پوشانی ۱۰ همسایه اول بین ۰.۹۹۴ تا ۰.۹۹۷ بود.

بازرتبه‌بند و یکپارچگی مدل

مدل بازرتبه‌بند IA0x00/ms-marco-MiniLM-L6-v2-codesage یک مدل استاندارد BERT است. از آنجایی که بهینه‌ساز پیش‌فرض ONNX Runtime در حال حاضر LayerNorm جاسازی، شش گره Attention, skip LayerNorm و bias GELU را ادغام می‌کند، کار اصلی تبدیل آن به fp16 بود. این تغییر زمان امتیازدهی به ۵۰ کاندید (پرس‌وجو، تکه) را از میانگین ۱۰۸.۰ میلی‌ثانیه به ۲۰.۶ میلی‌ثانیه کاهش داد. نتیجه برتر در ۴۰ مورد از ۴۰ پرس‌وجوی آزمایشی یکسان باقی ماند، با هم‌پوشانی ۱۰تایی ۰.۹۹۷۵ و حداکثر تغییر لوجیت ۰.۰۲۴.

برای تضمین اعتماد، هر دو مخزن از لایسنس Apache-2.0 استفاده می‌کنند. CodeSage مدل‌ها را از طریق کامیت‌های Hugging Face و هش‌های sha256 تثبیت (Pin) می‌کند. اسکریپت‌های scripts/derive-jina-onnx.py و scripts/derive-reranker-onnx.py به کاربران اجازه می‌دهد فایل‌های اصلی تثبیت شده را دانلود کرده و فایل‌های منتشر شده را بیت‌به‌بیت بازسازی کنند.

حل مشکل «قاتل خاموش» SQLite

در حالی که بهینه‌سازی‌های مدل قابل توجه بود، بزرگ‌ترین پیروزی مربوط به یک اصلاح در پایگاه‌داده بود. در نسخه‌های قبلی، حذف تکه‌های قدیمی در هنگام تغییر یک فایل، نیازمند اسکن ستون‌های بدون ایندکس در جداول sqlite-vec و FTS5 بود. برای پروژه‌ای مانند php-src با ۵۴,۰۰۰ ردیف، این اسکن تقریباً یک ثانیه برای هر فایل زمان می‌برد.

در یک ایندکس کامل، این سربار حدود ۲۰ دقیقه از ۲۸ دقیقه زمان کل اجرا را می‌بلعید. CodeSage 0.38 یک جدول جانبی کوچک به نام <chunk_table>_paths(id, file_path) معرفی کرد که مسیر فایل‌ها را به rowidها نگاشت می‌کند. این تغییر زمان حذف را از یک ثانیه برای هر فایل به تنها ۳.۲ میلی‌ثانیه کاهش داد.

جزئیات تکه‌بندی و ایندکس‌گذاری

دو تغییر اضافی در تکه‌بند (Chunker) در نسخه ۰.۳۸ اعمال شد:

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

علاوه بر این، مدل جاسازی اکنون تا ۱۰۲۴ توکن در هر تکه را می‌خواند، به جای ۵۱۲ توکن قبلی. این تغییر ضروری بود زیرا کدهای واقعی C در php-src به طور میانگین ۶۱۱ توکن در هر تکه ۱۵۰۰ بایتی دارند؛ سقف قدیمی بیش از نیمی از محتوا را قطع می‌کرد.

بهبود قابلیت اطمینان عامل

سرعت بدون داشتن پاسخ درست بی‌فایده است. این به‌روزرسانی مشکلات «بازیابی» (Recall) را برطرف کرد؛ جایی که ابزار قبلاً برای کلاس‌هایی که در واقع وابسته‌های زیادی داشتند، تعداد صفر را گزارش می‌کرد. در ماه اوت، impact_analysis گزارش داد که AxiosError در کتابخانه axios صفر وابستگی دارد، در حالی که در واقع ۲۳ وابستگی داشت. این اتفاق به این دلیل می‌افتاد که واردات‌های مسیر-فایل مانند ./core/AxiosError.js هرگز حل نمی‌شدند و فقط مسیرهای سبک Rust (مانند ::) کار می‌کردند.

با اصلاح حل واردات (Import Resolution) و شمارش Foo.staticMethod() و x instanceof Foo به عنوان استفاده، نرخ بازیابی وابسته‌ها در axios از ۰.۳۷ به ۰.۶۶ با دقت ۰.۸۵ افزایش یافت. این رویکرد دقیق در تحلیل ساختاری، مشابه روش‌هایی است که در بازسازی سیستم‌های میراثی با استفاده از عامل‌های هوش مصنوعی برای درک پیچیدگی‌های کدهای قدیمی به کار می‌رود.

اکنون CodeSage گزارش‌های «حد پایین» (Lower Bound) ارائه می‌دهد تا از حذف با اعتمادِ بیش از حد کدها توسط عامل‌ها جلوگیری کند:

  • impact_analysis: یک حد پایین را گزارش می‌کند زیرا فراخوانی‌های پویا و واردات‌های حل‌نشده می‌توانند وابسته‌ها را پنهان کنند.
  • assess_risk: برای فایل‌هایی که تاریخچه git ایندکس شده ندارند، به جای عدد پایین، مقدار "unscored" را برمی‌گرداند.
  • find_references: وقتی نام نمادها مبهم است، تعداد را به عنوان یک "floor" (کف) علامت‌گذاری می‌کند.
  • search: نتایج خالی اکنون شامل تعداد فایل‌های ایندکس شده به تفکیک زبان هستند تا تفاوت بین «پیدا نشد» و «هرگز ایندکس نشد» مشخص شود.

بنچ‌مارک و اعتبارسنجی

دقت به طور سخت‌گیرانه‌ای اندازه‌گیری می‌شود. در ماه اوت، یک عدد بازیابی منتشر شده (recall@10 0.932 و NDCG@10 0.788 روی ۶۰۲ پرس‌وجو) پس از آنکه توسعه‌دهنده متوجه شد سیستم به جای ریشه‌ها، کل مخازن را ایندکس کرده و پرس‌وجوهای کرش کرده را ۰.۰۰۰ امتیاز داده است، پس گرفته شد.

جدول جایگزین در README اکنون ۶۶۳ پرس‌وجو را در ۳۳ مخزن و ۹ زبان اجرا می‌کند. این جدول NDCG@10 را به تفکیک زبان از ۰.۷۴۵۵ (برای C) تا ۰.۹۴۳۴ (برای جاوااسکریپت) گزارش می‌کند که روی یک بیلد اصلاح‌شده ۰.۲۷.۰ اندازه‌گیری شده است.

یکپارچه‌سازی و محدودیت‌ها

برای تازه نگه داشتن ایندکس، CodeSage از git hooks استفاده می‌کند تا در هر کامیت، checkout و merge، دوباره ایندکس‌گذاری کند. نسخه ۰.۲۳.۰ مسیر «بدون تغییر» را بهینه کرد؛ به این صورت که اگر فایلی تغییر نکرده باشد، از بارگذاری مدل ONNX و محیط CUDA صرف‌نظر می‌کند. این کار مصرف حافظه پیک را از ۱.۱۶ گیگابایت به ۱۵۰ مگابایت و زمان اجرا را از ۲.۷-۴.۵ ثانیه به ۰.۰۸ ثانیه کاهش داد.

با وجود این دستاوردها، ابزار محدودیت‌های واضحی دارد:

  • پشتیبانی از زبان: در حال حاضر ۹ زبان را تجزیه می‌کند. در بنچ‌مارک‌های عمومی، ۴۷٪ پرس‌وجوها در زبان‌های پشتیبانی‌نشده (Ruby، Kotlin، Swift، Scala) هستند و بازیابی صفر دارند.
  • پذیرش توسط عامل: در تست‌ها با Claude Code، عامل‌ها در طول ۳۰ روز تنها ۱.۱٪ از اوقات برای پرس‌وجوهای شناسه‌ کد، CodeSage را انتخاب کردند. برای حل این مشکل، پلاگین codesage-tools اکنون یک اعلان کوتاه قبل از عملیات Edit یا Write نمایش می‌دهد. این چالش در پذیرش ابزارها، بخشی از بحث گسترده‌تر تله‌ی کارهای تکراری در عصر سرعت بالای کدنویسی با AI است که در آن سرعت تولید کد لزوماً به معنای بهره‌وری در طراحی نیست.
  • سخت‌افزار: سرعت‌های Fused fp16 منحصر به CUDA هستند؛ کاربران CPU و CoreML از گراف pooled fp32 استفاده می‌کنند.
  • استقرار: هیچ باینری پیش‌ساخته یا پشتیبانی رسمی از ویندوز وجود ندارد؛ کاربران باید از طریق Cargo آن را بیلد کنند.
  • دامنه: ابزار فقط خواندنی است؛ کدها را ویرایش نمی‌کند و نمی‌تواند بین چندین مخزن پرس‌وجو کند.

خلاصه عملکرد

اثر ترکیبی گراف fused fp16، سقف ۱۰۲۴ توکنی، حذف تکه‌های داده زائد، دسته‌بندی بهینه و اصلاح حذف SQLite در زمان‌های ایندکس کامل مشهود است:

  • php-src: از ۱۷۸۲ ثانیه $
    ightarrow$ ۳۷۳ ثانیه
  • بک‌اند موبایل خصوصی: از ۴۶۹ ثانیه $
    ightarrow$ ۸۰ ثانیه
  • اپلیکیشن فرانت‌اند خصوصی: از ۲۹۵ ثانیه $
    ightarrow$ ۶۰ ثانیه

کیفیت بازیابی ثابت ماند، به طوری که recall@10 در سه مجموعه داده خصوصی بدون تغییر باقی ماند و در یک مجموعه داده جلسه php-src از ۰.۷۶۵ به ۰.۷۹۰ افزایش یافت.

برای کسانی که از Claude Code استفاده می‌کنند، ابزار whetstone مکمل CodeSage است: در حالی که CodeSage به عامل می‌گوید کد چیست، whetstone نحوه بررسی، بازبینی و ارسال (ship) را پوشش می‌دهد. اولین ایندکس، مدل‌هایی با مجموع حدود ۳۷۰ مگابایت روی CUDA یا ۷۳۶ مگابایت برای گراف‌های fp32 روی CPU/CoreML دانلود می‌کند.

این تلاش بهینه‌سازی ثابت می‌کند که گلوگاه در ابزارهای توسعه مبتنی بر هوش مصنوعی، اغلب در «لوله‌کشی‌ها» — یعنی کوئری‌های دیتابیس و جابه‌جایی تانسورها — است، نه در هوش خام مدل.

گام بعدی شما

  • اگر از Claude Code استفاده می‌کنید، پلاگین codesage-tools را نصب کنید تا عامل شما به‌جای حدس زدن، از گراف ساختاری کد استفاده کند.
  • برای کاهش مصرف VRAM در سیستم‌های ضعیف، از نسخه CPU با گراف pooled fp32 استفاده کنید.
  • مخازن کد خود را با git hooks متصل کنید تا ایندکس شما هم‌زمان با هر کامیت به‌روز شود.

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

چرا این موضوع مهم است؟

این دستاورد با تکیه بر تخصص در مهندسی سیستم‌های استنتاج، ثابت می‌کند که سرعت عامل‌های کدنویسی را می‌توان بدون آموزش مجدد مدل‌ها، چندین برابر کرد. این موضوع باعث می‌شود توسعه‌دهندگان در پروژه‌های عظیم، بدون تأخیرهای طولانی با AI تعامل داشته باشند.

تأثیر برای ایران

به‌دلیل نیاز به کامپایل از طریق Cargo و نبود باینری آماده، استقرار این ابزار برای توسعه‌دهندگان ایرانی نیازمند محیط Rust است. با این حال، به دلیل ماهیت Open Weights مدل‌ها، محدودیت API در استفاده از آن وجود ندارد.

·نگاه ما
تحریریه دات‌هوش

این به‌روزرسانی نشان می‌دهد که در ابزارهای Agentic، بهینه‌سازی لایه‌ی داده (Data Plumbing) تأثیری به‌مراتب بیشتر از ارتقای مدل دارد. جابه‌جایی تانسورها بین GPU و Host و ناکارآمدی‌های SQLite، موانعی بودند که حتی قدرتمندترین مدل‌ها را کند می‌کردند. این رویکرد، الگوی جدیدی برای توسعه‌دهندگان ابزارهای AI است: ابتدا لوله‌کشی را بهینه کنید، سپس به دنبال مدل بزرگ‌تر بروید.

منابع

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

گفتگو

پنج‌شنبه‌های هوش‌محور

بسته‌ی هفتگی دات‌هوش

۵ خبر، ۲ ابزار، ۱ پرامپت در هر شماره. به‌زودی راه‌اندازی می‌شود — هر پنج‌شنبه صبح.

خبر کلیدی
ابزار کاربردی
پرامپت حرفه‌ای
تحلیل پژوهش
به‌زودی
زاویه‌ی ایرانی
به‌زودی
تمرین این هفته
به‌زودی

راهنماهای دات‌هوش

راهنماهای کاربردیِ دات‌هوش برای کار با هوش مصنوعی — از همین‌جا شروع کنید:

دات‌هوش

راهنمای فارسی هوش مصنوعی — با نگاه به ایران

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