Benutzer-Werkzeuge

Webseiten-Werkzeuge


ki:oracle_mcp_database

MCP-Architektur in der Oracle Datenbank: LLM-Integration via PL/SQL und APEX

In Arbeit

Aufgabe

Native Implementierung eines Model Context Protocol (MCP)-Servers direkt innerhalb der Oracle-Datenbank – in PL/SQL mit einem eigenen Datenmodell.

Das Hauptziel dieses Architekturansatzes ist es, Large Language Models (LLMs) wie Mistral sicher und performant über ein REST-Interface anzubinden, ohne auf externe Serverkomponenten oder zusätzliche Middleware angewiesen zu sein.

Die vorgestellte Lösung nutzt ein zentrales, JSON-basiertes MCP-Interface in PL/SQL, um folgende Komponenten bereitzustellen:

  • Ressourcen: Zugriff auf Vertragsdokumente und Thesaurus-Daten.
  • Tools: Datenbanknahe Funktionen wie Vektorsuche, Chunking sowie SQL- und Graph-Abfragen.
  • Prompts: Zentral verwaltete Prompt-Templates.
  • Execution Plans: Definition einzelner Schritte und der Reihenfolge des Tool-Einsatzes.

Die gesamte Applikation ist in Oracle APEX realisiert.

Eine Orchestrierungsschicht in PL/SQL übernimmt das Mapping zwischen LLM-Anfragen und den spezifischen Datenbankfunktionen (Oracle AI Vector Search, Graph Studio, SQL).

Die Datenhaltung erfolgt in klassischen Tabellen, wodurch die Verwaltung über eine APEX-UI transparent und einfach wartbar bleibt.

Über die Ablaufsteuerung mittels Execution Plans wird gesteuert, wie ein Chat mit dem LLM ablaufen soll.

Zusätzlich zum LLM-eigenen Tool-Konzept wird hier ein eigenes Tool-Konzept für die Prompt-Analyse umgesetzt.

Ziel ist es, die Daten bereits vor der Übergabe an das LLM so aufzubereiten, dass das Modell die passenden Tools gezielter aufrufen kann.


Model Context Protocol (MCP) - eine erste Übersicht

MCP Begriffswelt:

Das Model Context Protocol (MCP) ist ein offener Standard, der es ermöglicht, KI-Modellen einen standardisierten Zugriff auf Datenquellen und Werkzeuge zu gewähren. Erkennt das LLM das für eine korrekte Antwort noch Daten fehlen, kann das LLM diese Fehlenden Daten über einen „Tools Call“ nachladen.

In diesem Szenario fungiert dazu die Oracle-Datenbank selbst als MCP-Server d.h. wir setzen die LLM Anfrage aus dem Datenbank Kern ab und das LLM kann im Chat Verlauf mit den „Tools“ weitere Daten aus der DB anfragen.

Die wichtigsten Konzepte sind dabei:

Resources (Ressourcen)

Dies sind die Daten, die das LLM einlesen kann.

In der Oracle-Welt entsprechen diese z. B. Dokumenteninhalten aus BLOB/CLOB-Spalten wie den Tarifdaten / „harte Stammdaten“ aus der Relationen Welt eines ERP System und weitere Metadaten aus dem Data Dictionary der DB.

Tools (Werkzeuge)

Unsere Tools sind Funktionen in der Datenbank, deren Aufruf die das LLM anfordern kann.

Unsere DB Ressourcen werden wir mit PL/SQL Routinen abfragen.

Prompts (Vorlagen)

Die Prompts sind vordefinierte Anweisungen oder Kontext-Templates, die das LLM bei der Aufgabenbewältigung unterstützen.

Diese werden zentral in Tabellen gepflegt, um die Logik von der Anwendung zu trennen.

Katalog (Discovery)

Der Katalog bildet die „Capabilities“ des MCP-Servers ab.

In der Datenbank-Implementierung dient eine Tabelle als Verzeichnis aller verfügbaren Werkzeuge.

  • Registry: Jedes Tool wird mit seinem Namen, einer Beschreibung für das LLM und dem erwarteten JSON-Schema der Parameter gespeichert
    • In der Registry erfolgt das Mapping der LLM Tool Definition zu den eigentlichen PL/SQL Funktionen
  • Dynamic Discovery: Beim ersten Aufruf der LLM generiert ein PL/SQL Code aus dieser Tabelle automatisch die `list_tools`-Antwort im standardkonformen OpenAI JSON-Format, damit das LLM weiß, welche Fähigkeiten es nutzen kann.

In diesem Szenario fungiert die Oracle-Datenbank selbst als MCP-Server:

Die Datenbank stellt dem LLM nicht nur Rohdaten bereit, sondern bietet über PL/SQL-Schnittstellen direkt ausführbare „Tools“ an.

Je nach aufgerufenen Interface und je nach definierten Exekution Plan behält durch diese Architektur die Datenbank die volle Kontrolle darüber, welche Informationen (Ressourcen) und Funktionen (SQL, Vektorsuche) dem Modell zur Verfügung gestellt werden, während die Kommunikation über ein einheitliches JSON-Format erfolgt.


Ablauf (Orchestrierung)

Die Schritte die für einen vollständigen Chat notwendig werden in diesem Konzept über einen Ausführungsplan (Execution Plan) Tabelle gesteuert.

Die Idee dahinter ist die User Anfrage zuvor aktiv zu analysieren (siehe Oracle 26ai – Named Entity Extraction (NER) mit CTX_ENTITY zur Analyse von Tarifvertragsanfragen mit einem Hybrid Vector Ansatz um dann einen passenden Ausführungplan aufzurufen.

Diese Plan enthält dann die entsprechenden Prompts (System / Erweiterter System Prompt ) und die Tools mit denen dann ein Chat Lauf mit dem LLM gestartet wird.

Der Prozess der LLM-Interaktion folgt einem zyklischen Muster, das durch die PL/SQL-Schicht gesteuert wird.

Phase 1 Tool-Injection (Handshake)

Bei der ersten Anfrage (JSON mit System & User Prompt) übermittelt die Datenbank mit einem JSON Record im OpenAI Format den dynamisch generierten Tool-Katalog.

Das LLM erfährt so durch die technische Definition im `tools`-Array, welche Datenbankoperationen (z. B. Dokumente suche) es ausführen kann.

Wichtig: Im System-Prompt wird explizit auf die Strategie der Tool-Verwendung hinterlegt, um Halluzinationen zu vermeiden und die Entscheidungssicherheit des Modells zu erhöhen!

Phase 2 Tool-Call Detection - PL/SQL-Orchestrierung

Die Datenbankumgebung empfängt die Antwort des Modells als JSON-Record. Die PL/SQL-Logik evaluiert nun zwei wesentliche Merkmale:

  • finish_reason: Steht dieser Wert auf stop, ist die Antwort final und kann direkt an den Benutzer in der APEX-UI ausgegeben werden.
  • tool_calls: Enthält die Antwort ein Tool-Array, hat das LLM entschieden, dass zur Beantwortung externe Daten benötigt werden.

Die Orchestrierungsschicht erkennt hierbei den `tool_name` (z.B. `getTarifVertrag`) und die vom Modell generierten `arguments`.

In diesem Fall wird der reguläre Antwortweg unterbrochen, um die Phase 3 einzuleiten.

Phase 3 Ausführung & Parsing:

Erkennt der Parser einen Tool-Wunsch, extrahiert er die Parameter aus dem übergebenen JSON und führt die entsprechende PL/SQL-Funktion (z. B. Vektorsuche) aus.

Das Ergebnis der Funktion wird in ein standardisiertes Tool-Output-Format überführt. Dieses enthält:

  • role: „tool“ (um den Absender zu identifizieren).
  • tool_call_id: Die Referenz-ID des ursprünglichen Aufrufs (wichtig für die Korrelation).
  • content: Das fachliche Ergebnis (z.B. eine Liste von Vertrags-Chunks oder eine Statusmeldung) als Text oder JSON-Struktur.
Phase 4 Feedback-Loop & Rekursion:

Das Ergebnis der Datenbankoperation wird als neue Nachricht im Chat-Verlauf (History) an das LLM zurückgesandt.

Die PL/SQL-Orchestrierung baut hierbei einen vollständigen Kontext-Stack auf.

Der Kontext-Stack umfasst:

  1. System/User Prompt: Die ursprüngliche Aufgabenstellung und Verhaltensregeln.
  2. Assistant Message: Der Tool-Call-Wunsch des Modells (inkl. ID).
  3. Tool Message: Die validen Fakten direkt aus der Oracle-Datenbank (Phase 3).

Agentic Workflow & Chaining:

Basierend auf diesem erweiterten Kontext generiert das Modell einen neuen Antwort-Token.

  1. Falls das Modell weitere Informationen benötigt (z.B. nach `getTarifVertrag` ein weiteres Tool zur Detailanalyse), wird erneut ein `tool_calls` Record gesendet. Dieser Zyklus (Phase 2 bis 4) wiederholt sich rekursiv, bis das Modell eine fundierte Antwort generieren kann.
  2. Erst wenn das Modell den `finish_reason: stop` liefert, wird die finale Antwort an die Business Logik unser App durchgereicht um am Ende in der APEX UX angezeigt zu werden.

Context Management: Da bei jedem Rekursionsschritt die gesamte Historie mitgesendet wird, überwacht die PL/SQL-Schicht das Token-Fenster des LLMs.

Bei komplexen „Multi-Tool-Abfragen“ wird ein intelligentes Pruning (Kürzen) der Historie oder eine Zusammenfassung (Summarization) alter Tool-Ergebnisse durchgeführt, um die Verarbeitungsgrenzen (Context Window) nicht zu überschreiten.

Logical Workflow Diagram

Übersicht über den Ablauf:

<code text>
[ User / APEX ]       [ PL/SQL Orchestrator ]       [ LLM (External API) ]
       |                       |                             |
       |---(1) User Query ---->|                             |
       |                       |---(2) Request + Tools ----->|
       |                       |                             |
       |                       |<--(3) Tool-Call Request ----|
       |                       |                             |
       |                       |--[Execute DB Function]      |
       |                       |--[e.g. Vector Search ]      |
       |                       |                             |
       |                       |---(4) Tool Result Context ->|
       |                       |                             |
       |                       |<--(5) Final Text Response --|
       |<--(6) Formatted Ans.--|                             |
</code>

Umsetzung

Um den Service betriebsbereit zu machen, müssen folgende technische Bausteine implementiert werden:

1. Datenbank-Modell (Service Core)

  • Interface Registry - Tabelle für die verschiedenen Interfaces der APP wie ChatBot, Dokumenten Analyse, Ontologie Funktionen etc.
  • Interface zu Tools - Welche Tools kann ein Interface verwenden
  • Tool-Registry-Tabelle: Speicherung von `tool_name`, `description` und dem `json_schema` (Definition der Input-Parameter für das LLM) und Mapping zu den PL/SQL Funktionen. als Resource-Katalog:
  • Exekution Plan Ausführungplan welches Interface welche Tools in welchen Business Prozess ausführen muss
  • Audit- & Logging-Tabelles: Speicherung von LLM-Anfragen, Tool-Aufrufen und Antwortzeiten zur Sicherstellung der Observability.
Datenbank-Modell (Service Core) für den Katalog

 Datenbank-Modell (Service Core) für den Katalog des MCP Servers


2. PL/SQL Tool-Request Wrapper

Als ein sehr aufwendigen Part stellt sich das „saubere“ Handling der JSON Strukturen heraus.

Ein direktes Arbeiten mit dem JSON Request und Response Payload der Chat Schnittstelle erzeugt doch relativ schnell einen sehr unübersichtlichen Code der sich schwer warten lässt.

Daher werden die JSON Elemente des Chat Verlaufs in eine jeweilige passende Type Struktur überführt. Im weiteren Flow der Business Logik wird mit diesem Type Objekten gearbeitet und die passende Type Struktur für die Antwort erzeugt.

Aus dem Antwort Type wird dann wieder das passende und wohlgeformte JSON erzeugt.

Tools Handling

Für die Tools wird ein eigenes Package erstellt:

  • Ein Package `PKG_OPENAI_TOOLS` erstellt auf Basis des Datenmodells einen Tools Type der später mit Hilfe von JSON_OBJECT_T/ARY/ELEMENT etc in das passende JSON transformiert bzw. eingelesen
  • Prüfung der Berechtigungen (Authorization Layer), bevor ein Datenbank-Tool ausgeführt wird.
Tools Bereitstellen

Beispiel JSON für die OpenAI Syntax (Tools Definition), um dem LLM die entsprechenden Fähigkeiten zu präsentieren:

{
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "getDialog",
        "description": "Wird aufgerufen, wenn die Benutzeranfrage unzureichende Informationen enthält (z.B. fehlendes Tarifgebiet oder Branche), um diese gezielt vom Anwender zu erfragen.",
        "parameters": {
          "type": "object",
          "properties": {
            "missing_parameters": {
              "type": "array",
              "items": { "type": "string" },
              "description": "Liste der fehlenden Parameter, die erfragt werden muessen."
            },
            "context": {
              "type": "string",
              "description": "Kurze Beschreibung des aktuellen Gesprächsstandes."
            }
          },
          "required": ["missing_parameters"]
        }
      }
    },
    {
      "type": "function",
      "function": {
        "name": "getTarifVertrag",
        "description": "Liefert eine Liste relevanter Tarifvertraege basierend auf konkreten Fachparametern wie Tarifgebiet, Fachbereich und fachlichen Suchbegriffen.",
        "parameters": {
          "type": "object",
          "properties": {
            "tarifgebiet": {
              "type": "string",
              "description": "Geographische Region des Tarifvertrags."
            },
            "fachbereich": {
              "type": "string",
              "description": "Die Branche oder der fachliche Bereich."
            },
            "search_terms": {
              "type": "array",
              "items": { "type": "string" },
              "description": "Liste von fachlichen Begriffen für die semantische Suche."
            }
          },
          "required": ["tarifgebiet", "fachbereich"]
        }
      }
    }
  ],
  "tool_choice": "auto"
}

Konfiguration des Parameter tool_choice:

Der Parameter `tool_choice` steuert die Autonomie des Modells bei der Werkzeugnutzung:

  • „none“: Das Modell nutzt keine Tools und antwortet nur mit Text (erzwungener Standard-Modus).
  • „auto“ (Empfohlen): Das Modell entscheidet autonom basierend auf der User-Query, ob ein Tool-Aufruf notwendig ist oder die interne Wissensbasis ausreicht. Dies bietet die höchste Dynamik für Chatbots.
  • „required“: Das Modell wird gezwungen, mindestens ein Tool aufzurufen (sinnvoll für strikte Agenten-Workflows).
  • {„type“: „function“, „function“: {„name“: „…“}}: Erzwingt den Aufruf einer ganz bestimmten Datenbank-Funktion.

Tool-Ausführungs-Engine

  • Dynamisches Mapping: Der Orchestrator ruft basierend auf dem `tool_name` die entsprechende PL/SQL-Logik auf.
  • Wie die Integration von Oracle AI Vector Search für semantische Suchen.
  • Rückgabe der Ergebnisse als strukturierte JSON-Objekte gemäß MCP-Spezifikation (`content`-Array).

4. Robuster JSON-Parser & Response Repair Engine

Dieser Punkt stellt die größte Herausforderung in der Praxis dar, da LLM-Antworten oft unvorhersehbare Anomalien aufweisen.

Ein bloßes `JSON_ELEMENT_T.parse` reicht hier nicht aus.

Die PL/SQL-Schicht benötigt eine spezialisierte Sanitizing-Logik:

  • Fragment-Reparatur: Falls das LLM aufgrund von Token-Limits oder Timeouts nur ein halbes JSON-Fragment sendet, versucht der Parser, fehlende schließende Klammern (`}`, `]`) zu ergänzen, um zumindest die bis dahin erhaltenen `tool_calls` zu retten.
  • Heuristische Bereinigung: - Entfernung von Markdown-Code-Blöcken (`` ```json … ``` ``), die das LLM oft fälschlicherweise mitsendet.
    1. Korrektur von nicht-eskapierten Sonderzeichen wie Anführungszeichen innerhalb von Textfeldern.
    2. Auflösung von fehlerhaften Konkatenationen (z.B. ein zufälliges `+` Zeichen zwischen Strings).
  • Normalisierung von Provider-Fehlern: Wenn statt des OpenAI-Schemas ein plattformspezifischer Fehler (z.B. Microsoft Azure API Management Error) zurückkommt, wird dieser abgefangen und in ein internes Fehlerformat überführt, anstatt den PL/SQL-Prozess mit einem `ORA-XXXX` Fehler abbrechen zu lassen.
  • Validation Layer: Jedes extrahierte Argument wird gegen das in der `APP_MCP_TOOLS`-Registry hinterlegte Schema geprüft. Fehlen Pflichtfelder, wird eine Korrekturanfrage (Phase 4) an das LLM gesendet („Tool-Aufruf fehlgeschlagen: Parameter 'tarifgebiet' fehlt“).

PL/SQL Tool-Request Wrapper

Im Detail

Die LLM-Antworten sind „untyped“ und oft fehleranfällig (ungültige Zeichen, Markdown-Artefakte, fehlende Klammern). Ein wiederholtes Parsen des rohen JSON-Strings innerhalb der Geschäftslogik führt zu hoher Komplexität und Fehlern.

Die Lösung:

Nachdem ein Validierer (Response Repair Engine) das JSON bereinigt hat, wird die Antwort sofort in ein strukturiertes PL/SQL Type Object (Object-Relational-Mapping) überführt.

Dieses Objekt dient als „Single Source of Truth“.

Alle weiteren Prozessschritte (Routing, Tool-Ausführung, APEX-Output) arbeiten nur noch mit diesem validen Objekt.

Funktionsweise: 1. Der Orchestrator erhält das rohe JSON. 2. Er ruft `t_mcp_response.from_json(l_repaired_json)` auf. 3. Innerhalb dieser Funktion wird `JSON_TABLE` genutzt, um die Daten einmalig in das Objekt zu laden. 4. Falls das System nun wissen muss, ob ein Tool gerufen wurde, genügt ein Aufruf von `l_res_obj.has_tools()`.


Quellen

Referenzen:

Diese Website verwendet Cookies. Durch die Nutzung der Website stimmen Sie dem Speichern von Cookies auf Ihrem Computer zu. Außerdem bestätigen Sie, dass Sie unsere Datenschutzbestimmungen gelesen und verstanden haben. Wenn Sie nicht einverstanden sind, verlassen Sie die Website.Weitere Information
"Autor: Gunther Pipperr"
ki/oracle_mcp_database.txt · Zuletzt geändert: von gpipperr