Artikelbild für den Artikel: LLM-Funktionsaufrufe skalieren nicht; Code-Orchestrierung ist einfacher und effektiver

LLM-Funktionsaufrufe skalieren nicht; Code-Orchestrierung ist einfacher und effektiver

Die Verwendung von großen Sprachmodellen (LLMs) zur Verarbeitung von Toolaufrufen kann kostspielig und zeitaufwendig sein. Durch die Einführung von Ausgabeschemas können Entwickler jedoch strukturierte Daten erhalten, die es ermöglichen, dass das LLM die Verarbeitung mit generiertem Code orchestriert. In diesem Artikel werden wir die Herausforderungen und Lösungen im Umgang mit LLMs und der Code-Orchestrierung untersuchen.

Die Herausforderungen bei LLM-Funktionsaufrufen

Eine gängige Praxis beim Arbeiten mit MCP-Toolaufrufen besteht darin, die Ausgaben eines Tools als Nachricht zurück in das LLM zu geben und das LLM nach dem nächsten Schritt zu fragen. Die Hoffnung ist, dass das Modell in der Lage ist, die Daten zu interpretieren und die richtige nächste Aktion zu identifizieren. Diese Methode funktioniert gut, wenn die Datenmenge klein ist, aber in der realen Welt stößt sie schnell an ihre Grenzen.

MCP in der realen Welt

In unserem Unternehmen verwenden wir Linear und Intercom. Wir haben uns mit ihren neuesten offiziellen MCP-Servern verbunden, um zu verstehen, wie sie Toolaufrufe zurückgeben. Es stellte sich heraus, dass beide Server große JSON-Blobs in ihrem Textinhalt zurückgaben. Diese schienen ihren APIs ähnlich zu sein, mit dem Unterschied, dass der Textinhalt ohne vordefinierte Schemas kam. Das bedeutete, dass die einzige vernünftige Möglichkeit, sie zu parsen, darin bestand, das LLM die Daten interpretieren zu lassen.

Diese JSON-Blobs sind riesig! Als wir Linear’s MCP baten, die Probleme in unserem Projekt aufzulisten, gab der Toolaufruf standardmäßig nur 50 Probleme zurück, was etwa 70.000 Zeichen und ~25.000 Tokens entsprach. Die JSON-Daten enthalten viele ID-Felder, die viele Tokens beanspruchen und semantisch nicht bedeutungsvoll sind.

Die Probleme mit der Datenverarbeitung

Wenn wir Claude mit MCPs verwenden, scheint es, dass das gesamte JSON-Blob unverändert an das Modell zurückgesendet wird. Dieses Vorgehen stößt schnell auf Probleme. Wenn wir beispielsweise die KI dazu bringen wollten, alle Probleme nach Fälligkeitsdatum zu sortieren und anzuzeigen, müsste sie alle Probleme wortwörtlich als Ausgabetokens reproduzieren! Das wäre langsam, kostspielig und könnte potenziell Daten übersehen.

Die Daten in unseren Problemen enthalten oft viele ablenkende Informationen: Schritte zur Reproduktion eines Problems, Fehler, möglicherweise sogar Eingabeaufforderungen eines Benutzers oder Anweisungen zur Nachverfolgung mit einem Benutzer. Das Modell könnte einige dieser Daten nicht genau wiedergeben oder, noch schlimmer, von den ursprünglichen Anweisungen abweichen.

Daten vs. Orchestrierung

Das Kernproblem hier ist, dass wir Orchestrierung und Datenverarbeitung im selben Chat-Thread vermischen. Der “Multi-Agent”-Ansatz versucht, dies zu beheben, indem er einen weiteren Chat-Thread („Agent“) startet, der sich ausschließlich auf die Datenverarbeitung konzentriert. Dies funktioniert besser, wenn es sorgfältig abgestimmt ist, ist jedoch immer noch umständlich, wenn unsere Daten bereits gut strukturiert sind.

Wenn die MCP-Server bereits Daten im JSON-Format zurückgeben, scheint es viel natürlicher, die Daten zu parsen und stattdessen mit den strukturierten Daten zu arbeiten. Zurück zu unserem Sortierbeispiel: Anstatt das LLM zu bitten, die Ausgaben direkt zu reproduzieren, könnten wir stattdessen eine Sortieroperation auf den Daten ausführen und das neue Array zurückgeben. Keine Halluzinationen und das skaliert mit jeder Größe von Eingaben.

Codeausführung als Datenverarbeitung

Dies klingt seltsam vertraut, da wir bereits Code-Interpreter mit KI haben. Wenn wir die Codeausführung als grundlegende Methode zur Verarbeitung von Daten aus MCP-Tools einführen, öffnet sich die Tür zu skalierbaren Möglichkeiten für KI-Modelle. Variablen als Speicher: Anstatt ein externes Speichersystem zu haben, kann das LLM Variablen (Systemspeicher) verwenden, um Daten zu speichern. Das Speichern eines Speichers bedeutet, einen Wert einer Variablen zuzuweisen, und das Auslesen der Variablen bedeutet, sie auszudrucken.

Code kann mehrere Funktionsaufrufe orchestrieren: Sie können sie parallel ausführen oder die Ausgaben von einem oder mehreren Aufrufen als Eingaben in einen anderen verwenden. Die Abhängigkeiten zwischen den Funktionsaufrufen werden implizit über das Berechnungsdiagramm dargestellt, das der Code repräsentiert. Wichtig ist, dass das LLM nicht verpflichtet ist, die Daten wiederzugeben, und wir Garantien für die Vollständigkeit haben.

Skalierbare Verarbeitung

Die Transformation großer Datenmengen ist mit Code natürlich möglich. Das Modell kann entscheiden, Schleifen zu verwenden oder auf Bibliotheken wie NumPy oder pandas für große Datenumwandlungen zurückzugreifen. Code kann auch andere LLMs im Hintergrund aufrufen: Sie können das LLM dazu bringen, Code zu schreiben, der LLMs für die Verarbeitung unstrukturierter Daten aufruft (LLM-Inception).

Ist MCP bereit?

MCP-Spezifikationen definieren bereits Eingabeschemas, und sie haben gerade Ausgabeschemas eingeführt. Sobald Ausgabeschemas weit verbreitet sind, erwarten wir, dass sie Anwendungsfälle für große Datensätze freischalten: benutzerdefinierte Dashboards erstellen, wöchentliche Berichte über abgeschlossene Tickets erstellen oder autonome Agenten haben, die stagnierende Probleme überwachen und anstoßen.

Was macht die Codeausführung schwierig?

Die Herausforderung verschiebt sich nun auf die MCP-Clientseite. Die meisten Ausführungsumgebungen laufen heute in einer streng kontrollierten Sandbox; Sicherheit hat oberste Priorität, da wir mit benutzer-/KI-generiertem Code arbeiten. Es erfordert sorgfältiges Design, um zu bestimmen, wo API-Schlüssel gespeichert werden und wie Tools exponiert werden.

In unseren Designs haben wir sandboxed Umgebungen erstellt, die mit spezifischem API-Zugriff versehen sind. Die Modelle erhalten Dokumentationen, wie sie diese APIs aufrufen können, sodass sie Informationen senden/abrufen können, ohne jemals Geheimnisse zu sehen. Die meisten Ausführungsumgebungen sind zustandsbehaftet (z. B. können sie auf laufende Jupyter-Kernel für jede Benutzersitzung angewiesen sein). Dies ist schwer zu verwalten und teuer, wenn Benutzer erwarten, dass sie später zu AI-Aufgabensitzungen zurückkehren können. Eine zustandslose, aber persistente Ausführungsumgebung ist entscheidend für lang laufende (mehrtägige) Aufgabensitzungen.

Diese Einschränkungen schaffen, was wir für eine neue Kategorie von Laufzeiten halten – “AI-Runtimes”, die LLMs zur Orchestrierung und Durchführung von Aufgaben verwenden. Wir befinden uns noch in den frühen Phasen der Ausarbeitung aller Details für diesen Codeausführungsansatz und würden uns über Feedback von jedem freuen, der ähnliche Probleme angeht. Wenn Sie an unserem Ansatz interessiert sind, können Sie Lutra ausprobieren.

Quellenliste:

Dieser Artikel wurde mithilfe von KI verfasst und basiert auf automatisch gesammelten Informationen.
0 Kommentare

Hinterlasse einen Kommentar

An der Diskussion beteiligen?
Hinterlasse uns deinen Kommentar!

Schreibe einen Kommentar