Das Discourse AI-Plugin verfügt über viele Funktionen, die ein LLM erfordern, um aktiviert zu werden – Zusammenfassung, AI Helper, semantische Suche, AI Bot und dessen Agents. Du kannst eine API von Drittanbietern nutzen, wie API-Schlüssel für OpenAI konfigurieren oder API-Schlüssel für Anthropic konfigurieren, aber Discourse AI wurde von Anfang an so entwickelt, dass du nicht an diese Anbieter gebunden bist.
Dieser Leitfaden behandelt die lokale Bereitstellung eines offenen Modells (Open-Weight) und dessen Verbindung zu Discourse.
Hier verwendetes Modell: Qwen/Qwen3.8-27B – ein dichtes 27B-Modell, das im August 2026 veröffentlicht wurde. Es verfügt über ein natives Kontextfenster von 256K, Bild-/Videoverständnis, Tool-Aufrufe (Tool Calling) und einen standardmäßig aktivierten Denkmodus. Es ist derzeit der ideale Kompromiss für selbst gehostete Umgebungen: stark genug für echte Zusammenfassungs-/Agent-Arbeiten und klein genug für eine einzelne GPU. Ersetze es durch ein anderes Modell deiner Wahl; die Flags, die sich ändern, sind unten aufgeführt.
Was Discourse von deinem Inferenzserver benötigt
- Ein OpenAI-kompatibler
POST /v1/chat/completions-Endpunkt (Streaming unterstützt). - Natives Tool-/Function Calling, wenn AI Bot, Agents oder strukturierte Ausgaben gut funktionieren sollen. Ohne dies fällt Discourse auf XML-basierte Tool-Aufrufe zurück, die von schwächeren Modellen schlecht verarbeitet werden.
- Ein echtes Kontextfenster – strebe mindestens 16K Tokens an, bevorzugt 32K+. Die Prompt-Größen von Discourse für Zusammenfassungen und RAG (Retrieval-Augmented Generation) wachsen schnell.
- Optional: Bildeingabe, wenn das Modell Bilder lesen soll, die an Beiträge angehängt sind.
Alles, was die ersten drei Punkte erfüllt, funktioniert. Die Wahl unten hängt daher tatsächlich von deiner Hardware ab.
| Setup | Geeignet für |
|---|---|
| vLLM | Dedizierter GPU-Server, ≥24GB VRAM (quantisiert) / 80GB (volle Präzision), anhaltender Traffic, mehrere Benutzer |
| llama.cpp | Consumer-GPUs, Apple Silicon, rein CPU-basierte Systeme, einzelne kleine Foren |
| Gemanagt / Cloud | Du möchtest das Modell nicht auf deinem Laptop hosten, aber auch nicht auf deiner eigenen Hardware: jeder OpenAI-kompatible Endpunkt |
Bereitstellung mit vLLM
vLLM ist die empfohlene Engine für GPU-Server: Apache-lizenziert, OpenAI-kompatibler Server out-of-the-box und erstklassige Unterstützung für die Qwen-Familie.
mkdir -p /opt/vllm-cache
export VLLM_API_KEY="$(openssl rand -hex 24)"
docker run -d --name vllm \
--runtime nvidia --gpus all \
-v /opt/vllm-cache:/root/.cache/huggingface \
-e HF_HOME=/root/.cache/huggingface \
-e "HF_TOKEN=${HF_TOKEN}" \
-p 8080:8000 \
--ipc=host \
vllm/vllm-openai:latest \
Qwen/Qwen3.8-27B \
--host 0.0.0.0 \
--port 8000 \
--max-model-len 32768 \
--reasoning-parser qwen3 \
--enable-auto-tool-choice \
--tool-call-parser qwen3_xml \
--api-key "$VLLM_API_KEY"
Hinweise zu den Flags:
--max-model-lenbegrenzt den Kontext für Prompt+Ausgabe und somit den KV-Cache. Das Modell unterstützt native 256K; 32K sind für Foren-Arbeit ausreichend und halten den VRAM-Verbrauch vorhersehbar. Erhöhe diesen Wert (oder verwendeauto), wenn du genug Speicher hast.--reasoning-parser qwen3trennt das Denken des Modells in ein separatesreasoning-Feld, anstatt es in die Antwort zu werfen. Du musst diese Wahl in den Discourse-LLM-Einstellungen spiegeln (siehe unten).--enable-auto-tool-choice --tool-call-parser ...aktiviert natives Function Calling. Die Namen der Parser ändern sich zwischen vLLM-Releases – prüfepython3 -m vllm.entrypoints.openai.api_server --helpin deinem Image, wenn Tool-Aufrufe als reiner Text zurückkommen.HF_TOKENist nur für gesperrte Modelle (Gated Models) erforderlich;--api-keyschützt deinen eigenen Endpunkt. Caveat aus der vLLM-Dokumentation:--api-keyschützt nur die/v1-Routes, also halte den Server weiterhin vom öffentlichen Internet fern.- Wenig VRAM? Probiere
--quantization fp8(oder ein vorgequantisiertes AWQ-Checkpoint), bevor du den Kontext reduzierst. Multi-GPU: füge--tensor-parallel-size Nhinzu.
Teste es:
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $VLLM_API_KEY" \
-d '{
"model": "Qwen/Qwen3.8-27B",
"messages": [{"role": "user", "content": "What is Discourse?"}],
"max_tokens": 200
}'
Du solltest einen normalen Chat-Completion-JSON-Body zurückbekommen, mit message.reasoning neben message.content.
Bereitstellung mit llama.cpp
llama.cpp ist das richtige Werkzeug, wenn das Modell weniger VRAM verbrauchen muss, als vLLM bevorzugen würde, oder wenn du Apple Silicon, AMD, Vulkan oder CPU nutzt. Sein llama-server stellt ebenfalls eine OpenAI-kompatible API bereit.
Ziehe den offiziellen GGUF-Build und führe ihn mit dem Container-Image für dein Backend aus (server-cuda hier; server, server-rocm, server-vulkan usw. existieren ebenfalls):
export LLAMA_API_KEY="$(openssl rand -hex 24)"
docker run -d --name llama-server \
--gpus all \
-p 8080:8080 \
-v /opt/llama-models:/models \
ghcr.io/ggml-org/llama.cpp:server-cuda \
-hf ggml-org/Qwen3.8-27B-GGUF:Q4_K_M \
--host 0.0.0.0 \
--port 8080 \
--alias qwen3.8-27b \
--api-key "$LLAMA_API_KEY" \
--ctx-size 16384 \
--n-gpu-layers auto \
--flash-attn auto \
--jinja \
--reasoning auto
Q4_K_Mbenötigt etwa 16GB Gewichte; gemessen werden ca. 18,4 GiB VRAM bei 8K-Kontext und ~20 GiB bei 32K, sodass eine 24GB-Karte mit einem moderaten--ctx-sizefunktioniert. Unloth’sunsloth/Qwen3.8-27B-GGUF:UD-Q4_K_Mist eine beliebte Alternative.--jinjaverwendet das eigene Chat-Template des Modells – das ist es, was natives Tool Calling ermöglicht.--aliassetzt den Namen, den die API berichtet, sodass der Modellname, den du in Discourse eingibst, übereinstimmt.--reasoning autoberichtet das Denken separat und entspricht damit dem Verhalten von vLLM’s--reasoning-parser.- Für Bildeingaben wird der multimodale Projektor benötigt; mit
-hfwird er normalerweise automatisch abgerufen, andernfalls übergebe--mmproj /models/mmproj-...gguf(oder--no-mmproj, um VRAM für reine Textausgabe zu sparen).
Teste es:
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $LLAMA_API_KEY" \
-d '{
"model": "qwen3.8-27b",
"messages": [{"role": "user", "content": "What is Discourse?"}],
"max_tokens": 200
}'
Etwas anderes bereitstellen
Jeder Server, der OpenAI Chat Completions spricht – SGLang, TensorRT-LLM, LM Studio, ein Enterprise-Gateway, eine Cloud-dedizierte Bereitstellung – funktioniert wie er ist: Konfiguriere ihn in Discourse mit dem vLLM-Provider, unserer generischen OpenAI-kompatiblen Client-Lösung mit nativer Tool-Unterstützung.
Wenn du die Inferenz lieber nicht selbst betreiben möchtest, aber trotzdem die Abhängigkeit von großen API-Anbietern vermeiden willst, funktionieren Hugging Face Inference Endpoints (die jetzt standardmäßig vLLM als Engine nutzen) mit dem Hugging Face-Provider – zeige auf die /v1/chat/completions-URL des Endpunkts.
Es deiner Discourse-Instanz verfügbar machen
Du wirst dies normalerweise aufgrund der GPU-Anforderungen auf einer dedizierten Maschine betreiben. Wenn du das tust:
- Stelle einen Reverse Proxy vor den Server und beende dort TLS – Discourse kommuniziert gerne HTTPS damit.
- Beschränke den Endpunkt durch Firewall oder Client-Zertifikate, sodass nur deine Discourse-Hosts eine Verbindung herstellen können. Ein API-Key ist Authentifizierung, keine Netzwerkbarriere.
- Halte den Modell-Cache auf einem persistenten Volume, damit bei Neustarts nicht Dutzende von Gigabytes erneut heruntergeladen werden.
Discourse AI konfigurieren
LLM-Verbindungen werden über die Admin-Oberfläche konfiguriert, nicht über Site-Einstellungen. Gehe zu /admin/plugins/discourse-ai/ai-llms und füge ein neues LLM hinzu:
- Anzeigename – was deine Admins und Benutzer sehen.
- Name – wird in der API-Anfrage gesendet; muss mit dem übereinstimmen, was der Server erwartet (
Qwen/Qwen3.8-27Bfür vLLM, dein--aliasfür llama.cpp). - Provider – vLLM für vLLM, llama.cpp und jeden anderen OpenAI-kompatiblen Server; Hugging Face für HF-gehostete Endpunkte.
- URL – die vollständige Endpunkt-URL inklusive Pfad, z. B.
https://llm.example.com/v1/chat/completions. - API-Key – gib ihn ein oder verweise auf einen gespeicherten Schlüssel auf der Seite „AI Secrets“.
- Tokenizer – Qwen für Qwen3.8 (wähle den Tokenizer, der zu deiner Modellfamilie passt).
- Max Prompt Tokens / Max Output Tokens – halte die Summe unter oder gleich dem
--max-model-len/--ctx-sizedeines Servers. Beispiel bei einem 32768-Token-Server: 28000 Prompt und 4096 Output. Reasoning-Modelle verbrauchen einen Teil dieses Ausgabe-Budgets für das Denken, also übe keinen zu starken Druck aus. - Vision – aktiviere natives Vision, wenn du das Modell mit Bildunterstützung bereitgestellt hast und möchtest, dass es Bilder liest.
- Provider-Optionen (vLLM): Setze vLLM reasoning parser auf
qwen3, damit es mit dem Server-Flag übereinstimmt, und nutze die Felder für Thinking-Override / Reasoning-Intensität / Thinking-Token-Budget, wenn du möchtest, dass Discourse das Denken pro Anfrage steuert. Lass „Disable native tools“ deaktiviert, es sei denn, die Function Calling-Funktion des Modells ist defekt.
Klicke auf Test ausführen vor dem Speichern: Es sendet sowohl eine Streaming- als auch eine Nicht-Streaming-Anfrage und teilt dir mit, welche fehlgeschlagen ist.
Nach dem Speichern mache es zum Site-Standard mit der Site-Einstellung ai_default_llm_model, oder weise es jeder Funktion unter /admin/plugins/discourse-ai/ai-features zu. Individuelle Agents werden auf der Agents-Seite konfiguriert.
Ein Caveat: Semantische Such-Einbettungen (Embeddings) stammen nicht von diesem Modell. Embeddings verwenden ihr eigenes Embedding-Modell, das separat konfiguriert wird (ein API-Embedding-Modell oder ein selbst gehosteter Text Embeddings Inference-Server über die ai_hugging_face_tei_endpoint-Einstellungen). Wenn du AI Search vollständig selbst hosten möchtest, starte ein kleines Embedding-Modell wie bge-m3 neben deinem LLM.
Fehlersuche
| Symptom | Wahrscheinliche Ursache |
|---|---|
404 vom Endpunkt |
URL fehlt /v1/chat/completions |
model not found |
Name stimmt nicht mit der bereitgestellten Modell-ID / dem --alias überein |
401 / 403 |
API-Key-Abweichung zwischen --api-key und dem LLM-Eintrag |
| Tool-Aufrufe erscheinen als JSON-Text im Beitrag | Server wurde ohne Tool-Call-Parsing gestartet; Discourse fiel auf XML-Tools zurück |
| Denketext „leckt“ in die Antwort | --reasoning-parser fehlt auf dem Server, oder die Discourse-Reasoning-Parser-Einstellung stimmt nicht damit überein |
| CUDA out of memory | Reduziere --max-model-len, füge --quantization fp8 hinzu oder reduziere --gpu-memory-utilization |
| Requests laufen bei langen Zusammenfassungen in den Timeout | Reasoning-Modelle sind langsam; unser HTTP-Timeout beträgt 6 Minuten – reduziere den Kontext, senke die Thinking-Intensität oder deaktiviere Thinking |
| Abgeschnittene Antworten | max output tokens in Discourse ist zu klein, wenn Thinking-Tokens mitgezählt werden |