Reimar Bauer

HowTo: Lokale KI-gestützte PDF-Verarbeitung in einer abgesicherten Umgebung


In diesem Beitrag zeigen wir, wie man eine vollständig lokale Pipeline zur Analyse von PDF-Dokumenten aufbaut. Das Ziel ist es, sensible Daten ohne Cloud-Anbindung zu verarbeiten. Wir nutzen einen agentischen Coding-Workflow, der in der Lage ist, PDF-Screenshots oder Text von PDF zu extrahieren. Diese werten wir mittels eines lokalen LLM aus.

Die Tool-Landschaft: Das Setup

Bevor wir in die Konfiguration einsteigen, stellen wir die vier Kernkomponenten vor, die dieses System ermöglichen:

1. Vibepod (0.20.1)

Vibepod ist eine Python-basierte CLI, die als “Wrapper” für KI-Coding-Agents dient. Sie erlaubt es, Agents wie Pi in einer isolierten Docker-Container-Umgebung auszuführen, ohne dass der Nutzer sich mit komplexen Docker-Konfigurationen auseinandersetzen muss. Vibepod abstrahiert die Orchestrierung und stellt eine einfache Schnittstelle bereit, um Agenten zu starten und zu verwalten.

2. Pi (v0.84.2)

Pi ist ein minimaler, extrem performanter Terminal-Coding-Agent. Im Gegensatz zu schweren IDE-Integrationen lebt Pi direkt im Terminal. Er kann benutzerdefinierte Provider (LLMs) ansteuern, Dateien lesen/schreiben und Shell-Befehle ausführen, was ihn zum idealen “Operator” für die Automatisierung von Aufgaben macht.

3. LM Studio (LM Studio0.4.21 (Build 2))

LM Studio fungiert als unser lokales LLM-Backend. Es lädt Modelle im GGUF-Format oder MLX-Format herunter und stellt diese über eine OpenAI-kompatible API (lokaler Server) bereit. In diesem Setup nutzen wir das Modell poolside/laguna-s-2.1 (ein 118B Mixture of Experts-Modell mit 8B aktiven Parametern), das speziell für agentisches Coding und komplexe Logik optimiert wurde. Dieses Modell benötigt mindestens 71 GB VRAM-Memory. Weiteres Memory wird für den Context benötigt. Alternativ haben wir in der Datei models.json noch qwen/qwen3.8-27b (ein 27B dense vision-language model) definiert. Dieses benötigt mindestens 17 GB VRAM-Memory. Dieses Modell muss mit medium oder weniger reasoning betrieben werden.
Für Systeme mit wenig VRAM empfiehlt sich die Nutzung quantisierter Modelle oder kleinere Alternativen, wie das erwähnte Qwen-Modell.

4. Pixi (0.77.0)

Pixi ist ein moderner, extrem schneller Paketmanager (basierend auf dem conda-forge Ökosystem). Er löst ein kritisches Problem in Container-Umgebungen: die Installation von System-Binaries ohne Root-Rechte. Pi nutzt Pixi, um Poppler zu installieren – das Toolkit, das für die Extraktion von Bildern aus PDFs zwingend erforderlich ist. Wir können Pixi nutzen, um Vibepod auf unserem System zu installieren.

Teil 1: Verbindung von Pi (via Vibepod) mit LM Studio

1.1 LM Studio vorbereiten

  1. Installiere LM Studio.
  2. Lade die Modell poolside/laguna-s-2.1 und qwen/qwen3.8-27b herunter.
  3. Starte den lokalen Server (standardmäßig auf http://localhost:1234/v1).

1.2 Installation von vibepod und Konfiguration

Zunächst installieren wir Vibepod mit Pixi in unserem System als Nutzer.
pixi global install vibepod

Da wir es global installiert haben, können wir es später einfach in jedem Verzeichnis anwenden.
Wir benötigen noch Podman oder Docker, dazu bitte die Anleitungen beachten.

Damit der Pi-Agent “denken” kann, müssen wir ihn mit dem in LM Studio laufenden Modell verbinden.

Damit Vibepod die Konfiguration in den Container übernimmt, muss die Datei an der richtigen Stelle im Host-System liegen. Das globale Verzeichnis, in dem VibePod die Konfigurationen speichert, kann mit vp config path ermittelt werden. Die models.json muss in das Agenten-Verzeichnis von Pi kopiert werden:
.../vibepod/agents/pi/.pi/agent/models.json

Pi nutzt eine JSON-Datei, um KI-Agenten Modelle zur Verfügung zu stellen. Wir definieren einen Provider, der auf den lokalen LM Studio Server zeigt. Wir verwenden dazu die host.docker.internal Adresse anstelle der 127.0.0.1. Wichtig für Linux: Damit das Binding von LM Studio auf host.docker.internal funktioniert, muss der Service an das Docker-Gateway-Netzwerk gebunden sein: docker network inspect bridge | grep Gateway. Ohne diesen Schritt funktioniert es mit Linux nicht.
Verschiedene Modelle können mit unterschiedlichen Parametern definiert werden. Der oberste Eintrag in der Liste ist das Standard Model:


{
"providers": {
"lmstudio-local": {
"baseUrl": "http://host.docker.internal:1234/v1",
"api": "openai-completions",
"apiKey": "lm-studio",
"models": [
{
"id": "poolside/laguna-s-2.1",
"name": "Poolside Laguna S 2.1 (Local)",
"reasoning": true,

"contextWindow": 200000,
"maxTokens": 4096,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
},

{
"id": "qwen/qwen3.8-27b",
"name": "Qwen3.8-27b (Local)",
"reasoning": true,
"reasoning_effort": "medium",

"contextWindow": 200000,
"maxTokens": 4096,
"cost": { "input": 0, "output": 0, "cacheRead": 0, "cacheWrite": 0 }
}
]
}
}
}


Wir haben ein Context Window von 200.000 Token definiert. Bei sehr großen PDF-Dateien oder vielen hochauflösenden Bildern kann dieser Speicher dennoch knapp werden oder die Performance sinken. In diesem Fall empfiehlt es sich z.B. PDF-Dateien in kleinere Abschnitte zu unterteilen.

1.3 Start des Agenten

Nun starten wir den Agenten über die Vibepod-CLI:

cd workspace/TestDir
vp run pi
start

Sobald Pi gestartet ist, wird das Standard Modell in LM Studio geladen. Andere konfigurierte Modelle stehen im Terminal unter dem Befehl /model zur Auswahl bereit. Das aktuelle Arbeitsverzeichnis wird dabei automatisch als /workspace in den Container gemountet.

Alles was Pi macht, passiert nur im rootless Container und nicht auf eurem Host. Alles was Pi schreibt, konfiguriert oder installiert hat keine Auswirkung auf euren Host. Pi kann Euer System nicht umkonfigurieren. Falls Pi auf die Idee kommt alles zu löschen, wäre davon nur das TestDir und die Pi Konfiguration betroffen. Pi kommuniziert über host.docker.internal nach außen. Für den Proxy von vibepod ist ein White-/Blacklisting von Adressen geplant.

Das Setup ist in der aktuellen Version nicht gegen Prompt-Injection oder unbefugten Datenabfluss geschützt, solange das Whitelisting nicht implementiert ist. Ein konkreter Workaround ist z.B. eine eigene Firewall Regel oder kein internet Zugang auf dem eigenen Rechner.

Mit "start" als minimale Prompt-Nachricht im Terminal wird Pi veranlasst den aktuellen Workspace zu untersuchen und das Modell in LM Studio zu laden. Pi versucht herauszufinden, was Dein Auftrag ist.

Über den Prompt wird in LM Studio das Modell geladen.

Die Ausgabe zeigt den Startprozess und die Konfiguration des Modells nach der Ausführung von vp run pi start

In der models.json haben wir reasoning eingeschaltet. In der Pi-Konsole können wir verschiedene Level des reasoning mit /settings den "Thinking-Level" einstellen. Jedoch kann unser verwendetes Modell nur Reasoning ein- oder ausschalten. Dem Protokoll können wir weiterhin entnehmen, wie viel Zeit von "Streaming response" bis "Finished streaming response" vergeht.
Wenn Du mit dem Agenten per Prompt kommunizieren willst, reicht ein "vp run pi".

Teil 2: Erweiterung der Fähigkeiten mit Pixi & Poppler

Ein LLM allein kann keine PDFs “sehen”. Wir benötigen System-Tools, um PDF-Seiten in Bilder oder Text umzuwandeln, die der Agent dann analysieren kann.

2.1 Warum Pixi?

In vielen Docker-Umgebungen fehlen curl, wget oder die Berechtigung für apt-get install. Pixi erlaubt es uns, Binaries isoliert im User-Space zu installieren. D. h. Pi kann Pixi im Userspace installieren.

Installation von Pixi (für minimale Umgebungen)

Falls Pixi noch nicht vorhanden ist, kann Pi ein Script schreiben, der das Binary direkt über HTTPS lädt:
Anders geht das im Container nicht, da weder curl noch wget installiert ist und Pi keine root Rechte hat.

Es reicht, Pi mitzuteilen, dass es Pixi mit Node.js installieren und den Download mit einer Checksumme verifizieren soll; dann schreibt es sich das dafür nötige Skript.

So würde das z.B. aussehen:

#!/usr/bin/env bash
# install-pixi.sh — pixi herunterladen, Checksumme prüfen, entpacken
set -euo pipefail

# Zielverzeichnis (bewusst NICHT $PIXI_HOME überschreiben, das gehört pixi zur Laufzeit)
INSTALL_DIR="${PIXI_INSTALL_DIR:-$PWD/.pixi}" # aus dem Workdir ausführen -> ./.pixi
FILE="pixi-aarch64-unknown-linux-musl.tar.gz"
BASE="https://github.com/prefix-dev/pixi/releases/latest/download"

# Download via Node (fetch) — weder curl noch wget vorhanden auf dem Zielsystem
fetch_file() {
local url="$1" out="$2"
node --input-type=module -e '
import { writeFileSync } from "node:fs";
const [url, out] = process.argv.slice(1);
const res = await fetch(url, { redirect: "follow" });
if (!res.ok) { console.error(`HTTP ${res.status} for ${url}`); process.exit(1); }
const buf = Buffer.from(await res.arrayBuffer());
writeFileSync(out, buf);
console.error(`downloaded ${buf.length} bytes -> ${out}`);
' "$url" "$out"
}

TMPDIR_WORK="$(mktemp -d)"
trap 'rm -rf "$TMPDIR_WORK"' EXIT
cd "$TMPDIR_WORK"

# 1) Datei + Checksumme herunterladen
fetch_file "$BASE/$FILE" "$FILE"
fetch_file "$BASE/$FILE.sha256" "$FILE.sha256"

# 2) Checksumme verifizieren (Dateiname -> lokalen Pfad umschreiben)
sed "s|$FILE|$TMPDIR_WORK/$FILE|" "$FILE.sha256" | sha256sum -c -

# 3) Entpacken nach $INSTALL_DIR/bin
mkdir -p "$INSTALL_DIR/bin"
tar xzf "$FILE" -C "$INSTALL_DIR/bin"
chmod +x "$INSTALL_DIR/bin/pixi"

echo "✅ pixi installiert nach: $INSTALL_DIR/bin"
"$INSTALL_DIR/bin/pixi" --version

export PATH="
$INSTALL_DIR/bin:$PATH"

Installation von Poppler

Nun fügt Pi "Poppler" hinzu, um PDF-Bildextraktion zu ermöglichen:

pixi init # Erstellt pixi.toml
pixi add poppler # Installiert Poppler (z.B. Version >=26.7.0)

Wichtiger Hinweis zur Architektur:
Pixi dokumentiert die Installation in pixi.toml und pixi.lock. Damit garantiert Pixi die Reproduzierbarkeit. Beachte, dass im Container oft linux-aarch64 verwendet wird. Binaries, die dort installiert wurden, funktionieren nicht auf dem Host-System (z.B. osx-arm64). Sofern die Plattform explizit in der pixi.toml ergänzt wird, können die gleichen Versionen der Binaries für unser Betriebssystem in einem eigenen Environment installiert werden. Dies ermöglicht eine Reproduktion dessen, was Pi gemacht hat.
Die Dokumentation erfolgt im workspace-Verzeichnis und bleibt nach der Verwendung von Vibepod erhalten.

Der Container mit linux-aarch64 bietet gegenüber der direkten Nutzung von Pi ohne Vibepod den Vorteil, dass potenziell unsicherer Code nicht vom Host-Betriebssystem ausgeführt wird, sondern nur von Pi im Container.

2.2 Nutzung der Binaries in Code

Die installierten Tools liegen in ~/.pixi/envs/default/bin/. Ein JavaScript-Snippet zur Extraktion sieht dann z.B. so aus:


const path = require('path');
const { spawnSync } = require('child_process');

const PIXI_ENV_BIN = '/workspace/.pixi/envs/default/bin';

// PDF-Seiten als PNG-Bilder extrahieren (300 DPI für optimale OCR-Qualität)
spawnSync(path.join(PIXI_ENV_BIN, 'pdftoppm'), [
'-png', '-r', '300',
pdfPath, outputPrefix
]);

Dieser Code wird nur im Container ausgeführt und nicht auf eurem Host.

Teil 3: Der Workflow in der Praxis

Sobald die Infrastruktur steht (vp run pi), übernimmt der Pi-Agent die Steuerung.

Ein Beispiel-Prompt an Pi könnte so aussehen:

"Verwende pixi (https://pixi.prefix.dev/latest/installation/) für pdf tools Installation. Überprüfe den Download von pixi mit einer Checksumme. Bitte extrahiere alle URLs, die als anklickbare Links unter einem Wort oder einer direkten Verknüpfung zu finden sind. Zusätzlich sollst du Mastodon-Links, E-Mail-Adressen, Telefonnummern und den Kontext zum Inhalt jedes PDF-Beitrags im Verzeichnis extrahieren. Verwende ausschließlich die gefundenen PDFs als Quelle. Es ist korrekt, wenn eine Anfrage nicht erfüllt werden kann. Erstelle anschließend eine Zusammenfassung in deutscher Sprache."

Pi führt daraufhin folgende Schritte autonom aus:

  1. Tool-Check: Pi erkennt, dass Pixi noch installiert werden muss und installiert es. Dann bemerkt es, dass Poppler benötigt wird, und nutzt Pixi init & pixi add poppler.
  2. Extraktion: Er führt pdftoppm aus, um die PDF-Seiten in hochauflösende PNGs umzuwandeln. Oder pdftotext, wenn Text enthalten ist.
  3. Analyse: Die Bilder (und der Text) werden an das lokale Laguna-s-2.1 Modell in LM Studio mit einer Anweisung übergeben.
  4. Ausgabe: Pi liefert die Zusammenfassung direkt im Terminal.

3.1 Lokales Analytics Dashboard: Volltransparenz über Modellverhalten und Traffic

Ein entscheidender Vorteil des lokalen Setups ist die vollständige Transparenz darüber, was das LLM tut. Vibepod bietet ein lokales Analytics Dashboard, das Nutzung und HTTP-Traffic pro Agent verfolgt — inklusive Token-Metriken.

Was wird getrackt?

  • All Agents Token Usage: Eingabe-, Ausgabe- und Cache-Token pro Anfrage
  • HTTP-Requests Dashboard: Alle ausgehenden API-Anfragen werden protokolliert — einschließlich Ziel-URL, Provider und Status.
  • Agent-Session Dashboard: Anzeige aus den Vibepod Logs

So behältst Du den Überblick

Da alles lokal läuft, hast Du jederzeit vollständige Kontrolle über:

  1. Welche Modell-Instanz aktiv ist
  2. Womit sich das LLM/Pi verbindet— im Analytics Dashboard werden alle HTTP-Requests protokolliert,
  3. Token-Metriken in Echtzeit — siehst Du exakt wie viele Token für PDF-Verarbeitung, Bildanalyse oder Codegenerierung verbraucht wurden.

Hinweis: Da LM Studio lokal läuft und Pi über models.json konfiguriert ist, fließen alle Metriken ausschließlich lokal — keine Daten werden an externe Dienste gesendet. Das Analytics Dashboard ist Teil von Vibepod und kann jederzeit eingesehen werden.
Die Logs und die Proxy-Datenbank liegen lokal als SQLite vor und können mit weiteren Tools verarbeitet werden.

3.2 Beispiel:

Wir speichern diesen Blogpost in einer PDF und legen diese Datei in ein Verzeichnis TestDir

In dem Verzeichnis TestDir:
vp run pi

Wir schreiben dann den Prompt: "Verwende pixi (https://pixi.prefix.dev/latest/installation/) für pdf tools Installation. Überprüfe den Download von pixi mit einer Checksumme. Bitte extrahiere alle URLs, die als anklickbare Links unter einem Wort oder einer direkten Verknüpfung zu finden sind. Zusätzlich sollst du Mastodon-Links, E-Mail-Adressen, Telefonnummern und den Kontext zum Inhalt jedes PDF-Beitrags im Verzeichnis extrahieren. Verwende ausschließlich die gefundenen PDFs als Quelle. Es ist korrekt, wenn eine Anfrage nicht erfüllt werden kann. Erstelle anschließend eine Zusammenfassung in deutscher Sprache."

Das sind nur einige der Ausgaben, die dieser Workflow erstellt. Es wurde die Version des Blogposts vom 20.8.2026 verwendet.

Der Abschlussbericht von poolside/laguna-s-2.1, die Aufnahme im Video

Ein Ausschnitt eines Bildschirms mit grünem Hintergrund und weißer Schrift. (Mistral: Mistral Medium 3.5, 2026-08-21)

Der Abschlussbericht von qwen/qwen3.8-27b, die Aufnahme im Video.

Eine Zusammenfassung von der Pixi Installation über die Extraktion bis zur Ablage der Zusammefassung

3.3 Vergleich: Ergebnisse der beiden Modelle (poolside/laguna-s-2.1, qwen/qwen3.8-27b)

Für qwen/qwen3.8-27b ist es wichtig, das Reasoning auf "medium" oder "off" in Pi einzustellen. Das Modell hat Probleme, wenn etwas, das abgefragt wird, nicht im Dokument enthalten ist, und sucht dann nach Lösungen.
Da qwen Bildinformationen verarbeiten kann, extrahiert das Modell bei Bedarf die Abbildungen selbständig aus dem PDF.

Beide Modelle haben die Teilaufgabe, Pixi und darüber die nötigen Tools zu installieren bewältigt.
Bei der Verarbeitung der PDF Datei mit den installierten Werkzeugen hatte qwen/qwen3.8-27b nicht alle Urls gefunden. Nur poolside/laguna-s-2.1 hat die Aufgabe aus dem Prompt jedesmal direkt abgeschlossen.

Damit qwen/qwen3.8-27b die Aufgabe abschließt, wurde die Aufgabe nach dem Abbruch präzisiert (Eine Abbruchregel hinzugefügt).

"Verwende pixi (https://pixi.prefix.dev/latest/installation/) für pdf tools Installation. Überprüfe den Download von pixi mit einer Checksumme. Bitte extrahiere alle URLs, die als anklickbare Links unter einem Wort oder einer direkten Verknüpfung zu finden sind. Zusätzlich sollst du Mastodon-Links, E-Mail-Adressen, Telefonnummern und den Kontext zum Inhalt jedes PDF-Beitrags im Verzeichnis extrahieren. Verwende ausschließlich die gefundenen PDFs als Quelle. Es ist korrekt, wenn eine Anfrage nicht erfüllt werden kann. Erstelle anschließend eine Zusammenfassung in deutscher Sprache."

Mit qwen/qwen3.8-27b habe ich noch sehr wenig Erfahrungen, was diese Art von Aufgaben angeht. Es ist vor wenigen Tagen veröffentlicht worden. Welche anderen lokalen Modelle habt ihr für agentisches Coding getestet? Falls ihr Ideen habt, schreibt mir diese in die Kommentare.

3.4 Reproduzierbarkeit der Ergebnisse

Wenn wir den Modellen überlassen ihre Werzeuge für die Aufgabe zu installieren, sind unterschiedliche Ergebnisse zu erwarten.
Daher bietet es sich an die nötigen Programme von pixi bis poppler über ein sogenanntes Docker-Overlay vorher zu installieren.
Dann können beide Modelle direkt die eigentliche Aufgabe bewältigen.

Dazu müssen wir in unserem TestDir eine Datei .vibepod/overlay/Dockerfile ablegen.

# overlay: pixi + PDF/OCR tools (issue #140)
# FROM-less Dockerfile fragment; VibePod prepends the base image's `FROM <image>`

ENV PIXI_HOME=/opt/pixi

# Download pixi binary + official SHA256 checksum via Docker ADD (no curl/wget needed)
ADD https://github.com/prefix-dev/pixi/releases/latest/download/pixi-aarch64-unknown-linux-musl.tar.gz /tmp/pixi.tar.gz
ADD https://github.com/prefix-dev/pixi/releases/latest/download/pixi-aarch64-unknown-linux-musl.tar.gz.sha256 /tmp/pixi.sha256

# Verify checksum with sha256sum -c, then extract to $PIXI_HOME/bin
RUN set -ex && \
cd /tmp && \
sed 's|pixi-aarch64-unknown-linux-musl.tar.gz|/tmp/pixi.tar.gz|g' pixi.sha256 | sha256sum -c - && \
mkdir -p ${PIXI_HOME}/bin && \
tar xzf /tmp/pixi.tar.gz -C ${PIXI_HOME}/bin && \
chmod +x ${PIXI_HOME}/bin/pixi && \
rm -f /tmp/pixi.tar.gz /tmp/pixi.sha256

ENV PATH=/opt/pixi/bin:$PATH
RUN pixi --version

# Create vp_pixi project at /opt/vp_pixi (/opt to avoid overwriting user pixi installations)
RUN mkdir -p /opt/vp_pixi
WORKDIR /opt/vp_pixi
RUN pixi init

# Install PDF tools + OCR: poppler, qpdf, ghostscript, tesseract (all with checksum verification)
RUN pixi add poppler qpdf ghostscript tesseract

ENV PATH=/opt/vp_pixi/.pixi/envs/default/bin:$PATH

Beim nächsten vp run pi wird das Overlay Image gebildet
Building overlay image localhost/vibepod/overlay-pi:071bf6cdda07 from vibepod/pi:latest (/Users/reimarbauer/workspace/TestDir/.vibepod/overlay/Dockerfile)

Mit einer Zeile wie "Starting pi with image localhost/vibepod/overlay-pi:071bf6cdda07" wird dem Benutzer die Ergänzung angezeigt.

3.5 Der Workflow als eigenständiges Programm mit oder ohne Modell

Pi ist ein Terminal-basierter Coding-Agent. Naheliegend wäre, wenn Ihr Code lesen könnt, Pi aufzufordern den Workflow in Code umzusetzen.

Sicherheit: Stand heute

Das beschriebene Setup isoliert Codeausführung (rootless-Container) und hält LLM-Verarbeitung lokal. Es ist keine vollständige Datenabfluss-Abwehr. Bis das Adress-Whitelisting im Vibepod-Proxy implementiert ist, kann der Agent theoretisch über host.docker.internal auf Host-Services oder – je nach Netzwerkkonfiguration – auf externe Adressen zugreifen. Der in 1.3 genannte Workaround (eigene Firewall Regeln) sollte in sensiblen Umgebungen standardmäßig gesetzt werden. Prompt-Injection über PDF-Inhalt (z. B. versteckte Textanweisungen in eingebetteten Metadaten) ist nicht ausgeschlossen.

Fazit

Durch die Kombination dieser vier Tools schaffen wir eine mächtige, lokale KI-Workstation:

  • Vibepod sorgt für eine saubere, containerisierte Umgebung.
  • Pi agiert als intelligenter Operator, der Tools bedient und installieren kann.
  • LM Studio + Laguna-s-2.1 oder qwen/qwen3.8-27b liefert die nötige “Intelligenz” ohne Datenabfluss in die Cloud.
  • Pixi überwindet Installationshürden in eingeschränkten Umgebungen.

Das Ergebnis ist ein reproduzierbarer Workflow zur PDF-Verarbeitung, der Datenschutz und maximale Kontrolle vereint.

Ausblick

Vibepod kann viele KI-Coding-Agenten (claude, gemini, opencode, devstral, auggie, copilot, codex, pi, agy, tau, jcode) isoliert in Containern ausführen. Daher sind Dockerfile Overlays eine Erweiterung, die wir individuell erstellen, eine hervorragende Ergänzung einer bereits jetzt genialen Software.
Das im Blogpost beschrieben Setup könnte z.B. zur lokalen Analyse von sensiblen Daten genutzt werden. Der Workflow könnte auch in eine größere Pipeline z. B. automatisches Überwachen eines Ordners auf neue PDFs integriert werden.

Ressourcen

Tags: Softwareentwicklung
Letzte Änderung: 28.08.2026