Skip to main content

Übersicht

FIM One basiert auf einer Reihe von dünnen abstrakten Basisklassen — eine pro austauschbare Komponente. Jede Komponente hat eine einzelne Verantwortung und eine minimale Schnittstelle. Sie implementieren die abstrakten Methoden, verbinden die Instanz mit der entsprechenden Registry oder dem Injector und der Rest des Systems verwendet Ihre Implementierung automatisch.

Benutzerdefinierter LLM-Anbieter

BaseLLM hat zwei erforderliche Methoden — chat und stream_chat — plus eine optionale abilities-Eigenschaft, die dem Rest des Systems mitteilt, was das Modell kann.

Registrierung über ModelRegistry

ModelRegistry ordnet Namen BaseLLM-Instanzen zu und löst sie nach Rolle auf. Das System verwendet vier integrierte Rollen: general, fast, compact und vision. Sie können eigene hinzufügen.
Das abilities-Wörterbuch ist der Vertrag zwischen dem LLM und der ReAct-Engine. Wenn tool_call=True und der Agent mit use_native_tools=True erstellt wurde, verwendet die Engine natives Function Calling. Andernfalls wird automatisch auf JSON-Modus zurückgegriffen.

Benutzerdefiniertes Werkzeug

Werkzeuge sind die häufigste Erweiterung. BaseTool hat drei erforderliche Teile: name, description und run. Alles andere hat sinnvolle Standardwerte.

Auto-discovery

Legen Sie Ihre Datei in src/fim_one/core/tool/builtin/ ab. Der discover_builtin_tools()-Scanner findet automatisch jede konkrete (nicht-abstrakte) BaseTool-Unterklasse – keine manuelle Registrierung erforderlich.
Der Scanner überspringt Klassen, die in _SKIP_AUTO_DISCOVER aufgelistet sind. Verwenden Sie diesen Satz für Werkzeuge, die externe Konfiguration erfordern (z. B. einen API-Schlüssel) und bei der Initialisierung bedingt instanziiert werden müssen.

Signalisierung von Nichtverfügbarkeit

Überschreiben Sie availability(), um eine Nachricht im Werkzeugkatalog anzuzeigen, wenn eine Abhängigkeit fehlt:

Umfangreiche Ergebnisse mit Artefakten

Geben Sie ein ToolResult statt eines einfachen str zurück, wenn Ihr Werkzeug Dateien erzeugt:

Benutzerdefinierter Speicher

BaseMemory ist die Persistierungsschicht für den Gesprächsverlauf. Drei Methoden: add_message, get_messages, clear.
Injizieren Sie über den Agent-Konstruktor: ReActAgent(llm=llm, memory=RedisMemory(conv_id, url)).

Benutzerdefinierte Einbettung

BaseEmbedding bietet zwei Methoden: embed_texts (Batch) und embed_query (einzeln), plus eine dimension-Eigenschaft.
Der Unterschied zwischen embed_texts und embed_query existiert, weil viele Einbettungsmodelle (z. B. E5, BGE) unterschiedliche Präfixe für Dokumente und Abfragen verwenden, um die Abrufqualität zu verbessern.

Benutzerdefinierte Bildgenerierung

BaseImageGen hat eine einzelne Methode generate. Sie speichert das Bild in output_dir und gibt ein ImageResult mit dem Dateipfad und einer serverelativen URL zurück.

Benutzerdefinierter Reranker

BaseReranker nimmt eine Abfrage und eine Liste von Dokumentzeichenfolgen entgegen und gibt sie neu geordnet mit Bewertungen zurück.

Benutzerdefinierte Web-Backends

Web-Abruf

BaseWebFetch ruft eine URL ab und gibt ihren Inhalt als Markdown oder Klartext zurück.

Websuche

BaseWebSearch gibt eine sortierte Liste von SearchResult-Objekten zurück.

Benutzerdefinierte RAG-Komponenten

Die RAG-Pipeline hat drei unabhängig austauschbare Stufen: Laden, Chunking und Abruf.

Dokument-Loader

BaseLoader konvertiert einen Dateipfad in eine Liste von LoadedDocument-Objekten. PDF-Loader geben normalerweise ein Dokument pro Seite zurück.

Text-Chunker

BaseChunker teilt Text in Chunk-Objekte auf. MAX_CHUNK_SIZE = 6000 Zeichen ist die harte Obergrenze — Chunk-Größen über diesem Wert können das Token-Fenster von Jina Embeddings v3 überlasten.

Retriever

BaseRetriever fragt jeden Backend ab und gibt sortierte Document-Objekte zurück.

Designprinzipien

Einige Muster sind konsistent über alle Basisklassen hinweg, um das Schreiben korrekter benutzerdefinierter Implementierungen zu erleichtern: Async-first. Jede Methode ist async def. Auch wenn Ihre Implementierung synchron ist, wickeln Sie sie mit asyncio.to_thread() ein, anstatt die Event Loop zu blockieren. Textausgabe von Tools. BaseTool.run() gibt str (oder ToolResult) zurück. Das LLM sieht nur Text — Tool-Implementierungen sind verantwortlich für die Serialisierung komplexer Daten in ein lesbares Format. Minimale Schnittstellen. Jede Basisklasse definiert den kleinsten erforderlichen Vertrag. BaseMemory hat drei Methoden; BaseWebFetch hat eine. Sie müssen nie Funktionalität implementieren, die Sie nicht benötigen. Komposition statt Vererbung. Die Basisklassen sind Schnittstellen, keine Frameworks. Sie injizieren Ihre Implementierung zur Konstruktionszeit; die Runtime patcht oder subklassifiziert sie nie weiter.