
048: ABAP - ADT for VS Code (Part 4)
Wie gelingen dir die ersten Schritte mit ABAP in Visual Studio Code? In dieser Folge schauen wir uns einige Beispiele im Agentic AI und RAP Umfeld an. Dabei schauen wir auch auf einige Punkte, die nch zubeachten sind.
Inhaltsverzeichnis
In der letzten Folge hatten wir Agentic AI in unserem System eingerichtet und einen ersten Testlauf mit einer Klassengenerierung durchgeführt. In dieser Folge werden wir uns weitere Beispiele anschauen und zum Abschluss noch ein paar Hinweise mitgeben, auf welche Dinge du achten solltest, wenn du mit Agentic AI in deinem System arbeitest. Zum Schluss werden wir die Session abschließen und eine kurze Zusammenfassung über das komplette Thema geben, wie es mit VS Code weitergeht.
Unit Test
Für das nächste Beispiel wechseln wir die Klasse und schauen uns den Datenbank-Reader an. Hierbei handelt es sich um eine kleine Klasse, die zwei Methoden zur Verfügung stellt, die Daten lesen. Im ersten Fall lesen wir die Business Partner und fünf Zeilen daraus aus. Im zweiten Beispiel lesen wir eine Language-Konfiguration hier über den Schlüssel, den wir in die Methode geben. Dazu wechseln wir in die Testklasse und geben dem LLM mit, dass wir eine Testklasse anlegen wollen und dabei alle Methoden in der Klasse testen wollen. Wie zuvor schaut sich nun der Agent an, was wir eigentlich von ihm wollen, liest die eigentlichen Objekte und die Typen davon aus und fängt dann an, sich die nächsten Schritte zu überlegen.
Dabei fängt der Assistent an zu arbeiten und überlegt sich, den SQL-Double zu verwenden, welcher in diesem Fall komplett richtig ist. Daraufhin generiert er ersten Testcode, der soweit erst mal in Ordnung aussieht. Wir sehen hier allerdings auch, dass es bereits eine Fehlermeldung gibt, und die Fehlermeldung verweist darauf, dass der Name der Methode zu lang ist und dieser gekürzt werden muss. Anhand der Fehlermeldung und der Nicht-Aktivierbarkeit erkennt das LLM sofort den Fehler und beginnt mit der Korrektur des Codes. Wie immer bestätigen wir alle Änderungen, die das Large Language Modell durchführt. Hier ist unsere letzte Chance, noch einmal per Review über die Änderungen zu schauen. Als Nächstes findet das LLM immer noch einen Fehler in den Daten. Es sieht, dass es eine Identifikation nicht ordentlich setzen kann. Hier ist das Modell davon ausgegangen, wenn wir mit einem Language-Objekt oder einer Language-Tabelle arbeiten, dass wir dann auch entsprechende Language Keys übergeben. Nun versucht das Modell, den Core Data Service zu lesen und herauszufinden, woran das Problem liegt. Allerdings wird das Modell keine Lösung finden, denn der Core Data Service ist nicht im Scope der aktuell eingebundenen Pakete. Damit kann es keine Informationen erhalten, wie die Sprache aufgebaut ist.
Da wir nun sehen, dass das Modell sich im Kreis dreht, geben wir eine weitere Information mit, damit der Agent nun den Test vollständig abschließen kann. Dazu sagen wir, dass die Identification vom Typ UUID ein Raw-16-Feld ist, damit es weiß, dass es hier UUIDs erzeugen muss, um den Schlüssel sauber zu befüllen. Das Modell reagiert auf unseren Kommentar und baut eine Methode ein, um die Schlüsselfelder nun generieren zu können. Sind die Änderungen dann am Ende durchgeführt, sehen wir, dass die Klasse wieder aktiviert werden kann. Beim Ausführen der Unit-Tests merkt das Modell allerdings auch, dass die verwendeten Typen nicht korrekt sind, denn der SQL-Double benötigt die Datenbanktypen und nicht die definierten Typen aus der Klasse. Hier haben wir lokale Typen der Einfachheit halber und zur Verwendung angegeben, für den Unit-Test muss allerdings der Original-Datenbanktyp angegeben werden. Der Agent tauscht zum Abschluss auch diesen Typen aus und aktiviert die Klasse. Dann führt er auch alle Unit-Tests aus. Diese sind nun auf Grün und wir erhalten ein Ergebnis. Der Loep des Agenten ist abgeschlossen.
RAP Generator
Im nächsten Beispiel wollen wir ein RAP-Objekt generieren. Dabei verwenden wir dieses mal einen vorgeschriebenen Prompt, den wir einfach einfügen. Wir geben an, dass wir eine RAP-Applikation erzeugen wollen, in welchem Paket wir diese erzeugen wollen und welchen Präfix wir benutzen. Grundsätzlich wird im Hintergrund der klassische RAP-Generator "from scratch" verwendet, um das Objekt zu erzeugen. Deshalb ist der Präfix auch wichtig. Dabei geben wir Informationen mit, dass wir eine RAP-Entität haben wollen, die Informationen für eine Dokumentation enthält und Felder wie Titel, Beschreibung, Langtext, Ersteller und Review beinhalten soll. Am Ende geben wir ihm noch eine weitere Information mit, dass wir nämlich die UUID Felder und administrativen Felder im UI ausblenden wollen. Normalerweise generiert der RAP-Generator diese Informationen mit, und wir erhalten ein überladenes UI und haben sehr viele Informationen, die wir eigentlich vor unserem Endanwender verstecken wollen.
Der Agent beginnt mit der Arbeit im System und fragt erst einmal ab, auf welchem System wir arbeiten. Als nächstes möchte er dann erst mal eine Liste der RAP-Generatoren auf dem System haben. Das erlauben wir ihm, das heißt, er holt sich erst mal eine Liste der möglichen RAP-Generatoren. Im Anschluss möchte dieser dann wissen, welches Schema der RAP-Generator benötigt, um zu funktionieren. Daraufhin baut das Large Language Modell das entsprechende Schema auf, definiert die ersten Felder und übergibt dann das Schema an den RAP-Generator, um die Objekte zu erzeugen. In diesem Fall arbeitet dann auch nicht mehr das Large Language Modell, sondern die Generierung passiert allein über den RAP-Generator, was semantisch korrekt ist und damit auch weniger Token verbraucht, als wenn unser Agent jedes Objekt einzeln und per Hand anlegen würde. Grundsätzlich eine interessante Idee zur Optimierung der Prozesse im Kontext von Agenten. Die Generierung des Objektes dauert dann einige Minuten, bevor die Objekte konsistent im System angelegt sind.
Ist der RAP-Generator dann fertig, sind die Objekte im System angelegt und wir können uns zum Beispiel auch den Service anschauen. Gleichzeitig arbeitet der Agent im Hintergrund weiter, um die UI-Felder und die Admin-Felder im UI auszublenden. Dazu navigieren wir neben dem Service schon einmal in die Metadata Extension, wo wir dann erwarten, dass Änderungen vorgenommen werden. Nachdem die Änderungen vorgenommen wurden, sehen wir bereits, dass das "hidden" auf "true" gesetzt wurde. Scrollen wir nach unten, finden wir auch die anderen administrativen Felder, die ebenfalls nun versteckt sind. Somit sollten sie in der Oberfläche nicht mehr aktiv angezeigt werden. Zum Abschluss gehen wir dann in das Service Binding und klicken auf die Inline-Action für Publish, um den Veröffentlichungsvorgang des Services anzustoßen. Im Gegensatz zu Eclipse gibt es hier keinen eigenen Button, sondern Inline werden bestimmte Aktionen angezeigt, um dann die Veröffentlichung anzustoßen. Im unteren Bereich findest du Informationen, dass der Prozess aktuell noch am Laufen ist.
Ist dann die Aktivierung des Services abgeschlossen, finden wir direkt über der Service-Definition den Preview-Button und können den Preview unserer Fiori-Elements-Anwendung starten. Dabei werden wir innerhalb von VS Code noch gefragt, welche Entität wir starten wollen; hier ist bereits die Leading Entity oben vorgeschlagen. Entsprechend sehen wir nun unsere Anwendung im UI. Wir finden nur noch entsprechende Felder vor, die wir auch befüllen können. Legen wir dazu erst einmal einen neuen Datensatz an und geben einige Grundinformationen mit. Hier fällt auf, dass das Modell uns einen sehr kurzen Schlüssel für den Titel definiert hat mit nur 10 Characters. Grundsätzlich funktioniert aber die Anlage von neuen Datensätzen und auch die Visualisierung im UI.
RAP Validierung
Allerdings fällt im Moment auch auf, dass wir auch leere Datensätzen anlegen können, was eigentlich nicht so praktisch ist. Deshalb wollen wir das Objekt noch einmal über den Agenten erweitern lassen und eine Validierung aufnehmen, die prüft, dass gewisse Pflichtinformationen befüllt sind. Dazu wechseln wir zurück in unseren Editor und gehen noch einmal mit dem Agenten in den Chat. Wir öffnen dazu die Behavior-Definition und geben damit dem Large Language Modell einen gewissen Kontext. Danach befüllen wir unseren Prompt und sagen, dass wir den Titel, die Beschreibung und den Ersteller als "mandatory" definiert haben wollen. Zusätzlich soll er noch eine Validierung erstellen, die prüft, dass diese Felder auch wirklich befüllt sind. Denn grundsätzlich könnten wir zwar Felder auf "mandatory" setzen, die Prüfung müssen wir allerdings trotzdem immer wieder selber durchführen, da das Framework auf diese Kennzeichen nur im UI reagiert.
Als Nächstes beginnt der Agent damit, die aktuelle Verhaltensdefinition zu analysieren, und fängt dann bereits an, erste Änderungen vorzunehmen. Er fügt die Felder ein, die dann auf "mandatory" definiert wurden, und ebenfalls eine Validation, die eingefügt wird. Wir sehen auch, dass es noch erste Fehler gibt, denn die Felder wurden auch mit einem Update-Flag versehen. Das LLM merkt das und ändert dann die Felddefinition auf "mandatory" und entfernt dabei den Status. Im nächsten Schritt beginnt die Implementierung der Validierung, die ebenfalls auch noch einmal in die Prepare Action übernommen wird, sodass die Validierung auch während des Drafts stattfindet. Navigieren wir dann in die Implementierung, sehen wir, dass diese angelegt wurde. Entsprechende EML-Statements wurden ausgeführt. Es wird über die Daten geloopt und pro Feld geprüft, ob die Inhalte auch entsprechend befüllt sind. Dann werden auch Meldungen erzeugt, sodass der User im UI Fehlermeldungen erhält, wenn er eine leere Instanz anlegen möchte.
Zum Abschluss wechseln wir noch einmal ins UI. Wir sehen, dass die Felder nun als Pflichtfelder definiert sind, und wir versuchen, einen leeren Datensatz anzulegen. Wir erhalten dabei drei Fehlermeldungen; diese Fehlermeldungen hatten wir über den Agenten anlegen lassen. Damit ist auch eine Validierung sichergestellt, dass wir keine leeren Datensätze anlegen, sondern nur Informationen, die wir dann weiterverarbeiten können.
Achtungspunkte
Auf einige Punkte wollen wir allerdings noch einmal eingehen, wenn es um die Arbeit mit Agenten innerhalb eines echten produktiven beziehungsweise Entwicklungssystems eines Kunden geht. Dabei muss man immer darauf hinweisen, dass SAP-Ressourcen zentral sind; sobald sie gespeichert und aktiviert sind, liegen sie im System und sind damit aktiv für jeden anderen Benutzer. Grundsätzlich sollten wir KI-generierten Code vorher prüfen, bevor wir ihn in die Test- und Produktionsumgebungen schieben. Das heißt, hier sollte ein Review-Prozess durch den Entwickler oder einen zweiten Entwickler durchgeführt werden.
Im Umgang mit der Versionshistorie ist zu beachten: Wenn ein Objekt neu generiert wird, gibt es keine Versionshistorie. Wurde ein bestehendes Objekt angepasst, dann gibt es höchstwahrscheinlich eine Versionshistorie, aber nur zu dem Stand, wann ein Export erfolgt ist. Das heißt, eine Wiederherstellung der Version ist entweder gar nicht oder nur teilweise möglich.
Arbeitest du mit bestehenden Objekten, solltest du auf "Explain" und "Ask" als Modus zurückgreifen oder du solltest zumindest über ein Git-Repository vorher eine Sicherung vornehmen, sodass du dann auf den Daten arbeiten kannst und eine Möglichkeit hast, zurück auf den Originalstand zu gehen, wenn dir die Ergebnisse nicht gefallen oder der Agent nicht mehr die korrekten Änderungen vorgenommen hat.
Die Arbeit mit Agenten ist vor allem sinnvoll, wenn du neue Entwicklungen anlegst, also auf der grünen Wiese beginnst, Sachen migrierst (vielleicht auf eine neue Umgebung), Unit-Tests erstellst in einer leeren Klasse oder zum Beispiel Mock-ups durchführst, die du mit deinem Fachbereich besprechen willst. Hier lohnt es sich auf jeden Fall, mit AI zu arbeiten, da du hier sehr viel Zeit sparst und es noch nicht zu 100 % korrekt sein muss.
Zusammenfassung
Fassen wir die verschiedenen Sessions noch einmal zusammen. Die erste Version des MCP-Servers für die ABAP Development Tools ist nun verfügbar und kann damit in Eclipse und VS Code genutzt werden. In Eclipse gibt es dabei noch kleinere Fehler, wenn der Server lädt und es zu Fehlermeldungen kommt. Grundsätzlich ist aber der MCP-Server die erste Anlaufstelle, wenn es um einen guten Kontext für ein LLM geht oder auch im agentischen Modus Feedback gibt, um Fehler zu bereinigen, die im Quellcode entstanden sind. Schauen wir dann auf die Features von VS Code, handelt es sich noch um einen frühen Status für die Umgebung. Das heißt, grundsätzlich ist es in der Cloud-Entwicklung schon sehr gut einsetzbar, zusammen mit Fiori als Full-Stack-Tool. Allerdings fehlt hier noch der Support für die zahlreichen Objekte, die auch in Eclipse verfügbar sind, beziehungsweise auch der Support für verschiedene Tools wie den Debugger, die Data Preview und andere Tools, die ein Entwickler im Alltag benötigt. Schauen wir auf das Thema AI, so können wir endlich auch mit Agenten arbeiten und haben verschiedene Möglichkeiten, mit Tools und dem MCP-Server mit dem System zu interagieren. Aktuelle Use Cases sind dabei vor allem die Verwendung im RAP-Kontext und die Entwicklung von Klassen, um damit die Vorteile eines Agents zu genießen und Geschwindigkeit bei der Erweiterung und der Entwicklung zu bekommen. Grundsätzlich werden die nächsten Releases zeigen, was es noch an weiteren Features gibt und wie wir auch in Zukunft dann mit Skills unseren Agenten so weit erweitern können, dass wir auch Migrationen von Altcoding in die neue Welt beginnen können.
VS Code ist noch in einem frühen Stand, das heißt, es sind noch Bugs vorhanden und es ist noch nicht so rund geschliffen wie Eclipse, doch grundsätzlich kann man erste Änderungen am Code damit durchführen. Parallel wird man eine Eclipse-Installation benötigen, um die letzten Tools immer an der Hand zu haben, die man benötigt. Doch wie die letzten Releases auch gezeigt haben, ist SAP hier sehr schnell beim Thema Patching und Nachliefern von ersten Features, sodass nun mittlerweile auch der ABAP Cleaner zum Beispiel zur Verfügung steht, aber auch Objekte wie die Funktionsgruppe, Reports und klassische Tabellen bearbeitet werden können. Damit kannst du dem Editor nun eine erste Chance geben, um damit Objekte zu bearbeiten und agentisch unterwegs zu sein. Wir bedanken uns fürs Zuschauen und bis zum nächsten Mal.
YouTube
Video