<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Local LLM on kenji.blog</title><link>http://kenji.blog/de/tags/local-llm/</link><description>Recent content in Local LLM on kenji.blog</description><generator>Hugo -- gohugo.io</generator><language>de</language><copyright>kenjinote</copyright><lastBuildDate>Fri, 11 Sep 2026 02:00:00 +0900</lastBuildDate><atom:link href="http://kenji.blog/de/tags/local-llm/index.xml" rel="self" type="application/rss+xml"/><item><title>Einfacher Aufbau eines lokalen LLMs mit Ollama und API-Integration</title><link>http://kenji.blog/de/p/ollama-local-llm-api-guide/</link><pubDate>Fri, 11 Sep 2026 02:00:00 +0900</pubDate><guid>http://kenji.blog/de/p/ollama-local-llm-api-guide/</guid><description>&lt;img src="http://kenji.blog/p/ollama-local-llm-api-guide/img/eyecatch.jpg" alt="Featured image of post Einfacher Aufbau eines lokalen LLMs mit Ollama und API-Integration" />&lt;h1 id="einführung-warum-benötigen-wir-lokale-llms">Einführung: Warum benötigen wir lokale LLMs?
&lt;/h1>&lt;p>Mit dem Aufstieg von Large Language Models (LLMs) haben sich unser Leben und unsere Entwicklungsmethoden dramatisch verändert. Leistungsstarke Cloud-basierte KI-Dienste wie ChatGPT, Claude und Gemini entwickeln sich täglich weiter und bieten hoch entwickelte Schlussfolgerungsfähigkeiten. Dennoch sind Cloud-LLMs nicht für jeden Anwendungsfall optimal. Bei Cloud-LLMs bestehen folgende Herausforderungen:&lt;/p>
&lt;ol>
&lt;li>&lt;strong>Datenschutz- und Sicherheitsprobleme&lt;/strong>: Das Senden von Daten mit vertraulichen oder persönlichen Informationen an externe Server ist aus Compliance- und Sicherheitssicht für Unternehmen oft inakzeptabel.&lt;/li>
&lt;li>&lt;strong>Kostenunsicherheit&lt;/strong>: Da die API-Nutzungsgebühren von der Anzahl der Token abhängen, besteht bei Systemen, die große Datenmengen verarbeiten oder häufige Anfragen stellen, das Risiko unbegrenzt steigender laufender Kosten.&lt;/li>
&lt;li>&lt;strong>Latenz und Netzwerkabhängigkeit&lt;/strong>: Die Netzwerkkommunikation wird bei der Nutzung in Offline-Umgebungen oder bei der Ausführung auf Edge-Geräten, die eine extrem niedrige Latenz erfordern, zum Flaschenhals.&lt;/li>
&lt;li>&lt;strong>Vendor Lock-in&lt;/strong>: Die Abhängigkeit vom Modell eines bestimmten Anbieters kann dazu führen, dass man durch zukünftige Diensteinstellungen, Änderungen der Nutzungsbedingungen oder unbeabsichtigte Verhaltensänderungen aufgrund von Modell-Updates beeinträchtigt wird.&lt;/li>
&lt;/ol>
&lt;p>Als Lösung für diese Herausforderungen gewinnen &amp;ldquo;lokale LLMs&amp;rdquo; zunehmend an Aufmerksamkeit. Indem man Modelle auf der eigenen Hardware ausführt, sendet man keinerlei Daten nach außen, muss sich keine Sorgen um monatliche Kosten machen und kann KI frei nutzen.&lt;/p>
&lt;p>In diesem Artikel werden wir das Tool &amp;ldquo;&lt;strong>Ollama&lt;/strong>&amp;rdquo;, mit dem sich lokale LLMs erstaunlich einfach einführen, verwalten und über eine API integrieren lassen, von den Grundlagen über die interne Architektur und die fortgeschrittene API-Integration mit Python und Node.js bis hin zu den Berechnungsformeln für das Performance-Tuning umfassend erläutern.&lt;/p>
&lt;hr>
&lt;h1 id="was-ist-ollama-die-interne-architektur">Was ist Ollama? Die interne Architektur
&lt;/h1>&lt;p>Ollama ist eine Plattform zur einfachen Ausführung und Verwaltung von quelloffenen Large Language Models (wie Llama 3, Phi-3, Mistral, Gemma usw.) in einer lokalen Umgebung. Um eine lokale LLM-Umgebung aufzubauen, waren bisher sehr komplizierte Schritte erforderlich: die Einrichtung einer Python-Umgebung, die Installation des CUDA-Toolkits, das Auflösen von PyTorch-Abhängigkeiten, das Herunterladen riesiger Modelldateien von Hugging Face und die Formatkonvertierung (z. B. von Safetensors nach GGUF).&lt;/p>
&lt;p>Ollama verbirgt diese Komplexität und ermöglicht den Umgang mit LLMs mit einer Benutzerfreundlichkeit, die an Docker erinnert. Mit einem einzigen Befehl können Modelle heruntergeladen (&lt;code>pull&lt;/code>), ausgeführt (&lt;code>run&lt;/code>) und als HTTP-Server gestartet werden.&lt;/p>
&lt;h2 id="die-kerntechnologie-ein-wrapper-für-llamacpp">Die Kerntechnologie: Ein Wrapper für llama.cpp
&lt;/h2>&lt;p>Als Backend der Inferenz-Engine von Ollama fungiert &amp;ldquo;&lt;strong>llama.cpp&lt;/strong>&amp;rdquo;, eine in C/C++ geschriebene, schnelle LLM-Inferenzbibliothek. llama.cpp besitzt die Fähigkeit, Modelle durch maximale Ausnutzung der Hardwareleistung auszuführen – unabhängig davon, ob es sich um Apple Silicon (Metal), NVIDIA GPUs (CUDA), AMD GPUs (ROCm) oder sogar um reine CPU-Umgebungen handelt.&lt;/p>
&lt;p>Ollama integriert llama.cpp und verwendet eine Architektur, bei der ein in Go geschriebener Serverprozess eine REST-API bereitstellt und im Hintergrund die llama.cpp-Inferenz-Engine aufruft.&lt;/p>
&lt;p>Das folgende Mermaid-Diagramm zeigt die Gesamtarchitektur von Ollama:&lt;/p>
&lt;div class="mermaid">graph TD
A["Client-Apps (Python / Node.js)"] -- "HTTP/REST API" --> B["Ollama-Server (Go)"]
B --> C["Modell-Manager (GGUF-Verarbeitung)"]
B --> D["Inferenz-Engine (llama.cpp)"]
D --> E["GPU-Beschleunigung (CUDA / Metal / ROCm)"]
D --> F["CPU-Fallback (AVX2 / AVX-512)"]
C --> G["Lokaler Modell-Speicher"]&lt;/div>
&lt;p>Durch diese Architektur können Entwickler fortgeschrittene Inferenzfähigkeiten über standardmäßige HTTP-Anfragen nutzen, ohne sich um C++-Builds oder detaillierte GPU-Treiber-Einstellungen kümmern zu müssen.&lt;/p>
&lt;hr>
&lt;h1 id="installation-und-ersteinrichtung-von-ollama">Installation und Ersteinrichtung von Ollama
&lt;/h1>&lt;p>Die Installation von Ollama ist sehr einfach. Für jedes Betriebssystem werden optimierte Binärdateien bereitgestellt.&lt;/p>
&lt;h2 id="macos--windows">macOS / Windows
&lt;/h2>&lt;p>Laden Sie einfach den Installer von der offiziellen Website (&lt;a class="link" href="https://ollama.com/" target="_blank" rel="noopener"
>https://ollama.com/&lt;/a>) herunter und führen Sie ihn aus. Die macOS-Version erkennt automatisch die Metal-API von Apple Silicon, die Windows-Version NVIDIA-GPUs (CUDA) und aktiviert, falls verfügbar, die Hardwarebeschleunigung.&lt;/p>
&lt;h2 id="linux">Linux
&lt;/h2>&lt;p>In Linux-Umgebungen (wie Ubuntu) reicht die Ausführung des folgenden Einzeilers aus, um die erforderlichen Komponenten zu installieren und den Ollama-Server als systemd-Dienst zu starten.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl -fsSL https://ollama.com/install.sh &lt;span class="p">|&lt;/span> sh
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Überprüfen Sie nach Abschluss der Installation die Version im Terminal.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama --version
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Wenn die Versionsinformationen angezeigt werden, war die Installation erfolgreich.&lt;/p>
&lt;h2 id="ausführung-mit-docker">Ausführung mit Docker
&lt;/h2>&lt;p>Wenn Sie Ihre bestehende Umgebung nicht beeinträchtigen oder Ollama in eine containerbasierte Infrastruktur integrieren möchten, können Sie auch das offizielle Docker-Image verwenden. Wenn Sie eine GPU nutzen, ist die Installation des NVIDIA Container Toolkits erforderlich.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Für die Ausführung nur mit CPU&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">docker run -d -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Für die Nutzung einer NVIDIA GPU&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">docker run -d --gpus&lt;span class="o">=&lt;/span>all -v ollama:/root/.ollama -p 11434:11434 --name ollama ollama/ollama
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Standardmäßig lauscht der Ollama-Server auf &lt;code>http://localhost:11434&lt;/code>.&lt;/p>
&lt;hr>
&lt;h1 id="modellverwaltung-und-grundlegende-cli-befehle">Modellverwaltung und grundlegende CLI-Befehle
&lt;/h1>&lt;p>Der größte Reiz von Ollama liegt in der äußerst intuitiven Verwaltung von Modellen. Sie können verschiedene Modelle ausprobieren, ähnlich wie beim Umgang mit Docker-Images.&lt;/p>
&lt;h2 id="1-ausführen-eines-modells-run">1. Ausführen eines Modells (&lt;code>run&lt;/code>)
&lt;/h2>&lt;p>Dies ist der am häufigsten verwendete Befehl. Wenn das angegebene Modell nicht existiert, wird es automatisch heruntergeladen (&lt;code>pull&lt;/code>), und danach öffnet sich ein interaktiver Prompt.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama run llama3.1
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Wenn Sie den obigen Befehl ausführen, startet Metas neuestes Modell Llama 3.1 (in der 8B-Parameter-Version). Sobald Sie eine Nachricht im Prompt eingeben, wird die Antwort des Modells als Stream angezeigt. Zum Beenden geben Sie &lt;code>/bye&lt;/code> ein oder drücken &lt;code>Ctrl+D&lt;/code>.&lt;/p>
&lt;h2 id="2-herunterladen-eines-modells-pull">2. Herunterladen eines Modells (&lt;code>pull&lt;/code>)
&lt;/h2>&lt;p>Verwenden Sie den Befehl &lt;code>pull&lt;/code>, wenn Sie ein Modell vorab im Hintergrund herunterladen möchten.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama pull phi3:instruct
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">ollama pull mistral:v0.3
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>In der Modellbibliothek von Ollama können Sie die Version und das Quantisierungsniveau im Format &lt;code>Modellname:Tag&lt;/code> angeben. Wenn Sie das Tag weglassen, wird &lt;code>latest&lt;/code> angewendet. Es ist aber auch möglich, explizit ein bestimmtes quantisiertes Modell (z. B. &lt;code>llama3:8b-instruct-q4_0&lt;/code>) anzugeben.&lt;/p>
&lt;h3 id="was-ist-quantisierung-quantization">Was ist Quantisierung (Quantization)?
&lt;/h3>&lt;p>Lassen Sie uns hier kurz auf die Quantisierung eingehen. Ein gewöhnliches LLM speichert einen Gewichtsparameter als 16-Bit-Gleitkommazahl (FP16). Bei einem Modell mit 8 Milliarden (8B) Parametern verbrauchen allein die Gewichte etwa 16 GB VRAM. Die Quantisierung ist eine Technik, die diese Werte in 4-Bit (Q4) oder 8-Bit (Q8) Integer komprimiert.&lt;/p>
&lt;p>Durch Quantisierung lassen sich der erforderliche Speicherplatz und die Speicherbandbreite drastisch reduzieren, während die Genauigkeitsverluste des Modells minimiert werden. Die von Ollama bereitgestellten Modelle liegen standardmäßig im GGUF-Format vor, bei dem eine optimale Quantisierung (meistens 4-Bit) bereits angewendet wurde.&lt;/p>
&lt;h2 id="3-anzeigen-von-modellen-list">3. Anzeigen von Modellen (&lt;code>list&lt;/code>)
&lt;/h2>&lt;p>Dieser Befehl zeigt eine Liste der lokal heruntergeladenen Modelle und deren Größen an.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama list
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Beispielausgabe:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl">NAME ID SIZE MODIFIED
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">llama3.1:latest 43f7a214e532 4.7 GB 2 hours ago
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">phi3:instruct a2c89ceaed85 2.3 GB 3 days ago
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="4-löschen-eines-modells-rm">4. Löschen eines Modells (&lt;code>rm&lt;/code>)
&lt;/h2>&lt;p>Löschen Sie Modelle, die Sie nicht mehr benötigen, um Speicherplatz freizugeben.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama rm phi3:instruct
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h1 id="modellanpassung-mit-dem-modelfile">Modellanpassung mit dem Modelfile
&lt;/h1>&lt;p>Mit Ollama können Sie durch ein &amp;ldquo;Modelfile&amp;rdquo; System-Prompts injizieren und Hyperparameter für bestehende Modelle anpassen, um eigene benutzerdefinierte Modelle zu erstellen. Dies entspricht genau dem Konzept eines Dockerfiles bei Docker.&lt;/p>
&lt;p>Das folgende Diagramm zeigt, wie ein benutzerdefiniertes Modell von einem Basismodell abgeleitet wird.&lt;/p>
&lt;div class="mermaid">graph LR
A["Basis-Modell (llama3.1)"] -->|"System-Prompt hinzufügen"| B["Zwischenkonfiguration"]
B -->|"Temperature &amp; Top_p festlegen"| C["Benutzerdefiniertes Modell (kansai-coder)"]
C -->|"Ausführen (Run)"| D["Interaktive CLI / API"]&lt;/div>
&lt;p>Lassen Sie uns als Beispiel ein Modell für einen Programmierassistenten erstellen, der im Kansai-Dialekt (japanischer Dialekt) antwortet.&lt;/p>
&lt;p>Erstellen Sie in Ihrem Arbeitsverzeichnis eine Textdatei mit dem Namen &lt;code>Modelfile&lt;/code> und fügen Sie Folgendes ein:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-text" data-lang="text">&lt;span class="line">&lt;span class="cl"># Das Basismodell angeben
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">FROM llama3.1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># Hyperparameter wie Kreativität (temperature) festlegen
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER temperature 0.7
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER top_p 0.9
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER repeat_penalty 1.1
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">PARAMETER num_ctx 4096
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"># Den System-Prompt festlegen
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">SYSTEM &amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Du bist ein erstklassiger Senior Software Engineer.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Bitte antworte auf technische Fragen der Benutzer immer freundlich und im &amp;#34;Kansai-Dialekt&amp;#34;.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">Wenn du Code-Beispiele zeigst, liefere modernen Code, der den Best Practices entspricht.
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;#34;&amp;#34;&amp;#34;
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Aus diesem Modelfile wird nun ein neues Modell gebaut (erstellt).&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama create kansai-coder -f Modelfile
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Sobald der Build abgeschlossen ist, können Sie es ausführen und testen.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">ollama run kansai-coder
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&amp;gt;&amp;gt;&amp;gt; Pythonでリストをソートするにはどうすればええの？
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Das Modell wird dann ein angepasstes Verhalten zeigen und etwa mit &amp;ldquo;Das geht ganz einfach, nutze einfach die &lt;code>sorted()&lt;/code>-Funktion oder die &lt;code>sort()&lt;/code>-Methode in Python!&amp;rdquo; (im entsprechenden Dialekt) antworten. Auf diese Weise können Sie lokal unzählige Agenten erstellen und verwalten, die auf spezielle Anwendungsfälle zugeschnitten sind.&lt;/p>
&lt;hr>
&lt;h1 id="umfassende-erläuterung-der-ollama-rest-api">Umfassende Erläuterung der Ollama REST-API
&lt;/h1>&lt;p>Interaktionen über die CLI sind zwar praktisch, doch die wahre Stärke von Ollama für die Entwicklung echter Anwendungen liegt in der leistungsstarken REST-API. Durch das Senden von HTTP-Anfragen an den Serverprozess (standardmäßig &lt;code>http://localhost:11434&lt;/code>) können Sie Inferenz-Ergebnisse abrufen.&lt;/p>
&lt;p>Die 3 wichtigsten Endpunkte sind:&lt;/p>
&lt;ol>
&lt;li>&lt;code>/api/generate&lt;/code>: Textgenerierung basierend auf einem einzelnen Prompt&lt;/li>
&lt;li>&lt;code>/api/chat&lt;/code>: Chat-(Dialog-)Generierung in einem Format ähnlich der OpenAI API&lt;/li>
&lt;li>&lt;code>/api/embeddings&lt;/code>: Generierung von Vektor-Einbettungen (Embeddings)&lt;/li>
&lt;/ol>
&lt;h2 id="textgenerierung-mit-apigenerate">Textgenerierung mit /api/generate
&lt;/h2>&lt;p>Dies ist der grundlegendste Generierungsendpunkt. Senden wir eine Anfrage mit cURL.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl -X POST http://localhost:11434/api/generate -d &lt;span class="s1">&amp;#39;{
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;model&amp;#34;: &amp;#34;llama3.1&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;prompt&amp;#34;: &amp;#34;Explain the concept of quantum entanglement in simple terms.&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;stream&amp;#34;: false
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">}&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Durch die Angabe von &lt;code>&amp;quot;stream&amp;quot;: false&lt;/code> wird das JSON auf einmal zurückgegeben, nachdem die gesamte Generierung abgeschlossen ist. Beim Standardwert (&lt;code>true&lt;/code>) werden die generierten Tokens nacheinander im JSON Lines-Format gesendet, was sich ideal für die Implementierung einer Streaming-UI eignet.&lt;/p>
&lt;p>Beispiel für eine Antwort (gekürzt):&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-json" data-lang="json">&lt;span class="line">&lt;span class="cl">&lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;model&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;llama3.1&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;created_at&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;2026-09-11T10:00:00.000Z&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;response&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s2">&amp;#34;Quantum entanglement is like having a pair of magical dice...&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;done&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;context&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="p">[&lt;/span>&lt;span class="mi">128006&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">882&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">128007&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">271&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="mi">10445&lt;/span>&lt;span class="p">],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;total_duration&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">4567890000&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;load_duration&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">1234000&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;prompt_eval_count&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">14&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;eval_count&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">256&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nt">&amp;#34;eval_duration&amp;#34;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="mi">4321000000&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Das Array &lt;code>context&lt;/code> enthält den kodierten vergangenen Konversationsstatus. Wenn Sie dies in Ihre nächste Anfrage aufnehmen, bleibt der Kontext erhalten. Für eine einfachere Verwaltung des Gesprächsverlaufs sollten Sie jedoch &lt;code>/api/chat&lt;/code> verwenden.&lt;/p>
&lt;h2 id="dialoggenerierung-mit-apichat">Dialoggenerierung mit /api/chat
&lt;/h2>&lt;p>Da aktuelle LLMs für Chat-Formate feingetunt sind, wird &lt;code>/api/chat&lt;/code> für die Anwendungsentwicklung empfohlen.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">curl -X POST http://localhost:11434/api/chat -d &lt;span class="s1">&amp;#39;{
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;model&amp;#34;: &amp;#34;llama3.1&amp;#34;,
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;messages&amp;#34;: [
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> { &amp;#34;role&amp;#34;: &amp;#34;system&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;You are a helpful AI assistant.&amp;#34; },
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> { &amp;#34;role&amp;#34;: &amp;#34;user&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;What is the capital of France?&amp;#34; },
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> { &amp;#34;role&amp;#34;: &amp;#34;assistant&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;The capital of France is Paris.&amp;#34; },
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> { &amp;#34;role&amp;#34;: &amp;#34;user&amp;#34;, &amp;#34;content&amp;#34;: &amp;#34;What is its famous tower?&amp;#34; }
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> ],
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1"> &amp;#34;stream&amp;#34;: false
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="s1">}&amp;#39;&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Durch die Übergabe eines Arrays von Nachrichtenobjekten mit einer &lt;code>role&lt;/code> (system, user, assistant) können komplexe Dialogkontexte problemlos verarbeitet werden.&lt;/p>
&lt;hr>
&lt;h1 id="integration-in-python-anwendungen">Integration in Python-Anwendungen
&lt;/h1>&lt;p>Python ist die Standard-Sprache für die KI-Entwicklung. Es gibt mehrere Möglichkeiten, Ollama aus Python heraus zu nutzen, aber die Verwendung des offiziellen &lt;code>ollama-python&lt;/code>-Pakets ist am einfachsten und zuverlässigsten.&lt;/p>
&lt;h2 id="installation">Installation
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">pip install ollama
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="nutzung-der-synchronen-synchronous-api">Nutzung der synchronen (Synchronous) API
&lt;/h2>&lt;p>Hier ist der grundlegende Code zur Erstellung eines Chats.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">ollama&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Liste, um den Chatverlauf zu speichern&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">messages&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span>&lt;span class="s1">&amp;#39;role&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;system&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;Du bist ein hervorragender Assistent.&amp;#39;&lt;/span>&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">def&lt;/span> &lt;span class="nf">chat_with_ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">user_input&lt;/span>&lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">messages&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s1">&amp;#39;role&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;user&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">user_input&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Ollama API aufrufen&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">ollama&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">chat&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;llama3.1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">messages&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="n">messages&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">assistant_reply&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">response&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;message&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">]&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">messages&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">append&lt;/span>&lt;span class="p">({&lt;/span>&lt;span class="s1">&amp;#39;role&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;assistant&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="n">assistant_reply&lt;/span>&lt;span class="p">})&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">return&lt;/span> &lt;span class="n">assistant_reply&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chat_with_ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Erkläre mir die drei Hauptansätze des maschinellen Lernens.&amp;#34;&lt;/span>&lt;span class="p">))&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="nutzung-von-asynchronem-streaming-async-streaming">Nutzung von asynchronem Streaming (Async Streaming)
&lt;/h2>&lt;p>Bei der Entwicklung von Webanwendungen (wie FastAPI oder Starlette) oder Bots für Discord / Slack ist es wichtig, asynchrone APIs und Streaming zu verwenden, um das Blockieren von Threads zu vermeiden.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">import&lt;/span> &lt;span class="nn">asyncio&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">ollama&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">AsyncClient&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="k">async&lt;/span> &lt;span class="k">def&lt;/span> &lt;span class="nf">generate_stream&lt;/span>&lt;span class="p">():&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">client&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">AsyncClient&lt;/span>&lt;span class="p">()&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Durch stream=True wird ein asynchroner Generator zurückgegeben&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">async&lt;/span> &lt;span class="k">for&lt;/span> &lt;span class="n">chunk&lt;/span> &lt;span class="ow">in&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="n">client&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">chat&lt;/span>&lt;span class="p">(&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;llama3.1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">messages&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="p">[{&lt;/span>&lt;span class="s1">&amp;#39;role&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;user&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">:&lt;/span> &lt;span class="s1">&amp;#39;Erkläre Dekoratoren in Python im Detail.&amp;#39;&lt;/span>&lt;span class="p">}],&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="n">stream&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">):&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1"># Jeden Chunk nacheinander in die Standardausgabe schreiben&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">chunk&lt;/span>&lt;span class="p">[&lt;/span>&lt;span class="s1">&amp;#39;message&amp;#39;&lt;/span>&lt;span class="p">][&lt;/span>&lt;span class="s1">&amp;#39;content&amp;#39;&lt;/span>&lt;span class="p">],&lt;/span> &lt;span class="n">end&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s1">&amp;#39;&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="n">flush&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="kc">True&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nb">print&lt;/span>&lt;span class="p">()&lt;/span> &lt;span class="c1"># Abschließender Zeilenumbruch&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1"># Asynchrone Funktion ausführen&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">asyncio&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">run&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">generate_stream&lt;/span>&lt;span class="p">())&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Mit diesem Ansatz lässt sich ganz einfach eine UX implementieren, bei der der Text nach und nach auf dem Bildschirm erscheint, ähnlich wie bei der ChatGPT-UI.&lt;/p>
&lt;h2 id="integration-mit-langchain-und-llamaindex">Integration mit LangChain und LlamaIndex
&lt;/h2>&lt;p>Ollama wird auch nativ von LangChain und LlamaIndex unterstützt, die häufig beim Aufbau von RAG-Systemen (Retrieval-Augmented Generation) verwendet werden.&lt;/p>
&lt;p>Beispiel für LangChain:&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;span class="lnt">2
&lt;/span>&lt;span class="lnt">3
&lt;/span>&lt;span class="lnt">4
&lt;/span>&lt;span class="lnt">5
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-python" data-lang="python">&lt;span class="line">&lt;span class="cl">&lt;span class="kn">from&lt;/span> &lt;span class="nn">langchain_community.llms&lt;/span> &lt;span class="kn">import&lt;/span> &lt;span class="n">Ollama&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">llm&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">Ollama&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">model&lt;/span>&lt;span class="o">=&lt;/span>&lt;span class="s2">&amp;#34;llama3.1&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="n">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="n">llm&lt;/span>&lt;span class="o">.&lt;/span>&lt;span class="n">invoke&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Explain dark matter.&amp;#34;&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nb">print&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="n">response&lt;/span>&lt;span class="p">)&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;p>Damit ist es möglich, die leistungsstarken Ketten (Chains) und Agentenfunktionen von LangChain lokal auszuführen, ohne externe API-Schlüssel konfigurieren zu müssen.&lt;/p>
&lt;hr>
&lt;h1 id="integration-in-nodejs-anwendungen">Integration in Node.js-Anwendungen
&lt;/h1>&lt;p>Für Frontend- und Full-Stack-Entwickler ist die Möglichkeit, lokale LLMs aus einer TypeScript/Node.js-Umgebung aufzurufen, ein großer Vorteil. Dazu wird das offizielle &lt;code>ollama&lt;/code> NPM-Paket verwendet.&lt;/p>
&lt;h2 id="installation-1">Installation
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt">1
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-bash" data-lang="bash">&lt;span class="line">&lt;span class="cl">npm install ollama
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="implementierungsbeispiel-eines-chatbots-mit-typescript">Implementierungsbeispiel eines Chatbots mit TypeScript
&lt;/h2>&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-typescript" data-lang="typescript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">ollama&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">Message&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="kr">from&lt;/span> &lt;span class="s1">&amp;#39;ollama&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">async&lt;/span> &lt;span class="kd">function&lt;/span> &lt;span class="nx">runChatbot() {&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">messages&lt;/span>: &lt;span class="kt">Message&lt;/span>&lt;span class="p">[]&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="p">[&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">role&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;system&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">content&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;You are a concise expert.&amp;#39;&lt;/span> &lt;span class="p">},&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">{&lt;/span> &lt;span class="nx">role&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;user&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">content&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;Explain RESTful APIs.&amp;#39;&lt;/span> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">];&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">response&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">await&lt;/span> &lt;span class="nx">ollama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">chat&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">model&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;llama3.1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">messages&lt;/span>: &lt;span class="kt">messages&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">stream&lt;/span>: &lt;span class="kt">false&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Assistant:&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">response&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">message&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">content&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">error&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">error&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Error communicating with Ollama:&amp;#34;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">error&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">runChatbot&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;h2 id="aufbau-eines-express-servers-mit-streaming-unterstützung">Aufbau eines Express-Servers mit Streaming-Unterstützung
&lt;/h2>&lt;p>Hier ist ein Beispiel für die Implementierung einer Backend-API, die Antworten als Stream an ein Web-Frontend zurückgibt. Hierbei werden Chunks über SSE (Server-Sent Events) oder reguläres HTTP-Streaming gesendet.&lt;/p>
&lt;div class="highlight">&lt;div class="chroma">
&lt;table class="lntable">&lt;tr>&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code>&lt;span class="lnt"> 1
&lt;/span>&lt;span class="lnt"> 2
&lt;/span>&lt;span class="lnt"> 3
&lt;/span>&lt;span class="lnt"> 4
&lt;/span>&lt;span class="lnt"> 5
&lt;/span>&lt;span class="lnt"> 6
&lt;/span>&lt;span class="lnt"> 7
&lt;/span>&lt;span class="lnt"> 8
&lt;/span>&lt;span class="lnt"> 9
&lt;/span>&lt;span class="lnt">10
&lt;/span>&lt;span class="lnt">11
&lt;/span>&lt;span class="lnt">12
&lt;/span>&lt;span class="lnt">13
&lt;/span>&lt;span class="lnt">14
&lt;/span>&lt;span class="lnt">15
&lt;/span>&lt;span class="lnt">16
&lt;/span>&lt;span class="lnt">17
&lt;/span>&lt;span class="lnt">18
&lt;/span>&lt;span class="lnt">19
&lt;/span>&lt;span class="lnt">20
&lt;/span>&lt;span class="lnt">21
&lt;/span>&lt;span class="lnt">22
&lt;/span>&lt;span class="lnt">23
&lt;/span>&lt;span class="lnt">24
&lt;/span>&lt;span class="lnt">25
&lt;/span>&lt;span class="lnt">26
&lt;/span>&lt;span class="lnt">27
&lt;/span>&lt;span class="lnt">28
&lt;/span>&lt;span class="lnt">29
&lt;/span>&lt;span class="lnt">30
&lt;/span>&lt;span class="lnt">31
&lt;/span>&lt;span class="lnt">32
&lt;/span>&lt;span class="lnt">33
&lt;/span>&lt;span class="lnt">34
&lt;/span>&lt;/code>&lt;/pre>&lt;/td>
&lt;td class="lntd">
&lt;pre tabindex="0" class="chroma">&lt;code class="language-javascript" data-lang="javascript">&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="nx">express&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;express&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">import&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">Ollama&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="nx">from&lt;/span> &lt;span class="s1">&amp;#39;ollama&amp;#39;&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">app&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">express&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">use&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">express&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">json&lt;/span>&lt;span class="p">());&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="kr">const&lt;/span> &lt;span class="nx">ollama&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="k">new&lt;/span> &lt;span class="nx">Ollama&lt;/span>&lt;span class="p">({&lt;/span> &lt;span class="nx">host&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;http://127.0.0.1:11434&amp;#39;&lt;/span> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">post&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;/api/stream-chat&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="kr">async&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">req&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="nx">res&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="p">{&lt;/span> &lt;span class="nx">prompt&lt;/span> &lt;span class="p">}&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="nx">req&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">body&lt;/span>&lt;span class="p">;&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="c1">// HTTP-Response-Header konfigurieren (Chunked Transfer)
&lt;/span>&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="c1">&lt;/span> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">setHeader&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Content-Type&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;text/plain; charset=utf-8&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">setHeader&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Transfer-Encoding&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="s1">&amp;#39;chunked&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">try&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="kr">const&lt;/span> &lt;span class="nx">stream&lt;/span> &lt;span class="o">=&lt;/span> &lt;span class="kr">await&lt;/span> &lt;span class="nx">ollama&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">generate&lt;/span>&lt;span class="p">({&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">model&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="s1">&amp;#39;llama3.1&amp;#39;&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">prompt&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="nx">prompt&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">stream&lt;/span>&lt;span class="o">:&lt;/span> &lt;span class="kc">true&lt;/span>&lt;span class="p">,&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="k">for&lt;/span> &lt;span class="kr">await&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="kr">const&lt;/span> &lt;span class="nx">chunk&lt;/span> &lt;span class="k">of&lt;/span> &lt;span class="nx">stream&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="nx">chunk&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">response&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">end&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span> &lt;span class="k">catch&lt;/span> &lt;span class="p">(&lt;/span>&lt;span class="nx">err&lt;/span>&lt;span class="p">)&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">status&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">500&lt;/span>&lt;span class="p">).&lt;/span>&lt;span class="nx">write&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s2">&amp;#34;Error generating response.&amp;#34;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">res&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">end&lt;/span>&lt;span class="p">();&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="p">}&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="nx">app&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">listen&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="mi">3000&lt;/span>&lt;span class="p">,&lt;/span> &lt;span class="p">()&lt;/span> &lt;span class="p">=&amp;gt;&lt;/span> &lt;span class="p">{&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl"> &lt;span class="nx">console&lt;/span>&lt;span class="p">.&lt;/span>&lt;span class="nx">log&lt;/span>&lt;span class="p">(&lt;/span>&lt;span class="s1">&amp;#39;Server is running on port 3000&amp;#39;&lt;/span>&lt;span class="p">);&lt;/span>
&lt;/span>&lt;/span>&lt;span class="line">&lt;span class="cl">&lt;span class="p">});&lt;/span>
&lt;/span>&lt;/span>&lt;/code>&lt;/pre>&lt;/td>&lt;/tr>&lt;/table>
&lt;/div>
&lt;/div>&lt;hr>
&lt;h1 id="leistungsmetriken-und-mathematische-analyse">Leistungsmetriken und mathematische Analyse
&lt;/h1>&lt;p>Um lokale LLMs in Produktionsqualität bereitzustellen, ist eine Analyse von Latenz und Durchsatz unerlässlich. Die API-Antworten von Ollama enthalten detaillierte Leistungskennzahlen.&lt;/p>
&lt;h2 id="berechnungsmodell-der-token-generierungsgeschwindigkeit">Berechnungsmodell der Token-Generierungsgeschwindigkeit
&lt;/h2>&lt;p>Die Reaktionszeit eines LLMs, die sich direkt auf die Benutzererfahrung auswirkt, kann grob in die &amp;ldquo;&lt;strong>Time To First Token (TTFT)&lt;/strong>&amp;rdquo; (Zeit bis zum ersten Token) und die &amp;ldquo;&lt;strong>Time Per Output Token (TPOT)&lt;/strong>&amp;rdquo; (Zeit pro ausgegebenem Token) unterteilt werden.&lt;/p>
&lt;p>Die gesamte Generierungszeit $T_{total}$ bei einer Anzahl von $N$ generierten Token lässt sich wie folgt formulieren:&lt;/p>
$$
T_{total} = t_{ttft} + \sum_{i=1}^{N-1} t_{tpot}^{(i)}
$$
&lt;p>Wenn wir die durchschnittliche Zeit zur Generierung eines Tokens durch $\bar{t}_{tpot}$ approximieren, vereinfacht sich die Gleichung:&lt;/p>
$$
T_{total} \approx t_{ttft} + (N - 1) \times \bar{t}_{tpot}
$$
&lt;p>Die Zuordnung zu den Feldern der Ollama API-Antwort sieht wie folgt aus:&lt;/p>
&lt;ul>
&lt;li>&lt;code>prompt_eval_duration&lt;/code>: Dies entspricht in etwa $t_{ttft}$ (Evaluierungszeit des Prompts) und wird in Nanosekunden zurückgegeben.&lt;/li>
&lt;li>&lt;code>eval_duration&lt;/code>: Die gesamte Zeit, die der Generierungsprozess in Anspruch genommen hat.&lt;/li>
&lt;li>&lt;code>eval_count&lt;/code>: Die Anzahl der generierten Token $N$.&lt;/li>
&lt;/ul>
&lt;p>Die Token-Generierungsgeschwindigkeit pro Sekunde (Tokens Per Second: TPS) lässt sich folglich mit dieser Formel berechnen:&lt;/p>
$$
TPS = \frac{eval\_count}{(eval\_duration / 10^9)} \quad [\text{tokens/sec}]
$$
&lt;p>Ein Beispiel: Bei &lt;code>eval_count: 256&lt;/code> und &lt;code>eval_duration: 4321000000&lt;/code> (etwa 4,32 Sekunden) ergibt sich:
&lt;/p>
$$
TPS = \frac{256}{4.321} \approx 59.24 \text{ tokens/sec}
$$
&lt;p>
Wenn die Geschwindigkeit in einer lokalen Umgebung 50 Token/Sekunde überschreitet, übertrifft dies die menschliche Lesegeschwindigkeit bei Weitem, was bedeutet, dass eine sehr komfortable Reaktionszeit erreicht wird.&lt;/p>
&lt;h2 id="schätzformel-für-die-benötigte-vram-kapazität">Schätzformel für die benötigte VRAM-Kapazität
&lt;/h2>&lt;p>Wenn Sie Modelle lokal ausführen, ist es für die Leistung entscheidend, ob das Modell in den VRAM der GPU passt. Wenn der VRAM nicht ausreicht und auf den Hauptspeicher (RAM) des Systems ausgewichen werden muss (Fallback), sinkt die Generierungsgeschwindigkeit erheblich.&lt;/p>
&lt;p>Eine einfache Formel zur Schätzung der benötigten Speicherkapazität $M$ (in Gigabyte) sieht folgendermaßen aus:&lt;/p>
$$
M \approx \frac{P \times Q}{8 \times 1024} + C
$$
&lt;ul>
&lt;li>$P$: Anzahl der Parameter des Modells (z. B. 8B = $8000 \times 10^6$)&lt;/li>
&lt;li>$Q$: Quantisierung in Bit (z. B. 4-bit, 8-bit, 16-bit)&lt;/li>
&lt;li>$C$: Zusätzlicher Speicher für das Kontextfenster (wie der KV-Cache; hängt vom Modell und den Einstellungen ab, jedoch rechnet man im Allgemeinen mit etwa 1 bis 2 GB)&lt;/li>
&lt;/ul>
&lt;p>&lt;strong>Berechnungsbeispiel&lt;/strong>: Bei der Ausführung von Llama 3 (8B Parameter) mit einer 4-Bit-Quantisierung
&lt;/p>
$$
M_{model} = \frac{8,000 \times 4}{8 \times 1024} = \frac{32,000}{8192} \approx 3.9 \text{ GB}
$$
&lt;p>
Wenn man den Speicher für den Kontext addiert, erkennt man, dass das Modell bei etwa 5 GB bis 6 GB VRAM vollständig auf der GPU abgelegt (Full Offload) werden kann. Selbst eine Mittelklasse-GPU aus heutiger Zeit mit 8 GB VRAM (wie eine RTX 4060) reicht also völlig aus, um ein leistungsstarkes LLM zu betreiben.&lt;/p>
&lt;hr>
&lt;h1 id="fortgeschrittene-anwendungsfälle-und-fazit">Fortgeschrittene Anwendungsfälle und Fazit
&lt;/h1>&lt;p>Wenn man Ollama als API in einem lokalen Netzwerk bereitstellt, ergeben sich vielfältige Anwendungsmöglichkeiten, die weit über einen bloßen Chatbot hinausgehen.&lt;/p>
&lt;h3 id="1-aufbau-eines-lokalen-rag-retrieval-augmented-generation">1. Aufbau eines lokalen RAG (Retrieval-Augmented Generation)
&lt;/h3>&lt;p>Durch die Kombination einer lokalen Vektordatenbank wie ChromaDB oder Qdrant mit dem Ollama-Endpunkt &lt;code>/api/embeddings&lt;/code> (unter Nutzung von Embedding-Modellen wie &lt;code>nomic-embed-text&lt;/code>) kann ein sicheres, komplett offline funktionierendes RAG-System aufgebaut werden, in dem interne, vertrauliche Dokumente eingelesen und Fragen dazu beantwortet werden können.&lt;/p>
&lt;h3 id="2-ki-assistent-für-ides-und-editoren">2. KI-Assistent für IDEs und Editoren
&lt;/h3>&lt;p>Indem man Ollama als Backend für VS Code-Erweiterungen (wie Continue.dev) oder Neovim-Plugins festlegt, können Code-Vervollständigung und Code-Erklärungen im Stil von GitHub Copilot lokal (z. B. mit Modellen wie &lt;code>codellama&lt;/code> oder &lt;code>deepseek-coder&lt;/code>) und vollkommen kostenlos durchgeführt werden.&lt;/p>
&lt;h3 id="3-integration-in-automatisierungsskripte">3. Integration in Automatisierungsskripte
&lt;/h3>&lt;p>Durch die Einbindung von Ollama-API-Anfragen in Python- oder Shell-Skripte lässt sich die KI in zahlreiche alltägliche Arbeitsabläufe integrieren – von der automatischen Zusammenfassung von Protokollen über die automatische Erstellung von Git-Commit-Nachrichten bis hin zur Klassifizierung von Standardtexten.&lt;/p>
&lt;h2 id="fazit">Fazit
&lt;/h2>&lt;p>Mit dem Erscheinen von Ollama ist die Einstiegshürde für lokale LLMs dramatisch gesunken. Die Kombination aus einem einfachen Befehlssystem, das an die Bedienung von Docker-Containern erinnert, und einer REST-API, die sich leicht aus externen Anwendungen heraus nutzen lässt, ist heute de facto der Standard für die Entwicklung lokaler KI-Lösungen.&lt;/p>
&lt;p>Entwickler, die mit den Kosten und Sicherheitsbeschränkungen von Cloud-LLMs kämpfen, sollten unbedingt die in diesem Artikel vorgestellten Schritte nutzen, um eine lokale LLM-Umgebung mit Ollama aufzubauen und in ihre Anwendungen zu integrieren. Auf diese Weise können Sie die Potenziale der KI noch freier und greifbarer erleben.&lt;/p></description></item></channel></rss>