Startseite / Artikel

Siebzehn kleine MCP-Tools anstelle eines riesigen Agenten: Ein KI-gestütztes Schreibsystem

Wie ein System für Forschung und Schreiben die Aufnahme von Videos, die Suche, das Entwerfen, die Kritik sowie die Code-Validierung in begrenzte MCP-Tools unter Verwendung von Artefakten und Nachverfolgung aufteilt.

Verlag: REACTAPP.TOP13 Min. Lesezeit2957 Wörter

Quellen: Why I Built MaxyAI as 17 Small MCP Tools Instead of One Giant Agent

Der schwierige Teil eines KI-Schreibassistenten besteht nicht darin, ein Sprachmodell zum Schreiben zu bringen. Vielmehr geht es darum, zu entscheiden, wofür das Modell nicht verantwortlich sein sollte. Frühe Versuche solcher Assistenten neigen dazu, sich auf eine einzige Architektur zu reduzieren: Man gibt einem Modell ein Thema, fügt ein Suchwerkzeug hinzu und bittet es, in einem einzigen langen Prozess zu recherchieren, zu argumentieren, zu schreiben, zu überprüfen und Fehler zu beheben. Die Anfragen werden immer umfangreicher, die Abläufe schwer zu debuggen, und deterministische Fehler vermischen sich mit semantischen Entscheidungen. MaxyAI, ein KI-Forschungs- und Schreibsystem, ging von einer anderen Idee aus: Jede Fähigkeit, die unterschiedliche Eingaben, Fehlermuster, Wiederholungsregeln oder eine wiederverwendbare Ausgabe hat, soll zu einem eigenen, begrenzten Tool hinter einem einzigen MCP-Server werden.

Die Eingabedaten sind selten ordentlich strukturiert. Es kann sich um einen YouTube-Vortrag, ein GitHub-Repository, eine Dokumentationsseite sowie einige Referenzlinks handeln. MaxyAI nimmt all das auf, erweitert die Recherche durch Websuche, speichert das wachsende Korpus auf der Festplatte und formt es zu einem Überblicksplan um. Anschließend erstellt es Abschnitt für Abschnitt einen Entwurf, übergibt diesen an einen numerischen Kritiker, extrahiert alle Python-Blöcke, validiert und führt den Code aus, behebt Syntaxfehler und exportiert schließlich einen eigenständigen HTML-Artikel.

Hinter diesem Prozess steckt kein riesiger Prompt. Das System ist ein FastMCP-Server mit 17 registrierten Tools, von denen 12 für die Recherche genutzt werden. Die Tools sind absichtlich klein gehalten. Eines transkribiert Videos, eines versteht Repositorys, eines durchsucht das Internet, eines erstellt einen Überblicksplan, eines kritisiert den Artikel und eines validiert den Code. Das Modell entscheidet, welche Fähigkeit aufgerufen werden soll, und der Python-Code hinter jedem Tool erledigt die deterministische Arbeit.

Diese Trennung ist das Nützlichste an diesem Design. Das Modell kann geändert werden, ohne die Einbindung in YouTube zu beeinflussen. Der Crawler kann ausgetauscht werden, ohne den Writer zu stören. Die Code-Überprüfungsphase kann debuggt werden, ohne die Forschungsarbeit erneut durchführen zu müssen. Da jeder wichtige Schritt ein Artefakt oder eine Spur hinterlässt, kann ein langer autonomer Ablauf anschließend geprüft werden, anstatt als ein einziger riesiger Chat-Transkript zu betrachtet zu werden.

Die Zahl 17 war niemals ein Ziel. Sie entstand aus einer einfachen Regel: Eine Funktionalität erhält ein eigenes, begrenztes Tool oder Handler, wenn sie mit einem anderen externen System kommuniziert, ein wiederverwendbares Artefakt erzeugt, ein separates Verhalten bei Wiederholungsversuchen benötigt oder von deterministischer Überprüfung profitiert. MCP stellt anschließend allen diesen Spezialisten eine gemeinsame Schnittstelle zur Verfügung.

Warum nicht ein einziges großes Tool? Weil das System mehrere unterschiedliche Ingenieurprobleme löst anstelle eines einzigen logischen Problems. Diese Aufgaben – Videoaufnahme, Parsing von Repositorien, Web-Entdeckung, Zustandsverwaltung, Entwurf, Kritik, Ausführung von Code, Reparatur, Veröffentlichung – haben jeweils ihre eigenen Eingaben, Kosten, Fehlermöglichkeiten und Anforderungen an Wiederholungsversuche. Ein Mega-Tool würde die Anweisungen verkürzen, doch das System würde dadurch schwieriger zu beobachten und zu erweitern sein.

Das bedeutet keineswegs, dass jeder Agent 17 Tools benötigt. Es handelt sich um eine Fallstudie zur Aufteilung von Aufgaben: Wo semantische Beurteilungen einem Modell zukommen sollten, wo gewöhnlicher Code die Kontrolle übernehmen muss, wie Artefakte statt umfangreicher konversationeller Zustände dienen können und warum generierter Code vor der Sichtbarkeit für den Benutzer deterministische Prüfungen bestehen muss.

Von Anfang bis Ende

Nehmen wir das Thema Aufruf von LLM-Funktionen und strukturierte Ausgaben, ausgestattet mit einer Ausgangsgruppe an Richtlinien wie einem YouTube-Vortrag, einem GitHub-Repository und einigen Dokumentations-URLs.

Phase 1 erzeugt keine Prosa. Ihre Aufgabe besteht darin, Beweismittel zu sammeln. Der MCP-Server wählt URLs aus, übermittelt Videos an Geminis multimodales API, wandelt Repositorys mithilfe von gitingest in für das Modell geeignete Zusammenfassungen um, durchsucht Seiten mit Firecrawl, füllt Lücken durch Suchen in Tavily und verfolgt den Bestand der Quellen in State-Dateien innerhalb von .nova/. Das Ergebnis ist research.md, ein umfangreiches Forschungsdokument, das jeder öffnen und lesen kann, anstelle einer versteckten Konversationsmemorie.

Phase 2 nimmt dieses Artefakt und plant die Veröffentlichung. generate_article_outline weist Abschnitte, Wortzahllimits sowie Codeziele zu, und draft_article_section schreibt anschließend bei jedem Aufruf einen einzigen begrenzten Abschnitt. Danach bewertet critic_evaluate_article den vollständigen Entwurf hinsichtlich technischer Tiefe, Codequalität, Struktur und Genauigkeit der Zitierungen, und refine_and_save_article führt die von ihm geforderten Änderungen durch, bevor article.md erstellt wird.

Phase 3 behandelt Markdown als etwas, das während der Ausführung tatsächlich funktionieren muss und nicht nur überzeugend aussehen soll. Python-Blöcke werden extrahiert und mit ast.parse() analysiert. Gültige Codeausschnitte werden unter .nova/sandbox/ gespeichert und mit einer Fünf-Sekunden-Frist ausgeführt. Bei einer Syntaxfehler wird der Fehler sowie der Codeausschnitt an fix_code_snippets gesendet, wobei das Ergebnis erneut der Validierung unterzogen wird. Sobald der Code bestanden ist, erzeugt export_publication_bundle das eigenständige HTML-Dokument.

Die Opik-Überwachung umfasst die gesamte Ausführung. Jede Modell- und Tool-Überwachung gibt Latenzzeiten, Provider-Metadaten, die Tool-Hierarchie sowie Zwischenergebnisse an. Als Diagramm dargestellt besteht die Architektur aus drei Phasen (Forschung, Verfasser und Kritiker, Code-QA und Verleger), die gemeinsam Modell-Backup-Funktionen sowie Überwachungsmöglichkeiten nutzen.

Der MCP-Server als Rückgrat

Die erste Gestaltungsentscheidung erfolgte auf Protokollebene: Die Funktionalitäten wurden über das Model Context Protocol bereitgestellt, anstatt jede Funktion direkt in einen einzigen Anwendungszyklus einzubinden.

MCP bietet einem Client ein standardisiertes Vokabular zur Entdeckung und Aufrufung von Tools. FastMCP macht dies in Python angenehm, da eine gewöhnliche typisierte Funktion durch einen Dekorator zu einem MCP-Tool wird und ihre Signatur Teil des Vertrags des Tools wird. Die Implementierung kann weiterhin rein in Python bestehen, selbst wenn der Client ein Agent ist.

Im Projekt ist mcp_server/src/routers/tools.py der Eingangspunkt zur Tool-Schicht. Eine vereinfachte Registrierung sieht wie folgt aus:

import opik
from fastmcp import FastMCP

from ..tools import run_web_research_tool

def register_mcp_tools(mcp: FastMCP) -> None:
    @mcp.tool(name="run_web_research")
    @opik.track(type="tool", tags=["research", "tavily"])
    async def run_web_research(
        queries: list[str],
        research_directory: str,
    ) -> dict:
        return await run_web_research_tool(
            queries=queries,
            research_directory=research_directory,
        )

Der Dekorator dient nicht nur dazu, die Syntax zu verschönern. Der Client sieht ein benanntes Werkzeug mit typisierten Argumenten, während die Implementierung im Werkzeug- und Handler-Schicht verbleibt. Diese Trennung ist wichtig, sobald der Server über eine begrenzte Anzahl an Funktionen hinauswächst.

Ein einzelnes Werkzeug do_everything(topic) wurde absichtlich vermieden, da es die Kopplung wieder einführen würde, die das Design beseitigen sollte. Kleinere Werkzeuge ermöglichen es dem Modell, Verhaltensweisen zu kombinieren: Quellen extrahieren, überprüfen, was fehlt, erneut suchen, einen Überblick erstellen, einen Entwurf vorbereiten, kritisieren und reparieren. Zudem machen sie die Protokolle viel leichter lesbar, da jeder Zeitabschnitt einer sinnvollen Aktion entspricht.

Der Server mit 17 Werkzeugen ist daher nicht 17 verschiedene Anfragen – es handelt sich um eine Reihe begrenzter Fähigkeiten. Die Forschung erhält den größten Anteil mit 12 Werkzeugen, da bei der Quellenbeschaffung die größte Vielfalt im Workflow erforderlich ist.

Forschung: verschiedene Quellen, verschiedene Werkzeuge

Die Forschung erforderte den größten Teil der Entwicklungsarbeit, da „Suche im Internet“ mehrere Schritte verbirgt. Ein Video, ein GitHub-Repository sowie eine dokumentationsreiche Website mit viel JavaScript stellen jeweils unterschiedliche Datenaufgaben dar, und die Verarbeitung all dieser Quellen mit einem einzigen Scraper liefert dem Autor von Anfang an unzureichenden Kontext.

Gemini für YouTube

Die lokale Verarbeitung von Langzeitvideos ist aufwendig: Man muss das Audio herunterladen, Sprache in Text umwandeln, die GPU-Geschwindigkeit verwalten und anschließend die Transkription zusammenfassen. Das Modul youtube_handler.py wählt einen einfacheren Ansatz. Es übermittelt die öffentliche YouTube-URL direkt an Gemini als multimodales Eingabedatum und bittet um strukturierten Markdown mit Zeitstempeln.

Der Grund für die Wahl von Gemini liegt nicht darin, dass es das beste Modell für das gesamte Projekt ist. Vielmehr passt diese Fähigkeit zur Aufgabe: Die native multimodale Eingabe ermöglicht es dem Server, Videos zu verarbeiten, ohne dass auf dem Client-Rechner eine lokale Whisper-Stack-Struktur oder eine GPU erforderlich ist.

Serverfehler der Anbieter werden vom selben Modul mit exponentiellen Wiederholungsversuchen behandelt, wodurch vorübergehende Fehler auf der Modellseite innerhalb der Tool-Struktur bleiben, sodass der externe Agent keine Kenntnisse über Netzwerkdetails benötigt.

@retry(
    retry=retry_if_exception_type(errors.ServerError),
    wait=wait_exponential(multiplier=1, min=5, max=60),
    stop=stop_after_attempt(3),
)
async def transcribe_youtube(url: str, output_path: Path, timestamp: int = 30):
    client = track_genai_client(
        genai.Client(api_key=settings.google_api_key.get_secret_value())
    )

    parts = [
        types.Part(file_data=types.FileData(file_uri=url)),
        types.Part(text=PROMPT_YOUTUBE_TRANSCRIPTION.format(timestamp=timestamp)),
    ]

    response = await client.aio.models.generate_content(
        model=settings.youtube_transcription_model,
        contents=parts,
    )

    output_path.write_text(response.text, encoding="utf-8")

In einem berichteten Test wurde ein 39 Minuten langer Vortrag in 17,8 Sekunden in strukturierte Notizen umgewandelt, ohne dass dabei GPU-Speicher auf der Client-Seite genutzt wurde. Es handelt sich dabei um einen beobachteten Testlauf und nicht um einen universellen Vergleichswert, da die Last des Anbieters sowie die Netzwerkbedingungen dies verändern können. Die aufgezeichnete Ausgabe zeigte den Modellidentifikator gemini-3.7-flash sowie das gespeicherte Zustandsdokument .nova/guidelines_filenames.json.

gitingest für Repositorien

Ein Repository ist keine Webseite. Das Modell benötigt die Dateistruktur sowie den eigentlichen Quellcode – nicht GitHubs Navigationsstruktur – weshalb der GitHub-Handler gitingest verwendet, um eine für LLMs geeignete Zusammenfassung des Repositoriums zu erstellen.

Die Validierung der AST ist eine separate Angelegenheit. gitingest liest lediglich Daten ein und stellt dem Forschungsmodell eine Verzeichnisübersicht sowie die Datein Inhalte zur Verfügung, während der AST-Parser in Python erst viel später zum Einsatz kommt, wenn der Veröffentlichungspfad den generierten Code überprüft. Die Kombination beider würde die Architektur verschleiern.

Das Trennen beider Ansätze erleichtert außerdem Erweiterungen. Ein späterer Einleser aus GitLab oder einer lokalen Ordnerstruktur muss lediglich dasselbe Forschungsobjekt bereitstellen, da der Ersteller unbeeindruckt davon ist, woher der Code stammt.

Tavily und Firecrawl zusammen

Beide lösen unterschiedliche Aspekte der Webforschung. Tavily unterstützt bei der Suche, indem es die Frage „Was fehlt mir noch?“ in eine Reihe gezielter Abfragen umwandelt. Firecrawl kommt zum Einsatz, sobald der Server eine bestimmte Seite ausgewählt hat und deren Inhalt sauber extrahiert werden soll.

Das Projekt nutzt diesen Unterschied aus, um die Forschung iterativ zu gestalten. Das Einlesen der anfänglichen Referenzen ist nicht das Ende. Der Agent durchsucht das Korpus, erstellt neue Abfragen für das, was noch fehlt, führt sie aus, fügt die Ergebnisse hinzu und kann bis zu drei Runden wiederholen.

Das Design ist absichtlich asymmetrisch: Das LLM entscheidet, was fehlt, während Tavily und Firecrawl die Datensuche übernehmen. Dieses Muster wiederholt sich stets – das Modell wird eingesetzt, wo semantische Beurteilungen vorteilhaft sind, und gewöhnlicher Code sowie Dienste, wo deterministische Arbeitsweisen besser geeignet sind. Die Aktivitäten von Firecrawl bei einer Forschungsrunde zeigen, dass es vor dem Erstellen von Entwürfen heterogene technische Quellen durchsucht.

Dateien in .nova/ anstelle einer einzigen großen Konversation

Forschungsarbeiten können leicht Zehntausende von Tokens erzeugen, und das Mitnehmen jeder gescrapten Seite sowie jeder Zwischendecision bei jeder nachfolgenden Toolaufruf wäre verschwenderisch.

Stattdessen erstellt das System kleine Steuerdateien unter .nova/, wie zum Beispiel guidelines_filenames.json und next_queries.json, und speichert den umfangreichen Inhalt in Dateien wie research.md. Das Modell erhält nur den für die aktuelle Operation benötigten Teil.

Das ist weniger „magisch“ als „Agentenmemorie“, lässt sich aber viel leichter überprüfen. Wenn eine Ausführung mitten im Lauf abgebrochen wird, zeigt der Zustandsordner an, welche Referenzen gesammelt wurden oder welche Suchrunde als nächstes fällig war. Im Grunde dient das Dateisystem als eine grobe, aber funktionierende Vereinbarung zwischen den Phasen.

Der Schreiber ist ein Pipeline

Sobald research.md vorhanden ist, besteht die offensichtliche Versuchung, die gesamte Datei an ein großes Modell zu senden und einen 2.000-Wörter-Artikel anzufordern. Das Projekt hat das von Anfang an vermieden, weil Ausgabebeschränkungen sowie die Aufmerksamkeit für lange Kontexte es erschweren, Struktur, Codeabdeckung und Zitate gleichzeitig unter Kontrolle zu halten.

Die Schreibphase teilt die Arbeit stattdessen auf vier Tools auf:

  • generate_article_outline wandelt das Forschungskorpus in eine Liste von Abschnitten mit Wortbudgets und Codezielen um.
  • draft_article_section erstellt begrenzte Abschnitte anstelle eines einzigen umfangreichen Ergebnisses.
  • critic_evaluate_article bewertet den zusammengestellten Entwurf anhand einer strukturierten Skala von 0 bis 100.
  • refine_and_save_article führt die notwendigen Überarbeitungen durch, erstellt den Inhaltstext, überprüft die Zitierstruktur und speichert article.md.

Wichtig ist, dass der Kritiker nicht einfach nur „sieht gut aus“ sagt. Seine Ausgabe sind strukturierte Rückmeldungen, auf die ein anderes Tool reagieren kann:

{
 "overall_score": 85,
 "status": "APPROVED",
 "category_scores": {
 "technical_depth": 27,
 "code_quality": 26,
 "structure_clarity": 17,
 "citation_fidelity": 15
 },
 "specific_critiques": [
 "Section 3.2 mentions timeout handling but omits the asyncio.wait_for example.",
 "Citation [14] is cited twice with conflicting author names."
 ],
 "required_revisions": [
 "Add the timeout example.",
 "Deduplicate bibliography reference [14]."
 ]
}

Dieses Muster beschränkt jeweils die Rolle des Modells. Das Überblicksmodell bestimmt die Struktur, der Entwerfer synthetisiert einen Abschnitt, der Kritiker sucht nach Fehlern und der Verfeinerungsschritt wendet eine Checkliste an. Kein einzelnes Modell soll alle vier Aufgaben in einer einzigen Durchführung erledigen.

Die 85 von 100 Punkte sind keine wissenschaftliche Qualitätsmetrik. Es handelt sich um ein Steuerungssignal für den Arbeitsablauf, und der wertvolle Teil ist die maschinenlesbare Kritik- und Überarbeitungsliste.

Ein Hinweis auf eine echte Schreibkette zeigt einen strukturierten Prompt, einen Aufruf eines Chat-Modells sowie einen Pydantic-Parser – eine Art Aufzeichnung, die einen autonomen Schreibprozess im Nachhinein verständlich macht.

Code als ausführbares Artefakt

Ein technischer Artikel kann gut geschrieben sein und dennoch die Leser enttäuschen, wenn sein Code nicht läuft. Deshalb gibt es überhaupt eine dritte Phase.

Der Builder öffnet article.md, extrahiert den darin enthaltenen Python-Code, validiert jeden Block mit ast.parse(), speichert die überprüften Ausschnitte in .nova/sandbox/, führt sie als Unterprozess aus und erfasst dabei stdout sowie stderr. Bei Fehlern wird eine weitere Bearbeitung mit einem LLM-Reparaturwerkzeug durchgeführt.

Statische Analyse und Ausführung erkennen unterschiedliche Probleme. ast.parse() ist kostengünstig und lehnt ungültigen Python-Code sofort ab. Der Unterprozess fängt Laufzeitfehler auf, die allein durch die Syntax nicht erkannt werden können.

def validate_python_syntax(code: str):
 try:
 ast.parse(code)
 return True, None
 except SyntaxError as exc:
 return False, f"SyntaxError at line {exc.lineno}: {exc.msg}"
result = subprocess.run(
 [sys.executable, str(file_path)],
 capture_output=True,
 text=True,
 timeout=5,
 env={"PYTHONUNBUFFERED": "1"},
)

Ein fehlerhafter Codeausschnitt wird repariert und vor der Kompilierung des Artikels erneut der Validierung zugeführt. In einem Fall enthielt ein generierter Artikel pip install google-genai innerhalb eines Python-Blocks. In Markdown sah das plausibel aus, doch Python lehnte es sofort ab. fix_code_snippets erhielt den Fehlerbericht sowie den fehlerhaften Block, schrieb den Ausschnitt um und gab ihn zur erneuten Validierung zurück.

# Broken
pip install google-genai
from google import genai

# Repaired
# Requires: pip install google-genai
import os
from google import genai

client = genai.Client(
    api_key=os.environ.get("GEMINI_API_KEY", "mock-key")
)

Der Reparaturzyklus wird absichtlich lokal gehalten. Das Modell darf den gesamten Artikel nicht überschreiben, nur weil ein einzelner Abschnitt fehlschlägt. Es erhält die kleinste nützliche Einheit – den Code sowie dessen Fehler – und die deterministischen Überprüfungen bilden weiterhin die Kontrollstufe.

Einfach ausgedrückt: article.md wird auf eingeschlossenen Python-Code durchsucht, jeder Abschnitt wird analysiert, unter .nova/sandbox/ abgespeichert und in einem begrenzten Unterprozess ausgeführt. Bei einem Fehler werden der Code sowie die Fehlerausgabe für fix_code_snippets verpackt, und der vorgeschlagene Reparaturvorschlag durchläuft erneut denselben Validierungsprozess. Das Modell genehmigt niemals seine eigene Reparatur. Das LLM schlägt vor, und ast.parse() zusammen mit der Ausführung entscheiden. Erst wenn der Zyklus abgeschlossen ist, wandelt export_publication_bundle das überprüfte Ergebnis in die eigenständige HTML-Ausgabe um.

Eine Grenze verdient besondere Betonung. Die Ausführungsschicht ist ein geschützter Subprozess-Runner und keine stark abgesicherte Sicherheits-Sandbox. Zeitlimits sowie Kindprozesse helfen dabei, Syntaxfehler, Laufzeitfehler und Abstürze frühzeitig zu erkennen. Wirklich unzuverlässiger Code würde eine stärkere Isolation benötigen – beispielsweise in Form von Containern, Namensräumen und seccomp, MicroVMs oder einem speziellen Sandbox-Dienst mit Limits für Dateisystem, Netzwerk, Systemaufrufe, CPU und Speicher.

Zwei gemeinsame Schichten: Modell-Routing und -Tracing

Die sichtbare Architektur setzt sich aus drei Phasen zusammen, doch zwei gemeinsame Komponenten spielen im täglichen Gebrauch genauso eine wichtige Rolle.

Modell-Routing unter Berücksichtigung von Quoten

Ein Forschungslauf kann viele Modellaufrufe auslösen, wodurch die Quoten der kostenlosen Version leicht erschöpft werden können. Um eine an den Anbieter gebundene Initialisierung in jedem Handler zu vermeiden, wird die Modellerrichtung zentral in llm_utils.py gesteuert, wobei Konfigurationen für Anbieter und API-Schlüssel in den Einstellungen gespeichert werden.

Das Projekt entwickelte sich um eine Kette von Gemini Flash, Gemini Flash Lite sowie von Groq gehosteten Llama-Modellen herum. Diese speziellen Modelle sind nicht dauerhaft vorhanden – doch das ist nicht entscheidend. Jedes Tool kommuniziert mit einer Modellabstraktion, wobei keine Details zu den Anbietern in den Forschungs- und Programmiercode eingebaut sind.

Auch Experimente werden günstiger, denn wenn eine Aufgabe auf ein günstigeres oder derzeit verfügbares Modell verlagert wird, bleibt der MCP-Tool-Vertrag unverändert.

def get_chat_model(model_id: str, schema=None):
    selected = settings.llm_configs[model_id]
    identifier = selected["identifier"]
    params = selected.get("params", {}).copy()

    # resolve provider-specific API key
    ...

    model = init_chat_model(identifier, **params)
    return track_langchain_model(model)

Opik macht lange Ausführungsabläufe überprüfbar

Protokolle verlieren ihre Nützlichkeit, sobald ein MCP-Server ein Modell aufruft, das wiederum ein Tool aufruft, das ein Artefakt schreibt, das ein weiteres Modell auslöst. Durch die Instrumentierung der Modellklienten und MCP-Tools mit Opik-Tracking wird diese Hierarchie direkt angezeigt, ohne dass man sie aus Ausgabeanweisungen zusammensetzen muss.

Der Nutzen ist praktisch: Ein langsamer Firecrawl-Schritt kann mit einem Modellaufruf verglichen werden, das tatsächlich antwortende Modell kann identifiziert werden, der von einem Parser empfangene Datenträger kann eingesehen werden und der Weg, der ein fehlerhaftes Artefakt erzeugt hat, kann nachvollzogen werden. Die Screenshots der Spuren bilden die Entwicklungsoberfläche zur Verständnis des Arbeitsablaufs – keine bloße Dekoration.

Was das Projekt über das Design von Agenten lehrt

Die Fähigkeit, Artikel zu erstellen, ist es nicht, die MaxyAI interessant macht, denn bereits ein State-of-the-Art-Modell kann einen Prompt in einen brauchbaren Artikel umwandeln. Besonders hervorzuheben ist, wie die Arbeit aufgeteilt ist. Das Einlesen von Videos, das Verarbeiten von Repositorien, das Suchen, das Erstellen eines Überblicks, das Entwerfen, die Kritik, das Extrahieren von Code, die Validierung, die Reparatur und die Exportierung sind jeweils separate Tools. MCP bietet ihnen eine gemeinsame Struktur, Dateien auf der Festplatte ermöglichen es den einzelnen Phasen, große Mengen an Daten weiterzugeben, ohne diese in das Chat-Gedächtnis pressen zu müssen, und Opik sorgt dafür, dass der gesamte Ablauf sichtbar bleibt.

Erweiterungspunkte sind leicht zu erkennen. Ein PDF-Einleser liefert Phase 1 eine andere Art von Quelle. Das Austauschen von Tavily beeinflusst den Schreibmodul nicht. Zu Phase 3 kann JavaScript-basierte Validierung hinzugefügt werden, während der Suchmotor unverändert bleibt. Das Wechseln der Modellanbieter lässt die MCP-Oberfläche unberührt.

Die Absicherung für die Produktion würde mit einer stärkeren Isolation im Sandbox-Modus beginnen, gefolgt von einem festgelegten Bewertungssatz, der Forschung, Zitierungen und Codequalität abdeckt, klareren Metadaten zu den Fähigkeiten der Anbieter sowie zuverlässigen Kontrollpunkten während des Laufs. Schon heute betont das Projekt, dass ein Modell zwar die nächste Aktion wählen kann, die Qualität des Systems jedoch von den Tools, Grenzen, Erzeugnissen und Rückkopplungsschleifen abhängt, die es umgeben.

Drei ingenieurwissenschaftliche Erkenntnisse sind auf andere Agentensysteme übertragbar:

  1. Grenzen der Tools sind wichtiger als ihre Anzahl. Geben Sie einer Fähigkeit eigene Grenzen, wenn sie auf ein anderes System zugreift, fehlschlägt oder anders versucht, oder wenn sie ein Erzeugnis liefert, das von jemandem wiederverwendet wird.
  2. Modelle schlagen vor, deterministische Überprüfungen entscheiden – sofern das möglich ist. Ein LLM kann einen Codeausschnitt korrigieren, doch die endgültige Entscheidung erfolgt durch Parsing und Ausführung.
  • Es ist besser, anzugeben, welche Daten überprüft werden können, anstatt vage von „Gedächtnis“ zu sprechen. Gespeicherte Forschungsergebnisse, Kontrolldateien und Spuren machten lange Ausführungen debugfähig und ermöglichten es, einzelne Phasen erneut auszuführen, ohne eine riesige Chat-Geschichte neu erstellen zu müssen.