وقت القراءة : 12 minutes

قاعدة الكود الخاصة بك تنمو. الاعتمادات بين الوحدات تزداد. توثيق الهندسة يصبح قديمًا قبل حتى أن يُكتب. وإذا كان بإمكان بناء Gradle الخاص بك تلقائيًا إنشاء مخططات محدثة من بنية الكود الفعلية؟ هذا بالضبط ما يفعله خط أنابيب Graphify + Gradle Plugin PlantUML :`graphify . --no-viz`يستخرج Knowledge Graph،`./gradlew generateKnowledgeGraphDiagram`يقوم بتحويله إلى مخططات PlantUML. صفر LLM، صفر دليل، 100% حتمي.

عُصبة

[]

المشكلة: المخططات دائمًا متأخرة عن الكود

كل مشروع يتجاوز بضعة آلاف من الأسطر يعرف هذا المتلازمة :

  1. نرسم مخططًا معماريًا في بداية المشروع

  2. يتطور الكود، وتتغير الاعتمادات

  3. المخطط يصبح كذبة زخرفية

  4. لا أحد يحدّثه لأنه متعب

  5. المستجدون يعتمدون عليه ويخطئون

probleme diagrammes obsoletes

السؤال ليس هل يجب أن تكون هناك مخططات؟ — الجميع يعلم أن نعم. السؤال هو :من يحافظ على تحديثهم؟

الجواب: لا أحد. ما لم يكن تلقائيًا

الحل: مسار محدد Knowledge Graph → PlantUML

المبدأ بسيط: بدلاً من رسم المخططات يدويًا، نحنيولد من الهيكل الحقيقي للرمز.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

actor Développeur
component "Graphify
^^^^^
 Syntax Error? (Assumed diagram type: sequence)

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

actor Développeur
component "Graphify
(pip install graphifyy)" as Graphify
collections "graphify-out/graph.json\n(رسم المعرفة)" as KGJSON
component "PlantUML Gradle Plugin\n(generateKnowledgeGraphDiagram)" as Plugin
component "KnowledgeGraphParser" as Parser
component "معرض الرسم المعرفي" as Renderer
component "PlantumlService
(التحقق + العرض PNG)" as PS
collections "diagrams/knowledge-graph/\n(.puml + .png)" as Output

Développeur --> Graphify : graphify . --no-viz
Graphify --> KGJSON : extrait la structure\ndu code source
Développeur --> Plugin : ./gradlew generateKnowledgeGraphDiagram
Plugin --> Parser : parse(graph.json)
Parser --> Plugin : KnowledgeGraph\n(noeuds + arêtes + communautés)
Plugin --> Renderer : render(graph, filters)
Renderer --> Plugin : code PlantUML\ndéterministe
Plugin --> PS : validateSyntax + generateImage
PS --> Output : .puml + .png

note bottom of Plugin
  Pipeline DÉTERMINISTE
  Aucun appel LLM
  Résultat reproductible
end note

@enduml

أمران. هذا كل شيء.

# Étape 1 : extraire le Knowledge Graph
graphify . --no-viz

# Étape 2 : générer les diagrammes PlantUML
./gradlew generateKnowledgeGraphDiagram

النتيجة؟ ملفات`.puml` et .png`في`diagrams/knowledge-graph/, مُصدَّر في Git، دائمًا محدث مع الكود.

الخطوة 1: تثبيت Graphify واستخراج Knowledge Graph

التثبيت

Graphify هو أداة بايثون التي تحلل قاعدة الكود الخاصة بك وتنشئ رسمًا معرفيًا منظمًا:

# Méthode recommandée
uv tool install graphifyy && graphify install --platform opencode

# Alternative avec pip
pip install graphifyy && graphify install --platform opencode

ضبط الاستثناءات

إنشاء ملف`.graphifyignore`في جذر المشروع لاستبعاد الملفات التي ليست جزءًا من منطق العمل :

# Secrets — JAMAIS dans le graphe
*-context.yml
*.env

# Fichiers générés
build/
.gradle/

# Tests fonctionnels
src/functionalTest/

استخراج رسم المعرفة

graphify . --no-viz

العلم`--no-viz`يتخطى إنشاء HTML (غير ضروري في خط أنابيب Gradle). النتيجة ملف`graphify-out/graph.json`يحتوي :

  • عقدالصفوف، الدوال، الملفات — مع نوعها ومجتمعها

  • حافات: علاقات بين العقد (EXTRACTED من الكود, INFERRED من قبل LLM)

  • المجتمعات: تجميعات تلقائية للعقد المرتبطة

مثال للهيكل`graph.json`
{
  "nodes": [
    {"id": "0", "label": "LlmService", "file_type": "code", "community": 0},
    {"id": "1", "label": "ApiKeyPool", "file_type": "code", "community": 0},
    {"id": "2", "label": "PlantumlService", "file_type": "code", "community": 1}
  ],
  "links": [
    {"source": "1", "target": "0", "relation": "uses", "confidence": "EXTRACTED", "weight": 0.9},
    {"source": "0", "target": "2", "relation": "calls", "confidence": "INFERRED", "weight": 0.7}
  ]
}

شفرة المصدر (.kt, .java) يتم تحليله محليًا بواسطة tree-sitter,بدون استئناف LLM. فقط ملفات الوثائق (.adoc, .md) تتطلب استدعاء LLM لاستخراج الدلالي. إذن`--update`تنفيذ كود كوتلن فوري تقريبًا.

الخطوة 2 : الإضافة Gradle تُحَوِّل Knowledge Graph إلى PlantUML

هيكل خط الأنابيب

الإضافة`com.cheroliv.plantuml`يتضمن مهمة`generateKnowledgeGraphDiagram`الذي يحوّل`graph.json`في مخططات PlantUML بشكلتماماً حتمي:

architecture pipeline kg

المكونات الداخلية

مكون دور

KnowledgeGraphParser

تحليل`graph.json`— يدعم 3 تنسيقات : graphify أصلي (nodes+links), legacy (communities), flat. يحلّ المعرفات الرقمية إلى تسميات.

KnowledgeGraphRenderer

حوّل حتميًا`KnowledgeGraph`في كود PlantUML. مجموعات حسب النوع، المجتمعات في الحزم، legend التلقائية.

GenerateKnowledgeGraphDiagramTask

مهمة Gradle التي تنظم: parse → render → validate → PNG. قابل للتكوين عبر خصائص Gradle.

kgmodels.kt

نماذج البيانات :`KnowledgeGraph`, KnowledgeGraphNode, KnowledgeGraphEdge, KnowledgeGraphCommunity, EdgeType.

PlantumlService

التحقق من الصياغة + عرض PNG (يُعاد استخدامه من قبل جميع مهام البرنامج المساعد).

قواعد العرض

يُطبق الـrenderer اتفاقيات بصرية حتمية :

نوع الحافة التدوين PlantUML معنى

مستخرج

-→(خط متصل, أسود)

علاقة مستخرجة من شفرة المصدر (اليقين)

مستنتج

..>(خط منقط)

العلاقة المستنتجة من قبل LLM (درجة الثقة)

مبهم

--x(خط أحمر منقط)

علاقة مبهمة (للتحقق)

تُعَرَضُ المجتمعات كحزم PlantUML مع لوحة ألوان تلقائية.

الخطوة 3: الاستخدام اليومي

مخطط كامل

# Générer le diagramme du Knowledge Graph complet
./gradlew generateKnowledgeGraphDiagram

المخرج :`diagrams/knowledge-graph/knowledge-graph-full.puml`+

(Note: spaces preserved as in original).png

فلتر حسب المجتمع

# Une seule communauté
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.community=community_0

# Limiter le nombre de noeuds (lisibilité)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.community=community_0 \
  -Pplantuml.kg.maxNodes=15

فلتر حسب نوع الحافة

# Uniquement les relations certaines (EXTRACTED)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.edgeTypes=EXTRACTED

# Relations certaines + inférées
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.edgeTypes=EXTRACTED,INFERRED

تصفية حسب نوع العقدة والثقة

# Uniquement les classes de code
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.nodeTypes=code

# Seuil de confiance minimum (pour les INFERRED)
./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.minConfidence=0.7

مجلد الإخراج المخصص

./gradlew generateKnowledgeGraphDiagram \
  -Pplantuml.kg.outputDir=docs/architecture

المرجع الكامل للخصائص

ملكية عطل الوصف

plantuml.kg.community

(جميع)

تصفية المجتمعات بالاسم (مطابقة جزء من السلسلة)

plantuml.kg.edgeTypes

(الكل)

أنواع الحواف مفصولة بفواصل :`EXTRACTED`, INFERRED, AMBIGUOUS

plantuml.kg.minConfidence

0.0

الحد الأدنى للثقة للحواف

plantuml.kg.maxNodes

(غير محدود)

الحد الأقصى لعدد العقد للعرض

plantuml.kg.nodeTypes

(الجميع)

أنواع العقد المفصولة بفواصل (مثال`class`, code)

plantuml.kg.outputDir

diagrams/knowledge-graph

مجلد الإخراج للملفات`.puml` et .png

الـ بايبلاين الكامل في سير عمل Gradle

نوع سير العمل

workflow complet

التكامل في دورة التطوير

يتكامل خط الأنابيب بشكل طبيعي في المراحل الرئيسية للتطوير :

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 5) ]

@startuml
skinparam backgroundColor #FEFEFE

state "التطوير" as dev
state "استخراج
^^^^^
 Syntax Error? (Assumed diagram type: state)

@startuml
skinparam backgroundColor #FEFEFE

state "التطوير" as dev
state "استخراج
graphify . --no-viz" as extract
state "إنشاء
./gradlew generateKnowledgeGraphDiagram" as generate
state "Commit
مخططات ذات إصدارات" as commit

[*] --> dev
dev --> extract : Code modifié
extract --> generate : graph.json à jour
generate --> commit : .puml + .png générés
commit --> dev : Diagrammes dans le repo

note right of extract
  Quasi instantané sur du code Kotlin
  (tree-sitter, pas de LLM)
end note

note right of generate
  Déterministe
  Pas de LLM
  Résultat reproductible
end note

@enduml

تحديث تدريجي

عند تغيير الكود، لا يُعاد بناء كل المخطط من الصفر:

# Mise à jour incrémentale (fichiers modifiés uniquement)
graphify . --update

# Puis régénérer les diagrammes
./gradlew generateKnowledgeGraphDiagram

--update`يُستخرج مجددًا فقط الملفات المعدّلة (التي تم اكتشافها باستخدام SHA256 في`graphify-out/cache/). على كود Kotlin، يكون الأمر فوريًا تقريبًا لأن tree-sitter يعمل محليًا دون استدعاء LLM.

الـdogfooding : البرنامج يوثق نفسه

يوجد إضافة PlantUML لتحويل المطالبات إلى مخططات. يمكنها أيضًا تحويل رسم المعرفة الخاص بقاعدته الخاصة إلى مخططات توثيقية. هذا هو dogfooding : الإضافة تستهلك خدمتها الخاصة.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "خط أنابيب عادي
(المستخدم → المخططات)" as normal {
^^^^^
 Syntax Error? (Assumed diagram type: activity)

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "خط أنابيب عادي
(المستخدم → المخططات)" as normal {
    [Fichier .prompt] as prompt
    [LlmService\n+ ApiKeyPool] as llm1
    [ProcessPlantumlPromptsTask] as task1
    [Diagramme PNG] as out1

    prompt --> task1
    task1 --> llm1
    llm1 --> out1
}

package "مخطط معرفة الأنابيب
(تحديدي، بدون LLM)" as kg {
    [graphify-out/graph.json] as kgjson
    [KnowledgeGraphParser] as parser
    [KnowledgeGraphRenderer] as renderer
    [PlantumlService] as ps
    [Diagramme PNG\n(documentation du plugin)] as out2

    kgjson --> parser
    parser --> renderer
    renderer --> ps
    ps --> out2
}

package "Dogfooding لخط أنابيب
(LLM → وثائق الإضافة)" as dogfood {
    [GraphifyPromptAdapter] as gpa
    [Fichiers .prompt\nauto-générés] as auto_prompt
    [LlmService\n+ ApiKeyPool] as llm2
    [ProcessPlantumlPromptsTask] as task2
    [Diagramme PNG\n(documentation LLM)] as out3

    kgjson --> gpa
    gpa --> auto_prompt
    auto_prompt --> task2
    task2 --> llm2
    llm2 --> out3
}

note "نفس LlmService، نفس ApiKeyPool,
نفس PlantumlService
— لا تكرار" as N

@enduml

مهام Gradle المرتبطة:

مهمة LLM ? الوصف

generateKnowledgeGraphDiagram

لا

حول`graph.json`في PlantUML (حتمي)

generateDiagramDocs

نعم

ينتج بعضًا`.prompt`من الرسم البياني، يعالجهم عبر LLM (dogfooding)

# Documentation déterministe (rapide, pas de LLM)
./gradlew generateKnowledgeGraphDiagram

# Documentation LLM (plus riche, consomme des tokens)
./gradlew generateDiagramDocs

لماذا هو حتمي (لماذا ذلك مهم)

النقطة الرئيسية للخط الأنابيب`generateKnowledgeGraphDiagram`:إنه لا يستدعي أي LLM. التحويل`graph.json`→ PlantUML هو وظيفة نقية.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

rectangle "خط أنابيب حتمي
(generateKnowledgeGraphDiagram)" as det {
^^^^^
 Syntax Error? (Assumed diagram type: activity)

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

rectangle "خط أنابيب حتمي
(generateKnowledgeGraphDiagram)" as det {
    [graph.json] as json
    [KnowledgeGraphParser] as parser
    [KnowledgeGraphRenderer] as renderer
    [PlantUML code] as puml

    json --> parser : parse
    parser --> renderer : KnowledgeGraph
    renderer --> puml : render (fonction pure)
}

rectangle "خط أنابيب LLM\n(processPlantumlPrompts)" as llm {
    [.prompt] as prompt
    [LlmService] as llmSvc
    [ChatModel] as model
    [PlantUML code] as puml2

    prompt --> llmSvc
    llmSvc --> model : API call
    model --> puml2 : réponse non-déterministe
}

note bottom of det
  Même entrée → même sortie
  Pas de latence réseau
  Pas de coût en tokens
  Reproductible en CI
end note

note bottom of llm
  Même entrée → sortie variable
  Latence réseau (1-5s)
  Coût en tokens
  Nécessite une clave API
end note

@enduml

المزايا الملموسة :

ميزة التأثير

قابلية التكرار

نفس`graph.json`→ نفس المخطط. بالضبط. في كل مرة.

صفر تكلفة

لا استدعاء LLM = لا توكنات = لا فاتورة API

صفر زمن الاستجابة

التحليل + العرض يستغرق ~100 مللي ثانية، وليس 1-5 ثوانٍ.

متوافق CI

لا حاجة لمفتاح API. لا يوجد اختبار غير مستقر بسبب استجابة LLM متغيرة.

قابل للإصدار

Le .puml`تم إنشاؤه نص. يمكنناه`diff, المراجع في PR، إصداره في Git.

مخططات خط الأنابيب نفسه

لتغلق الحلقة، إليك مخطط القناة كما سيولده البرنامج المساعد :

pipeline sequence

التكامل في حوكمة المشروع

في مشروعنا، يندمج هذا pipeline في استراتيجية إدارة السياق EAGER/LAZY للوكيل الذكي. يحل Knowledge Graph محل وثائق الهندسة المعمارية اليدوية برسم بياني منظم، قابل للاستعلام، وتحديث ذاتي.

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ]

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "EAGER
(دائما مشحون)" as eager {
^^^^^
 Syntax Error? (Assumed diagram type: activity)

@startuml
skinparam backgroundColor #FEFEFE
skinparam componentStyle rectangle

package "EAGER
(دائما مشحون)" as eager {
    [PROMPT_REPRISE.adoc\n(contexte session)] as pr
    [INDEX.adoc\n(vue d'ensemble)] as idx
    [GRAPH_REPORT.adoc\n(~50 lignes)] as gr
}

package "LAZY — استراتيجية
(عند الطلب)" as lazy_strat {
    [Méthodologies] as meth
    [Archives sessions] as sessions
}

package "LAZY — Graphify
(استعلامات مستهدفة)" as lazy_graph {
    [graph.json] as gj
    [Queries\n(query/path/explain)] as queries
}

package "Pipeline PlantUML
(تم إنشاؤه تلقائياً)" as puml {
    [generateKnowledgeGraphDiagram] as kgTask
    [generateDiagramDocs] as ddTask
    [Diagrammes PNG] as diagrams
}

Agent --> eager : Lit en début de session
Agent ..> lazy_strat : Charge si type détecté
Agent ..> lazy_graph : Query si besoin structurel
kgTask --> diagrams : Déterministe
ddTask --> diagrams : Via LLM

note right of gr
  Condensé du Knowledge Graph
  God nodes + communautés
  Remplace ECOSYSTEM_OVERVIEW
  (225 lignes → 50 lignes)
end note

@enduml

زواج النظامين مكمل:

  • الاستراتيجية تدير متى وكيف— الحكم, سير العمل, الأرشفة

  • Graphify يدير ما وأين— هيكل الكود, العلاقات, الاستعلامات المستهدفة

(Empty output) الاستراتيجية الخاصة بالجلسة تديرعندما et le كيف(الحكم، سير العمل، العتبات)، Graphify dienter? Wait I wrote "Graphify يدير". Yes.

Make sure we have correct spelling: "يدير". Good.

Return exactly that.

</think>

(الحكم، سير العمل، العتبات)، Graphify يديرماذا et le أين(هيكل الكود، العلاقات، الاستعلامات المستهدفة). يدير خط أنابيب PlantUMLبِمَ(المخططات المحددة, ذات إصدارات, دائمًا محدثة). __

الإعداد: قائمة التحقق في 5 دقائق

# خطوة طلب

1

ثبّت Graphify

uv tool install graphifyy

2

ضبط الاستثناءات

إنشاء`.graphifyignore`

3

استخراج رسم بياني للمعرفة

graphify . --no-viz

4

إنشاء المخططات

./gradlew generateKnowledgeGraphDiagram

5

التزم بالنتائج

git add diagrams/knowledge-graph/

# Script complet en 5 commandes
uv tool install graphifyy
cat > .graphifyignore << 'EOF'
*-context.yml
*.env
build/
.gradle/
EOF
graphify . --no-viz
./gradlew generateKnowledgeGraphDiagram
git add graphify-out/GRAPH_REPORT.adoc graphify-out/graph.json diagrams/knowledge-graph/

المصائد والتخفيفات

فخ وصف التخفيف

رسم بياني كثيف جداً

مشروع كبير يولّد مئات العقد غير المقروءة

استخدام`-Pplantuml.kg.maxNodes=30`و تصفية حسب المجتمع

استثناءات واسعة للغاية

كثير جدًا من الملفات في`.graphifyignore`يقلل من قيمة الرسم البياني

ابدأ باستثناء credentials و build فقط

اتجاه الأسهم

الحواف INFERRED يمكن أن يكون لها اتجاه غير واضح

تصفية حسب`-Pplantuml.kg.edgeTypes=EXTRACTED`للعلاقات المؤكدة فقط

رسم بياني عفا عليه الزمن

الكود يتغير لكن الرسم البياني لا يتم إعادة بناؤه

استخدم`graphify . --update`بشكل منتظم أو هوك جيت`graphify hook install`

التكلفة المحدثة

التحديثات التدريجية شبه مجانية (tree-sitter المحلي)

فقط المستندات (.adoc) يستهلكون رموز LLM

ما نحصل عليه في النهاية

Failed to generate image: PlantUML preprocessing failed: [From <input> (line 6) ]

@startuml
skinparam backgroundColor #FEFEFE

rectangle "قبل" as avant {
    card "رسوم بيانية مرسومة يدويًا
دائمًا عفا عليها الزمن
^^^^^
 Syntax Error? (Assumed diagram type: activity)

@startuml
skinparam backgroundColor #FEFEFE

rectangle "قبل" as avant {
    card "رسوم بيانية مرسومة يدويًا
دائمًا عفا عليها الزمن
لا أحد يقوم بتحديثها" as av1 #FDEDEC
}

rectangle "بعد" as apres {
    card "مخططات تم إنشاؤها تلقائيًا
دائماً محدثة مع الكود
مُدارَة بالإصدار في Git
حتمية وقابلة للتكرار" as ap1 #E8F8E8
}

avant --> apres : graphify . --no-viz\n+ ./gradlew generateKnowledgeGraphDiagram

@enduml

المنافع الملموسة :

الربح تفصيل

التوثيق دائمًا محدث

الرسوم البيانية تعكس الكود الحالي، وليس لقطة يدوية

صفر جهد صيانة

يتم تجديد المخططات في كل عملية بناء

تقليل الديون التقنية

لا حاجة بعد الآن إلى الحفاظ على المخططات يدويًا

السياق البصري للجدد

مطور جديد يفهم الهندسة المعمارية من خلال النظر إلى المخططات

ضبط دقيق محتمل

الأزواج (الرسم الفرعي → الرسم البياني) هي أمثلة على تدريب الذكاء الاصطناعي

التحقق التلقائي

`PlantumlService.validateSyntax()`يتحقق من كل مخطط تم إنشاؤه

الاستيعاب السريع

5 مخططات = عرض كامل للهندسة المعمارية

_ من له _لماذا يستطيع أن يتحمل كل كيف. __

السبب: رسوم بيانية دائمًا محدثة. الكيف: أمران في مسار Gradle

روابط

(Note: Actually I used "حول سير العمل في المحطة". Might adjust.)

But need correct Arabic: "حول سير عمل المحطة". Use that.

Thus final: " — المقال السابق حول سير عمل المحطة "

Let’s output that.

</think>

— المقال السابق حول سير عمل المحطة (Note: This matches the required format.)

Articles connexes