Das Problem
LLMs zahlen für Kontext in zwei Währungen: Token und Aufmerksamkeit. Jede Werkzeugdefinition, die in den System-Prompt injiziert wird, kostet beides. Ein einzelner MCP-Server kann über 90 Werkzeuge bereitstellen. Fünf API-Konnektoren mit je 20 Aktionen erzeugen 100 Werkzeugdefinitionen. Drei Datenbank-Konnektoren mit je 30 Tabellen generieren weitere 90 Schemabeschreibungen. Bevor der Benutzer auch nur ein Wort tippt, kann der System-Prompt bereits 50–100 KB Kontext verbrauchen – die Hälfte des Budgets eines 128K-Modells. Die Kosten sind nicht nur Token. Forschung und Praxis zeigen konsistent, dass die Genauigkeit von LLMs mit wachsendem irrelevantem Kontext abnimmt. Ein Agent mit 80 Werkzeugdefinitionen in seinem System-Prompt schneidet bei der Werkzeugauswahl messbar schlechter ab als einer mit 6. Das Modell verschwendet Aufmerksamkeit auf Werkzeugschemas, die es nie verwenden wird, und schwächt damit seinen Fokus auf die Werkzeuge und Anweisungen, die wichtig sind. Die naive Lösung – alles injizieren und das Modell sortieren lassen – skaliert nicht. FIM One verfolgt den gegenteiligen Ansatz: Zeige dem LLM das Minimum, das es für eine Entscheidung braucht, und lass es mehr anfordern, wenn es mehr braucht.Das Muster
Progressive Offenlegung folgt einer zweistufigen Architektur über alle Ressourcentypen hinweg:- Stufe 1 — Stubs im System-Prompt. Leichte Zusammenfassungen: ein Name, eine kurze Beschreibung und genug Metadaten (Aktionsanzahl, Tabellenanzahl, Werkzeuganzahl), damit das LLM entscheiden kann, ob es mehr braucht.
- Stufe 2 — Vollständige Details auf Anfrage. Das LLM ruft ein Meta-Werkzeug auf, um vollständige Schemas, Parameter und Ausführungsfähigkeiten abzurufen. Die vollständigen Details werden als Werkzeug-Ergebnis-Nachricht in das Gespräch eingegeben — begrenzt auf diese Runde, nicht dauerhaft im System-Prompt.
Fünf Offenlegungsmechanismen
FIM One wendet progressive Offenlegung einheitlich auf fünf Ressourcentypen an. Jeder verwendet das gleiche zweistufige Muster, aber mit einem Meta-Tool, das auf seine Semantik zugeschnitten ist.| Ressource | Meta-Tool | Stubs zeigen | On-Demand-Rückgabe | Config-Variable | Standard |
|---|---|---|---|---|---|
| Skills | read_skill | Name + Beschreibung (120 Zeichen) | Vollständiger SOP-Inhalt + eingebettetes Skript | SKILL_TOOL_MODE | progressive |
| API-Konnektoren | connector | Konnektorname + Aktionsliste | Vollständige Aktionsschemas mit Parametern | CONNECTOR_TOOL_MODE | progressive |
| Datenbank-Konnektoren | database | DB-Name + Tabellennamen + Anzahl | Spaltenschemas, SQL-Abfrageausführung | DATABASE_TOOL_MODE | progressive |
| MCP-Server | mcp | Servername + Tool-Liste | Vollständige Tool-Schemas + Aufruf | MCP_TOOL_MODE | progressive |
| Integrierte Tools | request_tools | Kompakter Katalog (Name + 80-Zeichen-Beschreibung) | Vollständiges Tool-Schema in Sitzung injiziert | (auto) | Auto bei >12 Tools |
Fähigkeiten — read_skill
Was das LLM anfangs sieht:
read_skill("Customer Complaint SOP") auf und erhält den vollständigen SOP-Text — möglicherweise tausende Token mit Schritt-für-Schritt-Anweisungen, Entscheidungsbäumen und eingebetteten Skripten. Dieser Inhalt wird als Toolergebnis eingegeben, nicht als Systemaufforderungstext, daher unterliegt er der normalen Kontextverwaltung (Zusammenfassung, Kürzung) in späteren Durchläufen.
Legacy-Modus: SKILL_TOOL_MODE=inline bettet den vollständigen Fähigkeitsinhalt direkt in die Systemaufforderung ein. Geeignet, wenn Sie wenige, kleine Fähigkeiten haben — skaliert aber schlecht.
Kontexteinsparungen: Eine Bereitstellung mit 10 Fähigkeiten mit durchschnittlich 2.000 Token verbraucht ~300 Token im progressiven Modus (nur Stubs) gegenüber ~20.000 Token im Inline-Modus. Das ist eine 98%ige Reduktion der persistenten Kontextkosten.
API-Konnektoren — connector
Was der LLM zunächst sieht:
connector("discover", "salesforce") gibt die vollständigen Aktionsschemas zurück, einschließlich HTTP-Methoden, URL-Pfade, Parameter-JSON-Schemas und Request-Body-Vorlagen. connector("execute", "salesforce", "get_contacts", {"limit": 10}) leitet die Ausführung durch ConnectorToolAdapter mit vollständiger Auth-Injektion und Audit-Logging weiter.
Legacy-Modus: CONNECTOR_TOOL_MODE=legacy registriert jede Aktion als separates Tool (salesforce__get_contacts, salesforce__create_lead, usw.). Ein Konnektor mit 20 Aktionen wird zu 20 Tool-Definitionen im System-Prompt.
Kontexteinsparungen: Ein Konnektor mit 15 Aktionen generiert ~50 Token Stub gegenüber ~3.000 Token vollständiger Schemas. Fünf Konnektoren: ~250 Token progressiv gegenüber ~15.000 Token Legacy.
Datenbank-Konnektoren — database
Was das LLM anfangs sieht:
database("list_tables", "hr_postgres")— gibt alle Tabellennamen mit Beschreibungen und Spaltenzählungen zurück.database("discover", "hr_postgres", table="employees")— gibt vollständige Spaltenschemas zurück (Name, Typ, nullable, Primärschlüssel, Beschreibungen).database("query", "hr_postgres", sql="SELECT ...")— führt eine validierte SQL-Abfrage mit Sicherheitsprüfungen und Zeilenlimits aus.
DATABASE_TOOL_MODE=legacy registriert drei Tools pro Datenbank ({db}__list_tables, {db}__describe_table, {db}__query). Mit 5 Datenbank-Konnektoren sind das 15 Tool-Definitionen statt 1.
Kontexteinsparungen: Eine Datenbank mit 30 Tabellen und 200 Spalten erzeugt ~80 Token Stub gegenüber ~5.000 Token vollständigem Schema. Die Einsparungen verstärken sich mit mehreren Datenbanken.
MCP-Server — mcp
Was der LLM anfangs sieht:
mcp("discover", "github") gibt den vollständigen Tool-Katalog mit Parameter-Schemas zurück. mcp("call", "github", "create_issue", {"title": "Bug report", "body": "..."}) delegiert an den gespeicherten MCPToolAdapter, der mit dem MCP-Server-Prozess kommuniziert.
Legacy-Modus: MCP_TOOL_MODE=legacy registriert jedes MCP-Tool als separates Tool (github__create_issue, github__list_repos, usw.). Dies kann leicht die Tool-Auswahlschwelle überschreiten und unnötige Auswahlphasen auslösen.
Kontexteinsparungen: Die Einsparungen hier sind extrem. Die 35 Tools eines GitHub-MCP-Servers könnten 10.000+ Token des Schemas verbrauchen. Im Progressive-Modus kostet der Stub ~100 Token. Wenn der Benutzer GitHub in diesem Gespräch nie benötigt, werden diese 10.000 Token nie ausgegeben.
Integrierte Tools — request_tools
Der fünfte Mechanismus unterscheidet sich architektonisch von den anderen vier. Er konsolidiert keinen Ressourcentyp hinter einem Meta-Tool. Stattdessen adressiert er den Engpass bei der Tool-Auswahl — was passiert, wenn der Agent mehr als 12 Tools verfügbar hat.
Funktionsweise: Wenn die Gesamtzahl der Tools REACT_TOOL_SELECTION_THRESHOLD (Standard: 12) überschreitet, führt die ReAct-Engine einen leichtgewichtigen LLM-Aufruf durch, um die 6 relevantesten Tools für die aktuelle Abfrage auszuwählen. Die verbleibenden Tools werden in einer vollständigen Registry gespeichert. Ein request_tools Meta-Tool wird automatisch registriert und listet alle nicht geladenen Tools als kompakten Katalog auf (Name + 80-Zeichen-Beschreibung).
Was das LLM anfangs sieht:
request_tools(tool_names=["web_search", "email_send"]) kopiert diese Tools aus der vollständigen Registry in die aktive Registry. Der System-Prompt wird in der nächsten Iteration neu erstellt, damit das LLM die vollständigen Schemas sieht. Dies ist ein Nebeneffekt — das Tool mutiert die aktive Tool-Menge während des Gesprächs.
Keine Umgebungsvariable: Dieser Mechanismus aktiviert sich automatisch, wenn die Tool-Auswahl die Menge filtert. Es gibt keine REQUEST_TOOLS_MODE Umgebungsvariable. Wenn Sie die Tool-Auswahl vollständig deaktivieren möchten, setzen Sie REACT_TOOL_SELECTION_THRESHOLD auf eine sehr hohe Zahl.
Kontexteinsparungen: Die Einsparungen hängen davon ab, wie viele Tools verfügbar sind und wie viele die Auswahl auswählt. Ein Agent mit 30 Tools, der nur 6 aktive Schemas + den request_tools Katalog sieht, spart ungefähr 60—70% des Tool-Schema-Kontexts.
Wie es sich in die Werkzeugmontage-Pipeline einfügt
Die Systemübersicht beschreibt eine 8-Schritte-pro-Anfrage-Werkzeugmontage-Pipeline. Progressive Offenlegung wirkt sich an mehreren Punkten aus:| Pipeline-Schritt | Rolle der progressiven Offenlegung |
|---|---|
| 1. Basis-Erkennung | Keine Auswirkung — integrierte Werkzeuge werden normal geladen |
| 2. Agent-Kategorie-Filter | Keine Auswirkung — Kategoriefilterung wird unabhängig vom Modus angewendet |
| 3. KB-Injektion | Keine Auswirkung — KB-Werkzeuge sind natürlicherweise leichtgewichtig (1—2 Werkzeuge) |
| 4. Connector-Laden | ConnectorMetaTool konsolidiert alle API-Connectoren; DatabaseMetaTool konsolidiert alle DB-Connectoren |
| 5. MCP-Laden | MCPServerMetaTool konsolidiert alle MCP-Server in ein Werkzeug |
| 6. Skills-Injektion | ReadSkillTool ersetzt vollständigen Inhalt durch kompakte Stubs in System-Prompt |
| 7. CallAgent-Registrierung | Keine Auswirkung — call_agent ist bereits ein einzelnes Werkzeug mit einem Katalog |
| 8. Laufzeit-Auswahl | request_tools Meta-Werkzeug registriert, wenn die Auswahl die Menge filtert |
Konfiguration
Vier Umgebungsvariablen steuern die progressive Offenlegung, eine pro Ressourcentyp:| Variable | Werte | Standard | Effekt |
|---|---|---|---|
SKILL_TOOL_MODE | progressive / inline | progressive | Skills: Stubs + read_skill vs. vollständiger Inhalt im System-Prompt |
CONNECTOR_TOOL_MODE | progressive / legacy | progressive | API-Konnektoren: einzelnes connector Meta-Tool vs. einzelne Action-Tools |
DATABASE_TOOL_MODE | progressive / legacy | progressive | DB-Konnektoren: einzelnes database Meta-Tool vs. 3 Tools pro Datenbank |
MCP_TOOL_MODE | progressive / legacy | progressive | MCP-Server: einzelnes mcp Meta-Tool vs. einzelne Server-Tools |
model_config_json außer Kraft gesetzt werden:
progressive ausführen können (Standard) und selektiv für bestimmte Agenten außer Kraft setzen. Ein Agent mit einer einzelnen kleinen Skill könnte den inline-Modus verwenden. Ein Agent, der das LLM alle Konnektoren-Aktionen von vornherein sehen lassen muss (z. B. für feinabgestimmte Modelle, die Meta-Tools nicht zuverlässig aufrufen), könnte den legacy-Modus verwenden.
request_tools hat keine Konfiguration. Es wird automatisch aktiviert, wenn die Tool-Auswahl eine gefilterte Teilmenge erzeugt. Der Schwellenwert wird durch REACT_TOOL_SELECTION_THRESHOLD (Standard: 12) und die maximale Auswahlanzahl durch REACT_TOOL_SELECTION_MAX (Standard: 6) gesteuert.
Designentscheidungen
Warum explizit (LLM-gesteuert) statt implizit (Framework-gesteuert)?
Ein alternatives Design würde das Framework automatisch Tool-Schemas basierend auf Heuristiken erweitern — z. B. durch Erkennung, welcher Connector die Abfrage des Benutzers betrifft, und Einspeisung seiner Schemas, bevor das LLM den Prompt sieht. FIM One hat sich bewusst für den LLM-gesteuerten Ansatz aus drei Gründen entschieden:- Das LLM ist besser bei der Intentionserkennung als Heuristiken. Eine Abfrage wie “überprüfe, ob der Kunde ein offenes Ticket hat und aktualisiere sein Profil” betrifft zwei Connectors. Heuristische Schlüsselwortabstimmung ist fehleranfällig; das LLM identifiziert natürlicherweise beide.
-
Transparenz. Wenn das LLM
connector("discover", "jira")aufruft, erscheint die Aktion in der Tool-Trace. Der Benutzer (und der Entwickler beim Debugging) kann genau sehen, welche Schemas geladen wurden und wann. Implizite Erweiterung ist unsichtbar. - Kontexteffizienz. Das Framework kann nicht wissen, welche Aktionen innerhalb eines Connectors das LLM benötigt. Das Erweitern aller Aktionen eines Connectors verschwendet Token für irrelevante. Das LLM sieht zunächst die Aktionsnamen (über den Stub), fordert dann nur das Schema der spezifischen Aktion an — zweistufige Offenlegung in ihrer reinsten Form.
Warum Pro-Ressourcen-Meta-Tools statt eines universellen Tools?
Ein einzelnesdiscover_resource(type, name)-Tool wäre einfacher zu implementieren, aber schlechter für das LLM. Pro-Ressourcen-Meta-Tools bieten:
- Typisierte Parameter.
connectorhatsubcommand,connector,action,parameters.databasehatsubcommand,database,table,sql. Die Parameterschemas teilen dem LLM genau mit, was erwartet wird. - Enum-Einschränkungen. Jedes Meta-Tool listet seine gültigen Namen (Connector-Namen, Datenbanknamen, Servernamen) als Enum-Werte im Schema auf. Das LLM kann einen Connector-Namen nicht halluzinieren.
- Kategorie-Semantik. Das
connector-Tool hat die Kategorieconnector,databasehat die Kategoriedatabase,mcphat die Kategoriemcp. Dies fließt in die Agent-Kategoriefilterung ein – ein Agent, der nur mit der Kategorieconnectorkonfiguriert ist, sieht die Meta-Toolsdatabaseodermcpnicht.