Zum Hauptinhalt springen
Research-Agenten sind nützlich, wenn du mehr willst als ein einzelnes Suchergebnis oder eine schnelle Modellantwort. Ein guter Research-Agent kann ein breites Thema in Suchanfragen verwandeln, Quellen sammeln, die wichtigen Belege extrahieren, Lücken nachgehen und ein zitiertes Briefing schreiben, das du danach prüfen kannst. In diesem Tutorial bauen wir einen privaten Research-Agenten mit Python und der Venice-API. Am Ende hast du ein CLI, das ein Thema recherchieren, öffentliche Seiten in Markdown scrapen, Quell-Chunks zusammenfassen, gap-bewusste Folgesuchen ausführen und einen zitierten Bericht mit optionalen lokalen JSONL-Artefakten erzeugen kann. Interesse an der vollständigen Implementierung? Schau in das GitHub-Repo. Bevor wir loslegen, brauchst du einen Venice API-Schlüssel:

Was wir bauen

Die Referenzimplementierung ist ein kleines Python-Projekt mit einigen klar getrennten Teilen: Der Flow sieht so aus: Pipeline des privaten Research-Agenten
  1. Venice bitten, vielfältige Suchanfragen zum Thema zu generieren.
  2. Im Web mit einem oder mehreren Providern suchen.
  3. URLs vor dem Lesen deduplizieren.
  4. Mit Venices Scrape-Endpoint jede öffentliche Seite in Markdown verwandeln.
  5. Lange Seiten in Chunks splitten.
  6. Venice bitten, aus jedem Chunk Belege zu extrahieren.
  7. Venice bitten, aus den Chunk-Belegen Source-Notes zu machen.
  8. Research-Gaps und Source-Balance-Probleme identifizieren, bevor Folgequeries erzeugt werden.
  9. Venice bitten, den finalen Report mit Fußnoten-Zitaten zu synthetisieren.
Das ist „privat” im praktischen Sinn: Der Agent hält Orchestrierung, Source-Notes, Artefakte und finale Reports auf deinem Rechner. Venice übernimmt die Modellaufrufe und das Scraping über seine API. Die Default-Referenzimplementierung schickt Suchanfragen weiterhin an DuckDuckGo oder arXiv, behandle die Provider-Wahl also als Teil deines Privacy-Designs.

Projekt einrichten

Das Referenzprojekt nutzt Python 3.13 und uv, derselbe Code funktioniert aber auch mit einer klassischen Virtual Environment. Neues Projekt anlegen:
Abhängigkeiten installieren:
Wer lieber pip nutzt, legt eine Virtual Environment an und installiert dieselben Pakete:
Lege eine .env-Datei für die lokale Entwicklung an:
Wir nutzen VENICE_MODEL, damit du das Modell ohne Code-Änderungen wechseln kannst. Die Referenz nimmt aktuell standardmäßig openai-gpt-55, du kannst es aber gegen ein anderes für dein Venice-Konto verfügbares Chat-Modell tauschen.

Datenmodelle erstellen

Bevor wir die Agent-Logik schreiben, definieren wir die Objekte, die durch die Pipeline laufen. Diese Modelle machen den Rest des Codes leichter nachvollziehbar, weil jede Quelle Provenienz mit sich trägt: woher sie stammt, welche Query sie gefunden hat, wann sie abgerufen wurde und wie sie gechunkt wurde. Erstelle research_agent/models.py:
Wichtige Felder sind hier canonical_url, content_hash und chunks. Mit canonical_url vermeidet der Agent, dieselbe Quelle mehrfach zu lesen, wenn sich Suchergebnisse nur in Tracking-Parametern oder Fragments unterscheiden. content_hash hilft, Duplikate auch dann zu erkennen, wenn sie unter anderen URLs liegen. chunks erlaubt es, lange Seiten in kleineren Stücken zusammenzufassen, statt nützliche Belege an Kontextlimits zu verlieren. Ergänze die Helferfunktionen unter den Dataclasses:
Das Chunking ist hier bewusst einfach: feste Zeichen-Chunks mit Überlappung. Das reicht für einen Demo-Research-Agenten, weil Venices Scrape-Endpoint Markdown zurückgibt, das in der Regel viel sauberer ist als rohes HTML. Für Produktions-Research an langen technischen Dokumenten kannst du das verbessern, indem du an Überschriften, Absätzen oder Token-Counts splittest.

Den Venice-Client bauen

Als Nächstes erstellen wir einen kleinen Venice-Client. Du könntest das OpenAI-Python-SDK für Chat-Completions verwenden, weil Venice OpenAI-kompatibel ist – die Referenz nutzt aber direkt httpx, damit derselbe Client auch Venices POST /augment/scrape-Endpoint aufrufen kann. Erstelle research_agent/venice.py:
Der from_env()-Helper hält Secrets aus deinem Quellcode raus. Außerdem ist die lokale Entwicklung angenehmer, weil python-dotenv VENICE_API_KEY und VENICE_MODEL aus .env laden kann. Jetzt Chat-Completions ergänzen:
Für den finalen Report wollen wir Streaming nutzen, weil tiefe Berichte deutlich länger dauern können (sie produzieren viel mehr Text). Das kann zu Timeout-Problemen bei Anfragen führen, deren finale Ausgabe extrem lange dauert. Mit Streaming umgehen wir das und machen den Request robuster gegen Timeout-Fehler:
Dann Scraping ergänzen:
Venices Scrape-Endpoint akzeptiert eine öffentlich zugängliche URL und liefert die Seite als Markdown. Damit muss das Modell kein rohes HTML parsen, und deine Source-Extraction-Prompts können mit saubereren Texten arbeiten. Der verbleibende Helper kümmert sich um Retries und Response-Parsing:
Das vollständige Repo enthält außerdem einen robusten _post_chat_stream()-Helper, der Server-Sent Events aus Streaming-Chat-Completions liest. Du kannst zunächst ohne Streaming starten und es ergänzen, sobald der restliche Research-Flow läuft.

Such-Provider hinzufügen

Der Such-Layer hat zwei Aufgaben: Quell-URLs finden und diese URLs durch den Venice-Scraper holen. Die Referenzimplementierung nutzt DuckDuckGos HTML-Endpoint für allgemeine Websuche und arXivs Atom-API für Papers. Erstelle research_agent/web.py:
Jetzt DuckDuckGo ergänzen:
Und arXiv:
Die WebSearch-Klasse koordiniert Provider und holt Seiten:
Die vollständige Referenz ergänzt Retries, Host-bezogene Request-Delays und freundlichere Fehlermeldungen. Das ist wertvoll, weil Research-Agenten viel Zeit mit Seiten verbringen, die Automatisierung blockieren, unerwartet umleiten oder transiente Fehler liefern. Ergänze unten die kleinen Provider-Helper:

Lokale Artefakte schreiben

Für Research-Workflows zählt Auditierbarkeit. Wenn der finale Report etwas Überraschendes sagt, willst du nachvollziehen können, welche Quelle dazu geführt hat. Erstelle research_agent/artifacts.py:
Das schreibt ein JSON-Objekt pro Zeile, was die Artefakte leicht anhängbar, inspizierbar und später per Kommandozeilen-Tools verarbeitbar macht.

Den Research-Agenten bauen

Da wir Venice, Suche, Modelle und Artefakte haben, können wir den eigentlichen Agenten bauen. Erstelle research_agent/agent.py:
Der System-Prompt ist die zentrale Verhaltens-Leitplanke. Wir wollen keinen beeindruckend klingenden Report aus dem Modellgedächtnis. Wir wollen, dass es das Quellmaterial nutzt und Unsicherheit benennt, wenn die Belege dünn sind. Wir brauchen außerdem zwei finale Dataclasses in models.py, falls sie noch nicht da sind:
Als Nächstes definieren wir den ResearchAgent:
Die run()-Methode koordiniert die Research-Passes:
Die zwei seen_*-Sets verhindern, dass der Agent Zeit mit Duplikatquellen verschwendet. URL-Dedupe fängt wiederholte Links. Content-Hash-Dedupe fängt Spiegelseiten, syndizierte Posts und Seiten, die auf denselben Endinhalt umleiten.

Initiale und Folge-Suchen planen

Der erste Modell-Aufruf macht aus dem Thema Suchanfragen:
Nach jedem Research-Pass führt der aktualisierte Agent einen bewussteren Gap-Analyse-Schritt durch. Er schaut auf die aktuellen Notizen, zählt Source-Cluster nach Domain, fragt Venice, was an Coverage fehlt, schreibt diese Gaps in Artefakte und verwendet die resultierenden Queries für den nächsten Pass. Gap-Analyse-Loop Beginne damit, die Source-Balance zu verfolgen:
Das gibt dem Agent einen einfachen Weg, Source-Cluster-Capture zu erkennen. Wenn alle Quellen aus einer Firma, einem Framework oder einer Domain kommen, sollten Folgequeries die Quellbasis bewusst erweitern, statt mehr vom Gleichen zu sammeln. Diese Balance-Information jetzt beim Erstellen der Folgesuchen nutzen:
Die neuere Referenz wickelt das in _gap_follow_up_queries(), das Venice bittet, sowohl Gap-Records als auch Queries zurückzugeben:
Mit --artifacts werden diese Records nach research_gaps.jsonl geschrieben. Das gibt dir eine nützliche Audit-Spur, warum der Agent in einem zweiten Pass nach einer bestimmten Query gesucht hat. Der Parser sollte tolerant sein. Liefert das Modell fehlerhaftes JSON, fällt der Agent auf das Originalthema zurück:
Dieses Muster ist im Agent-Code überall hilfreich: strukturierte Ausgabe verlangen, parsen, und einen einfachen Fallback bereitstellen, wenn die Ausgabe unbrauchbar ist.

Quellen lesen und zusammenfassen

Jetzt sammeln wir Source-Notes. Der Agent sucht pro Query, holt jedes Ergebnis durch Venice Scrape, chunkt das Markdown und fasst die nützlichen Belege zusammen.
Einzelne Such- und Fetch-Fehler sollen nicht den ganzen Lauf stoppen. Das öffentliche Web ist chaotisch. Manche Seiten blockieren Scraping, manche liefern PDFs, manche sind down, manche leiten unerwartet um. Ein Research-Agent sollte weitermachen und festhalten, was fehlgeschlagen ist. So sieht die Methode zum Lesen einer Quelle aus:
Für jeden Quell-Chunk Venice nach einer kurzen Belegzusammenfassung und exakten Zitaten fragen:
Dann die Chunk-Zusammenfassungen in eine Source-Note zusammenführen:
Diese zweistufige Zusammenfassung ist der Teil, der den Agenten verlässlicher wirken lässt als ein einfaches „Fasse diese URLs zusammen”-Skript. Das Modell liest erst die Quell-Chunks, dann schreibt es aus den extrahierten Belegen eine Source-Note.

Den finalen Report schreiben

Sobald der Agent Source-Notes hat, kann er den Report schreiben. Starten wir mit einem einfachen Single-Pass-Report-Writer:
Die Referenz geht bei tiefen Reports weiter: Sie bittet Venice um eine Gliederung, schreibt jeden Abschnitt einzeln und lässt am Ende einen Editor-Pass den fertigen Report zusammenbauen und interne Source-IDs in Fußnoten-Zitate umwandeln. Dieser gestaffelte Ansatz ist nützlich für Long-Form-Research, weil ein einziger riesiger Prompt oft zu stark komprimiert. Die aktualisierten Prompts drängen den Report außerdem in Richtung breiter, quellenbasierter Übersicht statt eines dünnen Entscheidungsleitfadens. Ist die Quellbasis zu einem Cluster verschoben, weist der Editor-Prompt Venice an, diese Schieflage anzuerkennen und sie nicht als repräsentativ für das gesamte Feld darzustellen. Ergänze die Digest-Helper:
Zum Abschluss Fehler-Aufzeichnung ergänzen:
Damit steht der Kern-Research-Loop.

Das CLI ergänzen

Jetzt brauchen wir einen Command-Line-Einstieg. Erstelle main.py:
Das CLI macht die Stellschrauben verfügbar, die du beim Recherchieren tatsächlich anpasst: Jetzt alles verdrahten:
Damit haben wir ein lauffähiges lokales Research-CLI.

Den Agenten ausführen

Schneller Research-Pass:
Report in eine Markdown-Datei schreiben:
Mehr Quellen und mehrere Provider nutzen:
Den finalen Report-Stil wählen:
Verwende brief für ein knappes, quellenbasiertes Briefing, standard für eine umfangreichere Übersicht und deep für den gestaffelten Outline-/Section-/Editor-Workflow. Auditierbare Artefakte speichern:
Wenn Artefakte aktiviert sind, siehst du Dateien wie:
Diese Dateien sind nützlich, wenn du verstehen willst, wie der Agent zu einer Schlussfolgerung gekommen ist. So zeigt source_notes.jsonl die zusammengefassten Quellbelege, research_gaps.jsonl zeigt, warum Folgequeries entstanden sind, und errors.jsonl zeigt Seiten, die beim Suchen, Scrapen oder Zusammenfassen scheiterten.

Privacy- und Reliability-Hinweise

Ein Research-Agent berührt mehrere Systeme – es lohnt sich, präzise zu sein, was wohin geht: Datengrenzen des privaten Research-Agenten Willst du mehr vom Suchpfad innerhalb von Venice halten, kannst du den Provider-Layer anpassen, sodass er Venices POST /augment/search-Endpoint nutzt statt direkt DuckDuckGo. Die Referenz nutzt schlanke öffentliche Provider, damit die Demo leicht lauffähig und verständlich bleibt. Für Reliability die Defaults konservativ halten:
  • Retries für Venice-Aufrufe und Web-Requests nutzen.
  • Ein kleines --request-delay ergänzen, wenn du viele Seiten vom selben Host liest.
  • --max-sources deckeln, damit breite Themen nicht endlos laufen.
  • --artifacts für wichtige Reports speichern, um die finale Ausgabe auditieren zu können.
  • Den Report als Briefing behandeln, nicht als Wahrheit. Bei wichtigen Aussagen den Zitaten zur Originalquelle folgen.

Die Teile testen

Du brauchst keine echten Web-Requests oder Venice-Aufrufe, um den Großteil des Systems zu testen. Die Referenz nutzt Fake-Venice- und Fake-Web-Klassen, um Research-Loop, Dedupe-Verhalten, Artefakte und Report-Prompts zu testen. Ein guter erster Test ist die URL-Kanonisierung:
Dann testen, dass Duplikat-Content übersprungen wird:
Fakes machen Agent-Tests deutlich schneller und stabiler. Du kannst die Orchestrierungs-Logik prüfen, ohne dich auf Live-Suchergebnisse, Netzwerkbedingungen oder Modell-Output zu verlassen.

Benchmarking

Viele KI-Provider haben mittlerweile eigene Deep-Research-Workflows, deshalb enthält die Referenz einen einfachen Benchmark gegen Perplexitys Deep Research. Beide Agenten wurden gebeten, einen Report über die Architektur von KI-Agent-Frameworks zu schreiben, und die erzeugten Reports liegen im GitHub-Repo. Das ist kein formaler Benchmark, sondern ein praktischer Weg, Report-Struktur, Quellabdeckung, Zitationsqualität und etwaige Fokussierung auf einen Source-Cluster zu inspizieren. Genau deshalb verfolgt die aktualisierte Implementierung research_gaps.jsonl und die Source-Balance vor Folgesuchen.

Dieses Beispiel erweitern

Sobald der Baseline-Agent läuft, gibt es praktische Verbesserungen:
  • Einen Venice-Suchprovider mit POST /augment/search ergänzen.
  • Reports und Artefakte in einer kleinen SQLite-DB statt in JSONL-Dateien ablegen.
  • Allow- oder Blocklisten für vertrauenswürdige Research-Domains.
  • PDF-Support, indem Venice Scrape mit Document-Parsing für Quellen ohne sauberes HTML kombiniert wird.
  • Ein Evaluations-Set aus Themen und erwarteten Quelltypen, um Research-Qualität nach Prompt-Änderungen zu vergleichen.
  • Einen Review-Schritt, der Venice bittet, unsupportete Claims im finalen Report zu finden, bevor er gespeichert wird.
Das größte Upgrade ist meist bessere Quellauswahl. Query-Generierung hilft, du kannst die Qualität aber auch verbessern, indem du primäre Quellen, Standards-Dokumente, offizielle Docs, Papers, Changelogs und Datensatz-Seiten gegenüber Low-Signal-Zusammenfassungen bevorzugst.

Abschluss

Danke fürs Lesen! Hoffentlich hat dir das geholfen, einen praktischen privaten Research-Agenten mit Python und der Venice-API zu bauen. Das nützliche Muster hier ist nicht nur „ein Modell etwas recherchieren lassen”. Es ist das Zerlegen der Recherche in auditierbare Schritte: Suchen planen, Quellen sammeln, Belege extrahieren, Source-Notes schreiben, Lücken nachgehen und mit Zitaten synthetisieren. Durch die explizite Trennung dieser Schritte entsteht ein Research-Workflow, der leichter zu inspizieren, zu testen und über die Zeit zu verbessern ist.