[{"data":1,"prerenderedAt":339},["ShallowReactive",2],{"search-de":3,"content-de-developer\u002Fdecisions\u002F007-pluggable-llm":4,"surround-de-\u002Fdeveloper\u002Fdecisions\u002F007-pluggable-llm":330},[],{"id":5,"title":6,"body":7,"description":322,"extension":323,"meta":324,"navigation":325,"path":326,"seo":327,"stem":328,"__hash__":329},"content_de\u002F3.developer\u002Fdecisions\u002F8.007-pluggable-llm.md","ADR-007: Austauschbarer LLM-Provider",{"type":8,"value":9,"toc":316},"minimark",[10,27,32,36,57,60,85,89,100,110,122,145,198,205,244,248,253,297,302],[11,12,13,21],"ul",{},[14,15,16,20],"li",{},[17,18,19],"strong",{},"Status:"," Angenommen",[14,22,23,26],{},[17,24,25],{},"Datum:"," 2026-03-24",[28,29,31],"h2",{"id":30},"kontext","Kontext",[33,34,35],"p",{},"Agent Pipeline, Knowledge Graph und das semantische Dateisystem benötigen allesamt LLM-Fähigkeiten — Textgenerierung, strukturierte Ausgaben, Embeddings und Tool Calling. Owlat muss mehrere Deployment-Szenarien unterstützen:",[37,38,39,45,51],"ol",{},[14,40,41,44],{},[17,42,43],{},"Cloud-Nutzer",", die über API-Schlüssel die besten verfügbaren Modelle (GPT-4o, Claude usw.) einsetzen möchten",[14,46,47,50],{},[17,48,49],{},"Selbst-Hoster",", die einen vollständig offlinefähigen Betrieb mit lokalen Modellen (über Ollama, vLLM oder Ähnliches) benötigen",[14,52,53,56],{},[17,54,55],{},"Enterprise-Nutzer",", die über interne API-Gateways mit eigenen Endpunkten routen",[33,58,59],{},"Die geprüften Optionen:",[37,61,62,68,74],{},[14,63,64,67],{},[17,65,66],{},"OpenAI fest verdrahten"," — am einfachsten, schließt aber Selbst-Hoster aus, die Cloud-APIs nicht nutzen können oder wollen",[14,69,70,73],{},[17,71,72],{},"LangChain\u002FLlamaIndex"," — schwergewichtige Frameworks mit großen Abhängigkeitsbäumen, komplexen Abstraktionen und Funktionen, die Owlat nicht braucht (Chains, Memory-Verwaltung, Vector-Store-Adapter)",[14,75,76,79,80,84],{},[17,77,78],{},"Vercel AI SDK mit Provider-Abstraktion"," — leichtgewichtig, bereits im Abhängigkeitsbaum vorhanden (",[81,82,83],"code",{},"@ai-sdk\u002Fopenai","), anbieterunabhängig, unterstützt strukturierte Ausgaben und Tool Calling nativ",[28,86,88],{"id":87},"entscheidung","Entscheidung",[33,90,91,92,99],{},"Das ",[93,94,98],"a",{"href":95,"rel":96},"https:\u002F\u002Fsdk.vercel.ai\u002F",[97],"nofollow","Vercel AI SDK"," als LLM-Orchestrierungsschicht einsetzen, gekapselt in einer dünnen, über Umgebungsvariablen konfigurierten Provider-Abstraktion.",[101,102,107],"pre",{"className":103,"code":105,"language":106},[104],"language-text","LLM_PROVIDER=openai             # or: openrouter, ollama\nLLM_BASE_URL=                    # for ollama: http:\u002F\u002Follama:11434\u002Fv1 (localhost outside Docker)\nLLM_API_KEY=                     # not needed for ollama; openrouter resolves its own base URL\nLLM_MODEL_FAST=gpt-4o-mini       # classify \u002F extract \u002F guard \u002F summarize\nLLM_MODEL_CAPABLE=gpt-4o         # draft \u002F plan\nLLM_MODEL=gpt-4o                 # shared fallback when a tier var is unset\nLLM_EMBEDDING_MODEL=             # optional, defaults to text-embedding-3-small\n","text",[81,108,105],{"__ignoreMap":109},"",[33,111,112,113,117,118,121],{},"Modelle werden pro Task-Stufe ausgewählt statt als ein einzelnes Modell — die Routing-Regeln beschreibt ",[93,114,116],{"href":115},"\u002Fdeveloper\u002Fdecisions\u002F009-model-routing","ADR-009: Aufgabenbasiertes Model-Routing",". ",[81,119,120],{},"LLM_MODEL"," bleibt ein gemeinsamer Fallback, wenn die stufenspezifischen Variablen nicht gesetzt sind.",[33,123,124,125,128,129,132,133,136,137,140,141,144],{},"Die Factory ",[81,126,127],{},"createOpenAI()"," des AI SDK akzeptiert einen ",[81,130,131],{},"baseURL","-Parameter, wodurch ",[17,134,135],{},"jede OpenAI-kompatible API"," (Ollama, vLLM, LiteLLM, Azure OpenAI) ohne zusätzlichen Provider-Code funktioniert. ",[81,138,139],{},"openrouter"," und ",[81,142,143],{},"ollama"," werden vom selben OpenAI-kompatiblen Provider mit einer vorab aufgelösten Basis-URL bedient.",[146,147,150,192],"callout",{"title":148,"type":149},"Kein nativer Anthropic-Provider","warning",[33,151,152,153,156,157,160,161,163,164,167,168,171,172,175,176,179,180,183,184,187,188,191],{},"Natives Anthropic über ",[81,154,155],{},"@ai-sdk\u002Fanthropic"," ist ",[17,158,159],{},"nicht implementiert"," und nicht installiert — nur ",[81,162,83],{}," ist eine Abhängigkeit in ",[81,165,166],{},"apps\u002Fapi\u002Fpackage.json",". Der Wert ",[81,169,170],{},"anthropic"," für ",[81,173,174],{},"LLM_PROVIDER"," wird ",[17,177,178],{},"nicht"," gesondert behandelt: Er landet im Default-Zweig von ",[81,181,182],{},"resolveBaseURL()"," (",[81,185,186],{},"apps\u002Fapi\u002Fconvex\u002Flib\u002FllmProvider.ts:56-57","), der ",[81,189,190],{},"undefined"," zurückgibt, sodass er sich wie einfaches OpenAI verhält. Um heute Claude-Modelle zu betreiben, nutzen Sie den OpenAI-kompatiblen Provider mit Anthropics OpenAI-kompatiblem Endpunkt:",[101,193,196],{"className":194,"code":195,"language":106},[104],"LLM_PROVIDER=openai\nLLM_BASE_URL=https:\u002F\u002Fapi.anthropic.com\u002Fv1\u002F\nLLM_MODEL_CAPABLE=claude-sonnet-4-6\nLLM_MODEL_FAST=claude-haiku-4-5-20251001\n",[81,197,195],{"__ignoreMap":109},[33,199,200,201,204],{},"Für Ollama setzen Sie ein lokales Modell, etwa ",[81,202,203],{},"LLM_MODEL_FAST=llama3.1:8b",".",[33,206,207,208,211,212,215,216,215,219,215,222,140,225,228,229,231,232,234,235,183,237,240,241,243],{},"Die LLM-Auflösung liegt in einem einzigen Modul, ",[81,209,210],{},"apps\u002Fapi\u002Fconvex\u002Flib\u002FllmProvider.ts",", das ",[81,213,214],{},"getLLMProvider(task)",", ",[81,217,218],{},"getLLMProviderForUserText(task, userText)",[81,220,221],{},"getEmbeddingModel()",[81,223,224],{},"getLLMConfig()",[81,226,227],{},"assertEmbeddingDimension()"," exportiert. Es liest diese Umgebungsvariablen und ruft die Factory ",[81,230,127],{}," des AI SDK direkt auf, mit einer je nach ",[81,233,174],{}," durch ",[81,236,182],{},[81,238,239],{},"llmProvider.ts:48-59",") aufgelösten ",[81,242,131],{},". Jeder Consumer importiert und ruft diese Funktionen direkt auf.",[28,245,247],{"id":246},"konsequenzen","Konsequenzen",[33,249,250],{},[17,251,252],{},"Ermöglicht:",[11,254,255,258,261,268,283],{},[14,256,257],{},"Selbst-Hoster betreiben Ollama lokal für vollständig offlinefähige, kostenlose KI-Funktionen",[14,259,260],{},"Cloud-Nutzer wählen ihren bevorzugten Anbieter (OpenAI, OpenRouter, Claude über den OpenAI-kompatiblen Endpunkt oder jede kompatible API)",[14,262,263,264,267],{},"Enterprise-Nutzer zeigen über ",[81,265,266],{},"LLM_BASE_URL"," auf interne Gateways oder Proxy-Endpunkte",[14,269,270,271,215,273,215,275,278,279,282],{},"Eine einzige Konfigurationsfläche — eine Handvoll Umgebungsvariablen (",[81,272,174],{},[81,274,266],{},[81,276,277],{},"LLM_API_KEY",", die Modellstufen-Variablen und ",[81,280,281],{},"LLM_EMBEDDING_MODEL",") steuert das gesamte LLM-Verhalten",[14,284,285,286,288,289,292,293,296],{},"Das AI SDK ist bereits eine Abhängigkeit (",[81,287,83],{}," sowohl in ",[81,290,291],{},"apps\u002Fapi"," als auch in ",[81,294,295],{},"apps\u002Fweb",")",[33,298,299],{},[17,300,301],{},"Abwägungen:",[11,303,304,307,310,313],{},[14,305,306],{},"Die Qualität unterscheidet sich zwischen Anbietern erheblich — lokale Modelle liefern womöglich schlechtere Klassifikationen und Entwürfe als GPT-4o oder Claude",[14,308,309],{},"Embedding-Dimensionen unterscheiden sich zwischen Modellen — Vektorindizes müssen auf die Dimensionen des gewählten Embedding-Modells konfiguriert werden",[14,311,312],{},"Keine eingebauten RAG-Chains — Retrieval-Augmented Generation ist als explizite Convex-Funktionsschritte umgesetzt (Vektorindex abfragen, Ergebnisse an den Prompt übergeben), was ausführlicher, aber besser debugbar ist",[14,314,315],{},"AI-SDK-Updates können Breaking Changes einführen, auch wenn die Abstraktionsschicht den Anwendungscode isoliert",{"title":109,"searchDepth":317,"depth":317,"links":318},2,[319,320,321],{"id":30,"depth":317,"text":31},{"id":87,"depth":317,"text":88},{"id":246,"depth":317,"text":247},"Warum Owlat das Vercel AI SDK mit einer Provider-Abstraktionsschicht nutzt, statt einen einzelnen LLM-Anbieter fest zu verdrahten.","md",{},true,"\u002Fdeveloper\u002Fdecisions\u002F007-pluggable-llm",{"title":6,"description":322},"3.developer\u002Fdecisions\u002F8.007-pluggable-llm","M3NxQYsRG5j5JDpn-9FMA6YmCcZpPBvq02pgJQtGkCk",[331,335],{"title":332,"path":333,"stem":334,"children":-1},"ADR-006: Selbst gehostetes Convex","\u002Fdeveloper\u002Fdecisions\u002F006-self-hosted-convex","3.developer\u002Fdecisions\u002F7.006-self-hosted-convex",{"title":336,"path":337,"stem":338,"children":-1},"ADR-008: Prozessarchitektur des Agenten","\u002Fdeveloper\u002Fdecisions\u002F008-process-architecture","3.developer\u002Fdecisions\u002F9.008-process-architecture",1786915110755]