Vom statischen PDF zur lebendigen Wissensdatenbank: Wie das kb CLI-Tool Agenten den Zugriff auf Fachliteratur ermöglicht – inklusive Discovery, Vision AI und strukturierter JSON-Ausgabe.
1. Das Problem: Fachwissen ist in Silos gefangen
In der Welt der KI-Agenten ist der Zugriff auf aktuelles und tiefgreifendes Fachwissen oft die größte Hürde. Während LLMs über ein beeindruckendes Allgemeinwissen verfügen, stoßen sie bei spezifischen, mathematischen oder hochaktuellen Themen an ihre Grenzen.
Das wertvollste Wissen liegt oft in Fachbüchern (PDF und EPUB), die jedoch für Agenten schwer zugänglich sind: 1. Unstrukturierte Daten: PDFs und EPUBs sind für Menschen optimiert, nicht für Maschinen. 2. Kontext-Fenster: Man kann nicht einfach 40 Fachbücher in den Prompt eines Agenten kopieren. 3. Quellentreue: Agenten neigen zu Halluzinationen, wenn sie keine festen Referenzen haben. 4. Visuelle Inhalte: Diagramme und Abbildungen in Büchern enthalten oft zentrale Informationen, die reine Textextraktion nicht erfasst.
"The only way to make sense out of change is to plunge into it, move with it, and join the dance." — Alan Watts
Für einen KI-Agenten bedeutet "join the dance", dass er aktiv auf eine externe Wissensbasis zugreifen muss, um valide Antworten zu geben.
2. Die Lösung: Das kb CLI-Tool
kb ist ein spezialisiertes Command-Line-Interface, das eine Brücke zwischen statischer Fachliteratur und dynamischen KI-Workflows schlägt. Es implementiert eine vollständige RAG-Pipeline (Retrieval-Augmented Generation) direkt im Terminal.
Key Features
- Semantische Suche: Findet relevante Textstellen basierend auf Bedeutung, nicht nur auf Keywords.
- RAG-Antworten: Beantwortet komplexe Fragen unter direkter Einbeziehung der gefundenen Quellen.
- Multi-KB Management: Trennung von Wissensgebieten (z. B.
fpfür Funktionale Programmierung,catfür Kategorientheorie). - KB Discovery (
kb kbs): Agenten können alle verfügbaren Wissensdatenbanken mit Buchtiteln auflisten – per--jsonals strukturierte Daten. - Inkrementelle Updates (
kb add): Einzelne Bücher zu einer bestehenden KB hinzufügen, ohne den gesamten Index neu aufzubauen. - PDF- & EPUB-Support: Automatische Formaterkennung für beide Buchformate.
- Vision AI: Extraktion und Beschreibung von Abbildungen aus Büchern via GPT-4o Vision – die Bildbeschreibungen fließen in den Index und in RAG-Antworten ein.
- Deep Links: Ermöglicht das direkte Öffnen von PDFs an der exakt zitierten Stelle (macOS).
- JSON-First: Alle Ausgaben sind als JSON verfügbar – ideal für die Integration in Agenten.
→ GitHub: github.com/mhennemeyer/knowledgebase
3. In Action: Der Agent-Workflow
Der typische Workflow eines Agenten mit kb besteht aus zwei Schritten: Discovery und Abfrage.
Schritt 1: Discovery – Welche Wissensdatenbanken existieren?
kb kbs --json
Output (JSON):
{
"knowledgebases": [
{
"name": "fp",
"books": 8,
"chunks": 4163,
"book_titles": ["Functional Programming in Scala", "Haskell Programming from First Principles", "..."]
},
{
"name": "cat",
"books": 8,
"chunks": 3090,
"book_titles": ["Category Theory for Programmers", "Category Theory Illustrated", "..."]
},
{
"name": "ai",
"books": 25,
"chunks": 14457,
"book_titles": ["Designing Autonomous AI", "..."]
}
]
}
Der Agent kennt nun die verfügbaren Wissensgebiete, die jeweilige Tiefe (Chunks) und die konkreten Buchtitel. Ohne --name befragt kb ask nur die default-KB – mit kb kbs trifft der Agent eine informierte Entscheidung, welche KB relevant ist.
Schritt 2: Gezielte Abfrage
kb ask "Was ist ein Funktor?" --name cat --json
Output (JSON):
{
"answer": "Ein Funktor ist ein Konzept aus der Kategorientheorie, das eine Abbildung zwischen Kategorien darstellt. Er besteht aus zwei Abbildungen: einer für Objekte und einer für Morphismen. Diese müssen die Struktur (Identität und Komposition) bewahren...",
"sources": [
{
"book": "Category Theory Illustrated",
"page": 202,
"score": 0.55,
"open_cmd": "open -a Skim 'path/to/book.pdf' --args -page 202"
},
{
"book": "Category Theory for Programmers",
"page": 122,
"score": 0.50
}
]
}
Durch den --json-Flag erhält der Agent eine strukturierte Antwort, die er direkt verarbeiten kann. Er kennt die Antwort, die exakten Quellen und könnte dem Benutzer sogar anbieten, das Buch an der richtigen Stelle zu öffnen.
4. Statistische Übersicht
Aktuell verwaltet das kb-Tool für dieses Projekt vier thematische Wissensdatenbanken mit insgesamt 43 Büchern:
| KB Name | Thema | Bücher | Chunks |
|---|---|---|---|
fp |
Functional Programming | 8 | 4.163 |
cat |
Kategorientheorie | 8 | 3.090 |
arch |
Software-Architektur | 1 | 898 |
ai |
AI & Agentic Systems | 25 | 14.457 |
Diese Datenmengen wären für einen Agenten ohne semantische Indizierung nicht handhabbar.
5. Architektur: Pipeline mit Vision AI
Die technische Pipeline von kb verarbeitet Bücher in mehreren Stufen:
PDF/EPUB → extract → Markdown + Images → chunk → Chunks → index → FAISS
↓ ↓
Vision AI (GPT-4o) Question → search → Chunks → LLM → Answer + Sources
beschreibt Bilder
Durch die optionale Vision-AI-Stufe (GPT-4o Vision) werden Abbildungen aus Büchern extrahiert, beschrieben und als Textchunks indiziert. Diagramme, Grafiken und Formeln stehen dem Agenten damit als durchsuchbares Wissen zur Verfügung.
6. Integration: Warum CLI?
Die Entscheidung, die Wissensdatenbank als CLI-Tool zu realisieren, folgt dem Prinzip der Modularen Intelligenz. Anstatt die RAG-Logik in jede Applikation neu zu implementieren, bietet kb eine universelle Schnittstelle:
- Unabhängigkeit: Das Tool funktioniert unabhängig von der Web-Plattform oder dem spezifischen Agenten.
- Kombinierbarkeit: Via Pipes (
|) können Suchergebnisse in andere Tools (wiegrepoderjq) geleitet werden. - Agent-Ready: Moderne Agenten sind exzellent darin, CLI-Tools zu bedienen. Sie "verstehen" die Hilfe-Seiten von Typer/Click und können Parameter korrekt setzen.
- Discovery-First: Der
kb kbs --json-Befehl ermöglicht Agenten, die verfügbaren Wissensgebiete zu erkunden, bevor sie eine Abfrage stellen – ein Self-Service-Ansatz für autonome Agenten.
Selbst ausprobieren
Genau das macht kb für Agenten so attraktiv: Die kbs --json-Antwort ist Daten, die sich mit reinen Funktionen verarbeiten lassen. Hier ein kleines Discovery-Match: Gegeben die JSON-Struktur und eine Nutzerfrage, wird per simplem Keyword-Score die passendste KB ausgewählt – ohne LLM, ohne Embeddings, nur Standardbibliothek.
import json
import re
kbs_response = """
{
"knowledgebases": [
{"name": "fp", "books": 8, "chunks": 4163,
"book_titles": ["Functional Programming in Scala", "Haskell Programming from First Principles"]},
{"name": "cat", "books": 8, "chunks": 3090,
"book_titles": ["Category Theory for Programmers", "Category Theory Illustrated"]},
{"name": "ai", "books": 25, "chunks": 14457,
"book_titles": ["Designing Autonomous AI", "Building LLM Agents"]}
]
}
"""
def tokens(text):
return set(re.findall(r"[a-zäöüß]+", text.lower()))
def score_kb(kb, question_tokens):
"""Reiner Score: Anzahl Token-Treffer in Name + Buchtiteln."""
haystack = kb["name"] + " " + " ".join(kb["book_titles"])
return len(question_tokens & tokens(haystack))
def best_kb(kbs_json, question):
data = json.loads(kbs_json)
q = tokens(question)
ranked = sorted(
data["knowledgebases"],
key=lambda kb: (score_kb(kb, q), kb["chunks"]),
reverse=True,
)
return ranked[0]
questions = [
"Was ist ein Funktor in der Category Theory?",
"Wie baue ich einen autonomen LLM-Agent?",
"Erkläre Monaden in Haskell",
]
for q in questions:
kb = best_kb(kbs_response, q)
print(f"{q!r:55} → best KB: {kb['name']:4} (chunks={kb['chunks']})")
Erweiterungs-Idee: Ersetze den Keyword-Score durch eine reine Funktion score_by_overlap(kb, query_tokens), die zusätzlich die Buchtitel höher gewichtet als den KB-Namen – Auswahl-Logik bleibt testbar, ganz ohne externe Abhängigkeit.
Genau das ist der zweite, vertiefte Schritt: Buchtitel sind aussagekräftiger als der knappe KB-Name – also gewichten wir sie höher. Die Auswahl-Logik bleibt eine reine Funktion und das Scoring jeder KB ist nachvollziehbar.
import json, re
kbs_response = """
{
"knowledgebases": [
{"name": "fp", "books": 8, "chunks": 4163,
"book_titles": ["Functional Programming in Scala", "Haskell Programming from First Principles"]},
{"name": "cat", "books": 8, "chunks": 3090,
"book_titles": ["Category Theory for Programmers", "Category Theory Illustrated"]},
{"name": "ai", "books": 25, "chunks": 14457,
"book_titles": ["Designing Autonomous AI", "Building LLM Agents"]}
]
}
"""
def tokens(text):
return set(re.findall(r"[a-zäöüß]+", text.lower()))
def score_by_overlap(kb, q, w_name: int = 1, w_title: int = 3) -> int:
"""Reiner gewichteter Score: Titel zählen stärker als der KB-Name."""
name_hits = len(q & tokens(kb["name"]))
title_hits = len(q & tokens(" ".join(kb["book_titles"])))
return w_name * name_hits + w_title * title_hits
def rank(kbs_json, question):
data = json.loads(kbs_json)
q = tokens(question)
scored = [(kb["name"], score_by_overlap(kb, q)) for kb in data["knowledgebases"]]
return sorted(scored, key=lambda t: t[1], reverse=True)
for q in [
"Was ist ein Funktor in der Category Theory?",
"Wie baue ich einen autonomen LLM-Agent?",
"Erkläre Monaden in Haskell",
]:
ranking = rank(kbs_response, q)
print(f"{q!r:50} → ranking={ranking}")
Beobachtung: Die Reihenfolge folgt der Aussagekraft der Buchtitel, nicht dem KB-Namen – cat schlägt fp bei „Category Theory", weil beide Titel zur Frage passen.
7. Fazit
kb verwandelt eine Sammlung von PDFs und EPUBs in ein abfragbares Gehirn – inklusive der visuellen Inhalte. Der Discovery-Workflow (kbs → ask --name) und die durchgängige JSON-Unterstützung machen das Tool zu einer natürlichen Schnittstelle für KI-Agenten, die auf fundiertes Fachwissen zugreifen müssen.
Quellen & Ressourcen
- Knowledgebase Repo: github.com/mhennemeyer/knowledgebase
- FAISS: facebookresearch/faiss – Efficient similarity search.
- OpenAI Embeddings:
text-embedding-3-large. - OpenAI Vision:
GPT-4o Vision– Bildanalyse für die Indizierung visueller Buchinhalte.