Open WebUI — Konfigurations-Quirks

Open WebUI hat einige Eigenheiten die nicht in der Doku stehen (oder zumindest nicht offensichtlich auffindbar sind). Diese Sammlung spart bei kuenftigen Kunden-Setups Stunden.

Env-Var-Naming hat geaendert (0.6+)

Beim Setup ueber CDK/Docker-Compose nicht die alten Namen verwenden:

# DEPRECATED (werden nicht mehr gelesen):
ENABLE_RAG_WEB_SEARCH
RAG_WEB_SEARCH_ENGINE
RAG_WEB_SEARCH_RESULT_COUNT

# AKTUELLE NAMEN:
ENABLE_WEB_SEARCH
WEB_SEARCH_ENGINE
WEB_SEARCH_RESULT_COUNT
WEB_SEARCH_CONCURRENT_REQUESTS

Aber: manche Vars mit RAG_-Praefix werden trotzdem auf die neue Form gemappt (z.B. RAG_WEB_SEARCH_RESULT_COUNTWEB_SEARCH_RESULT_COUNT), andere nicht (ENABLE_RAG_WEB_SEARCH wird ignoriert). Inkonsistent, also lieber alle Vars ohne RAG_-Praefix setzen.

Verify-Endpoint: GET /api/v1/retrieval/config zeigt was Open WebUI tatsaechlich liest. Bei ENABLE_WEB_SEARCH: false obwohl du ENABLE_RAG_WEB_SEARCH=true gesetzt hast → falsche Var-Namen.

Web-Search ist KEIN LLM-Tool sondern RAG-Pipeline

Wichtige konzeptuelle Unterscheidung:

  • fetch_url Tool — built-in LLM-Tool, der Agent ruft das aktiv auf. Open WebUI registriert es als Tool wenn builtin_tools: true in Model-Capabilities. ABER: bei Custom Models mit attached MCP (z.B. unsere mcp-vf-hosted) werden Built-in-Tools NICHT durchgereicht — nur die MCP-Tools. Heisst: der Agent hat fetch_url nicht im Tool-Set.

  • Web Search Feature — RAG-Pipeline. User klickt im Chat-Input auf den „Web Search”-Toggle, Open WebUI ruft VOR dem LLM-Call die konfigurierte Search-Engine (Tavily, Brave, SearXNG, …), packt Ergebnisse + Volltext-Pages als Context-Block in den User-Prompt. Der LLM sieht’s als Teil des Prompts, nicht als Tool-Call.

Konsequenz: bei vf-sonnet-style Custom-Models mit MCP-Tools fehlen die builtin tools. Web-Recherche-Anfragen funktionieren nur ueber den Web-Search-Toggle. Optionen:

(a) User-Bildung — sie lernen den Toggle zu nutzen. Pragmatisch, aber bricht das „Agent-fuehlt-sich-wie-Praktikant”-Gefuehl.

(b) Web-Fetch als MCP-Tool nachbauen — eigenes Tool im Mono-MCP der die Search-Engine via API aufruft. Dann hat der Agent es im Tool-Set, immer verfuegbar. Empfohlener Pfad fuer Production-Kunden-Setups.

(c) builtin_tools: true plus defaultFeatureIds: ["web_search"] setzen und hoffen dass Open WebUI’s interne Logik beides parallel ausspielt. Hat im VF-Test nicht funktioniert.

WEB_LOADER_ENGINE MUSS gesetzt sein

Wenn Web-Search aktiv ist und der Agent fetch_url callt (auch ueber den User-Toggle), explodiert es mit:

UnboundLocalError: cannot access local variable 'WebLoaderClass' where it is not associated with a value
  in /app/backend/open_webui/tools/builtin.py:251, in fetch_url

Ursache: WEB_LOADER_ENGINE ist null/leer in der DB. Open WebUI’s fetch_url initialisiert WebLoaderClass nur in if/elif-Branches abhaengig vom Engine-Wert — bei null wird kein Branch genommen + die Variable bleibt undefiniert.

Fix:

WEB_LOADER_ENGINE=safe_web
ENABLE_WEB_LOADER_SSL_VERIFICATION=true
WEB_LOADER_CONCURRENT_REQUESTS=10
BYPASS_WEB_SEARCH_WEB_LOADER=false

Engines: safe_web (requests-basiert, Default-Wahl), playwright (rendert JS, braucht extra Setup), external (eigener Loader-Service).

Admin-API-Updates ueberschreiben Env-Vars (gut so)

Open WebUI persistiert Config aus drei Quellen, in dieser Prioritaet (niedrigste zuerst):

  1. Env-Vars beim Container-Start — Initialwerte
  2. DB-Config — was im Admin Panel oder via POST /api/v1/...config/update geaendert wird
  3. Sessions-Override — Per-User-Setting im Chat (z.B. Toggle)

Heisst: was du via Admin-API in der DB setzt, ueberlebt Container-Restart und ueberschreibt die Env-Vars beim naechsten Boot. Praktisch fuer Quick-Fixes ohne CDK-Redeploy. Trotzdem die Env-Vars im IaC korrigieren, damit bei einem Task-Replacement der State nicht aus dem Env-Var-Default verlorengeht — Open WebUI macht beim Boot nur die Initial-Population.

Tavily-Integration — Setup

WEB_SEARCH_ENGINE=tavily
TAVILY_API_KEY=tvly-xxx  (oder tvly-dev-xxx fuer Development-Tier)

API-Key ueber Secrets Manager injecten, nicht im IaC einklarschreiben. Tavily-Dev-Keys funktionieren grundsaetzlich, haben aber niedrigere Limits.

Alternative Engines: Brave (mehr Quota im Free-Tier, eher allgemein), SearXNG (self-hosted, kein API-Key noetig, braucht aber separate Container-Instanz), Google PSE, Serper, Serply, Mojeek, Kagi.

Modell-Filter im Custom-Model + LiteLLM

Open WebUI zeigt im Modell-Picker alles was LiteLLM exposed. Wenn man nur EIN Modell sichtbar haben will (z.B. nur vf-sonnet):

  1. In LiteLLM-Config nur das eine Base-Modell deklarieren (heute fuer VF: nur claude-sonnet-4-6, Haiku + Opus rausgenommen)
  2. DEFAULT_MODELS=vf-sonnet in Open-WebUI-Env — neue Chats starten direkt mit dem Custom Model
  3. TASK_MODEL anpassen — wenn Haiku als Background-Task-Model raus ist, TASK_MODEL auf claude-sonnet-4-6 setzen (sonst 500-Errors bei Title-Generation)

Cost-Tracking pro User via LiteLLM

LiteLLM kann Spend pro User-ID tracken. In litellm-config.yaml:

general_settings:
  track_cost_callback: true

Plus Open WebUI muss die User-ID im OpenAI-API-Request mitgeben (Feld user). Das macht Open WebUI automatisch wenn ENABLE_FORWARD_USER_INFO_HEADERS=true.

Spend pro User sichtbar via LiteLLM /ui (admin-only).

Bedrock-Quirks

LiteLLM-Backend ist Bedrock. Eigenheiten gegenueber Anthropic-direct:

  • Kein Assistant-Prefill — die Conversation muss mit user-Message enden. Wenn ein Open-WebUI-Background-Task (z.B. Title-Generation) eine Prefill-Strategie nutzt, kommt BedrockException - This model does not support assistant message prefill.
  • Mitigation: Title-Generation, Tag-Generation, Follow-up-Generation in Open WebUI deaktivieren ODER auf separates Modell zwingen das Prefill kann. Bei VF-Pilot: alle deaktiviert.

Verify-Endpoints fuers Debugging

WasEndpoint
Welche Tools hat ein Custom ModelGET /api/v1/models/model?id=<name>.meta.toolIds + .meta.capabilities
Aktive Web-Search-ConfigGET /api/v1/retrieval/config.web
Configs aktualisierenPOST /api/v1/retrieval/config/update mit {"web": {...}} Body
Audit-LogsCloudWatch Logs /aws/ecs/default/<stack> mit Filter `tavily
Vollstaendige Custom-Model-Specs (System Prompt etc.)GET /api/v1/models/model?id=<name>.params.system (das echte System-Prompt-Feld)
Custom-Model updatenPOST /api/v1/models/model/update?id=<name> mit komplettem Model-Object im Body
Image-Gen-Backend-ConfigGET /api/v1/images/config.IMAGE_GENERATION_ENGINE + Provider-Keys
Chat-Liste eines UsersGET /api/v1/chats/list

Admin-API-Quirks (gelernt 2026-05-19)

Cloudflare Error 1010 bei POST-Requests. Aus dem Vor-Auth-Tier des Cloudflare-Zugriffsschutzes blockt Default-curl/python urllib mit User-Agent python-urllib/3.x oder curl/8.x. Bei GET geht das durch, bei POST nicht. Fix: in jedem Admin-API-Call User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 Chrome/130.0 mitschicken. Auch bei urllib.request — sonst kommt HTTP 403 — error code 1010.

curl -X POST \
  -H "Authorization: Bearer $ADMIN_KEY" \
  -H "User-Agent: Mozilla/5.0" \
  -H "Content-Type: application/json" \
  --data @body.json \
  "https://vf-chat.agenticventures.de/api/v1/models/model/update?id=vf-nova"

Async-Chat-API /api/chat/completions. Nicht synchron wie OpenAI. Response ist {status: true, task_ids: [...], chat_id: ...} mit Pseudo-Chat-ID — der Chat wird erst beim Browser-Session-Use materialisiert. GET /api/v1/chats/{chat_id} fuer einen vom Admin-API-Aufrufer erzeugten Chat returned "detail": "We could not find what you're looking for". Konsequenz: OWUI ist nicht das richtige Tool fuer headless System-Prompt-Smoke-Tests. Stattdessen direkt aws bedrock-runtime invoke-model mit dem geholten System Prompt — siehe smoke-test-via-bedrock-cli-direkt-besser-als-owui-frontend.

Custom-Model-Update braucht VOLLES Model-Object zurueck, nicht Patch. Wenn man nur params.system aendert: man muss erst GET /api/v1/models/model?id=... fetchen, das ganze JSON im Speicher mutieren, und das komplette Object zurueck-POST-en. Patch-Pattern (PATCH oder Teil-Body) gibt es nicht.

Native Image-Gen-Provider — Stand OWUI 0.9.5

Aus GET /api/v1/images/config ablesbar, NICHT erweiterbar via Config:

ProviderAktivierbar viaDSGVO
OpenAI (GPT-image-1)IMAGE_GENERATION_ENGINE=openai + IMAGES_OPENAI_API_KEYUS-Hosting, eigener AVV noetig
Gemini (Nano Banana 2 via AI Studio)IMAGE_GENERATION_ENGINE=gemini + IMAGES_GEMINI_API_KEYUS-Default, Vertex EU separat zu buchen
Automatic1111IMAGE_GENERATION_ENGINE=automatic1111 + AUTOMATIC1111_BASE_URLSelf-Host, EU OK
ComfyUIIMAGE_GENERATION_ENGINE=comfyui + COMFYUI_BASE_URLSelf-Host, EU OK

Replicate, fal.ai, BFL direct sind KEINE nativen Provider in 0.9.5. Workaround: Image-Gen via MCP-Tool-Use, das LLM ruft Tool an, returns Bild-URL als Markdown-Image. Pattern angewandt im VF-Setup, siehe image-gen-provider-vergleich + Sprint-2-Plan fuer mcp-replicate-hosted.