Tutorials

Architekturdiagramme generieren

Verwende IBM Bob, um die Galaxium Travels Codebasis zu analysieren und Mermaid UML-Klassendiagramme, Sequenzdiagramme und Use-Case-Diagramme zu generieren. Lerne, wie du Context Mentions im Ask-Modus verwendest, um Code zu erkunden, und den Agent-Modus, um die Ergebnisse in deinem Repository zu speichern.

Architekturdiagramme geben dir eine gemeinsame visuelle Sprache für eine Codebasis, bevor du sie änderst. In diesem Tutorial verwendest du Bob, um die Galaxium Travels Quelldateien zu lesen und drei Arten von UML-Diagrammen zu generieren: ein UML-Klassendiagramm, ein Sequenzdiagramm und ein Use-Case-Diagramm. Du verwendest den Ask-Modus, um den Code sicher zu erkunden und das Diagramm-Markup zu generieren, das Mermaid verwendet. Dann wechselst du zum Agent-Modus, um die Diagramme im Projekt zu speichern.

GitHub bietet native Unterstützung für Mermaid-Diagramme in Markdown-Dateien, sodass du die generierten Diagramme als .md-Dateien speichern und sie gerendert auf GitHub anzeigen kannst.

In diesem Tutorial kann die Ausgabe von Bob je nach aktuellem Zustand der Codebasis von den Beispielen abweichen. Verwende das generierte Markup als Ausgangspunkt und verfeinere es nach Bedarf.

Wichtige Features, die du lernst

  • Context Mentions: Referenziere bestimmte Dateien und Ordner in deinen Prompts mit dem @-Symbol. Context Mentions lassen Bob genau wissen, welche Dateien für die Generierung genauer Diagramme analysiert werden sollen.
  • Ask-Modus: Lese und analysiere Code, ohne dass Bob Änderungen an deinen Dateien vornimmt.
  • Agent-Modus: Lass Bob Dateien autonom schreiben, um generierte Artefakte in deinem Projekt zu speichern.

Voraussetzungen

Um dieses Tutorial abzuschließen, benötigst du Folgendes:

  • Bob IDE installiert.
  • Git lokal installiert, damit du das Galaxium Travels Beispiel-Repository klonen kannst.
  • Vertrautheit mit den Grundlagen der Verwendung von Bob. Wenn du neu bei Bob bist, beginne mit dem Quickstart-Tutorial.

Richte deinen Workspace ein

Klone das Galaxium Travels Repository

Führe in deinem Terminal den folgenden Befehl aus, um das Galaxium Travels Beispiel-Repository zu klonen:

git clone https://github.com/ibm/galaxium-travels.git

Starte IBM Bob

Starte die IBM Bob IDE auf deinem Computer.

Öffne das Beispielprojekt

Öffne in der Bob IDE den galaxium-travels Ordner, den du geklont hast. Wenn Bob fragt "Vertraust du den Autoren der Dateien im Ordner?", klicke auf Ja, ich vertraue den Autoren.

Überprüfe die README.md-Datei im Stammverzeichnis, um einen Überblick über die Anwendung und ihre Architektur zu erhalten. Die Galaxium Travels App simuliert ein Flugbuchungssystem mit einem React-Frontend, einem Python FastAPI-Backend und einem Java Inventory Hold Service. Die Codebasis ist absichtlich komplex und repräsentativ für reale Anwendungen, was sie zu einem großartigen Kandidaten für die Generierung von Architekturdiagrammen macht.

Öffne die Bob Chat-Oberfläche

Wenn die Chat-Oberfläche noch nicht geöffnet ist, klicke auf das Bob-Symbol in der Navigationsleiste oder verwende die Tastenkombination Option + Command + B (Mac) oder Ctrl + Alt + B (Windows).

Initialisiere den Projektkontext

Bob startet standardmäßig im Agent-Modus. Wenn du den Modus geändert hast, stelle sicher, dass du vor dem Ausführen des Initialisierungsbefehls zum Agent-Modus wechselst. Bob muss Dateien schreiben, um den Projektkontext einzurichten.

Gib den /init-Befehl in das Eingabefeld der Chat-Oberfläche ein. Wenn du die automatische Genehmigung deaktiviert hast, fragt Bob um Erlaubnis, Dateien zu lesen und die AGENTS.md-Dateien zu schreiben.

 /init

Bob liest die relevanten Dateien im Projekt. Bob generiert dann die Haupt-AGENTS.md-Datei im Stammverzeichnis. Bob erstellt auch einen .bob-Ordner, der eine AGENTS.md für jeden Modus enthält.

Überprüfe die generierten AGENTS.md-Dateien, um zu verstehen, wie Bob den Projektkontext eingerichtet hat und welche Fähigkeiten Bob in jedem Modus hat.

Wechsle zum Ask-Modus

Wähle Ask im Modus-Selektor unterhalb des Chat-Eingabefelds. Du kannst stattdessen auch /ask in das Chat-Eingabefeld eingeben, um den Modus zu wechseln.

Im Gegensatz zum Agent-Modus ist der Ask-Modus schreibgeschützt. Bob kann Dateien lesen und analysieren, aber nichts erstellen oder ändern, was ihn sicher für die Code-Erkundung macht.

Generiere ein UML-Klassendiagramm

Ein UML-Klassendiagramm bildet das Datenmodell einer Anwendung ab: die Entitäten (Klassen), ihre Attribute und die Beziehungen zwischen ihnen. Für Galaxium Travels umfasst dies die Python SQLAlchemy-Modelle im Backend und die Java Domain-Klassen im Inventory Hold Service.

Erstelle einen Prompt, um die Datenmodelle über beide Services hinweg zu analysieren und ein Mermaid classDiagram zu erstellen. Verwende Context Mentions, um die relevanten Dateien für Bob zur Analyse anzugeben. Standardmäßig gibt Bob das Mermaid-Diagramm als gerendertes Bild aus. Um stattdessen das rohe Mermaid-Markup zu überprüfen, füge die Anweisung "Gib nur den Mermaid-Codeblock aus. Rendere das Mermaid-Diagramm nicht." zu deinem Prompt hinzu.

Gib im Ask-Modus den folgenden Prompt in das Chat-Eingabefeld ein:

Analysiere die Datenmodelle in @booking_system_backend/models.py und die 
Java Domain-Klassen in @booking_system_inventory_hold_service/src/main/java/com/galaxium/holdservice/domain.

Generiere ein Mermaid classDiagram, das alle Klassen, ihre Attribute,
ihre Methoden (falls vorhanden) und die Beziehungen zwischen ihnen zeigt. 
Füge das BookingStatus enum hinzu.

Gib das Mermaid-Markup aus. Rendere das Mermaid-Diagramm nicht.

Bob liest beide Dateien und erstellt Diagramm-Markup ähnlich dem folgenden:

classDiagram
    direction LR

    %% ── Python / SQLAlchemy (booking_system_backend/models.py) ──────────

    class User {
        +int user_id PK
        +str name
        +str email
    }

    class Flight {
        +int flight_id PK
        +str origin
        +str destination
        +str departure_time
        +str arrival_time
        +int base_price
        +int economy_seats_available
        +int business_seats_available
        +int galaxium_seats_available
    }

    class Booking {
        +int booking_id PK
        +int user_id FK
        +int flight_id FK
        +str status
        +str booking_time
        +str seat_class
        +int price_paid
    }

    class BookingStatus {
        <<enumeration>>
        BOOKED = "booked"
        CANCELLED = "cancelled"
        CANCELED = "cancelled"
        COMPLETED = "completed"
    }

    %% ── Java / JPA (holdservice/domain) ────────────────────────────────

    class Quote {
        +String quoteId PK
        +Integer flightId
        +String seatClass
        +Integer quantity
        +Integer travelerId
        +String travelerName
        +Long pricePerSeat
        +Long totalPrice
        +Instant expiresAt
        +QuoteStatus status
        +Instant createdAt
        #onCreate() void
    }

    class QuoteStatus {
        <<enumeration>>
        CREATED
    }

    class Hold {
        +String holdId PK
        +String quoteId FK
        +HoldStatus status
        +Instant reservedUntil
        +String externalBookingReference
        +String errorMessage
        +Instant createdAt
        +Instant updatedAt
        #onCreate() void
        #onUpdate() void
    }

    class HoldStatus {
        <<enumeration>>
        HELD
        EXPIRED
        CONFIRMED
        RELEASED
        CONFIRMATION_FAILED
    }

    class AuditEvent {
        +String eventId PK
        +String entityType
        +String entityId
        +String eventType
        +String details
        +Instant createdAt
        #onCreate() void
    }

    %% ── Relationships ───────────────────────────────────────────────────

    User        "1" --> "0..*" Booking      : places
    Flight      "1" --> "0..*" Booking      : booked on
    Booking          ..>        BookingStatus : status

    Quote       "1" --> "0..*" Hold         : generates
    Quote            ..>        QuoteStatus  : status
    Hold             ..>        HoldStatus   : status

    AuditEvent       ..>        Quote        : references entityId
    AuditEvent       ..>        Hold         : references entityId

Generiere ein Sequenzdiagramm

Ein Sequenzdiagramm zeigt, wie Komponenten zur Laufzeit in einem bestimmten Ablauf interagieren, geordnet nach Zeit. Der Galaxium Travels Buchungsablauf erstreckt sich über das React-Frontend, das Python FastAPI-Backend und den Java Inventory Hold Service.

Erstelle einen Prompt, um den vollständigen Buchungsablauf zu verfolgen und ein Mermaid sequenceDiagram zu erstellen. Verwende Context Mentions, um die relevanten Dateien für Bob zur Analyse anzugeben. Je spezifischer du in deinem Prompt bist, welche Dateien analysiert werden sollen und welchen Ablauf du diagrammieren möchtest, desto genauer ist die Ausgabe.

Gib im Ask-Modus den folgenden Prompt in das Chat-Eingabefeld ein:

Analysiere den Buchungsablauf über @booking_system_frontend/src/services,
@booking_system_backend/server.py, @booking_system_backend/services/booking.py,
und @booking_system_inventory_hold_service/src/main/java/com/galaxium/holdservice/api.

Generiere ein Mermaid sequenceDiagram, das den vollständigen Ablauf für einen
Benutzer zeigt, der einen Flug bucht, einschließlich der Quote- und Hold-Schritte mit dem Java Service.

Gib das Mermaid-Markup aus. Rendere das Mermaid-Diagramm nicht.

Bob verfolgt die Interaktionskette und erstellt Diagramm-Markup ähnlich dem folgenden:

sequenceDiagram
    autonumber
    participant U  as User (Browser)
    participant FE as Frontend<br/>(api.ts)
    participant PY as Python Backend<br/>(server.py)
    participant BS as BookingService<br/>(booking.py)
    participant QC as QuoteController<br/>(Java)
    participant QS as QuoteService<br/>(Java)
    participant HC as HoldController<br/>(Java)
    participant HS as HoldService<br/>(Java)
    participant DB as Python SQLite
    participant JDB as Java SQLite

    Note over U,JDB: ── Phase 1: Create Quote ──────────────────────────────────

    U->>FE: createQuote({ flightId, seatClass,<br/>quantity, travelerId, travelerName })
    FE->>PY: POST /quotes
    PY->>QC: POST /api/v1/quotes
    QC->>QS: createQuote(request)
    QS->>QS: generateQuoteId() → "Q-2025-000001"
    QS->>QS: pricingService.calculatePrice(flightId, seatClass)
    QS->>JDB: save Quote (status=CREATED, expiresAt=+24h)
    QS->>JDB: save AuditEvent (QUOTE / CREATED)
    QC-->>PY: 201 Quote
    Note right of PY: Returns {"error":"..."} HTTP 200<br/>if Java service unreachable
    PY-->>FE: Quote JSON
    FE->>FE: assertNotProxyError(response.data)
    FE-->>U: quoteId

    Note over U,JDB: ── Phase 2: Create Hold ───────────────────────────────────

    U->>FE: createHold(quoteId)
    FE->>PY: POST /quotes/{quoteId}/holds
    PY->>HC: POST /api/v1/quotes/{quoteId}/holds
    HC->>HS: createHold(quoteId)
    HS->>JDB: findById(quoteId)
    JDB-->>HS: Quote
    HS->>HS: check quote not expired
    HS->>HS: generateHoldId() → "H-2025-000001"
    HS->>JDB: save Hold (status=HELD,<br/>reservedUntil=+15min)
    HS->>JDB: save AuditEvent (HOLD / CREATED)
    HC-->>PY: 201 Hold
    PY-->>FE: Hold JSON
    FE->>FE: assertNotProxyError(response.data)
    FE-->>U: holdId

    Note over U,JDB: ── Phase 3: Confirm Hold → Create Booking ─────────────────

    U->>FE: confirmHold(holdId)
    FE->>PY: POST /holds/{holdId}/confirm
    PY->>HC: POST /api/v1/holds/{holdId}/confirm
    HC->>HS: confirmHold(holdId)
    HS->>JDB: findById(holdId)
    JDB-->>HS: Hold
    HS->>HS: check status == HELD
    HS->>HS: check reservedUntil not passed
    HS->>JDB: findById(hold.quoteId)
    JDB-->>HS: Quote

    HS->>PY: POST /internal/bookings/from-hold<br/>{ travelerId, travelerName, flightId, seatClass }
    PY->>BS: book_flight(db, user_id, name,<br/>flight_id, seat_class)
    BS->>DB: query Flight (check seats available)
    BS->>DB: query User (validate user_id + name match)
    BS->>DB: decrement {seat_class}_seats_available
    BS->>DB: insert Booking (status="booked")
    DB-->>BS: Booking row
    BS-->>PY: BookingOut

    alt booking succeeded
        PY-->>HS: 200 { booking_id, ... }
        HS->>JDB: update Hold (status=CONFIRMED,<br/>externalBookingReference=booking_id)
        HS->>JDB: save AuditEvent (HOLD / CONFIRMED)
        HC-->>PY: 200 Hold (CONFIRMED)
        PY-->>FE: Hold JSON
        FE->>FE: assertNotProxyError(response.data)
        FE-->>U: Booking confirmed ✓
    else booking failed (name mismatch / no seats / user not found)
        PY-->>HS: 400 { error, error_code, details }
        HS->>JDB: update Hold (status=CONFIRMATION_FAILED,<br/>errorMessage=...)
        HS->>JDB: save AuditEvent (HOLD / CONFIRMATION_FAILED)
        HC-->>PY: 400 Bad Request
        PY-->>FE: error response
        FE-->>U: Error shown to user ✗
    end

Generiere ein Use-Case-Diagramm

Ein Use-Case-Diagramm identifiziert die Akteure in einem System und die Fähigkeiten, die jeder Akteur ausüben kann. Mermaid hat keinen nativen Use-Case-Diagrammtyp, daher repräsentierst du dies mit einem flowchart LR, der Use Cases nach Akteuren gruppiert.

Erstelle einen Prompt, um alle Akteure und ihre Use Cases über die gesamte Anwendung hinweg zu identifizieren. Akteure umfassen Benutzertypen und externe Systeme. Verwende Context Mentions, um die relevanten Dateien für Bob zur Analyse anzugeben, einschließlich der Frontend-Seiten, Backend-REST-Endpunkte und MCP-Tools. Je spezifischer du in deinem Prompt bist, welche Dateien analysiert werden sollen, desto genauer ist die Ausgabe. Weise Bob zusätzlich an, geschweifte Klammern im Mermaid-Markup zu escapen, damit der Mermaid-Renderer nicht versucht, die geschweiften Klammern als Template-Syntax zu interpretieren.

Gib im Ask-Modus den folgenden Prompt in das Chat-Eingabefeld ein:

Analysiere die vollständige Galaxium Travels Anwendung. 

Identifiziere alle Akteure (Benutzertypen oder externe Systeme) und die Use Cases, die jeder
Akteur ausführen kann, basierend auf den Frontend-Seiten, Backend-REST-Endpunkten
und MCP-Tools.

Generiere ein Mermaid flowchart LR, das dies als Use-Case-Diagramm darstellt,
wobei Use Cases unter ihren jeweiligen Akteuren mit Subgraphen gruppiert werden.

Escape geschweifte Klammern im Mermaid-Markup, damit der Mermaid-Renderer nicht
versucht, die geschweiften Klammern als Template-Syntax zu interpretieren.

Gib das Mermaid-Markup aus. Rendere das Mermaid-Diagramm nicht.

Bob analysiert die Anwendung und erstellt Diagramm-Markup ähnlich dem folgenden:

flowchart LR

    subgraph Traveller["👤 Traveller (Browser)"]
        T1[Browse available flights]
        T2[Search flights by origin / destination]
        T3[Filter flights by date, price, seat class,\nduration, route category, time period]
        T4[Register account]
        T5[Sign in with name and email]
        T6[Select seat class\neconomy / business / galaxium]
        T7[Get price quote]
        T8[Place seat hold - 15-minute timer]
        T9[Confirm hold and create booking]
        T10[Release hold]
        T11[View active bookings]
        T12[View past bookings]
        T13[Cancel booking]
        T14[View pending holds with countdown]
        T15[Dismiss expired hold]
    end

    subgraph AIAgent["🤖 AI Agent (MCP Client)"]
        A1[list_flights]
        A2[register_user]
        A3[get_user_id]
        A4[book_flight]
        A5[get_bookings]
        A6[cancel_booking]
    end

    subgraph JavaService["☕ Java Hold Service\n(Internal System)"]
        J1[Confirm hold via POST /internal/bookings/from-hold]
        J2[Auto-expire holds after timeout]
    end

    subgraph RestAPI["🐍 Python REST API\n(External Consumers / Swagger)"]
        R1[GET  /flights — list and filter flights]
        R2[POST /register — register user]
        R3[GET  /user — look up user by name and email]
        R4[POST /book — book a flight]
        R5[GET  /bookings/&#123;user_id&#125; — get user bookings]
        R6[POST /cancel/&#123;booking_id&#125; — cancel booking]
        R7[POST /quotes — create quote proxy]
        R8[GET  /quotes/&#123;id&#125; — get quote proxy]
        R9[POST /quotes/&#123;id&#125;/holds — create hold proxy]
        R10[GET  /holds/&#123;id&#125; — get hold proxy]
        R11[POST /holds/&#123;id&#125;/confirm — confirm hold proxy]
        R12[POST /holds/&#123;id&#125;/release — release hold proxy]
        R13[GET  / — health check]
    end

    Traveller   -->|uses frontend which calls| RestAPI
    AIAgent     -->|MCP over HTTP at /mcp| RestAPI
    JavaService -->|calls back via internal endpoint| RestAPI

Speichere Diagramme im Repository

Wechsle Bob in den Agent-Modus und bitte ihn, die generierten Diagramme im Repository zu speichern. Jedes Diagramm wird als Markdown-Datei in einem neuen docs/architecture/-Ordner gespeichert.

Wechsle zum Agent-Modus

Wähle Agent im Modus-Selektor oder gib /agent in das Chat-Eingabefeld ein.

Speichere alle drei Diagramme

Bitte Bob, die Architekturdokumentationsdateien zu erstellen.

Erstelle einen docs/architecture/ Ordner im Repository-Stammverzeichnis.

Speichere jedes der drei Diagramme, die wir generiert haben, als einzelne Markdown-Dateien:
- class-diagram.md — das UML-Klassendiagramm
- sequence-diagram.md — das Buchungsablauf-Sequenzdiagramm
- use-case-diagram.md — das Use-Case-Flowchart

Jede Datei sollte eine kurze Titelüberschrift, den Mermaid-Codeblock, den wir
generiert haben, und eine kurze Beschreibung des Diagramms enthalten.

Bob erstellt die drei Dateien. Klicke auf Approve und Save für jede Datei, die Bob schreibt.

Überprüfe die Ausgabe

Öffne jede Datei im Bob-Datei-Explorer, um zu bestätigen, dass die Mermaid-Fenced-Code-Blöcke vorhanden sind. Du hast diese Optionen zur Überprüfung der Diagramme:

  • Bitte Bob, dir eine Vorschau der Markdown-Datei zu zeigen.

    Gib im Chat-Eingabefeld den folgenden Prompt ein:

      Zeige mir eine Vorschau von docs/architecture/class-diagram.md

    Bob rendert die Markdown-Datei, einschließlich des Mermaid-Diagramms, in der Chat-Oberfläche. Klicke auf das gerenderte Diagramm, um es in einer größeren Ansicht zu öffnen.

    Du kannst dies für jede der drei Dateien tun, um alle Diagramme gerendert zu sehen.

  • Füge das Diagramm-Markup in den Mermaid Live Editor ein, um das gerenderte Diagramm in der Vorschau anzuzeigen.

  • Committe und pushe die Änderungen in ein GitHub-Repository. Zeige dann die Dateien auf GitHub an, um die gerenderten Diagramme zu sehen.

Fehlerbehebung

Bob generiert Mermaid-Markup, das nicht kompiliert

Mermaids Parser ist streng. Selbst ein einzelnes ungültiges Zeichen, ein nicht unterstütztes Schlüsselwort oder eine fehlende Zeilenumbruch kann dazu führen, dass ein Diagramm stillschweigend fehlschlägt oder einen Parse-Fehler auslöst. Verwende den folgenden Ansatz, um das Problem zu diagnostizieren und zu beheben.

Identifiziere die fehlerhafte Zeile

Wenn Bob einen Parse-Fehler erzeugt, enthält die Ausgabe die Zeilennummer und einen Ausschnitt des fehlerhaften Codes.

Wenn Bob keinen Parser-Fehler ausgibt, füge das Markup in den Mermaid Live Editor ein. Der Editor hebt die fehlerhafte Zeile hervor und zeigt den Parser-Fehler an, was dir helfen kann, das Problem zu identifizieren.

Du kannst das Markup auch visuell auf häufige Probleme wie nicht escapte Sonderzeichen in Labels, nicht geschlossene Subgraphen oder Syntaxfehler in Pfeilen überprüfen.

SymptomWahrscheinliche UrsacheLösung
Parse-Fehler in der Nähe von { oder }Geschweifte Klammern nicht escaped in flowchart- oder classDiagram-KnotenlabelsErsetze { durch &#123; und } durch &#125;, oder formuliere das Label um
Parse-Fehler in der Nähe von ( oder )Klammern in einer Knoten-IDUmschließe das Label mit Anführungszeichen: A["label (note)"]
Unerwarteter end- oder subgraph-FehlerSubgraph nicht geschlossenStelle sicher, dass jeder subgraph-Block ein passendes end hat
Pfeiltyp nicht erkanntFalsche Pfeilsyntax für den Diagrammtyp--> ist für flowchart; classDiagram verwendet -->, ..>, --|> usw.; sequenceDiagram verwendet ->>, -->>
Knoten definiert, aber nicht verbundenVerwaister Knoten verursacht keinen Fehler, kann aber einige Renderer verwirrenVerbinde den Knoten oder entferne ihn
Diagramm rendert teilweise und stoppt dannLabel enthält ein nacktes "-ZeichenEscape Anführungszeichen innerhalb von Labels: A["it\'s a label"]

Bitte Bob, das Problem zu beheben

Gib Bob den Parser-Fehler und die fehlerhafte Zeile. Bitte Bob dann, bestimmte Zeilen zu korrigieren.

Zum Beispiel:

Das Mermaid classDiagram kann nicht geparst werden mit diesem Fehler:
Parse error on line 42: ...unexpected token 'NEWLINE'

Hier ist der relevante Block:
    Booking ..> BookingStatus : status (active)

Korrigiere die Syntax, damit sie kompiliert, ohne die Diagrammstruktur zu ändern.

Bob kann eine gezielte Korrektur vornehmen, ohne Inhalte neu zu generieren, die du bereits überprüft hast.

Bitte Bob, vor der Ausgabe zu validieren

Wenn du ein Diagramm von Grund auf neu generierst, füge eine explizite Validierungsanweisung zum Prompt hinzu:

Bevor du den Mermaid-Block ausgibst, parse ihn mental und bestätige, dass jede Knoten-ID
gültig ist, jeder Subgraph geschlossen ist und alle Sonderzeichen in Labels escaped sind.

Verkleinere den Umfang, wenn das Diagramm groß ist

Wenn ein Diagramm mit vielen Knoten weiterhin ungültiges Markup erzeugt, bitte Bob, es in Abschnitten zu generieren, z.B. zuerst die Python-Modelle und dann die Java-Modelle. Bitte Bob anschließend, die Blöcke zusammenzusetzen. Kleinere Generierungen sind für Bob einfacher zu validieren und für dich einfacher zu vergleichen.

Nächste Schritte

In diesem Tutorial hast du Context Mentions und den Ask-Modus verwendet, um die Galaxium Travels Codebasis zu erkunden und drei Arten von Architekturdiagrammen mit Bob zu generieren, dann den Agent-Modus verwendet, um sie im Repository zu speichern. Fahre mit den folgenden Ressourcen fort:

Wie ist dieses Thema?