تصور کنید یک عامل هوش مصنوعی (AI Agent) وارد یک مخزن کد عظیم و ناآشنا میشود؛ او دقیقاً مانند یک نیروی استخدامشده جدید در اولین روز کاریاش رفتار میکند: با استفاده از دستوراتی مثل grep برای جستجوی نامها و لیست کردن دایرکتوریها، سعی میکند بهکندی یک مدل ذهنی از پروژه بسازد. مشکل اساسی اینجاست که این مدل ذهنی به محض بسته شدن پنجره زمینه (Context Window) — که شبیه میز کاری است که جا برای چند ورق دارد و نه برای کل کتابخانه — کاملاً پاک میشود. این اتفاق باعث میشود هر نشست جدید مجبور شود دوباره هزینه توکنها و تأخیرها را بپردازد و همان اشتباهات قبلی را تکرار کند. این چالش مدیریت مصرف منابع، یادآور تلاشهای ابزارهای متنی چون Satori برای سازماندهی کدها با هدف جلوگیری از اتلاف توکنهاست.
برای حل این بحران، Olund یک نقشهی کدِ هرپروژهای (per-project code map) ساخته است که لایهای قابل پرسوجو برای ناوبری فراهم میکند. طبق مستندات فنی منتشرشده در olund.dev، این ابزار تضمین میکند عامل پیش از خواندن حتی یک فایل، «حس مکان» (sense of place) داشته باشد و بداند در کجای معماری قرار گرفته است.
این راهکار در زمانی ارائه میشود که صنعت با گلوگاه «پنجره زمینه» دستوپنجه نرم میکند. اگرچه تولید بازیابیافزا (RAG) — که مثل دانشآموزی است که قبل از جواب دادن، اول کتاب درسی را باز میکند و از آن نقل میآورد — برای یافتن تکههای کد خاص مفید است، اما عاملها اغلب درک سطح بالایی از معماری و نحوه ارتباط اجزا با یکدیگر ندارند. همانطور که در پوشش پیشین ما از کارهای Olund روی تثبیت حافظه شبانه (nightly memory consolidation) دیدیم، این نقشهی کد در واقع مکمل مکانی برای آن سیستم حافظه زمانی است.
تلفیق سه سیگنال حیاتی
نوآوری اصلی در اینجا ادغام سه جریان داده متمایز در یک گراف واحد است. نکته جالب این نیست که «هوش کد استاتیک» وجود دارد (چون این یک حوزه بالغ است)، بلکه ترکیب خاص این سه سیگنال است که تفاوت ایجاد میکند:
- سیگنال ساختاری (Structural Signal): این محور سنتی است. سیستم از tree-sitter برای تجزیه نمادها، فراخوانیها و Importها در هر زبانی که در مخزن ترکیب شده باشد، استفاده میکند. این لایه بهطور عمدی نسخهای سطحی از تحلیل استاتیک است. با ثبت اینکه هر لبه (edge) از کجا آمده است در جدول لبهها، سیستم اجازه میدهد تا تحلیلگران عمیقترِ هر زبان، بعداً لبههای resolved را بدون نیاز به بازطراحی کل سیستم اضافه کنند. این تمرکز بر تحلیل ساختاری، مشابه رویکردی است که ابزار code-review-graph برای کاهش ۸۲ برابری توکنهای بازبینی کد به کار گرفت.
- سیگنال زمانی (Temporal Signal): این داده مستقیماً از خروجی سادهی git log استخراج میشود، بدون اینکه به هیچ کتابخانه خارجی وابسته باشد. سیستم با تحلیل نرخ تغییرات (churn)، مالکیت کد و «تغییرات همزمان» (co-change) — یعنی اینکه کدام فایلها بهطور تاریخی در یک کامیت با هم تغییر کردهاند — از تاریخچه موجود مخزن برای شناسایی الگوهای تکاملی پروژه بهره میبرد.
- سیگنال رفتاری (Behavioral Signal): این بخش، نقطه تمایز کلیدی Olund است. سیستم هر فراخوانی ابزاری توسط عامل — اعم از هر عملیات خواندن، ویرایش یا نوشتن — را ثبت کرده و با برچسب پروژه و نشست (session) علامتگذاری میکند. این لاگها یک «ماتریس لمس همزمان» (co-touch matrix) میسازد که نشان میدهد عاملها در جلسات واقعی روی کدام فایلها با هم کار کردهاند. در این تجمیع دادهها، ویرایش وزن بسیار بیشتری نسبت به خواندن دارد؛ زیرا تغییر همزمان دو فایل، دلیل قویتری برای وابستگی و جفت شدن (coupling) آنهاست تا اینکه صرفاً به هر دو نگاه شده باشد.
سیگنالهای رفتاری وابستگیهایی را فاش میکنند که ابزارهای استاتیک هرگز نمیبینند، چون ابزارهای استاتیک هرگز «کار واقعی» را مشاهده نمیکنند. برای مثال، یک گراف فراخوانی ممکن است نشان دهد فایل A به فایل B وابسته است؛ اما اگر نیمی از کد پروژه به فایل B وابسته باشد، این داده عملاً بیفایده است. در مقابل، سیگنال رفتاری نشان میدهد که در ۳۰ نشست اخیر، هر بار که فایل A تغییر کرده، فایلهای B و C هم تغییر کردهاند. اینها همسایگان واقعی (de facto neighbors) فایل A هستند؛ یعنی مجموعهای از فایلها که هر زمان فایل A لمس شود، باید باز باشند.
قابلیت co-change در گیت این موضوع را تخمین میزند، اما این کار فقط در سطح دانهبندی کامیتها و فقط برای تغییرات انجام میشود. اما در نشستی که یک عامل چهار فایل را میخواند تا بتواند پنجمین فایل را بهطور ایمن ویرایش کند، هیچ ردی در گیت باقی نمیماند. ردپای خودِ عامل، تنها جایی است که این سیگنال در آن وجود دارد.
اقتصاد مصرف و بهرهوری
برای حفظ کارایی، این نقشه از دو مسیر مجزا مصرف میشود. این تفکیک عمدی است زیرا این دو مسیر اقتصادهای متفاوتی دارند (هزینه توکن و پردازش متفاوتی دارند):
مسیر محیطی (Ambient Path - ارزان)
یک خلاصه رندرشده و کوچک در ابتدای هر جلسه به زمینه (context) تزریق میشود. این بخش برای جلوگیری از پیمایشهای گرانقیمت در گراف، یک نمای کلی از زیرسیستمها، چند فایل کلیدی برای هر زیرسیستم و یک توضیح تکخطی برای هدف هر کدام ارائه میدهد.
این موارد بر اساس «تشخیص جامعه» (community detection) روی گراف تلفیقشده مرتب شدهاند. در یک پروژه اصلی، این فرآیند توانست ۹۱۳ فایل را در ۳۳ جامعه یا خوشه دستهبندی کند. برای بهینهسازی بیشتر، بخشهای این خلاصه بر اساس میزان مرتبط بودن آنها با تسکِ شاخه (branch) جاری، با استفاده از یک فایل اشارهگر (pointer file) بازطراحی میشوند. به عنوان مثال، نشستی که شاخهای مربوط به «کنترل کیفیت آپلود» (upload quality-control) را باز میکند، ابتدا زیرسیستم QC را میبیند، نه یک لیست الفبایی از فایلها. چنین بهینهسازیهایی در لایهی دسترسی به داده، یادآور معماری TokenFold است که توانست هزینههای عاملهای کدنویسی را تا ۳۰٪ کاهش دهد.
مسیر در-درخواست (On-Demand Path - عمیق)
عاملها در میانه جلسه از ابزارهای پرسوجوی خاصی استفاده میکنند تا عمق اطلاعاتی را به دست آورند که نمیتوان آن را بدون منفجر کردن پنجره زمینه در قالب متن رندر کرد. این ابزارها عبارتند از:
- همسایگی (Neighborhood): همسایگان ساختاری و رفتاری یک فایل خاص را برمیگرداند.
- نقاط داغ (Hotspots): مناطقی را که بر اساس وزن تغییرات (churn-weighted)، ریسک بالایی دارند شناسایی میکند.
- چرایی (Why): این ابزار، نقشه را به استاندارد مستندات Olund متصل میکند. وقتی عاملی میپرسد چرا یک فایل وجود دارد، پاسخ شامل سوابق تصمیمات معماری (ADRs) است که به آن فایل اشاره کردهاند، در کنار لیست فراخوانندههای آن. این کار باعث میشود مسیر تصمیمگیری و گراف فراخوانی در یک ایندکس واحد قرار گیرند.
تضمین بهروز بودن و تازگی
لایه ناوبری که با کد فاصله بگیرد (drift)، بدتر از نبود آن است؛ زیرا عاملی که توسط یک گراف فراخوانی قدیمی هدایت شود، با اطمینانی غلط مسیر را اشتباه میرود. Olund از یک مدل دوگانه برای حفظ سازگاری استفاده میکند:
اول، سیستم از «رویدادهای چرخه عمر» (lifecycle events) استفاده میکند. وقتی عاملی یک فایل را ویرایش میکند، یک قلاب (hook) پس از ویرایش، فقط همان فایل را با استفاده از tree-sitter مجدداً تجزیه میکند. این اتفاق در کسری از ثانیه رخ میدهد و ایندکس را در مورد کدی که عامل همین لحظه تغییر داده، صادق نگه میدارد.
دوم، چون قلابها «بهترین تلاش» (best-effort) هستند — یعنی ممکن است ویرایشهای دستی خارج از جلسه، حذفها یا rebases را از دست بدهند — یک جاروب کامل و دورهای (periodic full re-index sweep) اجرا میشود. قلابها مانع از آن میشوند که نقشه در مورد کار فعلی جلسه اشتباه کند، در حالی که جاروب کلی مانع از تجمع دائمی فاصله (drift) در سیستم میشود.
قابل ذکر است که خودِ خلاصه (digest) با سرعت کمتری (slow cadence) بازنویسی میشود و نه بعد از هر ویرایش. زیرا تعریف زیرسیستمها و آنچه بیشترین اهمیت را دارد، معمولاً هفته به هفته پایدار است و گام گرانقیمتِ استفاده از یک مدل زبانی بزرگ (LLM) برای نامگذاری جوامع، با هر ضربه کلید انجام نمیشود.
رد شدن برخی رویکردها در معماری
طراحی این سیستم با حذف عمدی سه مورد شکل گرفت:
۱. عدم استفاده از سرورهای زبان (Language Servers) یا استنتاج عمیق نوع: راهاندازی چندین LSP برای هر پروژه از نظر عملیاتی بسیار سنگین است. از آنجایی که سیگنال رفتاری مزیت رقابتی اصلی است، ساختار نحوی صرفاً به عنوان داربست (scaffolding) در نظر گرفته شده است. هرگونه مسیر احتمالی برای عمیقتر شدن در سطح زبان در نسخه دوم (v2) ثبت شده و برچسب منشأ خورده است، اما فعلاً ساخته نشده است.
۲. عدم وجود گراف سراسری بین-پروژهای: نقشه هر پروژه مستقل و خودکفا است. طراح سیستم اشاره کرد که پرسوجوهای بین-پروژهای (مثلاً «کدام مخازن از این الگو استفاده میکنند») در حال حاضر هیچ مصرفکنندهای ندارند و تعمیم متغیرگونه، فشار زیادی به امضای تمام ابزارها وارد میکند.
۳. عدم ایجاد لاگ رفتاری مجزا: ماتریس لمس همزمان صرفاً یک نمای SQL (view rollup) روی لاگ رویدادهایی است که سیستم حافظه از قبل نگه میدارد. ایجاد یک ذخیرهساز اختصاصی باعث تکرار دادهها و پیچیده شدن الزامات حذف دادهها (redaction) میشد.
گامهای کلیدی برای استقرار عاملها
این رویکرد این فرض را تغییر میدهد که هوش کد باید حتماً از تحلیل عمیق زبان به دست بیاید. با تبدیل تاریخهی کاری یک عامل به یک سیگنال درجهیک، توسعهدهندگان میتوانند دادههای وابستگی (coupling) را استخراج کنند که هیچ تحلیلگر استاتیکی هرگز نمیتواند ببیند.
اگر در حال استقرار عاملها در مخازن کد حجیم هستید، این اصول را در نظر بگیرید:
- ثبت فراخوانی ابزارها: «ردپای» عامل را به عنوان داده اصلی برای ناوبری در نظر بگیرید.
- تفکیک محیطی از در-درخواست: از یک خلاصه کوچک که همیشه تزریق میشود برای جهتدهی اولیه، و از ابزارها برای دسترسی به عمق استفاده کنید.
- مرتبسازی بر اساس تسک: از تسک شناختهشدهی یک شاخه برای اولویتبندی زمینهای (context) که به عامل ارائه میشود، استفاده کنید.
- تازهسازی ترکیبی: قلابهای سریع «بهترین تلاش» را با جاروبهای کند اما تضمینشده ترکیب کنید.
- ناوبری دور زدن ابزارهای بالغ: به جای رقابت با دههها مهندسی استنتاج نوع (Type Inference)، از تجزیه سطحی (مانند tree-sitter) در ترکیب با یک سیگنال منحصربهفرد استفاده کنید.
این سیستم یک پشته (stack) بزرگتر را تکمیل میکند: سیستم حافظه ردپاها را ثبت میکند، لایه حضور (presence layer) جلسات موازی را مدیریت میکند، استاندارد مستندات «چرایی» (why) را حفظ میکند و نقشهی کد همه اینها را برای ایجاد «حس مکان» در لحظه ورود عامل، تلفیق میکند.
اما داستان سختافزاری این تحول حتی شگفتانگیزتر است — به تحلیل ما دربارهی تراشههای Blackwell مراجعه کنید.




گفتگو