filemaker

FileMaker an lokalem KI-Server

Von peter portmann,

Veröffentlicht am 24. Mai 2026   —   15 min Lesezeit

kicodeselfhostedmacos
Bild erzeugt mit KI (Gemini Nano Banana)

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 engineering

Die 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 filemaker

Da 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 (Journal und KassePraxis) 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 aus KassePraxis::Text. Der extrahierte Text wird in der lokalen Variable $input zwischengespeichert.

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 $input und der $$KONTENPLAN hineingepackt.
  • 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 Funktion Zitat sorgt 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 $call bzw. $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 Feld BuchungKto der 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: Ein dafü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>

Auf Facebook teilen Auf Linkedin teilen Auf Twitter teilen Per E-Mail senden

Newsletter abonnieren

Abonnieren Sie den Newsletter für die neusten Nachrichten direkt in Ihrem Postfach.

einschreiben