Camunda 8.9 ist da – mit KI-Features wie dem Agentic Subprocess, Document Understanding und mehr. Mit Camunda 8.10 und ProcessOS steht die KI-Optimierung von Prozessen vor der Tür.
Doch die Realität in vielen Unternehmen sieht anders aus: Der Großteil der BPM-Landschaft läuft noch auf Camunda 7. Und solange das so bleibt, bleiben auch die neuen Möglichkeiten unerreichbar.
Das Problem: Der Umzug von Camunda 7 auf Camunda 8 ist kein einfaches Update. Es ist ein Architekturwechsel: Remote statt Embedded Engine, FEEL statt JUEL, Job Worker statt Java Delegates, ein anderer Umgang mit Listenern, Nachrichtenkorrelation und Transaktionen und weitere grundlegende Unterschiede. Vieles lässt sich mit Tools wie dem Camunda Diagram Converter oder den OpenRewrite-Rezepten automatisch umwandeln, aber dabei müssen viele Entscheidungen getroffen werden. Und das, was nicht automatisch übersetzt werden kann, muss mit Aufwand umgeschrieben werden. Über allem hängt die zentrale Frage: Läuft danach noch mein Prozess in Produktion? Eine Frage, die häufig nur mit intensiven, fachübergreifenden Tests sichergestellt werden kann.
Dieser Aufwand schreckt viele Teams ab und nimmt Organisationen die Möglichkeit, die neuen KI-Fähigkeiten zeitnah in ihre Prozesse zu übernehmen und von ihnen zu profitieren.
In unserer dreiteiligen Blog-Serie (Teil 1, Teil 2, Teil 3) haben wir gezeigt, wie die Migration am Beispiel Kfz-Glasbruch manuell abläuft. Heute gehen wir einen Schritt weiter: Was passiert, wenn wir selbst erstellte KI-Coding-Agenten die Migration durchführen lassen angeleitet durch Spezifikationen?
Unsere Antwort: Spec-Driven Development (BMAD) mit individuellen Software-Entwicklungsagenten für eine Code-, BPMN-, DMN- und fachliche Migration von Camunda 7.24 zu Camunda 8.9. Und damit wir nach jedem Schritt beweisen können, dass die Fachlichkeit erhalten bleibt, spannen wir ein Sicherheitsnetz auf: Behavior-Driven Development. Wir haben es gemacht.
Die Ausgangslage: eine klassische Camunda-7-Anwendung
Bevor wir über Agenten sprechen, ein Blick auf das, was migriert werden soll. Die C7-Anwendung ist ein klassisches Setup: Spring Boot mit eingebetteter Camunda-7-Engine, Java Delegates für die Service Tasks, ein External Task Worker für einen der Service Tasks, zwei DMN-Tabellen und HTML-Formulare für die User Tasks. Ein typischer Delegate sieht so aus:
// c7-app/src/main/java/de/demo/kglasbruch/delegate/SchadenAnlegenDelegate.java
@Component
public class SchadenAnlegenDelegate implements JavaDelegate {
private final UmsystemeService umsystemeService;
public SchadenAnlegenDelegate(UmsystemeService umsystemeService) {
this.umsystemeService = umsystemeService;
}
@Override
public void execute(DelegateExecution execution) throws Exception {
Schaden schaden = (Schaden) execution.getVariable("ext_schaden");
if (schaden == null) {
throw new IllegalStateException("Missing required process variable ext_schaden");
}
String schadenId = umsystemeService.createSchaden(schaden);
execution.setVariable("int_schadenId", schadenId);
}
}
Das Muster ist klar: Variable lesen, Service aufrufen, Ergebnis zurückschreiben. Das lässt sich migrieren, wenn man weiß, was rauskommen soll.
Der Ansatz: KI-Agenten migrieren, BDD sichert ab
Der Kern unseres Ansatzes ist Spec-Driven Development: Bevor KI-Coding-Agenten eine Zeile Code generieren, werden die Anforderungen, die Architektur und die Migrationsschritte als Spezifikation definiert. Der Agent arbeitet dann nicht "frei", sondern innerhalb klar definierter Leitplanken. Das verhindert, dass die KI kreative, aber falsche Lösungen erfindet oder, noch schlimmer: bestehende Fachlichkeit ändert. Dieser Ansatz würde grundsätzlich auch ohne Behaviour Driven Development (BDD) funktionieren.
Aber woher wissen wir am Ende, dass die Migration fachlich korrekt ist? Hier kommt das Sicherheitsnetz ins Spiel: BDD-Feature-Dateien sind der stabile Migrationsvertrag. Die Geschäftslogik, die in Gherkin-Szenarien beschrieben ist, ändert sich nicht zwischen Engine-Versionen. Was sich ändert, ist die technische Infrastruktur darunter: die Engine-APIs, die Serialisierung, das Deployment und in der Folge auch die Step Definitions, also der Java-Code, der die Gherkin-Sätze ausführbar macht (siehe Exkurs weiter unten). Das fachliche Verhalten und die Schnittstellenaufrufe zu umliegenden Systemen bleiben identisch.
Für unseren Kfz-Glasbruch-Prozess haben wir fünf Szenarien definiert, die das fachliche Verhalten des Prozesses abdecken (hier mit deutschen Gherkin-Schlüsselwörtern zur besseren Lesbarkeit):
# language: de
Funktionalität: KFZ Glasbruch Schadenmeldungsprozess
Szenario: Szenario 1 - Happypath ohne Pruefbericht
Angenommen eine Schadenmeldung fuer VSNR "TEST-001" mit Schadenshoehe 200.0 und Reparaturtyp "AUSTAUSCH"
Wenn der Schadenmeldungsprozess gestartet wird
Dann ist der Vertrag erfolgreich abgerufen worden
Und kein Pruefbericht ist erforderlich
Und die Zahlung wird erfolgreich angewiesen
Szenario: Szenario 2 - Happypath mit Pruefbericht
Angenommen eine Schadenmeldung fuer VSNR "TEST-001" mit Schadenshoehe 800.0 und Reparaturtyp "REPARATUR"
Wenn der Schadenmeldungsprozess gestartet wird
Und der Pruefbericht geht ein
Dann die Zahlung wird erfolgreich angewiesen
Szenario: Szenario 3 - SLA-Ueberschreitung
Angenommen eine Schadenmeldung fuer VSNR "TEST-001" mit Schadenshoehe 800.0 und Reparaturtyp "REPARATUR"
Wenn der Schadenmeldungsprozess gestartet wird
Und das SLA-Zeitlimit abläuft
Dann der SlaUeberschrittenListener wird ausgeloest
Szenario: Szenario 4 - Kein Versicherungsschutz
Angenommen eine Schadenmeldung fuer VSNR "HAFT-001" mit Schadenshoehe 200.0 und Reparaturtyp "AUSTAUSCH"
Wenn der Schadenmeldungsprozess gestartet wird
Und der Sachbearbeiter den Leistungsanspruch ablehnt
Dann der Ablehnungsbescheid wurde an die Werkstatt gesendet
Szenario: Szenario 5 - Vertrag nicht gefunden
Angenommen eine Schadenmeldung fuer VSNR "UNKNOWN" mit Schadenshoehe 200.0 und Reparaturtyp "AUSTAUSCH"
Wenn der Schadenmeldungsprozess gestartet wird
Diese fünf Szenarien decken den Happy Path (mit und ohne Prüfbericht), die SLA-Eskalation, den manuellen Ablehnungsfall und den technischen Fehlerpfad ab. Sie sind die fachliche Wahrheit und sie müssen nach der Migration unverändert bestehen.
Exkurs: Von Gherkin zu ausführbarem Code: Step Definitions
Gherkin ist die natürlichsprachliche Notation, in der die Szenarien geschrieben sind. Cucumber ist das Test-Framework, das diese Sätze ausführbar macht: Jede Gherkin-Zeile wird über eine Annotation einer Java-Methode zugeordnet – der sogenannten Step Definition:
@When("der Schadenmeldungsprozess gestartet wird")
public void derSchadenmeldungsprozessGestartetWird() {
// startet den Prozess über die Engine-API
}
Die Gherkin-Sätze sind engine-unabhängig. Die Step Definitions dahinter sind es nicht: Sie sprechen mit der konkreten Engine-API und müssen bei der Migration umgeschrieben werden. Genau deshalb sind die Feature-Dateien der stabile Vertrag und die Step Definitions Teil der Migrationsarbeit.
Der Coverage-Report erzeugt mit dem Community-Projekt Camunda Process Test Coverage, das während des Testlaufs mitschreibt, welche BPMN-Elemente durchlaufen wurden zeigt: Alle fünf Szenarien zusammen decken über 80 % des BPMN-Prozesses ab. Die grünen Elemente sind die Migrationsleitplanke. Alles, was grün ist, muss nach der Migration immer noch grün sein.
Vier Schritte der agentengestützten Migration
Schritt 1: Fachlichkeit der Camunda-7-Anwendung als BDD-Szenarien erfassen
Bevor überhaupt an Migration gedacht wird, muss die Fachlichkeit des bestehenden Prozesses festgehalten und testbar gemacht werden. In unserem Fall bedeutet das: Die oben gezeigten Gherkin-Szenarien werden mit Cucumber-Step-Definitions hinterlegt und gegen die Camunda-7-Anwendung ausgeführt. Wir haben dafür BDD benutzt, aber auch andere strukturierte Vorgehen sind denkbar.
Für die BDD-Suite nutzen wir WireMock-Stubs (JSON-Dateien, keine programmatische Registrierung), welche die Umsysteme simulieren. Die Suite läuft mit mvn test und alle fünf Szenarien sind grün. Das ist unsere Baseline und unsere Garantie.
Und wenn es noch keine BDD-Suite gibt? Das ist der Normalfall, die wenigsten Bestandsanwendungen bringen Gherkin-Szenarien mit. Genau hier können KI-Agenten ebenfalls unterstützen: Sie extrahieren Szenario-Kandidaten aus BPMN-Modell, DMN-Tabellen und Code, die dann gemeinsam mit den Fachexperten validiert und geschärft werden. Dieses Erfassen der fachlichen Wahrheit ist für uns kein Vorab-Hindernis, sondern der erste Baustein der Migration und einer, bei dem wir gerne unterstützen.
Schritt 2: Migrationsplan mit KI-Agenten definieren
Bevor die eigentliche Konvertierung beginnt, führen wir ein vollständiges Assessment durch. Ebenfalls agentengestützt, aber im reinen Read-Only-Modus. Das Ergebnis ist ein Migration Forecast, der jedes einzelne BPMN-Element, jede DMN-Tabelle und jede Java-Klasse inventarisiert und nach Komplexität und Migrationsrisiko bewertet. Ein Auszug aus dem Risikoregister:
| ID | Risiko | Komplexität | Mitigation |
|---|---|---|---|
| R1 |
SlaUeberschrittenListener – ExecutionListener auf Escalation End Event
|
Hoch |
C8.9 unterstützt zeebe:executionListener (seit 8.6+)
|
| R2 | Message Correlation Key – in C8 üblich, in C7 nicht vorhanden | Hoch | Prozessvariable als Correlation Key verwenden |
| R3 |
JUEL execution.getVariable() in Sequenzfluss-Bedingungen
|
Hoch |
FEEL-Äquivalent: =variable != null
|
| R5 | Timer-Ausdrücke hardcodiert im BPMN | Mittel | Externalisierung als FEEL-Prozessvariable |
| R7 |
ClockUtil hat kein C8-Äquivalent in Integrationstests
|
Hoch | Timer auf PT3S setzen, natürliches Warten mit Awaitility |
Zusätzlich deckt das Assessment Diskrepanzen zwischen Planungsdokumenten und dem tatsächlichen Code auf. Die wichtigste Regel dabei: Die Szenariotests sind die Quelle der Wahrheit, nicht die Dokumentation. Solche Diskrepanzen dürfen nicht stillschweigend wegmigriert werden. Sie müssen vor der Migration kritisch hinterfragt und aufgelöst werden.
Für die eigentliche Migration setzen wir einen dedizierten KI-Migrationsagenten ein, der vier spezialisierte Skills mitbringt:
BPMN-Namespace-Migration –
camunda:zuzeebe:, JUEL zu FEEL, Timer-Externalisierung (hardcodierte Timer-Ausdrücke aus dem BPMN in konfigurierbare Prozessvariablen verlagern, warum das nötig ist, zeigt Anlauf 3 weiter unten)DMN-FEEL-Adaptation – Ausführungsplattform umstellen, Typanpassungen, Variablen-Mapping
Glue-Code-Migration – Java Delegates zu Zeebe Job Workern, Spin zu Jackson
BDD-Test-Migration – Step Definitions von Camunda-7-API auf CamundaClient + Awaitility
Jeder Skill referenziert den Migration Forecast und kennt die exakten Job-Type-Bezeichnungen. Die gibt es in der C7-Anwendung noch gar nicht. Sie wurden im Forecast als Teil der Zielarchitektur festgelegt (ein Tippfehler bedeutet, dass ein Worker nie aufgerufen wird!). Und jeder Skill hat klare Grenzen: Die Feature-Dateien und der Umsysteme-Simulator sind eingefroren und dürfen nicht modifiziert werden.
Schritt 3: Camunda 8 durch Agenten aufbauen
Jetzt wird es konkret. Der Agent führt die Migration in drei Teilschritten durch:
BPMN-Namespace-Migration: Als Startpunkt ("Seed") dient die Roh-Konvertierung des offiziellen Camunda Diagram Converters – wir nennen sie Converter-Baseline. Der Agent kuratiert diese Baseline zu einem deploybaren Modell: Alle camunda:-Attribute werden durch zeebe:-Äquivalente ersetzt, Delegate Expressions werden zu Job Types, JUEL-Bedingungen zu FEEL-Ausdrücken, Business Rule Tasks bekommen zeebe:calledDecision.
DMN-Adaptation: Die Ausführungsplattform wird auf "Camunda Cloud 8.9.0" umgestellt (für die Ausführbarkeit selbst ist dieser Parameter unerheblich – er steuert vor allem die Validierung im Modeler), camunda:-spezifische Attribute werden entfernt und typeRef="double" zu typeRef="number" korrigiert (FEEL kennt kein double).
Zeebe Job Worker: Das ist der Kern der Code-Migration. Aus dem Delegate oben wird:
// c8-app/src/main/java/de/demo/kglasbruch/worker/SchadenAnlegenWorker.java
@Component
public class SchadenAnlegenWorker implements JobHandler {
private final UmsystemeService umsystemeService;
public SchadenAnlegenWorker(UmsystemeService umsystemeService) {
this.umsystemeService = umsystemeService;
}
@Override
public void handle(JobClient client, ActivatedJob job) throws Exception {
ProcessVariables vars = job.getVariablesAsType(ProcessVariables.class);
Schaden schaden = vars.getExtSchaden();
if (schaden == null) {
throw new IllegalStateException("Missing required process variable ext_schaden");
}
String schadenId = umsystemeService.createSchaden(schaden);
client.newCompleteCommand(job)
.variables(Map.of("int_schadenId", schadenId))
.send().join();
}
}
Die Geschäftslogik bleibt identisch umsystemeService.createSchaden(schaden) ändert sich nicht. Was sich ändert, ist die Infrastruktur drumherum: Variablen werden über ProcessVariables mit Jackson deserialisiert statt über execution.getVariable() mit Camunda Spin, der Camunda-7-eigenen (De-)Serialisierungsbibliothek. Das Ergebnis wird über den completeCommand zurückgeschrieben statt über execution.setVariable(). Der Service Layer, also die eigentliche Integrationslogik mit den Umsystemen, bleibt gleich. Das ist der Beweis unserer These: Die Migrationsgrenze ist die Engine-Schicht, nicht die Geschäftslogik. Fairerweise: Das gilt nur, wenn die Architektur sauber getrennt ist schlanke Delegates, Geschäftslogik im Service Layer. Wer Geschäftslogik direkt in Delegates oder gar in JUEL-Ausdrücken vergraben hat, migriert deutlich mehr als die Engine-Schicht.
Insgesamt wurden 10 Zeebe Job Worker implementiert: 8 für die ehemaligen Delegates, 1 für den External Task Worker und 1 für den Execution Listener.
Schritt 4: BDD-Szenarien auf Camunda 8 ausführen
Der letzte Schritt: Die Feature-Dateien werden unverändert in die C8-Anwendung übernommen, und die Step Definitions werden für die neue Engine-API umgeschrieben. Hier der Vergleich für den Gherkin-Schritt
Wenn der Schadenmeldungsprozess gestartet wird
Derselbe Satz, zwei Implementierungen:
Camunda 7 – REST-Call gegen die eingebettete Engine:
// C7: HTTP POST gegen /engine-rest/message
Map<String, Object> body = new HashMap<>();
body.put("messageName", START_MESSAGE);
body.put("resultEnabled", true);
body.put("processVariables", processVariables);
String response = restTemplate.postForObject(
CAMUNDA_REST_BASE + "/message", entity, String.class);
JsonNode root = objectMapper.readTree(response);
context.processInstanceId = root.get(0).get("processInstance").get("id").asText();
Camunda 8 – CamundaClient mit Message Publish:
// C8: CamundaClient.newPublishMessageCommand()
camundaClient.newPublishMessageCommand()
.messageName(START_MESSAGE)
.correlationKey(context.vsnr + "-" + startedAfter.toEpochMilli())
.variables(variables)
.send().join();
context.processInstanceKey = operateRestClient.awaitProcessInstanceKey(startedAfter);
Die Unterschiede sind substantiell: Keine Spin-Serialisierung mehr (Objekte werden direkt als POJOs übergeben, Jackson macht den Rest). Ein Correlation Key kommt hinzu. Beim Prozessstart per Message-Start-Event ist er zwar nicht zwingend erforderlich, wir setzen ihn aber bewusst, um Nachrichten eindeutig zuordnen zu können. Und statt einer synchronen Response müssen wir mit Awaitility pollen, bis die Prozessinstanz gestartet ist.
Wichtig zur Einordnung: Unverändert bleiben die Feature-Dateien – die Step Definitions darunter ändern. Der stabile Vertrag ist die fachliche Beschreibung, nicht der Testcode.
Das Ergebnis: mvn test -pl c8-app – 5 Tests, 0 Failures, 0 Errors. Alle fünf Szenarien grün. Die Fachlichkeit ist intakt.
Der C8 Coverage Report, hier mit einem selbst entwickelten Report-Generator erzeugt, da es für Camunda 8 (noch) kein fertiges Pendant zum C7-Coverage-Tooling gibt, zeigt dasselbe Bild wie der C7-Report: Alle Pfade wie vorher abgedeckt, alle Elemente grün. Die Migration ist fachlich korrekt.
Es geht nicht auf Anhieb: drei Anläufe und Guardrails
Wer jetzt denkt, ein Prompt genügt und die KI erledigt den Rest: So einfach ist es nicht. Es hat drei Anläufe gebraucht, bis die Migration sauber durchlief. Jeder Anlauf hat Fehler produziert, die durch menschliches Review aufgedeckt und durch neue Guardrails für den nächsten Lauf verhindert wurden.
Anlauf 1: Die Error-Code-Diskrepanz
Unser Spezifikationsdokument definierte den Fehlercode für "Vertrag nicht gefunden" als CONTRACT_NOT_FOUND. Der Agent implementierte den Zeebe Job Worker brav mit genau diesem Code:
// Was der Agent beim ersten Mal schrieb:
throw new CamundaError("CONTRACT_NOT_FOUND", "Vertrag nicht gefunden");
Das Problem: Im tatsächlichen BPMN-Modell und im bestehenden C7-Code heißt der Fehlercode vertrag-nicht-gefunden. Das BPMN-Error-Element referenziert diesen Code und ein Error Boundary Event fängt nur Fehler mit exakt dem richtigen Code. Mit CONTRACT_NOT_FOUND würde der Fehlerpfad nie ausgelöst.
Was passierte: Das Code Review deckte die Diskrepanz auf. Der Agent hatte die Spezifikation korrekt umgesetzt, aber die Spezifikation selbst enthielt einen Fehler.
Guardrail für den nächsten Lauf: "Das BPMN ist die Quelle der Wahrheit. Bei Widersprüchen gewinnt immer das BPMN." Diese Regel wurde als persistente Anweisung in den Migrationsagenten eingebaut.
Anlauf 2: @JobWorker existiert nicht in 8.9.0
Der Agent kannte das Spring-Boot-Camunda-SDK und versuchte, die elegante, annotationsbasierte Lösung zu verwenden:
// Was der Agent beim ersten Mal schrieb:
@JobWorker(type = "schadenAnlegen")
public Map<String, Object> schadenAnlegen(@Variable(name = "ext_schaden") Schaden schaden) {
// ...
}
Das Problem: Die Dependency camunda-client-java:8.9.0 ist der Low-Level-Client ohne Spring-Support. Die @JobWorker-Annotation gehört zum camunda-spring-boot-starter . In realen Projekten die erste Wahl, in unserem Setup aber nur als 8.10.0-SNAPSHOT verfügbar und nicht mit dem 8.9.0-Client kompatibel. mvn compile schlug fehl: Die Annotation existierte schlicht nicht im Classpath.
Was passierte: Rollback. Architektur-Pivot zu einer manuellen Worker-Registrierung über eine eigene ZeebeWorkerRegistry-Klasse, die beim ApplicationReadyEvent alle Worker per CamundaClient.newWorker().jobType(...).handler(...).open() registriert.
Guardrail für den nächsten Lauf: "Verwende io.camunda.client.CamundaClient (nicht ZeebeClient) und manuelle Worker-Registrierung via JobHandler-Interface. Keine @JobWorker- oder @ZeebeWorker-Annotationen."
Anlauf 3: Spring-Properties in BPMN-Timern
Der Agent externalisierte die Timer-Ausdrücke im BPMN, aber auf die falsche Art:
<!-- Was der Agent beim ersten Mal schrieb: -->
<bpmn:timerEventDefinition>
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">
${sla.timer.duration}
</bpmn:timeDuration>
</bpmn:timerEventDefinition>
Das Problem: ${sla.timer.duration} ist ein Property-Placeholder im JUEL-/Spring-Stil – in Camunda 7 konnte die eingebettete Engine solche Ausdrücke über den Spring-ApplicationContext auflösen. Zeebe ist eine Remote Engine: Sie hat keinen Zugriff auf den ApplicationContext der Prozessanwendung, versteht ausschließlich FEEL und wirft einen Deployment-Fehler.
Was passierte: Rollback. Die korrekte Lösung in Camunda 8 ist eine FEEL-Expression über eine Prozessvariable.
<!-- Korrekte Lösung: -->
<bpmn:timerEventDefinition>
<bpmn:timeDuration xsi:type="bpmn:tFormalExpression">
=slaTimerDuration
</bpmn:timeDuration>
</bpmn:timerEventDefinition>
Die Variable slaTimerDuration wird jetzt nach der Migration beim Prozessstart als Prozessvariable übergeben. Im Test-Profil ist das PT3S, in Produktion PT10M. Die Spring-Konfiguration steuert den Wert, wie schon vorher. Neu ist, dass die Prozessanwendung ihn beim Start als Variable mitgibt, statt dass die Engine ihn zur Laufzeit auflöst.
Guardrail für den nächsten Lauf: "Zeebe kann keine ${...}-Ausdrücke (JUEL bzw. Spring-Properties) in BPMN-Timern auflösen. Timer müssen als FEEL-Expressions über Prozessvariablen definiert werden (=variablenName). Die Variable wird beim Prozessstart injiziert."
Die Lektion
KI-Entscheidungen brauchen Reviews! Ein Agent ist nicht unfehlbar. Er arbeitet mit dem Kontext, den man ihm mit gibt. Wenn der Kontext unvollständig oder widersprüchlich ist (wie bei unserem Error-Code), produziert er konsistenten, aber falschen Code. Wenn er auf veraltete Dokumentation oder falsche SDK-Annahmen trifft, scheitert er an der Realität.
Der Schlüssel liegt im iterativen Vorgehen:
Agent ausführen – Code generieren lassen
Review durchführen – menschliches Auge auf die Ergebnisse
Guardrails definieren – die Erkenntnis als persistente Regel für den nächsten Lauf verankern
Erneut ausführen – diesmal mit der Leitplanke
Jede nicht-triviale Entscheidung wird dabei in einem Agent Transcript dokumentiert. Dieses Transcript ist sowohl Audit-Trail als auch Wissensquelle für zukünftige Läufe.
Das Ergebnis
Am Ende steht eine vollständig migrierte Camunda-8.9-Prozessanwendung:
10 Zeebe Job Worker implementiert (8 ehemalige Delegates + 1 External Task Worker + 1 Execution Listener)
1 BPMN-Modell komplett auf
zeebe:-Namespace migriert, mit FEEL-Bedingungen und mit externalisierten Timern2 DMN-Tabellen für Camunda 8.9 adaptiert
Step Definitions vollständig von der Camunda-7-REST-API auf CamundaClient + Awaitility portiert
5 BDD-Szenarien grün auf der neuen Engine
Feature-Dateien unverändert übernommen
Service Layer unverändert – die Integration mit den Umsystemen ist identisch geblieben
WireMock-Stubs unverändert – dieselben JSON-Dateien in beiden Anwendungen
Wie viel Arbeit steckt darin? Ein Blick allein auf die Test-Stage macht es konkret: Die Step Definitions mussten von der synchronen C7-REST-API auf den asynchronen CamundaClient mit Awaitility umgeschrieben werden (~350 Zeilen), dazu kamen ein eigener Polling-Client gegen die Operate-API (~180 Zeilen), das selbst entwickelte Coverage-Tooling (~250 Zeilen) und die Stabilisierung der Szenarien gegen Timer- und Eventual-Consistency-Effekte. Manuell schätzen wir das für erfahrene Entwickler, die die C8-APIs erst kennenlernen auf 5 bis 8 Personentage, nur für die Tests. Der Agent hat es in wenigen Stunden erledigt, verteilt auf die drei Anläufe. Rechnet man BPMN-, DMN- und Worker-Migration hinzu, wäre der rein manuelle Weg bei diesem überschaubaren Beispielprozess im niedrigen zweistelligen PT-Bereich gelandet. Bei realen Prozesslandschaften entsprechend mehr. Nicht auf Anhieb, nicht fehlerfrei, aber mit jedem Anlauf schneller, präziser und durch Guardrails und BDD abgesichert.
Das bedeutet nicht, dass man den Agenten blind vertrauen kann. Es bedeutet, dass die Kombination aus klarer Spezifikation (was soll rauskommen?), iterativem Review mit Guardrails (was hat der Agent falsch gemacht und wie verhindern wir das beim nächsten Mal?) und BDD als Sicherheitsnetz (stimmt die Fachlichkeit noch?) den Migrationsaufwand drastisch reduziert.
Ausblick
Die Migration ist die Voraussetzung, nicht das Ziel. Erst wenn Prozesse auf Camunda 8 laufen, können Organisationen die neuen KI-Features nutzen: Agentic Subprocesses, dynamische Entscheidungsfindung, intelligente Eskalation ...
Unser Ansatz zeigt: Es ist machbar. Nicht trivial, nicht auf Knopfdruck, aber mit der richtigen Methodik und den richtigen Werkzeugen deutlich weniger Aufwand.
Zusammenfassung
| Migrationsplan erstellen | KI-Agent im Assessment-Modus, Risiko- und Gap-Register, keine Code-Änderungen |
| Migration durchführen | Spezialisierte KI-Agenten mit Skills für BPMN, DMN, Glue-Code und Tests |
| Fachlichkeit sichern | BDD-Szenarien als stabiler Vertrag – ändern sich nicht zwischen Engine-Versionen |
| Qualität sicherstellen | Feature-Dateien unverändert, Coverage 100 %, alle Szenarien grün |
| Aus Fehlern lernen | Iterative Anläufe, menschliches Review, Guardrails als persistente Regeln |
Du stehst vor einer ähnlichen Herausforderung und möchtest über unsere Erfahrungen diskutieren oder Unterstützung bei deiner Camunda-Migration erhalten? Schreib uns gerne an. Wir melden uns!
Oder diskutiere direkt mit uns vor Ort: Wir organisieren die Camunda Chapter Münster und Rheinland – dort treffen sich Camunda-Anwender regelmäßig zum Erfahrungsaustausch, auch zu Migrations- und KI-Themen.