בניית גרף ידע אחד על פני 46 מאגרים (Repositories)

אני רייאן, CTO ב-airCloset.

ביליתי שלושה חודשים בבניית code-graph. זהו גרף ידע יחיד המאחד 46 מאגרים (repositories) על פני שירותים מרובים.

אנשים רבים חושבים שאפשר פשוט להגיש את כל הקוד שלהם ל-AI ולשאול שאלות. זה נכשל משתי סיבות:

  • חלונות הקשר (Context windows): אי אפשר להכניס שנים של קוד מ-46 מאגרים לתוך פרומפט אחד.
  • הזיות (Hallucination): AI עושה טעויות כשהוא מנסה להסיק קשרים. הוא מפספס חיבורים.

כדי לפתור זאת, השתמשתי בניתוח סטטי (static analysis) כדי לבנות מקור אמת (source of truth).

האתגר: חציית גבולות

בסיס קוד גדול הוא מבולגן. API אחד עשוי להיות נקרא על ידי חמישה מאגרים שונים. טבלת מסד נתונים אחת עשויה לשמש שלושה שירותים שונים.

אם מסתכלים רק על מאגר אחד, מפספסים את התמונה המלאה. זה מסוכן. אם משנים קוד ולא רואים את רדיוס הפגיעה (blast radius) האמיתי, שוברים את המערכת.

הגישה שלי משתמשת ב-tree-sitter כדי לנתח (parse) קוד לעצי תחביר (syntax trees). אך tree-sitter לבדו אינו יכול לראות מעבר לגבולות המאגרים.

בניתי צמתי גבולות (boundary nodes) כדי לפתור זאת.

איך זה עובד:

  • אנחנו מחלצים קשרים בתוך מאגר באמצעות tree-sitter.
  • אנחנו משתמשים ב-TypeScript Compiler API כדי לפתור (resolve) טיפוסים ומשתנים.
  • אנחנו משתמשים ב-Gemini כדי לטפל במקרים דינמיים שכלים אחרים מפספסים.

במקום לבקש מה-AI לנחש, אנחנו נותנים לו עובדות. אנחנו אומרים לו: "ה-API הזה נקרא גם מתוך Repo X". זה מונע הזיות.

החלק הקשה: גן החיות של ה-Frameworks

המאבק האמיתי היה בחילוץ הגבולות הללו. כל framework כותב גבולות בצורה שונה.

צוות אחד משתמש ב-NestJS decorators. אחר משתמש ב-Express routes. עוד אחד משתמש ב-jQuery גולמי. כל אחד יוצר מבנה שונה בקוד.

כדי לגרום לזה לעבוד, היינו צריכים לבנות parsers מותאמים אישית עבור:

  • NestJS ו-TypeORM
  • Express ו-Fastify
  • AngularJS ו-Redux
  • סכימות path-alias שונות

היינו צריכים לשאוף ל-99% דיוק. אם שיעור החיבורים שלנו הוא רק 90%, ה-AI מפספס 10% מהקשרים. במערכת ייצור (production), ה-10% האלה הם המקום שבו הבאגים מתחבאים.

כעת אנחנו מריצים בדיקה יומית. אם שיעור החיבורים שלנו יורד ביותר מ-5%, אנחנו מקבלים התראה. זה תופס מקרים שבהם תבניות קוד חדשות שוברות את ה-parsers שלנו.

מגבלות נוכחיות

הגרף אינו מושלם.

  • החיפוש הוא קשה. לעיתים קרובות צריך לדעת שם של פונקציה כדי להתחיל את החיפוש.
  • התפוצצות צמתים (Node explosion). מעקב אחר נתיב עלול למשוך פנימה אלפי פונקציות עזר קטנות וחסרות תועלת.
  • תחזוקה. בכל פעם ש-framework חדש נכנס ל-stack שלנו, עלינו לכתוב parser חדש.

זהו חלק 1. בחלק 2, אדון בשכבת ה-service-product-graph (SPG) שבניתי כדי לתקן את הפערים הללו.

Source: https://dev.to/ryantsuji/building-one-knowledge-graph-across-46-repositories-with-static-analysis-part-1-egm

Optional learning community: https://t.me/GyaanSetuAi