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

تکه‌بندی مبتنی بر ساختار؛ راهکار رفع خطاهای بازیابی کد در RAG

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

تغییر پارادایم از تکه‌بندی بر اساس تعداد توکن به تکه‌بندی بر اساس واحدهای منطقی کد (AST-based chunking) برای حذف پاسخ‌های تکه‌تکه در RAG.

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

تا ۳۰ ژوئن ۲۰۲۶، شواهد عملی از پیاده‌سازی‌های واقعی نشان می‌دهد که تقسیم کد منبع بر اساس تعداد خطوط، دقیقاً همان ساختاری را نابود می‌کند که به کد معنا می‌بخشد. این رویکرد منجر به نتایجی می‌شود که خروجی‌های تولید بازیابی‌افزا (RAG) — که شبیه دانش‌آموزی است که قبل از جواب دادن، اول کتاب درسی را باز می‌کند و از آن نقل می‌آورد — را عملاً بی‌فایده و ناکارآمد می‌کند. این چالش با مفاهیمی که در راهکارهای RAG برای توقف توهمات با اتصال مدل‌ها به داده‌های خارجی بررسی کردیم، همسو است؛ جایی که دسترسی به داده درست، کلید دقت مدل است.

بسیاری از توسعه‌دهندگان از آموزش‌های استاندارد RAG پیروی می‌کنند که پیشنهاد می‌دهد اسناد به پنجره‌های با اندازه ثابت، مثلاً ۵۰۰ توکن (تکه‌های کوچکی از متن شبیه برش‌های کیک)، تقسیم شوند. در حالی که این روش برای متون نثر و مقالات معمولی جواب می‌دهد، اما برای کدنویسی مخرب است. به عنوان مثال، یک پنجره ۵۰۰ توکنی مرزهای توابع را رعایت نمی‌کند. در نتیجه، شما با قطعاتی مواجه می‌شوید که شامل «یک‌سوم پایانی تابع transfer() و نیمی از ابتدای تابع approve()» است. در این حالت، هیچ‌یک از دو تابع کامل نیستند.

در چنین شرایطی، بردار معنایی (Embedding) — که مثل کارت معرفی عددی برای هر واژه است و همسایگی کلمات را مشخص می‌کند — در واقع یک قطعه تکه شده را نمایندگی می‌کند که به تنهایی هیچ معنایی ندارد. وقتی این تکه بازیابی می‌شود، شما نیمی از یک تابع را بدون امضا (Signature) و بدون زمینه (Context) به مدل می‌دهید. این موضوع باعث می‌شود سیستم با اطمینان کامل به پرس‌وجوهایی پاسخ دهد که تنها بخش میانی توابع آن‌ها را دیده است.

همان‌طور که در تحلیل‌های قبلی ما درباره‌ی امنیت مدل‌های بازمتن اشاره کردیم، کیفیت ورودی تعیین‌کننده است. به نقل از راهنمای فنی dev.to، راهکار جایگزین، تکه‌بندی بر اساس ساختار (Structure) به‌جای اندازه (Size) است. کد دارای واحدهای طبیعی مانند توابع، متدها، کلاس‌ها و قراردادها (Contracts) است؛ این‌ها دقیقاً همان واحدهایی هستند که یک برنامه‌نویس برای استدلال درباره منطق برنامه از آن‌ها استفاده می‌کند. بنابراین، هر یک تابع باید دقیقاً برابر با یک تکه (Chunk) باشد. این امر تضمین می‌کند که هر تکه، یک موجودیت کامل و معنادار باشد که مدل بتواند واقعاً درباره آن استدلال کند. این رویکرد تکه‌بندی ساختاری، گامی در راستای تکه‌بندی عامل‌محور برای حذف توهمات است که در آن مدل به جای برش‌های تصادفی، به صورت پویا و هوشمندانه زمینه را مدیریت می‌کند.

مکانیزم‌های استخراج

برای اجرای این روش، نویسنده پیشنهاد می‌کند به‌جای استفاده از Regex (عبارات منظم)، از یک پارسر برای پیمایش درخت نحو (Syntax Tree) استفاده شود. طبق مستندات، برای TypeScript ابزارهایی مثل compiler API یا ts-morph توصیه می‌شوند، در حالی که زبان Solidity نیازمند یک پارسر AST مناسب است تا برای هر گره در سطح تابع (Function-level node)، یک تکه ایجاد کند.

استخراجگر با استفاده از ابزاری مانند ts-morph منطق خاص زیر را دنبال می‌کند:

  • ابتدا یک Project را مقداردهی اولیه کرده و فایل منبع را از طریق مسیر (Path) آن اضافه می‌کند.
  • سپس توابع را با استفاده از متد source.getFunctions() پیمایش می‌کند.
  • نام تابع را استخراج می‌کند (و در صورت نبود نام، مقدار پیش‌فرض "anonymous" را اختصاص می‌دهد).
  • امضای کامل تابع (Signature) را از طریق fn.getSignature().getDeclaration()?.getText() ثبت می‌کند.
  • در نهایت، کل بدنه تابع و شماره خط شروع را ذخیره می‌کند.

عمق پیاده‌سازی فنی

یک تکه کد معنادار باید متادیتای خاصی داشته باشد تا کاربردی بماند. رابط CodeChunk پیشنهادی شامل موارد زیر است:

  • name: نام تابع یا متد
  • signature: امضای کامل برای درک زمینه
  • body: بدنه کامل تابع
  • filePath: مسیری که کد در آن قرار دارد
  • startLine: شماره خط دقیق شروع تابع

علاوه بر این، ایده‌آل است که تکه کد شامل کامنت‌های مستنداتی (Doc comments) باشد که دقیقاً بالای تعریف تابع قرار دارند تا زمینه بیشتری به مدل ارائه دهند.

برای اجرای محلی و حفظ حریم خصوصی، نویسنده از Ollama برای سرویس‌دهی به مدل جاسازی nomic-embed-text استفاده کرده است. این کار تضمین می‌کند که کد منبع خصوصی هرگز از ماشین محلی خارج نشود. با جاسازی ترکیبی از نام، امضا و بدنه (به فرمت ${chunk.name}\n${chunk.signature}\n${chunk.body})، سیستم تضمین می‌کند که پرس‌وجوهای نام‌محور، مانند «تابع withdraw چه می‌کند»، بردار صحیح را بازیابی کنند، زیرا نام تابع صراحتاً بخشی از متن جاسازی‌شده است.

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

این تغییر، فرض بنیادین در بازیابی کد را عوض می‌کند: کیفیت RAG اساساً یک مسئله تکه‌بندی (Chunking) است. وقتی مدل به‌جای پنجره‌های متنی تصادفی، واحدهای کامل معنایی را دریافت می‌کند، بازیابی «صادقانه» می‌شود. برای مثال، پرسشی مانند «این قرارداد چگونه reentrancy را در برداشت‌ها مدیریت می‌کند؟» اکنون تابع کامل withdraw و اصلاح‌گرهای (Modifier) مرتبط با آن را بازیابی می‌کند. این امر به مدل اجازه می‌دهد تا درباره ترتیب «بررسی-اثر-تعامل» (Checks-Effects-Interactions) استدلال کند، زیرا کل منطق در دسترس است.

برای متخصصان، این یعنی گلوگاه در کدنویسی با کمک هوش مصنوعی، به‌ندرت هوش مدل است، بلکه کیفیت زمینه (Context) ارائه‌شده است. انتقال از برش خطی به استخراج مبتنی بر AST، پاسخ‌های تکه‌تکه و نیمه‌اشتباه را به منطق دقیق و استدلالی تبدیل می‌کند. مشکل هرگز مدل یا بردارها نبودند؛ مشکل قیچی بود.

گام بعدی شما

  • خط لوله‌های RAG خود را بررسی کنید تا مطمئن شوید از تقسیم‌کننده‌های ساده (Character-splitters) روی کدهای ساختاریافته استفاده نمی‌کنید.
  • برای هر زبان برنامه‌نویسی در پروژه خود، یک پارسر اختصاصی (مانند ts-morph برای TS) جایگزین روش‌های متنی کنید تا مرزهای منطقی کتابخانه‌های اختصاصی شما حفظ شود.
  • متادیتای امضا و مسیر فایل را به بردار معنایی اضافه کنید تا دقت جست‌وجوهای نام‌محور افزایش یابد.

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

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

این متدولوژی با تکیه بر تخصص در تحلیل درخت نحو (AST)، نرخ توهم مدل‌ها در تحلیل کد را به‌شدت کاهش می‌دهد. اعتبار سیستم‌های بازیابی کد اکنون به جای اندازه مدل، به دقت پارسرهای ساختاری وابسته است.

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

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

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

بسیاری از تیم‌های مهندسی به‌اشتباه روی تعویض مدل یا افزایش اندازه پنجره متنی تمرکز می‌کنند، در حالی که مشکل در لایه پیش‌پردازش داده‌هاست. این رویکرد ثابت می‌کند که در حوزه کد، «ساختار» بر «حجم» اولویت دارد و RAGهای موفق، آن‌هایی هستند که معماری زبان برنامه‌نویسی را در لایه تکه‌بندی شبیه‌سازی می‌کنند.

منابع

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

گفتگو

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

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

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

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

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

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

دات‌هوش

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

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