Seit meinem letzten Blog über FileMaker im Oktober 2025 hat sich die professionelle Softwareentwicklung erneut gewaltig verändert. Hier stelle ich zwei Bereiche vor, wo ich für meine FileMaker Apps KI sinnvoll und effizient einsetzen kann.
- Skripts für Anfragen an einen lokalen KI-Server
- Entwicklung von Skripts mit KI in der Form von XML-Code
Ich verwende FileMaker seit über dreissig Jahren, ein eigener Server schnurrt stabil vor sich hin. Der Code für die Apps ist über lange Zeit in der Praxis für die Praxis entwickelt. Viele Module, welche vor allem in der Zahnarztpraxis zum Einsatz kamen, verwende ich kaum noch. Aber die Datenbanken für Korrespondenz, Buchhaltung und Steuern sind noch regelmässig im Einsatz. Unterhalt ist kaum nötig ausser den regelmässigen Updates und dem Zertifikat für den Server. Wenn ich die Funktionen massiv umbauen würde, sind andere Tools welche die gesamte Codebasis mit KI verwalten können, wohl besser geeignet.
Durch meine Arbeit bei der PopNet Informatik AG und bei der Kaformatik AG habe ich auch Einblick in Projekte der professionellen Softwareentwickler. Die Herangehensweise hat sich dort in den letzten Monaten, wegen der KI-Tools, radikal verändert.
Ein stabiler Unterbau ist jedoch nach wie vor nötig und benötigt fundiertes Wissen und Erfahrung. FileMaker ist in diesem Bereich nach wie vor gut aufgestellt. Entscheidend für zukünftige Projekte wird aber die Integration von KI-Entwicklungs-Tools sein. Für zeit- und kosteneffiziente Entwicklung muss Claris das Produkt noch deutlich verbessern.
Um die Situation mit FileMaker besser einordnen zu können, hier einige Überlegungen zum aktuellen Fortschritt der KI-Softwareentwicklung und zur Low-Code-Philosophie von FileMaker.
Quellen
FileMaker Forum
https://filemaker-magazin.de/forum/
ISO FileMaker Magazine, Matt Petrowsky
https://www.filemakermagazine.com/
agentic-fm, Matt Petrowsky
https://github.com/petrowsky/agentic-fm
Monkeybread Software, Christian Schmitz
https://www.monkeybreadsoftware.com/filemaker/
Using LM Studio as a local LLM for FileMaker AI Development
https://www.geniewave.com/blog/using-lmstudio-as-a-local-llm-for-filemaker-2024-development
Evolution der Softwareentwicklung
(Diskussion mit Gemini)
Eröffnet habe ich den Chat mit diesem Prompt:
erkläre den fortschritt der softwareentwicklung
mit ungefährer zeitangabe:
- code completion
- vibe coding
- agentic engineeringDie wichtigsten Punkte habe ich mir als Tabellen darstellen lassen:
Evolution der Softwareentwicklung mit KI
| Phase | Ungefährer Zeitraum | Rolle des Menschen | Rolle der KI |
|---|---|---|---|
| Code Completion | 1990er – heute | Schreibt 90% des Codes selbst, nutzt KI als Tipphilfe. | Passiver Assistent (schlägt Wörter/Zeilen vor). |
| Chat-driven | 2022 – heute | Denkt Architektur aus, kopiert KI-Codebausteine zusammen. | Berater und Text-Generator für Code-Snippets. |
| Vibe Coding | 2024 – heute | Beschreibt Konzepte, steuert Design und Logik per Sprache. | Übersetzer von Idee zu fertiger, visueller App. |
| Agentic Engineering | 2025 – Zukunft | Definiert Geschäftsziele, überwacht und reviewt Agenten. | Autonomer Softwareentwickler (sucht Fehler, testet, repariert). |
Dass die gesamte Codebasis (das Repository) als Kontext für das LLM dient, ist keine plötzliche Erfindung, sondern das Ergebnis einer technologischen Evolution, die zwischen Ende 2023 und Mitte 2024 ihren kommerziellen Durchbruch feierte.
Zuvor konnten LLMs immer nur "häppchenweise" (einzelne Dateien oder Funktionen) gefüttert werden. Die Entwicklung lässt sich in zwei technologische Wellen unterteilen:
Die Codebasis ist seit Anfang 2024 der native Kontext für LLMs. Erst diese Entwicklung hat den Weg für das heutige Vibe Coding und Agentic Engineering freigemacht, da ein KI-Agent ohne das Verständnis des gesamten Projekts keine autonomen Entscheidungen treffen könnte.
Zeitstrahl der Kontext-Evolution in der Softwareentwicklung
| Zeitraum | Ära / Phase | Funktionsweise & technologischer Hintergrund | Reichweite des KI-Gedächtnisses |
|---|---|---|---|
| Bis Mitte 2023 | Einzel-Datei-Fokus (Code Completion) | LLMs (wie GPT-3.5) haben winzige Kontextfenster (4k–8k Token). Sie sehen meist nur die Datei, in der du gerade tippst. Alles andere im Projekt existiert für sie nicht. | Isoliert: Nur die aktuelle Datei oder der geöffnete Tab. |
| Herbst 2023 | Die RAG-Ära (Der @workspace-Befehl) |
Tools beginnen, Codebasen im Hintergrund zu indizieren. Über Befehle wie @workspace in Editoren wie Cursor sucht sich die KI relevante Schnipsel zusammen. |
Fragmentiert: Relevante Code-Häppchen aus dem Projekt (Suchbasiert). |
| Februar 2024 | Das Millionen-Token-Fenster | Google knackt mit Gemini 1.5 Pro die Grenze. Ganze Codebasen passen nun nativ am Stück in den Prompt. Das LLM versteht plötzlich globale Architekturzusammenhänge. | Ganzheitlich: Das komplette Repository inklusive aller Ordnerstrukturen auf einmal. |
| 2025 / 2026 | Agentic Context Engineering | Heutiger Standard: Kontext-Fenster sind riesig und LLMs nutzen spezialisierte Tools (Call-Graph-Analysen, Compiler-Feedback), um sich autonom und präzise durch die gesamte Codebasis zu navigieren und sie zu verändern. | Interaktiv & Autonom: Die KI liest, versteht, testet und manipuliert das gesamte Projekt selbstständig. |
FileMaker als Low-Code Plattform
Auch hier ist die Interaktion mit Gemini Basis für den Text. Start Prompt:
beschreibe die low-code entwicklungsumgebung von filemakerDa man in FileMaker Logiken durch das Auswählen und Zusammenklicken vordefinierter Bausteine erstellt, spricht man im Englischen auch treffend von Click-based Programming oder Drag-and-Drop Development.
Hier ist eine genaue Beschreibung, wie diese Entwicklungsumgebung funktioniert und was sie so besonders macht:
Die FileMaker-Entwicklungsumgebung: So funktioniert das "Klicken"
FileMaker bricht mit dem klassischen Paradigma, bei dem man Codezeile für Zeile in eine leere Textdatei tippt. Die Umgebung ist extrem datenbankzentriert und teilt sich im Wesentlichen in drei visuelle Säulen auf:
1. Der Beziehungsgraf (Datenbankdesign per Maus)
Statt SQL-Befehle wie SELECT * FROM table JOIN... zu schreiben, werden Tabellen in FileMaker als visuelle Boxen dargestellt.
- Das Klick-Prinzip: Du ziehst mit der Maus eine Linie von einem Datenfeld (z. B.
Kunden_ID) zum Feld einer anderen Tabelle (z. B.Rechnungs_KundenID). Damit steht die relationale Datenbankbeziehung – komplett ohne Code.
2. Der Script-Workspace (Logik per Klick)
Die eigentliche "Programmierung" von Abläufen geschieht im sogenannten Script-Workspace.
- Das Klick-Prinzip: Auf der linken Seite hast du eine Liste von hunderten fertigen Befehlen
(z. B. Schreibe in Feld, Gehe zu Layout, Wenn / Falls). Per Doppelklick oder Drag-and-Drop schiebst du diese Befehle in dein Script. - Syntax-Sicherheit: Da du die Befehle klickst, statt sie einzutippen, gibt es in FileMaker so gut wie keine klassischen Syntaxfehler (wie ein vergessenes Semikolon
;oder ein Tippfehler im Befehl). Das System lässt dich oft nur gültige Parameter über Dropdown-Menüs auswählen
3. Der Layout-Modus (Das Auge programmiert mit)
In FileMaker sind die Benutzeroberfläche (UI) und die Programmierlogik extrem eng miteinander verzahnt.
- Das Klick-Prinzip: Du ziehst Felder, Buttons oder Diagramme direkt auf eine Leinwand. Per Rechtsklick definierst du, was passiert: "Wenn dieser Button geklickt wird, starte Script X".
Die Vor- und Nachteile dieses Ansatzes
| Vorteile | Nachteile |
|---|---|
| Enorme Geschwindigkeit: Prototypen und fertige Business-Apps entstehen in Tagen statt Monaten (Rapid Application Development). | Eingeschränkte Flexibilität: Man ist an die UI-Elemente und Logiken gebunden, die FileMaker zur Verfügung stellt. |
| Geringe Einstiegshürde: Perfekt für "Citizen Developer" (Fachkräfte aus der Praxis, die keine gelernten Informatiker sind). | Proprietäres Ökosystem: Der "Code" lässt sich nicht einfach exportieren und auf einer anderen Plattform ausführen. |
| Sicherheit: Kaum Abstürze durch klassische Tippfehler im Code. | Schwer versionierbar: Da es kein reiner Text ist, lassen sich Änderungen schwer mit klassischen Tools wie Git tracken. |
Nuance – Ganz ohne Text geht es nicht: Auch wenn FileMaker eine Low-Code-Umgebung ist, besitzt es für komplexe Berechnungen die sogenannte Formel-Engine (Calculation Engine). Wenn du tiefere Logiken brauchst (z. B. eine Mehrwertsteuer-Berechnung abhängig vom Bundesland), tippst du dort mathematische oder textbasierte Formeln ein – ähnlich wie man es von komplexen Excel-Formeln kennt.
Anbindung an LM Studio KI-Server
Skriptbefehl: Aus URL einfügen
Die Abfrage erfolgt mit dem Skriptbefehl 'Aus URL einfügen'. Dazu werden folgende Variablen verwendet:
$input, $jsonPayload, $url, $curl. Die Übermittlung erfolgt an $url, mit den Daten $jsonPayload. Die Antwort wird dann in die Variable $response geschrieben.
Variable setzen [ $input ; Wert: Journal::Text
]
Variable setzen [ $jsonPayload ; Wert:
JSONSetElement ( "" ;
["model" ; "openai/gpt-oss-120b" ; JSONString ];
["messages[0].role" ; "system" ; JSONString ];
["messages[0].content" ; "Du bist ein präziser Buchhaltungs-Assistent.
Deine Aufgabe ist es, ausschliesslich die reine Kontonummer
auszugeben. Schreibe niemals Sätze oder Erklärungen." ; JSONString ];
["messages[1].role" ; "user" ; JSONString ];
["messages[1].content" ; "Suche die passende Nummer zum TEXT:
" & $input & "aus dem KONTENPLAN: " & $$KONTENPLAN & ".
Gib NUR die reine 4-stellige Nummer zurück.
Wenn du absolut nichts Passendes findest, gib ein
einzelnesZeichen * zurück." ; JSONString ];
["max_tokens" ; 8000 ; JSONNumber ];
["stream" ; Falsch ; JSONBoolean ]
)
]
Variable setzen [ $url ; Wert:
"http://192.168.16.45:1234/v1/chat/completions"
]
Variable setzen [ $curl ; Wert:
"--request POST
--header \"Content-Type: application/json\"
--data " & Zitat($jsonPayload)
]
Aus URL einfügen [ Auswahl ; Mit Dialog: Aus ;
Ziel: $response ; $url ; cURL-Optionen: $curl
]
| Variable | Herkunft / Berechnung | Zweck |
|---|---|---|
$$KONTENPLAN |
Statischer Textblock (CSV-Format) | Enthält die Liste aller Kontonummern und Kontenbezeichnungen. |
$input |
Journal::Text oder KassePraxis::Text |
Holt den Buchungstext aus der aktuellen Tabelle (abhängig vom Layoutnamen). |
$jsonPayload |
JSONSetElement ( "" ; ... ) |
Baut das JSON-Objekt für den API-Request (Modell, System- und User-Prompt für LM Studio) zusammen. |
$url |
http://192.168.16.45:1234/ v1/chat/completion |
Der lokale API-Endpunkt deines LM Studio Servers. |
$curl |
"--request POST --header ... --data " & Zitat($jsonPayload) |
Die cURL-Optionen für den HTTP-Post-Request inkl. des maskierten Payloads. |
$response |
Ergebnis aus 'Aus URL einfügen' | Speichert die JSON-Antwort des lokalen LLMs (wird danach via JSONGetElement ausgelesen). |
FileMaker Skript via XML der KI zuführen
MBS-Plugin
FileMaker basiert auf XML. Datenbanken/Apps können vollständig als XML exportiert werden. Dennoch ist FileMaker aktuell nicht für effektive Softwareentwicklung mit agentischen Systemen konzipiert.
Bei bestehenden FileMaker Projekten muss im Moment häufig evaluiert werden, ob eine alternative Softwareplattform besser geeignet ist. Bei komplexen Systemen mit Anbindung an externe Schnittstellen, wird die Überführung in Systeme mit besserer KI-Unterstützung vermutlich mittelfristig kostengünstiger ausfallen. Die Erweiterung um zusätzliche Funktionalität wird so massiv erleichtert und ist um Faktoren günstiger.
Einzelne Module wie Skripts können aber sehr wohl mit KI erstellt, analysiert oder verbessert werden.
Dazu ist jedoch das MBS-Plugin von Monkeybread Software nötig, quasi der Industriestandard für FileMaker Erweiterungen.
Hier ein Beispiel für die Entwicklung eines Skripts mit KI.
FileMaker Skript für die automatische Kontierung in einer einfachen Buchhaltungslösung
Journal

Die Buchungen importiere ich per CSV Datei in FileMaker. Damit ich die Kontierung nicht manuell durchführen muss, habe ich diese mit einem Skript automatisiert. Dabei wird der Buchungstext mit dem Kontenplan an die lokale KI übergeben. Hier verwende ich das GPT-OSS-120b Modell in LM Studio auf einem Mac Studio als Server. Als Antwort kommt ein vierstelliges Konto zurück. Das Skript läuft in einer Schleife, so werden alle aufgerufenen Datensätze in einem Rutsch kontiert.
Skript
Bildschirmfoto

Skript in Textform
(nicht ausführbar, dient nur der Dokumentation)
# ki_abfrage_insert_from_url_v2 in file KassePraxis (fm.zahnarztportmann.ch)
#
# https://www.geniewave.com/blog/using-lmstudio-as-a-local-llm-for-filemaker-2024-development ➜🌍
#
# KONTENPLAN
Variable setzen [ $$KONTENPLAN ; Wert: "1000,Kasse, 1010,Post Kto. 87-286570-8, 1015,Post Kto. 92-306630-2, 1022,BEKB 42 9.371.986.64 , 1100,Forderungen aus Leistungen , 1109,Wertberichtigung Forderungen , 1035,Erneuerungsfonds Praxis , 1176,Guthaben Verrechnungssteuer , 1210,Vorräte Medikame…" ]
#
Gehe zu Datens./Abfrage/Seite [ Erste(r) ]
Schleife (Anfang) [ Flush: Immer ]
#
# Datei KassePraxis.fmp12 hat Tabelle 'KassePraxis' und 'Journal'
# Feldwerte müssen immer in der korrekten Tabelle angesprochen werden
# Wenn das Layout den Text 'journal' enthält befinden wir uns in der Tabelle 'Journal'
Wenn [ MusterAnzahl ( Hole ( LayoutName ) ; "journal" ) > 0 ]
Variable setzen [ $input ; Wert: Journal::Text ]
Sonst
Variable setzen [ $input ; Wert: KassePraxis::Text ]
Ende (wenn)
#
Variable setzen [ $jsonPayload ; Wert: JSONSetElement ( "" ; ["model" ; "openai/gpt-oss-120b" ; JSONString ]; ["messages[0].role" ; "system" ; JSONString ]; ["messages[0].content" ; "Du bist ein präziser Buchhaltungs-Assistent. Deine Aufgabe ist es, ausschliesslich die reine Kontonummer ausz… ]
Variable setzen [ $url ; Wert: "http://192.168.16.45:1234/v1/chat/completions" ]
Variable setzen [ $curl ; Wert: "--request POST --header \"Content-Type: application/json\" --data " & Zitat($jsonPayload) ]
#
Aus URL einfügen [ Auswahl ; Mit Dialog: Aus ; Ziel: $response ; $url ; cURL-Optionen: $curl ]
#
Wenn [ MusterAnzahl ( Hole ( LayoutName ) ; "journal" ) > 0 ]
Feldwert setzen [ Journal::BuchungKto ; JSONGetElement ( $response ; "choices[0].message.content" ) ]
Sonst
Feldwert setzen [ KassePraxis::BuchungKto ; JSONGetElement ( $response ; "choices[0].message.content" ) ]
Ende (wenn)
#
Gehe zu Datens./Abfrage/Seite [ Nächste(r) ; Nach letztem beenden: Ein ]
Schleife (Ende)$KONTENPLAN, Auszug
"1000,Kasse,
6010,Mietaufwand,
6020,Heizung,Warmwasser,NK,Energie,
6099,Diverse Raumkosten,
6130,EDV Unterhalt,iCloud, Hetzner, Lizenz, App
6512,Kommunikation, Telefon,Swisscom, Swype, Mobile
6710,Aus- und Weiterbildung,
6720,Fachliteratur,Udemy, Patreon, Medium
8900,Steuern,
"Codierung und Analyse mit Gemini
Codierung
Funktionsfähiger Code kann im XML-Format kopiert, mit KI analysiert und verbessert werden und anschliessend wieder eingesetzt werden. In FileMaker sind oft Korrekturen nötig, da das Sprachmodell statt dem korrekten 'falsch' oder '0' beispielsweise 'falls' ausgibt. Diese Fehler werden aber visuell gut sichtbar angezeigt und können einfach korrigiert werden.
Gemini wurde mit einem 'Basisgerüst' welches die Anbindung an die KI enthielt gefüttert. Funktionserweiterung wie Unterscheidung der Tabelle via Layoutnamen oder eine Schleife um alle Datensätze zu bearbeiten, hat die KI tadellos umgesetzt.
Gesamtanalyse & Funktionsweise
Die Funktionsanalyse erfolgt hier wegen besserer Lesbarkeit mit dem Skript in Textform. Der Text ist jedoch nicht vollständig und auch nicht lauffähig, dafür eben lesbar.
Das bereitgestellte Snippet enthält ein vollständiges, funktionstüchtiges FileMaker-Skript zur automatischen Zuweisung von Buchungskonten mithilfe einer lokalen Künstlichen Intelligenz (z. B. LM Studio).
Hier ist die detaillierte Analyse und die schrittweise Erklärung, was der Code in der FileMaker-Datenbank genau macht.
Das Skript ist als automatisierter Loop (Schleife) aufgebaut. Es läuft durch eine Reihe von Datensätzen, liest den Text einer Buchung aus, verpackt diesen zusammen mit einer Schweizer KMU-Kontenliste in ein standardisiertes Datenformat (JSON) und schickt das Ganze an einen lokalen KI-Server. Die Antwort der KI (die reine Kontonummer) wird abgefangen und direkt in das passende Datenbankfeld zurückgeschrieben.
Hier ist die Schritt-für-Schritt-Erklärung des FileMaker-Skripts in reiner Textform, aufgeteilt in die logischen Abschnitte:
1. Vorbereitung (Ausserhalb der Schleife)
Code-Snippet
Variable setzen [ $$KONTENPLAN ; Wert: "1000,Kasse, 1010,Post Kto. ..." ]
Gehe zu Datens./Abfrage/Seite [ Erste(r) ]- Den Kontenplan laden: Das Skript erstellt eine globale Variable (
$$KONTENPLAN) und hinterlegt dort die komplette Liste deiner Praxis-Kontonummern und Kontobezeichnungen. Da dieser Schritt vor der Schleife steht, wird er nur einmal ausgeführt, was das Skript extrem schnell macht. - An den Start springen: Der Befehl setzt den Cursor auf den allerersten Datensatz in deiner aktuellen Liste (Fundmenge), damit die Bearbeitung ganz vorne beginnt.
2. Der Schleifen-Start
Code-Snippet
Schleife (Anfang) [ Flush: Immer ]- Die Automatisierung aktivieren: Hier beginnt die Schleife (Loop). Alle nachfolgenden Schritte werden nun automatisch für jeden einzelnen Datensatz wiederholt.
- Daten sofort sichern: Die Option
[ Flush: Immer ]sorgt dafür, dass jede Änderung an einem Datensatz sofort fest in die Datenbank geschrieben wird.
3. Dynamische Layout- und Tabellenprüfung
Code-Snippet
Wenn [ MusterAnzahl ( Hole ( LayoutName ) ; "journal" ) > 0 ]
Variable setzen [ $input ; Wert: Journal::Text ]
Sonst
Variable setzen [ $input ; Wert: KassePraxis::Text ]
Ende (wenn)- Wo bin ich?: Da deine Datei zwei Tabellen (
JournalundKassePraxis) nutzt, prüft das Skript den Namen des aktuellen Layouts. - Text auslesen: Wenn das Wort 'journal' im Layoutnamen vorkommt, holt das Skript den Buchungstext aus dem Feld
Journal::Text. Wenn du dich auf einem anderen Layout befindest, holt es den Text ausKassePraxis::Text. Der extrahierte Text wird in der lokalen Variable$inputzwischengespeichert.
4. Datenpaket für die lokale KI schnüren
Code-Snippet
Variable setzen [ $jsonPayload ; Wert: JSONSetElement ( ... ) ]
Variable setzen [ $url ; Wert: "http://192.168.16.45:1234/v1/chat/completions" ]
Variable setzen [ $curl ; Wert: "--request POST --header ... --data " & Zitat($jsonPayload) ]- Das JSON-Paket (
$jsonPayload): FileMaker baut eine strukturierte Datenanfrage für die KI. Hier wird das Modell definiert und der System-Prompt übergeben ("Du bist ein präziser Buchhaltungs-Assistent. Deine Aufgabe ist es, ausschliesslich die reine Kontonummer ausz..."). Weiter hinten im Code werden auch dein$inputund der$$KONTENPLANhineingepackt. - Die Zieladresse (
$url): Das Skript definiert die IP-Adresse deines lokalen LM Studio Servers in der Praxis. Da es im eigenen Netzwerk läuft, verlassen keine sensiblen Daten deine Praxis. - Die Verbindungsauswahl (
$curl): Hier werden die technischen Befehle für das Netzwerk definiert (POST-Anfrage, JSON-Format). Die FunktionZitatsorgt dafür, dass das JSON-Paket fehlerfrei an den Server übertragen wird.
5. KI abfragen & Antwort eintragen
Code-Snippet
Aus URL einfügen [ Auswahl ; Mit Dialog: Aus ; Ziel: $response ; $url ; cURL-Optionen: $curl ]- Senden und Warten: FileMaker schickt die Anfrage an LM Studio ab, wartet kurz, bis die KI den Buchungstext analysiert hat, und speichert die gesamte Antwort in der Variable
$callbzw.$response.
6. Kontonummer in FileMaker eintragen
Code-Snippet
Wenn [ MusterAnzahl ( Hole ( LayoutName ) ; "journal" ) > 0 ]
Feldwert setzen [ Journal::BuchungKto ; JSONGetElement ( $response ; "choices[0].message.content" ) ]
Sonst
Feldwert setzen [ KassePraxis::BuchungKto ; JSONGetElement ( $response ; "choices[0].message.content" ) ]
Ende (wenn)- Präzises Auslesen: Das Skript prüft erneut das Layout. Mit dem Befehl
JSONGetElement ( $response ; "choices[0].message.content" )greift FileMaker über die direkte Punkt-Notation blitzschnell auf die nackte Antwort der KI zu. - Wert eintragen: Das ermittelte Konto (z. B.
1000) wird direkt in das FeldBuchungKtoder korrekten Tabelle eingetragen.
7. Weiterblättern oder Beenden
Code-Snippet
Gehe zu Datens./Abfrage/Seite [ Nächste(r) ; Nach letztem beenden: Ein ]
Schleife (Ende)- Nächster Datensatz: Das Skript springt eine Zeile weiter zum nächsten Buchungssatz und startet wieder bei Schritt 3.
- Automatischer Stopp: Sobald der absolut letzte Datensatz deiner Liste verarbeitet wurde, sorgt die Option
Nach letztem beenden: Eindafür, dass die Schleife sauber stoppt und das Skript beendet wird.
Technische Feinheiten
- Datenschutz: Weil die IP-Adresse (
192.168.16.45) in deinem lokalen Netzwerk liegt, verlassen keine sensitiven Buchungsdaten oder Praxisdaten das Haus in Richtung externer Cloud-Anbieter (wie OpenAI oder Anthropic). - Fehler-Resistenz im Code: Das JSON-Parsing ist hier bereits modern gelöst: Anstatt wie in älteren Versionen zwei
JSONGetElement-Befehle ineinander zu verschachteln, greift das Skript direkt über die Punkt-Notation ("choices[0].message.content") auf das Ergebnis zu. Das verhindert Abstürze, falls die API-Antwort unerwartete Leerzeichen enthält.
XML
Skript in XML-Form. Das MBS-Plugin muss installiert sein, damit der XML-Code im Skriptbereich kopiert und eingesetzt werden kann.
<?XML version="1.0" encoding="UTF-8"?>
<fmXMLsnippet type="FMObjectList">
<Step enable="True" id="89" name="# (Kommentar)"/>
<Step enable="True" id="89" name="# (Kommentar)">
<Text>https://www.geniewave.com/blog/using-lmstudio-as-a-local-llm-for-filemaker-2024-development</Text>
</Step>
<Step enable="True" id="89" name="# (Kommentar)"/>
<Step enable="True" id="89" name="# (Kommentar)">
<Text>KONTENPLAN</Text>
</Step>
<Step enable="True" id="141" name="Variable setzen">
<Value>
<Calculation><![CDATA["1000,Kasse,
6130,EDV Unterhalt,iCloud, Hetzner, Lizenz, App
6512,Kommunikation, Telefon,Swisscom, Swype, Mobile
6599,Diverse Verwaltungskosten
6710,Aus- und Weiterbildung
6720,Fachliteratur,Udemy, Patreon, Medium
6760,Liegenschaftskosten
6799,Diverse Unkosten
6801,Abschr. Stockwerkeigentum
8900,Steuern
"]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$$KONTENPLAN</Name>
</Step>
<Step enable="True" id="89" name="# (Kommentar)"/>
<Step enable="True" id="16" name="Gehe zu Datens./Abfrage/Seite">
<NoInteract state="True"/>
<RowPageLocation value="First"/>
</Step>
<Step enable="True" id="71" name="Schleife (Anfang)">
<Restore state="False"/>
<FlushType value="Always"/>
</Step>
<Step enable="True" id="89" name="# (Kommentar)"/>
<Step enable="True" id="89" name="# (Kommentar)">
<Text>Datei KassePraxis.fmp12 hat Tabelle 'KassePraxis' und 'Journal'</Text>
</Step>
<Step enable="True" id="89" name="# (Kommentar)">
<Text>Feldwerte müssen immer in der korrekten Tabelle angesprochen werden</Text>
</Step>
<Step enable="True" id="89" name="# (Kommentar)">
<Text>Wenn das Layout den Text 'journal' enthält befinden wir uns in der Tabelle 'Journal'</Text>
</Step>
<Step enable="True" id="68" name="Wenn">
<Restore state="False"/>
<Calculation><![CDATA[MusterAnzahl ( Hole ( LayoutName ) ; "journal" ) > 0]]></Calculation>
</Step>
<Step enable="True" id="141" name="Variable setzen">
<Value>
<Calculation><![CDATA[Journal::Text]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$input</Name>
</Step>
<Step enable="True" id="69" name="Sonst">
<Restore state="False"/>
</Step>
<Step enable="True" id="141" name="Variable setzen">
<Value>
<Calculation><![CDATA[KassePraxis::Text]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$input</Name>
</Step>
<Step enable="True" id="70" name="Ende (wenn)"/>
<Step enable="True" id="89" name="# (Kommentar)"/>
<Step enable="True" id="141" name="Variable setzen">
<Value>
<Calculation><![CDATA[JSONSetElement ( "" ;
["model" ; "openai/gpt-oss-120b" ; JSONString ];
["messages[0].role" ; "system" ; JSONString ];
["messages[0].content" ; "Du bist ein präziser Buchhaltungs-Assistent. Deine Aufgabe ist es, ausschliesslich die reine Kontonummer auszugeben. Schreibe niemals Sätze oder Erklärungen." ; JSONString ];
["messages[1].role" ; "user" ; JSONString ];
["messages[1].content" ; "Suche die passende Nummer zum TEXT: " & $input & " aus dem KONTENPLAN: " & $$KONTENPLAN & ". Gib NUR die reine 4-stellige Nummer zurück. Wenn du absolut nichts Passendes findest, gib ein einzelnes Zeichen * zurück." ; JSONString ];
["max_tokens" ; 8000 ; JSONNumber ];
["stream" ; Falls ; JSONBoolean ]
)]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$jsonPayload</Name>
</Step>
<Step enable="True" id="141" name="Variable setzen">
<Value>
<Calculation><![CDATA["http://192.168.16.45:1234/v1/chat/completions"]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$url</Name>
</Step>
<Step enable="True" id="141" name="Variable setzen">
<Value>
<Calculation><![CDATA["--request POST
--header \"Content-Type: application/json\"
--data " & Zitat($jsonPayload)]]></Calculation>
</Value>
<Repetition>
<Calculation><![CDATA[1]]></Calculation>
</Repetition>
<Name>$curl</Name>
</Step>
<Step enable="True" id="89" name="# (Kommentar)"/>
<Step enable="True" id="160" name="Aus URL einfügen">
<NoInteract state="True"/>
<DontEncodeURL state="False"/>
<SelectAll state="True"/>
<VerifySSLCertificates state="False"/>
<CURLOptions>
<Calculation><![CDATA[$curl]]></Calculation>
</CURLOptions>
<Calculation><![CDATA[$url]]></Calculation>
<Text/>
<Field>$response</Field>
</Step>
<Step enable="True" id="89" name="# (Kommentar)"/>
<Step enable="True" id="68" name="Wenn">
<Restore state="False"/>
<Calculation><![CDATA[MusterAnzahl ( Hole ( LayoutName ) ; "journal" ) > 0]]></Calculation>
</Step>
<Step enable="True" id="76" name="Feldwert setzen">
<Calculation><![CDATA[JSONGetElement ( $response ; "choices[0].message.content" )]]></Calculation>
<Field table="Journal" id="4" name="BuchungKto"/>
</Step>
<Step enable="True" id="69" name="Sonst">
<Restore state="False"/>
</Step>
<Step enable="True" id="76" name="Feldwert setzen">
<Calculation><![CDATA[JSONGetElement ( $response ; "choices[0].message.content" )]]></Calculation>
<Field table="KassePraxis" id="4" name="BuchungKto"/>
</Step>
<Step enable="True" id="70" name="Ende (wenn)"/>
<Step enable="True" id="89" name="# (Kommentar)"/>
<Step enable="True" id="16" name="Gehe zu Datens./Abfrage/Seite">
<NoInteract state="True"/>
<Exit state="True"/>
<RowPageLocation value="Next"/>
</Step>
<Step enable="True" id="73" name="Schleife (Ende)"/>
</fmXMLsnippet>