Ohne KYC — kein Ausweis, kein Selfie, keine Dokumente. Mit Krypto bezahlen: BTC, USDT, USDC, ETH, SOL, LTC
Sprache: Deutsch
API-Schlüssel erhalten

Anleitung · Python · etwa 60 Zeilen, beliebiges LLM

Deep-Research-Agenten in Python mit einer Websuche-API bauen

Deep Research ist eine Schleife, kein Modell. Diese Anleitung baut eine, die Sie in wenigen Minuten lesen können: Sie plant Suchanfragen, sucht im Web inklusive Seitentext, behält jede Quelle nur einmal, sucht nach Lücken und schreibt eine Antwort mit nummerierten Belegen.

Zuletzt aktualisiert: · 5 Min. Lesezeit

Kurze Antwort

Wie baue ich einen Deep-Research-Agenten in Python?

Schreiben Sie eine Schleife, die ein LLM nach Suchanfragen fragt, jede durch eine Websuche-API mit Seitentext laufen lässt, jede Quelle nur einmal behält, nach Folge-Suchanfragen fragt und dann eine belegte Antwort schreibt. Mit LLMWebSearch liefert jede Suchanfrage die ersten 3 Seiten als Markdown für einen Credit; das Skript unten führt sechs Suchanfragen pro Frage aus. Ab 1,20 $/1K Suchanfragen, ohne KYC, mit Krypto bezahlen.

Was wird der Agent tun?

  1. Plan

    Das Modell nach vier kurzen Suchanfragen fragen, die zusammen die Frage abdecken.

  2. Suchen

    Jede Suchanfrage mit read=3 ausführen, sodass die ersten drei Seiten als Markdown zurückkommen.

  3. Quellen nur einmal behalten

    Ergebnisse nach URL speichern und Seiten überspringen, die bereits gesammelt wurden oder keinen Text haben.

  4. Lücken finden

    Dem Modell die bisher gefundenen Titel zeigen und nach zwei Suchanfragen zu dem fragen, was fehlt.

  5. Schreiben

    Bis zu 12 Quellen nummerieren und eine Antwort anfordern, die sie als [1], [2] zitiert.

Was brauche ich, bevor ich anfange?

Drei Dinge:

  • Einen LLMWebSearch API-Schlüssel in der Umgebungsvariable LLMWEBSEARCH_API_KEY. Schlüssel erscheinen im Dashboard nach Ihrem ersten Paket.
  • Einen beliebigen OpenAI-kompatiblen Chat-Endpoint, gesetzt mit LLM_BASE_URL, LLM_API_KEY und LLM_MODEL. Gehostete Modelle und lokale Server funktionieren beide.
  • Python 3.9 oder neuer mit dem requests-Paket.

Das Skript verwendet für beide Dienste einfaches HTTP, sodass Sie das Modell austauschen können, ohne den Suchcode zu ändern.

Python: deep_research.py
import os

import requests

SEARCH = "https://llmwebsearch.com/api/v1/search"
SEARCH_HEADERS = {"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]}
# Any OpenAI-compatible chat endpoint works here: set your own base URL, key and model name.
LLM_URL = os.environ.get("LLM_BASE_URL", "https://llm.example.com/v1") + "/chat/completions"
LLM_HEADERS = {"Authorization": "Bearer " + os.environ.get("LLM_API_KEY", "")}
MODEL = os.environ.get("LLM_MODEL", "your-model-name")


def ask_llm(prompt):
    body = {"model": MODEL, "messages": [{"role": "user", "content": prompt}]}
    resp = requests.post(LLM_URL, headers=LLM_HEADERS, json=body, timeout=120)
    resp.raise_for_status()
    return resp.json()["choices"][0]["message"]["content"]


def plan_queries(question, n=4):
    text = ask_llm(f"Write {n} short web search queries, one per line, to answer: {question}")
    queries = [line.strip("-*0123456789. ").strip() for line in text.splitlines()]
    return [q for q in queries if q][:n]


def search(query):
    body = {"q": query, "max_results": 5, "read": 3, "max_chars": 5000}
    resp = requests.post(SEARCH, headers=SEARCH_HEADERS, json=body, timeout=60)
    resp.raise_for_status()
    return resp.json()["results"]


def research(question, rounds=2):
    sources = {}  # url -> result, so the same page is never cited twice
    queries = plan_queries(question)
    for _ in range(rounds):
        for query in queries:
            for r in search(query):
                if r.get("content_status") == "ok" and r["url"] not in sources:
                    sources[r["url"]] = r
        notes = "\n".join(f"- {r['title']}" for r in sources.values())
        queries = plan_queries(f"{question}\nAlready found:\n{notes}\nWhat is still missing?", n=2)
    numbered = list(sources.values())[:12]
    context = "\n\n".join(
        f"[{i}] {r['title']} ({r['url']})\n{r['content']}" for i, r in enumerate(numbered, 1)
    )
    prompt = (
        "Answer the question using only the sources below. Cite them as [1], [2]. "
        "Say so when the sources disagree or do not cover a point.\n\n"
        f"Question: {question}\n\nSources:\n{context}"
    )
    return ask_llm(prompt), [r["url"] for r in numbered]


if __name__ == "__main__":
    answer, urls = research("What changed in the EU rules for general-purpose AI models in 2025?")
    print(answer)
    for i, url in enumerate(urls, 1):
        print(f"[{i}] {url}")

Wie funktioniert jeder Teil?

plan_queries fragt das Modell nach kurzen Suchanfragen, eine pro Zeile, und entfernt Listenmarker. Kurze Suchanfragen passen besser dazu, wie Suchmaschinen Seiten ranken, als ganze Fragen.

search ruft POST https://llmwebsearch.com/api/v1/search mit max_results=5, read=3 und max_chars=5000 auf. Die Antwort listet fünf Ergebnisse auf; die ersten drei enthalten ihren Seitentext in content.

research führt die Runden aus. Es behält Quellen in einem Dictionary, das nach URL verschlüsselt ist, sodass eine Seite, die von zwei Suchanfragen gefunden wird, nur einmal zählt. Nur Ergebnisse mit content_status gleich ok werden behalten, weil die Antwort auf Text beruhen muss, den das Modell lesen kann.

Nach jeder Runde sieht das Modell die bisher gesammelten Titel und schlägt zwei neue Suchanfragen für das Fehlende vor. Der letzte Prompt nummeriert bis zu zwölf Quellen und legt die Zitierregeln fest.

Wie viel kostet ein Bericht?

Sechs Suchanfragen pro Frage mit den Standardeinstellungen: vier in der ersten Runde und zwei in der zweiten. Mit read auf 3 sind das sechs Credits. 25.000 Suchanfragen bei 41,25 $ deckt daher mehr als 4.000 Berichte ab.

Die Modellaufrufe kosten zusätzlich auf Ihrer LLM-Rechnung: drei Planungsaufrufe und ein langer Antwortaufruf pro Bericht. Der Antwortaufruf umfasst bis zu zwölf Seiten mit 5.000 Zeichen, senken Sie also max_chars, wenn Ihr Modell teuer ist.

Wie mache ich es gründlicher?

Ändern Sie die Zahlen, nicht die Struktur:

  • Mehr Runden. rounds=4 lässt das Modell zwei weitere Sätze Lücken verfolgen.
  • Mehr Suchanfragen pro Runde. Erhöhen Sie n im Aufruf zur Lückensuche von 2 auf 4.
  • Engere Quellen. Fügen Sie include_domains zum Such-Body hinzu, um offizielle oder akademische Seiten zu finden.
  • Nur aktuelle Inhalte. Fügen Sie "time_range": "month" oder "topic": "news" hinzu.
  • Mehr Seiten pro Suchanfrage. read=5 liest fünf Seiten, bei 2 Credits pro Suche.

Fügen Sie eine Stoppregel hinzu, bevor Sie die Limits erhöhen: Beenden Sie die Schleife, wenn eine Runde weniger als zwei neue Quellen bringt.

Wie halte ich den Agenten sicher und höflich?

Behandeln Sie jede Seite als nicht vertrauenswürdigen Text. Der finale Prompt weist das Modell an, die Quellen nur als Belege zu verwenden; fügen Sie eine explizite Zeile hinzu, dass Anweisungen innerhalb von Quellen ignoriert werden müssen. Lassen Sie eine Quelle niemals einen Tool-Aufruf oder ein Schreiben in eine Datei auslösen.

Auf der Web-Seite: Unser Reader respektiert robots.txt: Er stellt sich als LLMWebSearch vor, befolgt die Regeln, die eine Website für ihn oder für alle Roboter schreibt, und lässt den Inhalt jeder Seite aus, die er nicht lesen darf. Seiten, die den Zugriff verweigern, kommen ohne Inhalt zurück, und das Skript überspringt sie einfach. Wenn eine Website unseren Reader abweist, kommt das Ergebnis ohne Inhalt und mit dem Status der Website zurück: Wir lösen niemals CAPTCHAs, melden uns nicht in Konten an und umgehen weder eine Sperre noch eine Paywall.

Was kann schiefgehen?

Im Test zeigen sich drei Dinge:

  • Unpräzise Suchanfragen. Wenn der Plan schwach ist, findet jede Runde dieselben Seiten. Bitten Sie das Modell um Suchanfragen mit konkreten Namen und Daten.
  • Zu wenige Quellen mit Text. Manche Themen liegen hinter Paywalls. Erweitern Sie die Suchanfragen oder erlauben Sie mehr Ergebnisse.
  • Zu lange Prompts. Zwölf lange Seiten können den Kontext eines kleinen Modells überschreiten. Senken Sie max_chars oder behalten Sie acht Quellen.

Protokollieren Sie jede Suchanfrage und die URLs, die sie zurückgegeben hat. Dieses Protokoll zu lesen ist der schnellste Weg, den Plan-Prompt zu verbessern.

Deep-Research-Agent: häufige Fragen

Kann ich das mit einem lokalen Modell ausführen?

Ja, wenn der lokale Server das OpenAI-Chat-Completions-Format spricht. Setzen Sie LLM_BASE_URL auf seine Adresse und LLM_MODEL auf den Modellnamen.

Kann ich es in ein MCP-Tool umwandeln?

Ja. Packen Sie research() in ein MCP-Tool, oder geben Sie Ihrem Agenten das einfache Such-Tool von der MCP-Seite und lassen Sie ihn die Schleife selbst ausführen.

Warum nicht die Such-API direkt nach einer Antwort fragen?

Weil LLMWebSearch keine Antworten schreibt. Die API liefert Quellen, keine geschriebene Antwort: Ihr eigenes Modell liest die Seiten, schreibt die Antwort und zitiert die URLs.

Wie sehe ich, was jede Suche gekostet hat?

Jede Antwort enthält credits_used, und GET https://llmwebsearch.com/api/v1/credits zeigt Ihr verbleibendes Guthaben ohne Kosten.

Ab 1,20 $/1K Suchanfragen · ohne KYC

API-Schlüssel erhalten