Alle Konfigurationen werden überDocumentation Index
Fetch the complete documentation index at: https://docs.fim.ai/llms.txt
Use this file to discover all available pages before exploring further.
.env durchgeführt. Kopieren Sie example.env und füllen Sie Ihre Werte aus:
Konfigurationsebenen
Jede Integration hat eine Konfigurationsebene, die ihre Bedeutung angibt:| Ebene | Bedeutung | Verhalten wenn nicht konfiguriert |
|---|---|---|
| Erforderlich | Systemabhängigkeit | System gibt einen Fehler aus — Chat und primäre Funktionen funktionieren nicht |
| Empfohlen | Wichtiger Funktionsaktivator | Ordnungsgemäße Verschlechterung — die Funktion ist sichtbar nicht verfügbar, aber das System läuft |
| Optional | Verbesserungsfunktion | Transparente Verschlechterung — System funktioniert einwandfrei, Funktion ist einfach nicht vorhanden |
Hinweis: Von Administratoren konfigurierte Modelle (Admin → Seite „Modelle”) können LLM-Umgebungsvariablen ersetzen. Die Integritätsprüfung berücksichtigt beide Quellen.
Frontend (Nur lokale Entwicklung)
Das Frontend hat eine separate Env-Datei nur für die lokale Entwicklung:frontend/.env.local.
Diese Datei wird NICHT in Docker verwendet. Innerhalb des Docker-Containers leitet Next.js /api/* intern an das Python-Backend weiter (Port 8000 ist intern im Container), daher ist keine Frontend-Env-Datei erforderlich.
Für die lokale Entwicklung funktionieren die Standardwerte sofort — Sie müssen frontend/.env.local nicht erstellen, es sei denn, Ihr Backend läuft auf einem nicht-standardmäßigen Port.
Falls Sie überschreiben müssen, erstellen Sie frontend/.env.local manuell:
| Variable | Standard | Beschreibung |
|---|---|---|
NEXT_PUBLIC_API_URL | http://localhost:8000 (automatisch) | Backend-URL, die der Browser für direkte API-Aufrufe verwendet (OAuth-Umleitungen, Streaming). Wird automatisch von window.location erkannt, falls nicht gesetzt — überschreiben Sie nur, wenn Ihr Backend lokal auf einem nicht-standardmäßigen Port läuft. |
Hinweis zur Build-Zeit:NEXT_PUBLIC_*-Variablen werden zurpnpm build-Zeit in das JS-Bundle eingebettet. Das Ändern zur Laufzeit (z. B. über die root.env) hat keine Auswirkung — deshalb befinden sie sich nur für die lokale Entwicklung infrontend/.env.local.
LLM (erforderlich)
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
LLM_API_KEY | Ja | — | API-Schlüssel für den LLM-Anbieter |
LLM_BASE_URL | Nein | https://api.openai.com/v1 | Basis-URL einer beliebigen OpenAI-kompatiblen API |
LLM_MODEL | Nein | gpt-4o | Hauptmodell — verwendet für Planung, Analyse und ReAct-Agent |
FAST_LLM_MODEL | Nein | (fällt auf LLM_MODEL zurück) | Schnelles Modell — verwendet für DAG-Schrittausführung (günstiger, schneller) |
LLM_TEMPERATURE | Nein | 0.7 | Standard-Sampling-Temperatur |
LLM_CONTEXT_SIZE | Nein | 128000 | Kontextfenstergröße für das Haupt-LLM |
LLM_MAX_OUTPUT_TOKENS | Nein | 64000 | Max. Ausgabe-Token pro Aufruf für das Haupt-LLM |
FAST_LLM_API_KEY | Nein | (fällt auf LLM_API_KEY zurück) | API-Schlüssel für den Anbieter des schnellen Modells. Verwenden Sie dies, wenn das schnelle Modell von einem anderen Anbieter gehostet wird als das Hauptmodell |
FAST_LLM_BASE_URL | Nein | (fällt auf LLM_BASE_URL zurück) | Basis-URL für den Anbieter des schnellen Modells |
FAST_LLM_TEMPERATURE | Nein | (fällt auf LLM_TEMPERATURE zurück) | Sampling-Temperatur für das schnelle Modell |
FAST_LLM_CONTEXT_SIZE | Nein | (fällt auf LLM_CONTEXT_SIZE zurück) | Kontextfenstergröße für das schnelle LLM |
FAST_LLM_MAX_OUTPUT_TOKENS | Nein | (fällt auf LLM_MAX_OUTPUT_TOKENS zurück) | Max. Ausgabe-Token pro Aufruf für das schnelle LLM |
LLM_REASONING_EFFORT | Nein | (deaktiviert) | Erweitertes Denk-Level für unterstützte Modelle (OpenAI o-Serie, Gemini 2.5+, Claude). Werte: low, medium, high. LiteLLM übersetzt dies automatisch in das native Format jedes Anbieters. Die Chain-of-Thought des Modells wird im UI-Schritt „thinking” angezeigt. |
LLM_REASONING_BUDGET_TOKENS | Nein | (automatisch aus Effort) | Explizites Token-Budget für Anthropic-Denken (Minimum 1024). Für OpenAI/Gemini wird das Effort-Level direkt verwendet. Wirksam nur, wenn LLM_REASONING_EFFORT gesetzt ist. |
LLM_JSON_MODE_ENABLED | Nein | true | Globaler Schalter für response_format=json_object. Setzen Sie auf false, wenn Ihr Anbieter LiteLLMs Assistant-Prefill-Injektion ablehnt (z. B. AWS Bedrock Relay → ValidationException bei der 2.+ Agent-Iteration). Wenn deaktiviert, überspringen strukturierte Aufrufe den JSON-Modus und greifen auf einfache Text-Regex-Extraktion zurück — kein Qualitätsverlust. Gilt für alle Modelle (ENV-konfiguriert und Admin-konfiguriert). |
LLM_TOOL_CHOICE_ENABLED | Nein | true | Globaler Schalter für erzwungenes tool_choice bei strukturierter Ausgabeextraktion (Level 1 — Native Function Calling). Setzen Sie auf false, wenn Ihr Modell Fehler bei erzwungener Werkzeugauswahl zurückgibt (z. B. Denk-Modus-Modelle, die tool_choice='specified' ablehnen). Wenn deaktiviert, überspringen strukturierte Aufrufe natives FC und beginnen mit JSON-Modus. Pro-Modell-Überschreibung verfügbar in Einstellungen → Modelle → Erweitert. |
REASONING_LLM_MODEL | Nein | (fällt auf LLM_MODEL zurück) | Modellname für die Reasoning-Ebene. Verwendet für Aufgaben, die tiefe Analyse erfordern (z. B. DAG-Planung, Plan-Analyse) |
REASONING_LLM_API_KEY | Nein | (fällt auf LLM_API_KEY zurück) | API-Schlüssel für den Reasoning-Modell-Anbieter |
REASONING_LLM_BASE_URL | Nein | (fällt auf LLM_BASE_URL zurück) | Basis-URL für den Reasoning-Modell-Anbieter |
REASONING_LLM_TEMPERATURE | Nein | (fällt auf LLM_TEMPERATURE zurück) | Sampling-Temperatur für das Reasoning-Modell |
REASONING_LLM_CONTEXT_SIZE | Nein | (fällt auf LLM_CONTEXT_SIZE zurück) | Kontextfenstergröße für das Reasoning-Modell |
REASONING_LLM_MAX_OUTPUT_TOKENS | Nein | (fällt auf LLM_MAX_OUTPUT_TOKENS zurück) | Max. Ausgabe-Token pro Aufruf für das Reasoning-Modell |
REASONING_LLM_EFFORT | Nein | (fällt auf LLM_REASONING_EFFORT zurück) | Reasoning-Effort-Level für die Reasoning-Modell-Ebene. Werte: low, medium, high |
REASONING_LLM_BUDGET | Nein | (fällt auf LLM_REASONING_BUDGET_TOKENS zurück) | Token-Budget für Reasoning (hauptsächlich Anthropic). Überschreibt das automatisch berechnete Budget für die Reasoning-Ebene |
LLM_SUPPORTS_VISION | Nein | true (optimistisch) | Steuert, ob ENV-Modus-Dokument-OCR (über MarkItDown + markitdown-ocr) versucht wird. Gilt nur, wenn keine aktive Modellgruppe in Admin → Modelle konfiguriert ist (reiner ENV-Modus). Wenn der Standard true wirksam ist, nehmen convert_to_markdown und RAG-Erfassung an, dass LLM_MODEL Vision unterstützt, und rufen es für Bild-OCR auf — dies ist das richtige Verhalten für alle gängigen Optionen (gpt-4o, claude-3-5-sonnet, gemini-1.5-pro/flash). Setzen Sie dies auf false, wenn Ihr ENV-konfiguriertes LLM_MODEL Vision nicht unterstützt (z. B. deepseek-v3, qwen-chat, llama-3.1, gpt-3.5-turbo, o1-mini), um den fehlgeschlagenen Vision-Aufruf zu überspringen und direkt zur reinen Text-Extraktion zu gehen. Wenn eine aktive Modellgruppe im Admin → Modelle-Panel vorhanden ist, wird dieses Flag ignoriert und die supports_vision-Flags der Gruppe übernehmen — die von Admin kuratierte Wahl ist immer die Quelle der Wahrheit im DB-Modus. |
Auflösungsreihenfolge: Benutzereinstellung → Admin-Modelle (DB) → ENV-Fallback. Wenn ein Admin-Modell mit der Rolle „General” in Admin → Modelle konfiguriert ist, dienen diese ENV-Variablen nur als Fallback. Die Integritätsprüfung berücksichtigt beide Quellen.
MarkItDown OCR-Auflösung
Dasconvert_to_markdown Built-in-Tool und die RAG-Ingestion-Pipeline verwenden beide Microsofts MarkItDown + das offizielle markitdown-ocr Plugin, um Text aus Dokumenten zu extrahieren — einschließlich OCR auf eingebetteten Bildern und gescannten PDF-Seiten, wenn ein Vision-fähiges LLM verfügbar ist.
Vision-LLM-Auflösungsreihenfolge (erste Übereinstimmung gewinnt):
| # | Quelle | Prioritätsrationale |
|---|---|---|
| 1 | Primäres LLM des Agenten, wenn supports_vision=True | Konsistenz: gleicher API-Schlüssel, gleicher Abrechnungsbucket, gleicher Rate-Limit-Pool wie das Gespräch. |
| 2 | Aktive ModelGroup → Fast Model, wenn supports_vision=True | Fast Models (gpt-4o-mini, claude-haiku, gemini-1.5-flash) sind das ideale OCR-Arbeitstier — günstig, niedrige Latenz, normalerweise multimodal. |
| 3 | Aktive ModelGroup → General Model, wenn supports_vision=True | Qualitäts-Fallback, wenn das primäre Modell nicht in der Gruppe ist. |
| 4 | ENV primäres LLM (LLM_MODEL) | Optimistischer Fallback für reinen ENV-Modus. Wird nur verwendet, wenn keine aktive ModelGroup existiert. Gesteuert durch LLM_SUPPORTS_VISION. |
o1, o3-mini, DeepSeek-R1) haben historisch keine Vision-Unterstützung und sind ohnehin das falsche Werkzeug für OCR — OCR ist eine Wahrnehmungsaufgabe, keine Überlegungsaufgabe. Wenn ein Workspace nur ein Reasoning-Modell mit supports_vision=True hat, wird es trotzdem über den Primary-LLM-Pfad aufgegriffen, aber der Resolver stuft es nicht aktiv über Fast/General ein.
Null-Regressions-Fallback: Wenn auf keiner Ebene ein Vision-fähiges Modell gefunden wird, wird OCR stillschweigend deaktiviert und MarkItDown läuft im reinen Text-Modus. OCR für eingebettete Bilder in Word/PowerPoint/Excel wird nicht verfügbar (wie vor dieser Funktion), aber alle andere Textextraktion (Überschriften, Tabellen, Absatztext) funktioniert unverändert weiter. Es gibt niemals einen Fall, in dem das Hinzufügen dieser Funktion die Extraktion schlechter machte als das vorherige Verhalten.
Nicht-OpenAI-Provider (Anthropic, Google Gemini, etc.) werden transparent unterstützt: das aufgelöste LLM wird in einem LiteLLMOpenAIShim verpackt, das chat.completions.create(...)-Aufrufe durch litellm.completion() leitet, was die Provider-spezifische Nachrichtenformat-Übersetzung handhabt (z. B. Anthropics source.type="base64" Image-Block). Ein Shim deckt jeden Provider ab, den LiteLLM unterstützt — das Hinzufügen eines neuen Providers kostet null Code-Änderungen in FIM One.
Extended Thinking (Reasoning)
WennLLM_REASONING_EFFORT gesetzt ist, aktiviert FIM One die Extended-Thinking-Funktion des Modells, sodass die interne Gedankenkette im UI-Schritt “thinking” angezeigt wird. FIM One verwendet LiteLLM, um den Reasoning-Effort-Parameter automatisch in das native Format jedes Anbieters zu übersetzen.
Unterstützte Anbieter
| Anbieter | LLM_BASE_URL | Funktionsweise | Reasoning-Inhalt zurückgegeben? |
|---|---|---|---|
| OpenAI (o1 / o3 / o4-mini) | https://api.openai.com/v1 | reasoning_effort nativ gesendet | Ja |
| Anthropic (Claude 3.7+) | https://api.anthropic.com/v1/ | LiteLLM leitet über native Anthropic API mit thinking Parameter weiter | Ja |
| Google Gemini (2.5+) | https://generativelanguage.googleapis.com/v1beta/openai/ | reasoning_effort auf Kompatibilitäts-Endpunkt gesendet | Ja |
LLM_BASE_URL und ordnet ihn dem korrekten API-Format zu. Unbekannte URLs werden als OpenAI-kompatibel behandelt.
Wichtige Einschränkungen
Temperatureinschränkungen mit Reasoning
Einige Anbieter haben Temperatureinschränkungen, wenn Reasoning aktiv ist:- Anthropic: Erfordert
temperature=1, wenn erweitertes Denken aktiviert ist. Bei Verwendung von Anthropic mit erweitertem Denken müssen SieLLM_TEMPERATURE=1setzen — Anthropic lehnt andere Werte ab, wenn Denken aktiviert ist. - OpenAI GPT-5.x: Unterstützt nur
temperature=1zu allen Zeiten. LiteLLMsdrop_params-Filterung handhabt dies automatisch — nicht unterstützte Temperaturwerte werden stillschweigend gelöscht. Für GPT-5.x ist keine Benutzeraktion erforderlich.
Wie LLM_REASONING_BUDGET_TOKENS funktioniert
Diese Variable ist hauptsächlich für den Anthropic-Pfad relevant. Wenn gesetzt, überschreibt sie das automatisch berechnete Budget und wird als budget_tokens im thinking-Parameter über LiteLLM gesendet. Wenn nicht gesetzt, wird das Budget aus LLM_MAX_OUTPUT_TOKENS x Aufwandsverhältnis abgeleitet:
LLM_REASONING_EFFORT | Budget-Verhältnis | Beispiel (max_tokens = 64000) |
|---|---|---|
low | 20% | 12.800 Token |
medium | 50% | 32.000 Token |
high | 80% | 51.200 Token |
reasoning_effort-Ebene — LLM_REASONING_BUDGET_TOKENS hat keine Auswirkung.
Agent-Ausführung
ReAct-Agent
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
REACT_MAX_ITERATIONS | Nein | 20 | Max. Tool-Call-Iterationen pro ReAct-Anfrage. Höher = gründlicher, aber langsamer und teurer |
REACT_MAX_TURN_TOKENS | Nein | 0 | Notfall-Schutzschalter: max. kumulative Token (Prompt + Completion über alle Iterationen) pro einzelnem ReAct-Turn. Standard 0 = unbegrenzt. Dies ist NICHT für die tägliche Token-Kontrolle — verwenden Sie dafür token_quota pro Benutzer. Dies ist ein letzter Ausweg für extreme Szenarien wie einen Agent, der in einer Endlosschleife von Tool-Calls steckt. Das Erreichen dieses Limits bricht die Aufgabe während der Ausführung ab, verschwendet alle verbrauchten Token und gibt ein unvollständiges Ergebnis zurück. Behalten Sie 0 bei, es sei denn, Sie haben ein spezifisches Runaway-Agent-Problem zu kontrollieren |
REACT_TOOL_SELECTION_THRESHOLD | Nein | 12 | Wenn die Gesamtzahl der registrierten Tools diesen Schwellenwert überschreitet, wählt ein leichtgewichtiger LLM-Call die relevanteste Teilmenge vor jeder Anfrage aus |
REACT_TOOL_SELECTION_MAX | Nein | 6 | Max. Tools nach intelligenter Auswahl (nur wirksam, wenn die Tool-Anzahl REACT_TOOL_SELECTION_THRESHOLD überschreitet) |
REACT_SELF_REFLECTION_INTERVAL | Nein | 6 | Injizieren Sie alle N Tool-Calls einen Self-Reflection-Prompt, um dem Agent zu helfen, den Kurs zu korrigieren und Schleifen zu vermeiden |
REACT_TOOL_OBS_TRUNCATION | Nein | 8000 | Max. Zeichen pro Tool-Observation bei der Synthese der endgültigen Antwort. Höhere Werte bewahren mehr strukturierte Daten (JSON, Tabellen) auf Kosten von mehr Token |
REACT_TOOL_RESULT_BUDGET | Nein | 40000 | Aggregiertes Token-Budget für alle Tool-Ergebnisse in einer einzelnen Sitzung. Wenn die Gesamtzahl der Tool-Result-Token diese Obergrenze überschreitet, werden neue Ergebnisse mit einer Benachrichtigung gekürzt. Verhindert Context-Überfluss durch große API-Responses (z. B. 5 Connector-Calls, die jeweils 8K zurückgeben). Setzen Sie auf 0, um die Obergrenze zu deaktivieren |
REACT_COMPLETION_CHECK_SKIP_CHARS | Nein | 800 | Überspringen Sie den Post-Answer-Completion-Check-LLM-Call, wenn die endgültige Antwort des Agents diese Anzahl von Zeichen überschreitet. Lange detaillierte Antworten benötigen keine “Habe ich etwas übersehen?”-Verifikations-Roundtrip. Setzen Sie niedriger, um aggressiver zu überspringen; setzen Sie auf einen sehr großen Wert, um die Überprüfung immer auszuführen |
REACT_CYCLE_DETECTION_THRESHOLD | Nein | 2 | Wenn dasselbe Tool mit identischen Argumenten diese Anzahl von Malen hintereinander aufgerufen wird, wird eine deterministische Warnung injiziert, die den Agent auffordert, einen anderen Ansatz zu versuchen. Im Gegensatz zu Self-Reflection (das sich auf die LLM-Erkennung der Schleife verlässt), ist dies eine Hash-basierte Überprüfung, die nicht umgangen werden kann. Gilt auch für DAG-Schritte |
REACT_COMPLETION_CHECK_MIN_TOOLS | Nein | 3 | Minimale Anzahl von Tool-Calls, bevor die Completion-Checkliste ausgelöst wird. Einfache Aufgaben (1-2 Tool-Calls) überspringen die Verifizierung, um unnötige Latenz zu vermeiden. Setzen Sie auf 1 für immer aktivierte Verifizierung. Gilt auch für DAG-Schritte |
REACT_TURN_PROFILE_ENABLED | Nein | true | Geben Sie Pro-Turn-Phase-Level-Timing-Logs aus (memory_load, compact, tool_schema_build, llm_first_token, llm_total, tool_exec). Eine strukturierte Log-Zeile pro Turn. Setzen Sie auf false, um Profiling vollständig zu deaktivieren (null Overhead) |
LLM_RATE_LIMIT_PER_USER | Nein | true | Verwenden Sie Pro-Benutzer-Schlüssel-Rate-Limit-Buckets anstelle eines einzelnen prozessweiten Buckets. Verhindert, dass ein lauter Benutzer alle anderen auf demselben Worker aushungert. Die zugrunde liegende Rate ist auf 60 Anfragen/Min und 100K Token/Min pro Bucket fest codiert — diese Einstellung kontrolliert nur, ob der Bucket gemeinsam genutzt wird (global) oder partitioniert wird (pro Benutzer). Setzen Sie auf false, um zum Legacy-Global-Bucket zurückzukehren (nicht empfohlen) |
DAG-Planer
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
MAX_CONCURRENCY | Nein | 5 | Max parallele Schritte im DAG-Executor |
DAG_STEP_MAX_ITERATIONS | Nein | 15 | Max Tool-Call-Iterationen innerhalb jedes DAG-Schritts |
DAG_STEP_TIMEOUT | Nein | 600 | Timeout für Schrittausführung in Sekunden. Schritte, die diesen Wert überschreiten, werden als fehlgeschlagen markiert und ihre abhängigen Schritte werden kaskadierend übersprungen |
DAG_MAX_REPLAN_ROUNDS | Nein | 3 | Max autonome Neuplanungsversuche, wenn das Ziel nicht erreicht wird. Benutzerunterbrechungen (Inject) sind unbegrenzt und zählen nicht gegen dieses Budget |
DAG_REPLAN_STOP_CONFIDENCE | Nein | 0.8 | Wiederholungen beenden, wenn die Konfidenz des Agenten, dass das Ziel nicht erreichbar ist, diesen Schwellenwert überschreitet (0.0 = nie früh beenden, 1.0 = bei jedem Fehler beenden) |
DAG_VERIFY_TRUNCATION | Nein | 2000 | Max Zeichen der Schrittausgabe, die an die Schrittverifikations-LLM zur Qualitätsprüfung gesendet werden |
DAG_ANALYZER_TRUNCATION | Nein | 10000 | Max Zeichen pro Schrittergebnis bei der Formatierung für den Post-Execution-Analyzer |
DAG_REPLAN_RECENT_TRUNCATION | Nein | 500 | Max Zeichen pro Schrittergebnis aus der letzten Runde beim Aufbau des Neuplanungskontexts |
DAG_REPLAN_OLDER_TRUNCATION | Nein | 200 | Max Zeichen pro Schrittergebnis aus älteren Runden beim Aufbau des Neuplanungskontexts. Ältere Runden werden aggressiver gekürzt, um Kontext zu sparen |
DAG_TOOL_CACHE | Nein | true | Cache identischer Tool-Aufrufe innerhalb einer einzelnen DAG-Ausführung. Nur Tools, die explizit als cacheable markiert sind (schreibgeschützte Tools wie Suche, Wissensbeschaffung), werden gecacht. Auf false setzen, um das Caching vollständig zu deaktivieren |
DAG_STEP_VERIFICATION | Nein | false | Generische LLM-basierte Qualitätsprüfung nach jedem DAG-Schritt. Bei Fehler wird der Schritt einmal mit Feedback wiederholt. Standardmäßig aus — fügt auf jedem Schritt Latenz hinzu und ist selten erforderlich; die meisten Schrittergebnisse sind ohne erneute Überprüfung akzeptabel. Verwenden Sie dies nur, wenn Sie häufig niedrige Qualität der Schrittergebnisse beobachten |
DAG_CITATION_VERIFICATION | Nein | true | Genauigkeitsprüfung von Zitaten für Schritte in Spezialdomänen. Voraussetzung: Die Abfrage muss zunächst vom LLM-Domänenklassifizierer als Spezialdomäne klassifiziert werden (siehe ESCALATION_DOMAINS). Wenn die Domäne erkannt wird UND dieses Flag true ist, wird jeder abgeschlossene Schritt auf rechtliche/medizinische/finanzielle Zitate gescannt und auf Genauigkeit überprüft — um halluzinierte Artikelnummern, erfundene Fallreferenzen und falsche behördliche Zitate zu erkennen. Wenn die Domänenklassifizierung null zurückgibt (allgemeine Abfrage), wird die Zitatverifikation unabhängig von dieser Einstellung nicht ausgeführt |
DAG_CITATION_VERIFY_TRUNCATION | Nein | 6000 | Max Zeichen des Schrittergebnisses, die an den Zitatverifikationsprompt gesendet werden |
Domain-Klassifizierung
Steuert die unabhängige LLM-basierte Domain-Erkennungsschicht, die vor der ReAct- und DAG-Ausführung ausgeführt wird. Wenn eine Abfrage als spezialisierte Domain klassifiziert wird, aktiviert das System Domain-bewusste Funktionen: Modellsteigerung auf Reasoning-Modell, Domain-spezifische SOP-Anweisungen und Zitierverifikation (nur DAG).| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
ESCALATION_DOMAINS | Nein | legal,medical,financial,tax,compliance,patent | Kommagetrennte Liste spezialisierter Domains. Ein schnelles LLM klassifiziert jede Abfrage gegen diese Liste. Bei Übereinstimmung führt das System folgende Schritte durch: (1) Upgrade auf das Reasoning-Modell für höhere Genauigkeit, (2) Injektion von Domain-spezifischen SOP-Anweisungen (z. B. Zitate vor dem Schreiben per Suche verifizieren), (3) Aktivierung der Zitierverifikation für DAG-Schritte. Fügen Sie nach Bedarf benutzerdefinierte Domains hinzu (z. B. legal,education,construction) |
Context Guard
Steuert die automatische Verwaltung des Kontextfensters, die verhindert, dass Gespräche das Limit des Modells überschreiten.| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
CONTEXT_GUARD_DEFAULT_BUDGET | Nein | 32000 | Standard-Token-Budget für die Verwaltung des Kontextfensters. Wenn das Gespräch diesen Wert überschreitet, werden ältere Nachrichten komprimiert |
CONTEXT_GUARD_MAX_MSG_CHARS | Nein | 50000 | Hartes Zeichenlimit für jede einzelne Nachricht. Nachrichten, die diesen Wert überschreiten, werden als Sicherheitsmaßnahme gekürzt |
CONTEXT_GUARD_KEEP_RECENT | Nein | 4 | Anzahl der neuesten Nachrichten, die bei der Komprimierung des Gesprächsverlaufs beibehalten werden |
Agent-Arbeitsbereich
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
WORKSPACE_OFFLOAD_THRESHOLD | Nein | 8000 | Wenn eine Werkzeugausgabe diese Anzahl von Zeichen überschreitet, wird sie in einer Arbeitsbereichsdatei gespeichert und eine gekürzte Vorschau wird in den Gesprächskontext eingefügt |
WORKSPACE_PREVIEW_CHARS | Nein | 2000 | Anzahl der Vorschauzeichen, die in gekürzten Arbeitsbereichsreferenzen enthalten sein sollen |
WORKSPACE_CLEANUP_MAX_HOURS | Nein | 72 | Arbeitsbereichsdateien, die älter als diese Anzahl von Stunden sind, sind für die automatische Bereinigung berechtigt |
System
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
SYSTEM_PROMPT_RESERVE | — | — | Entfernt. Subtrahierte zuvor eine feste 4K-Reserve vom Kontext-Budget für System-Prompts. Dies führte zu Doppelzählungen, da ContextGuard die System-Prompt bereits bei der Schätzung der Token der Nachrichtenliste berücksichtigt. Die Budget-Formel ist nun einfach context_size - max_output_tokens, und die tatsächliche Größe der System-Prompt wird dynamisch berücksichtigt |
Web-Tools (Optional)
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
JINA_API_KEY | Nein | — | Jina API-Schlüssel. Fungiert als gemeinsamer Fallback für Suche, Abruf, Einbettung und Reranking, wenn kein servicespezifischer Schlüssel gesetzt ist. Erhalten Sie Ihren unter jina.ai |
TAVILY_API_KEY | Nein | — | Tavily Search API-Schlüssel (automatisch ausgewählt, wenn gesetzt und WEB_SEARCH_PROVIDER nicht gesetzt ist) |
BRAVE_API_KEY | Nein | — | Brave Search API-Schlüssel (automatisch ausgewählt, wenn gesetzt und WEB_SEARCH_PROVIDER nicht gesetzt ist) |
EXA_API_KEY | Nein | — | Exa Search API-Schlüssel (automatisch ausgewählt, wenn gesetzt und WEB_SEARCH_PROVIDER nicht gesetzt ist). Erhalten Sie Ihren unter exa.ai |
WEB_SEARCH_PROVIDER | Nein | jina | Suchanbieterwähler: jina / tavily / brave / exa |
WEB_FETCH_PROVIDER | Nein | jina (wenn Schlüssel gesetzt, sonst httpx) | Abrufsanbieter: jina (verwendet Jina Reader API) / httpx (direkte HTTP-Anfrage, kein API-Schlüssel erforderlich) |
Schnellstart-Tipp: Das Setzen von nur JINA_API_KEY aktiviert Web-Suche, Web-Abruf, Einbettung und Reranking auf einmal – ein Schlüssel, vier Services. Sie können jeden Service einzeln mit den folgenden Variablen überschreiben.
RAG & Wissensdatenbank (Empfohlen)
Embedding
Embedding konvertiert Text in Vektoren für die Wissensdatenbank-Suche. FIM One verwendet den Standard-OpenAI-kompatiblen/v1/embeddings-Endpunkt, daher funktioniert er mit jedem Anbieter, der diese Schnittstelle bereitstellt — nicht nur Jina.
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
EMBEDDING_API_KEY | Nein | (fällt auf JINA_API_KEY zurück) | API-Schlüssel für den Embedding-Anbieter |
EMBEDDING_BASE_URL | Nein | https://api.jina.ai/v1 | Basis-URL für den Embedding-Anbieter |
EMBEDDING_MODEL | Nein | jina-embeddings-v3 | Modellbezeichner |
EMBEDDING_DIMENSION | Nein | 1024 | Vektordimension |
| Anbieter | EMBEDDING_BASE_URL | EMBEDDING_MODEL | EMBEDDING_DIMENSION |
|---|---|---|---|
| Jina (Standard) | https://api.jina.ai/v1 | jina-embeddings-v3 | 1024 |
| OpenAI | https://api.openai.com/v1 | text-embedding-3-small | 1536 |
| Voyage | https://api.voyageai.com/v1 | voyage-3 | 1024 |
| Ollama (lokal) | http://localhost:11434/v1 | nomic-embed-text | 768 |
Abruf
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
RETRIEVAL_MODE | Nein | grounding | grounding (vollständige Pipeline mit Zitaten und Konfidenzscoring) oder simple (grundlegende RAG) |
Reranker
Reranker bewertet abgerufene Dokumente neu, um die Relevanz zu verbessern. Drei Anbieter werden unterstützt — wählen Sie überRERANKER_PROVIDER oder lassen Sie das System automatisch aus verfügbaren API-Schlüsseln erkennen.
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
RERANKER_PROVIDER | Nein | (automatische Erkennung) | jina / cohere / openai. Falls nicht gesetzt: verwendet Cohere, wenn COHERE_API_KEY gesetzt ist, andernfalls Jina |
RERANKER_MODEL | Nein | jina-reranker-v2-base-multilingual | Modellkennung (gilt für Jina- und OpenAI-Anbieter) |
COHERE_API_KEY | Nein | — | Cohere API-Schlüssel (wählt automatisch Cohere-Reranker aus, wenn gesetzt und RERANKER_PROVIDER nicht gesetzt ist) |
COHERE_RERANKER_MODEL | Nein | rerank-multilingual-v3.0 | Cohere-spezifisches Reranker-Modell |
Jina verwendetJINA_API_KEY(aus Web Tools oben). OpenAI verwendetLLM_API_KEY/LLM_BASE_URLerneut — kein zusätzlicher Schlüssel erforderlich. Cohere benötigt seinen eigenenCOHERE_API_KEY.
Reranker ist optional — die Wissensdatenbanksuche funktioniert ohne ihn mit Fusion-Scoring. Embedding wird empfohlen für Wissensdatenbankfunktionen.
Vektorspeicher
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
VECTOR_STORE_DIR | Nein | ./data/vector_store | Verzeichnis für LanceDB-Vektorspeicherdaten (dateibasiert, keine externen Dienste) |
Code-Ausführung
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
CODE_EXEC_BACKEND | Nein | local | local (direkte Host-Ausführung) oder docker (isolierte Container) |
DOCKER_PYTHON_IMAGE | Nein | python:3.11-slim | Docker-Image für Python-Ausführung |
DOCKER_NODE_IMAGE | Nein | node:20-slim | Docker-Image für Node.js-Ausführung |
DOCKER_SHELL_IMAGE | Nein | python:3.11-slim | Docker-Image für Shell-Ausführung |
DOCKER_MEMORY | Nein | (Docker-Standard) | RAM-Limit pro Container (z. B. 256m, 512m, 1g) |
DOCKER_CPUS | Nein | (Docker-Standard) | CPU-Kontingent pro Container (z. B. 0.5, 1.0) |
SANDBOX_TIMEOUT | Nein | 120 | Standard-Ausführungs-Timeout in Sekunden |
DOCKER_HOST_DATA_DIR | Nein | (nicht gesetzt) | Host-seitiger absoluter Pfad des ./data Volume-Mounts. Erforderlich für DooD-Bereitstellungen (Docker-outside-of-Docker); docker-compose.yml setzt dies automatisch über ${PWD}/data. |
Sicherheit: Derlocal-Modus führt von KI generierte Code direkt auf dem Host aus. Für internetgestützte oder Multi-User-Bereitstellungen sollten Sie immerCODE_EXEC_BACKEND=dockersetzen.
Werkzeug-Artefakte
Größenlimits für Dateien, die durch Werkzeugausführung erstellt werden (Code-Ausführung, Template-Rendering, Bildgenerierung).| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
MAX_ARTIFACT_SIZE | Nein | 10485760 (10 MB) | Maximale Größe einer einzelnen Artefaktdatei in Bytes |
MAX_ARTIFACTS_TOTAL | Nein | 52428800 (50 MB) | Maximale Gesamtgröße der Artefakte pro Sitzung in Bytes |
Dokumentverarbeitung (Optional)
Steuert, wie hochgeladene PDF-/DOCX-Dateien für die LLM-Verarbeitung verarbeitet werden. Vision-fähige Modelle (GPT-4o, Claude 3/4, Gemini) können PDF-Seiten als gerenderte Bilder für höhere Genauigkeit empfangen.| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
DOCUMENT_PROCESSING_MODE | Nein | auto | auto (Vision, falls Modell unterstützt), vision (Seiten immer rendern), text (nur Text extrahieren) |
DOCUMENT_VISION_DPI | Nein | 150 | DPI für PDF-Seitenrendering. Höher = bessere Qualität, mehr Token |
DOCUMENT_VISION_MAX_PAGES | Nein | 20 | Maximale Anzahl von Seiten, die pro PDF als Bilder gerendert werden |
Hinweis: Die Vision-Unterstützung pro Modell wird über den supports_vision-Schalter in Admin → Models konfiguriert. Wenn nicht explizit festgelegt, erkennt das System die Vision-Fähigkeit automatisch anhand des Modellnamens.
Bildgenerierung (Optional)
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
IMAGE_GEN_PROVIDER | Nein | google | google (Gemini native API) oder openai (OpenAI-kompatible /v1/images/generations) |
IMAGE_GEN_API_KEY | Nein | — | Google AI Studio Schlüssel (google) oder Proxy/OpenAI API Schlüssel (openai) |
IMAGE_GEN_MODEL | Nein | gemini-3.1-flash-image-preview | Bildgenerierungsmodell (z. B. dall-e-3, gemini-nano-banana-2) |
IMAGE_GEN_BASE_URL | Nein | (pro Anbieter) | Google: https://generativelanguage.googleapis.com/v1beta; OpenAI: https://api.openai.com/v1 |
E-Mail (SMTP) (Empfohlen)
Registriert dasemail_send Built-in-Tool automatisch, wenn SMTP_HOST, SMTP_USER und SMTP_PASS alle gesetzt sind.
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
SMTP_HOST | Bed. | — | SMTP-Server-Hostname |
SMTP_PORT | Nein | 465 | SMTP-Port |
SMTP_SSL | Nein | ssl | TLS-Modus: ssl (Port 465) / tls (STARTTLS, Port 587) / "" (unverschlüsselt) |
SMTP_USER | Bed. | — | SMTP-Benutzername |
SMTP_PASS | Bed. | — | SMTP-Passwort |
SMTP_FROM | Nein | (verwendet SMTP_USER) | Absenderadresse im From-Header |
SMTP_FROM_NAME | Nein | — | Anzeigename im From-Header |
SMTP_REPLY_TO | Nein | — | Reply-To-Adresse; Antworten gehen hierher statt zu SMTP_FROM |
SMTP_ALLOWED_DOMAINS | Nein | — | Kommagetrennte Domain-Allowlist (z. B. example.com,corp.io); blockiert Empfänger außerhalb der aufgelisteten Domains |
SMTP_ALLOWED_ADDRESSES | Nein | — | Kommagetrennte Exact-Address-Allowlist; kombiniert mit SMTP_ALLOWED_DOMAINS; beide nicht gesetzt, um jeden Empfänger zuzulassen (nicht empfohlen für gemeinsame Postfächer) |
Konnektoren
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
CONNECTOR_RESPONSE_MAX_CHARS | Nein | 50000 | Maximale Anzahl von Zeichen für Antworten von Nicht-Array-JSON-/Klartext-Konnektoren |
CONNECTOR_RESPONSE_MAX_ITEMS | Nein | 10 | Maximale Array-Elemente, die beibehalten werden, wenn die Konnektor-Antwort ein JSON-Array ist |
CREDENTIAL_ENCRYPTION_KEY | Nein | (nicht gesetzt) | Fernet-Verschlüsselungsschlüssel für Konnektor-Anmeldedaten-Blobs. Wenn gesetzt, werden Auth-Token in connector_credentials im Ruhezustand verschlüsselt. Wenn nicht gesetzt, werden Anmeldedaten als einfaches JSON gespeichert (abwärtskompatibel). Das Ändern dieses Schlüssels macht alle vorhandenen verschlüsselten Anmeldedaten ungültig. |
CONNECTOR_TOOL_MODE | Nein | progressive | Wie Konnektor-Tools für Agenten verfügbar gemacht werden. progressive: einzelnes ConnectorMetaTool mit discover/execute-Unterbefehlen (~30 Token/Konnektor). classic: ein Tool pro Aktion (Legacy, ~250 Token/Aktion). |
DATABASE_TOOL_MODE | Nein | progressive | Wie Datenbank-Konnektor-Tools für Agenten verfügbar gemacht werden. progressive: einzelnes DatabaseMetaTool mit list_tables/discover/query-Unterbefehlen. legacy: ein Tool pro Aktion pro Datenbank-Konnektor (3 Tools jeweils). |
MCP_TOOL_MODE | Nein | progressive | Wie MCP-Server-Tools für Agenten verfügbar gemacht werden. progressive: einzelnes MCPServerMetaTool mit discover/call-Unterbefehlen. legacy: ein Tool pro MCP-Server-Aktion (ursprüngliche einzelne Tools). |
Plattform
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
DATABASE_URL | Nein | sqlite+aiosqlite:///./data/fim_one.db | Datenbankverbindungszeichenfolge. SQLite (keine Konfiguration erforderlich): sqlite+aiosqlite:///./data/fim_one.db. PostgreSQL (Produktion): postgresql+asyncpg://user:pass@localhost:5432/fim_one. Docker Compose konfiguriert PostgreSQL automatisch. |
JWT_SECRET_KEY | Nein | CHANGE_ME | Geheimer Schlüssel zum Signieren von JWT-Token. Der Platzhalterwert CHANGE_ME (oder ein anderer Legacy-Standard) löst beim ersten Start die automatische Generierung eines sicheren 256-Bit-Zufallsschlüssels aus, der in .env zurückgeschrieben wird. Legen Sie diesen in der Produktion explizit fest, um Token über Neustarts und Replikationen hinweg gültig zu halten. |
CORS_ORIGINS | Nein | — | Kommagetrennte Liste zusätzlicher zulässiger CORS-Ursprünge neben den Standard-Localhost-Einträgen. Erforderlich, wenn das Frontend auf einer Nicht-Localhost-Domain ausgeführt wird (z. B. https://app.example.com). |
UPLOADS_DIR | Nein | ./uploads | Verzeichnis für hochgeladene Dateien |
MAX_UPLOAD_SIZE_MB | Nein | 50 | Maximale Dateigröße beim Upload in Megabyte (Backend-Durchsetzung) |
NEXT_PUBLIC_MAX_UPLOAD_SIZE_MB | Nein | 50 | Maximale Dateigröße beim Upload in der Frontend-UI. Build-Zeit-Variable — muss mit MAX_UPLOAD_SIZE_MB übereinstimmen. |
MCP_SERVERS | Nein | — | JSON-Array von MCP-Serverkonfigurationen (erfordert uv sync --extra mcp) |
ALLOW_STDIO_MCP | Nein | false | Erlaube stdio MCP-Server. Setzen Sie auf true nur für vertrauenswürdige lokale Bereitstellungen |
ALLOWED_STDIO_COMMANDS | Nein | npx,uvx,node,python,python3,deno,bun | Kommagetrennte Liste zulässiger Basisbefehle für stdio MCP-Server. Wirksam nur, wenn ALLOW_STDIO_MCP=true |
LOG_LEVEL | Nein | INFO | Protokollierungsstufe: DEBUG / INFO / WARNING / ERROR / CRITICAL |
REDIS_URL | Nein | — | Redis-Verbindungs-URL für Worker-übergreifendes Interrupt-Relay. Erforderlich, wenn WORKERS>1 — ohne diese können Mid-Stream-Interrupt-/Inject-Anfragen einen anderen Worker treffen und stillschweigend fehlschlagen. Wird von Docker Compose automatisch konfiguriert. |
WORKERS | Nein | 1 | Uvicorn-Worker-Prozesse. 1 ist sicher und benötigt keine externen Dienste. Für Multi-Worker-Produktion verwenden Sie PostgreSQL (SQLite ist Single-Writer). SQLite funktioniert für lokale Entwicklung unter leichter Last. Authentifizierung, OAuth und Dateivorgänge sind vollständig Multi-Worker-sicher (JWT-basiert). Docker Compose konfiguriert automatisch sowohl PostgreSQL als auch Redis. |
Workflow Run Retention
Background cleanup task that automatically purges old workflow runs. Per-workflow overrides (configured in the workflow settings UI) take priority over these global defaults.| Variable | Required | Default | Description |
|---|---|---|---|
WORKFLOW_RUN_MAX_AGE_DAYS | No | 30 | Delete workflow runs older than this many days |
WORKFLOW_RUN_MAX_PER_WORKFLOW | No | 100 | Keep at most this many runs per workflow (oldest deleted first) |
WORKFLOW_RUN_CLEANUP_INTERVAL_HOURS | No | 24 | How often the background cleanup task runs, in hours |
Channel Confirmation Request Expiry
Background sweeper that marks stale pending approval requests (produced by channel hooks likeFeishuGateHook or the Approval Playground) as expired. Ensures a click days later on a forgotten card doesn’t flip agent state that has already been torn down.
| Variable | Required | Default | Description |
|---|---|---|---|
CHANNEL_CONFIRMATION_TTL_MINUTES | No | 1440 | Pending confirmations older than this are auto-expired (default: 24 hours) |
CHANNEL_CONFIRMATION_SWEEP_INTERVAL_SECONDS | No | 600 | How often the expiry sweeper runs (default: every 10 minutes) |
OAuth (Optional)
Wenn sowohlCLIENT_ID als auch CLIENT_SECRET für einen Anbieter gesetzt sind, zeigt die Anmeldeseite automatisch die entsprechende OAuth-Schaltfläche an.
| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
GITHUB_CLIENT_ID | Nein | — | GitHub OAuth App Client ID. Erstellen Sie diese unter github.com/settings/developers → OAuth Apps |
GITHUB_CLIENT_SECRET | Nein | — | GitHub OAuth App Client Secret |
GOOGLE_CLIENT_ID | Nein | — | Google OAuth Client ID. Erstellen Sie diese unter console.cloud.google.com/apis/credentials |
GOOGLE_CLIENT_SECRET | Nein | — | Google OAuth Client Secret |
DISCORD_CLIENT_ID | Nein | — | Discord OAuth2 Client ID. Erstellen Sie diese unter discord.com/developers |
DISCORD_CLIENT_SECRET | Nein | — | Discord OAuth2 Client Secret |
FEISHU_APP_ID | Nein | — | Feishu (Lark) App ID. Erstellen Sie diese unter open.feishu.cn. Erfordert die Berechtigung contact:user.email:readonly |
FEISHU_APP_SECRET | Nein | — | Feishu (Lark) App Secret |
FRONTEND_URL | Prod | http://localhost:3000 | Wo der Browser nach Abschluss von OAuth landet. Muss in der Produktion gesetzt werden (z. B. https://yourdomain.com) |
API_BASE_URL | Prod | http://localhost:8000 | Extern erreichbare Backend-URL, wird zum Erstellen von OAuth-Callback-URLs verwendet. Muss in der Produktion gesetzt werden |
NEXT_PUBLIC_API_URL | Prod | (automatisch erkannt als <hostname>:8000) | Browser-seitige API-Basis-URL für OAuth-Umleitungen. Dies ist eine Frontend-Build-Zeit-Variable — setzen Sie diese in frontend/.env.local für lokale Entwicklung oder übergeben Sie sie als Docker-Build-Argument für benutzerdefinierte Produktionsbereitstellungen. Die automatische Erkennung funktioniert für Standard-Reverse-Proxy-Setups (Port 80/443). |
Prod = lokal optional (Standardwerte funktionieren), aber erforderlich für jede Bereitstellung mit Internetzugriff.
OAuth-Callback-URLs zum Registrieren bei jedem Anbieter
Das Backend konstruiert Callback-URLs als:{API_BASE_URL}/api/auth/oauth/{provider}/callback
| Anbieter | Zu registrierende Callback-URL |
|---|---|
| GitHub | https://yourdomain.com/api/auth/oauth/github/callback |
https://yourdomain.com/api/auth/oauth/google/callback | |
| Discord | https://yourdomain.com/api/auth/oauth/discord/callback |
Cloudflare Tunnel (Optional)
Leiten Sie den gesamten Datenverkehr über Cloudflares Netzwerk um, anstatt Ports direkt freizulegen. Eliminiert die Notwendigkeit für Nginx, SSL-Zertifikate und offene Firewall-Regeln. Siehe den Abschnitt Production Deployment für Setupanweisungen.| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
CLOUDFLARE_TUNNEL_TOKEN | Ja (bei Verwendung von Tunnel) | — | Token von Cloudflare Zero Trust → Networks → Tunnels → Ihr Tunnel → Configure. Beginnt mit eyJ.... Erforderlich durch den cloudflared Sidecar in docker-compose.tunnel.yml. |
Analytics (Optional)
Alle Analytics-Anbieter sind optional. Legen Sie eine beliebige Kombination fest — alle aktiven Anbieter werden gleichzeitig geladen. Lassen Sie alle leer, um Analytics vollständig zu deaktivieren (empfohlen für lokale Entwicklung).| Variable | Erforderlich | Standard | Beschreibung |
|---|---|---|---|
NEXT_PUBLIC_GA_MEASUREMENT_ID | Nein | — | Google Analytics 4 Measurement ID (z. B. G-XXXXXXXXXX). Rufen Sie Ihre ID unter analytics.google.com ab |
NEXT_PUBLIC_UMAMI_SCRIPT_URL | Nein | — | Umami Analytics Script URL (z. B. https://your-umami.com/script.js). Selbst gehostete, datenschutzfreundliche Alternative — umami.is |
NEXT_PUBLIC_UMAMI_WEBSITE_ID | Nein | — | Umami Website ID. Erforderlich, wenn NEXT_PUBLIC_UMAMI_SCRIPT_URL gesetzt ist |
NEXT_PUBLIC_PLAUSIBLE_DOMAIN | Nein | — | Plausible Analytics Domain (z. B. yourdomain.com). Leichtgewichtig, datenschutzfreundlich — plausible.io |
NEXT_PUBLIC_PLAUSIBLE_SCRIPT_URL | Nein | https://plausible.io/js/script.js | Benutzerdefinierte Plausible Script URL für selbst gehostete Instanzen |
Alle NEXT_PUBLIC_* Analytics-Variablen sind Build-Zeit — Änderungen erfordern einen Frontend-Rebuild, um wirksam zu werden.