# Websuche in LangChain und LlamaIndex: ein Tool und ein Retriever

> Websuche für LangChain und LlamaIndex: ein search_web-Tool und ein Retriever mit einem Document pro Seite. Ohne KYC, mit Krypto zahlen.

- URL: https://llmwebsearch.com/de/docs/langchain/
- Zuletzt aktualisiert: 2026-10-22
- Herausgeber: LLMWebSearch (https://llmwebsearch.com)

Zwei Formen decken die meisten Frameworks ab. Ein Tool lässt einen Agenten entscheiden, wann er sucht. Ein Retriever hängt das Live-Web in eine Retrieval-Chain ein, wobei jede gelesene Seite zu einem Dokument wird, dessen URL in den Metadaten steht.

**Kurze Antwort — Wie füge ich Live-Websuche zu LangChain oder LlamaIndex hinzu?**

Verpacken Sie den `/search`-Aufruf von **LLMWebSearch** in ein LangChain `@tool`, einen LangChain-Retriever oder ein LlamaIndex `FunctionTool`. Jede Variante liefert gerankte Quellen mit den Top-3-Seiten als Markdown und ihren URLs, bereit für Zitate. Kein Paket von uns zu installieren: Der Code unten ist die Integration. Eine Suche kostet 1 Credit, ab 1,20 $/1K Suchanfragen Stand Oktober 2026. Ohne KYC; mit Krypto bezahlen.

## Wofür die einzelnen Wrapper gedacht sind

| Attribut | Wert |
| --- | --- |
| LangChain-Tool | Ein Agent ruft `search_web` auf, wenn er entscheidet, dass er das Web braucht |
| LangChain-Retriever | Eine Chain holt für jede Frage frische Dokumente, ohne zu fragen |
| LlamaIndex FunctionTool | Dieselbe `search_web`-Funktion, für LlamaIndex-Agenten |
| Pakete | `langchain-core` oder `llama-index-core`, plus `requests` |
| API-Schlüssel | `LLMWEBSEARCH_API_KEY` in der Umgebung |
| Abrechnung | Ein Credit bezahlt eine Suchanfrage: bis zu 20 gerankte Ergebnisse, wobei die Seiten der ersten 3 gelesen und als Markdown zurückgegeben werden. Werden 4 bis 10 Seiten gelesen, sind es 2 Credits. Ein Aufruf, der mit einem Fehler endet, kostet nichts |

## Wie baue ich ein Suchtool für einen LangChain-Agenten?

Dekorieren Sie eine Funktion mit `@tool` aus `langchain_core.tools`. LangChain liest den Namen, die typisierten Argumente und den Docstring, um das Tool für das Modell zu beschreiben, halten Sie den Docstring also kurz und präzise. Die Funktion gibt einen String mit nummerierten Quellen zurück, der zu jedem Chat-Modell passt und die URLs direkt neben dem Text behält.

Rufen Sie sie zum Testen direkt mit `.invoke()` auf und übergeben Sie sie dann in der tools-Liste Ihres Agenten.

*LangChain-Tool: search_web*

```python
import os

import requests
from langchain_core.tools import tool

API = "https://llmwebsearch.com/api/v1/search"
HEADERS = {"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]}


@tool
def search_web(query: str, read: int = 3) -> str:
    """Search the live web. Returns numbered sources with URLs; the first `read` include page text."""
    body = {"q": query, "max_results": 5, "read": max(0, min(read, 10)), "max_chars": 5000}
    resp = requests.post(API, headers=HEADERS, json=body, timeout=60)
    resp.raise_for_status()
    parts = []
    for i, r in enumerate(resp.json()["results"], start=1):
        text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
        parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
    return "\n\n".join(parts)


print(search_web.invoke({"query": "postgres connection pool size"})[:500])

```

## Wie nutze ich das Live-Web als Retriever?

Leiten Sie eine Unterklasse von `BaseRetriever` ab und geben Sie ein `Document` pro gelesener Seite zurück. Der Seitentext kommt in `page_content`; URL, Titel, Rang und Datum kommen in `metadata`, wo Chains, die ihre Quellen zitieren, danach suchen. Ergebnisse ohne Inhalt werden übersprungen, denn ein Retriever sollte Text liefern, den das Modell zitieren kann.

Ein Retriever läuft bei jeder Frage. Das ist richtig für eine Question-Answering-Chain zu aktuellen Themen und verschwenderisch für einen Chat, bei dem die meisten Turns keine Suche brauchen; verwenden Sie in diesem Fall das Tool.

*LangChain-Retriever: LLMWebSearchRetriever*

```python
import os
from typing import List

import requests
from langchain_core.callbacks import CallbackManagerForRetrieverRun
from langchain_core.documents import Document
from langchain_core.retrievers import BaseRetriever


class LLMWebSearchRetriever(BaseRetriever):
    """Live web search results as Documents, one per page that was read."""

    max_results: int = 5
    read: int = 3
    max_chars: int = 6000

    def _get_relevant_documents(self, query: str, *, run_manager: CallbackManagerForRetrieverRun) -> List[Document]:
        resp = requests.post(
            "https://llmwebsearch.com/api/v1/search",
            headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
            json={"q": query, "max_results": self.max_results, "read": self.read, "max_chars": self.max_chars},
            timeout=60,
        )
        resp.raise_for_status()
        docs = []
        for r in resp.json()["results"]:
            if r["content_status"] != "ok":
                continue
            meta = {"source": r["url"], "title": r["title"], "position": r["position"], "published_at": r.get("published_at")}
            docs.append(Document(page_content=r["content"], metadata=meta))
        return docs


retriever = LLMWebSearchRetriever(read=3)
for doc in retriever.invoke("pgbouncer transaction mode limitations"):
    print(doc.metadata["position"], doc.metadata["source"], len(doc.page_content))

```

## Wie gebe ich einem LlamaIndex-Agenten dieselbe Suche?

Schreiben Sie eine einfache Funktion und verpacken Sie sie mit `FunctionTool.from_defaults` aus `llama_index.core.tools`. LlamaIndex erstellt Name und Beschreibung des Tools aus dem Namen, der Signatur und dem Docstring der Funktion. Der Aufruf des Tools gibt ein `ToolOutput` zurück, dessen `content` der Text ist, den der Agent liest.

Die Funktion ist dieselbe wie die für LangChain, sodass ein Team, das beide Frameworks nutzt, sie gemeinsam verwenden kann.

*LlamaIndex: FunctionTool*

```python
import os

import requests
from llama_index.core.tools import FunctionTool


def search_web(query: str, read: int = 3) -> str:
    """Search the live web and return numbered sources; the first `read` include their page text."""
    resp = requests.post(
        "https://llmwebsearch.com/api/v1/search",
        headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
        json={"q": query, "max_results": 5, "read": max(0, min(read, 10)), "max_chars": 5000},
        timeout=60,
    )
    resp.raise_for_status()
    parts = []
    for i, r in enumerate(resp.json()["results"], start=1):
        text = r["content"] if r["content_status"] == "ok" else "(snippet only) " + r["snippet"]
        parts.append(f"[{i}] {r['title']} - {r['url']}\n{text}")
    return "\n\n".join(parts)


search_tool = FunctionTool.from_defaults(fn=search_web)
print(search_tool.metadata.name)
print(search_tool.call(query="postgres connection pool size").content[:300])

```

## Wie halte ich das Kontextfenster unter Kontrolle?

Setzen Sie `max_chars` beim API-Aufruf, statt nachträglich zu kürzen: So werden weniger Daten übertragen, und das Framework hält nie die lange Version. 5.000 Zeichen pro Seite und 3 Seiten ergeben etwa 4.000 Tokens, was für die meisten Modelle bequem ist.

Für Retrieval-Chains, die das Live-Web mit Ihren eigenen Dokumenten kombinieren, geben Sie Web-Dokumenten ein geringeres Gewicht oder einen eigenen Prompt-Abschnitt. Webseiten ändern sich und können falsch sein; Ihre eigenen Dokumente sind in der Regel die Referenz.

## Kann ich das, was der Retriever zurückgibt, in einer Vektordatenbank speichern?

Ja, soweit es uns betrifft. Wir trainieren kein Modell mit Ihren Suchanfragen oder mit dem, was die API zurückgibt, und wir stellen keine eigene Regel gegen das Speichern von Ergebnissen auf; die Rechte der Websites, deren Seiten Sie lesen, gelten weiterhin. Speichern Sie die URL und `published_at` mit jedem Chunk, damit der Agent die Seite zitieren kann und Sie veraltete Chunks verwerfen können.

Die meisten Teams cachen die Web-Ergebnisse häufiger Fragen für einen Tag oder eine Woche. Das reduziert wiederholte Suchanfragen, und jede vermiedene Suchanfrage spart einen Credit.

## LangChain und LlamaIndex: häufige Fragen

### Gibt es ein langchain-llmwebsearch-Paket?

Nein. Wir veröffentlichen kein Paket. Der Code auf dieser Seite ist kurz genug, um ihn selbst zu besitzen: Kopieren Sie ihn, ändern Sie die Standardwerte und behalten Sie ihn in Ihrem Repository.

### Kann ich das Tool asynchron machen?

Ja. Ersetzen Sie `requests` durch `httpx.AsyncClient` und definieren Sie die Funktion mit `async def`. LangChains `@tool` dekoriert asynchrone Funktionen direkt; in LlamaIndex übergeben Sie die asynchrone Version als `async_fn` an `FunctionTool.from_defaults`.

### Wie lese ich eine Seite, die der Agent woanders gefunden hat?

Fügen Sie ein zweites Tool hinzu, das URLs an `https://llmwebsearch.com/api/v1/extract` sendet. Das Lesen von Seiten, deren URLs Sie bereits haben, kostet 1 Credit für jede angefangene Gruppe von 3 Seiten, die mit Inhalt zurückgegeben werden, bis zu 20 URLs pro Aufruf; abgelehnte oder fehlgeschlagene URLs werden nicht gezählt. Die [extract-Referenz](https://llmwebsearch.com/de/docs/extract/) zeigt die Anfrage.

---

LLMWebSearch: LLMWebSearch ist eine Websuch-API für KI-Agenten, die gerankte Ergebnisse mit dem Inhalt der Top-Seiten als Markdown liefert, bezahlt mit Krypto ohne Ausweis-Upload. Vorausbezahlte Credits ab 1,20 $/1K Suchanfragen verfallen nie. Ohne KYC — kein Ausweis, kein Selfie, keine Dokumente. Mit Krypto bezahlen.
