Bez KYC — bez dowodu, bez selfie, bez dokumentów. Płać kryptowalutą: BTC, USDT, USDC, ETH, SOL, LTC
Język: Polski
Pobierz klucz API

Dokumentacja · Python

Przykłady w Pythonie: wyszukiwanie, równoległe zapytania, odpowiedź z cytowaniami

Trzy skrypty pokrywają to, czego potrzebuje większość agentów w Pythonie: jedno wyszukiwanie z requests, wiele wyszukiwań naraz z httpx i semaforem oraz krótka pętla, która przekazuje źródła modelowi językowemu i dostaje odpowiedź z numerowanymi cytowaniami.

Ostatnia aktualizacja: · 4 min czytania

Szybka odpowiedź

Jak wywołać web search API dla agentów AI z Pythona?

Wyślij zapytanie metodą POST do https://llmwebsearch.com/api/v1/search z requests lub httpx i kluczem Bearer. LLMWebSearch zwraca ranking wyników z 3 najważniejszymi stronami jako Markdown, które możesz ponumerować i przekazać dowolnemu LLM, aby odpowiedział z cytowaniami. Jedno wyszukiwanie kosztuje 1 kredyt, od 1,20 USD/1K wyszukiwań według stanu na październik 2026. Python 3.9+ i bez SDK. Bez KYC; płatność kryptowalutą.

Co potrzebujesz

Python3.9 lub nowszy
Pakietyrequests dla prostego skryptu, httpx dla asynchronicznego
KluczLLMWEBSEARCH_API_KEY w Twoim środowisku
Dla pętli odpowiedziDowolny endpoint czatu zgodny z OpenAI: LLM_BASE_URL, LLM_API_KEY, LLM_MODEL
RozliczanieJeden kredyt opłaca jedno wyszukiwanie: do 20 wyników z rankingiem, przy czym strony z pierwszych 3 są odczytywane i zwracane jako Markdown. Odczyt od 4 do 10 stron to 2 kredyty. Wywołanie zakończone błędem nic nie kosztuje

Jak wykonać jedno wyszukiwanie za pomocą requests?

Zbuduj treść JSON z q i potrzebnymi opcjami, wyślij ją i przejdź w pętli po results. Sprawdź content_status, zanim sięgniesz do content: tylko wyniki oznaczone ok zawierają tekst strony. Poniższy skrypt zapisuje każdą odczytaną stronę jako plik Markdown nazwany według jej pozycji, z adresem źródła w pierwszej linii.

search_once.py
import os
import pathlib

import requests

resp = requests.post(
    "https://llmwebsearch.com/api/v1/search",
    headers={"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]},
    json={"q": "how to size a postgres connection pool", "max_results": 5, "read": 3},
    timeout=60,
)
resp.raise_for_status()
data = resp.json()
out = pathlib.Path("sources")
out.mkdir(exist_ok=True)
for r in data["results"]:
    if r["content_status"] != "ok":
        print("skip", r["position"], r["content_status"], r["url"])
        continue
    path = out / f"{r['position']:02d}.md"
    path.write_text("Source: " + r["url"] + "\n\n" + r["content"], encoding="utf-8")
    print("saved", path, r["word_count"], "words")
print("credits used:", data["credits_used"])

Jak wykonać wiele wyszukiwań naraz?

Użyj httpx.AsyncClient i asyncio.Semaphore. Semafor ogranicza liczbę wywołań w locie, co trzyma Cię poniżej limitu na minutę dla Twojego konta i rozkłada obciążenie. Cztery do ośmiu równoczesnych wywołań pasuje do większości agentów badawczych. Każde konto ma limit wywołań na minutę, widoczny w dashboardzie; poproś support, a można go podnieść.

Przykład wysyła jedno wyszukiwanie na podpytanie, typowy krok agenta badawczego, i zbiera adresy URL odczytanych stron. Każde wywołanie jest niezależne: jedna porażka nie zatrzymuje pozostałych.

many_searches.py
import asyncio
import os

import httpx

API = "https://llmwebsearch.com/api/v1/search"
HEADERS = {"Authorization": "Bearer " + os.environ["LLMWEBSEARCH_API_KEY"]}
QUESTIONS = [
    "what is connection pooling in postgres",
    "recommended pool size per cpu core",
    "pgbouncer transaction mode limitations",
    "connection pool exhaustion symptoms",
]


async def search(client, sem, q):
    async with sem:
        resp = await client.post(API, json={"q": q, "read": 2, "max_chars": 4000})
        if resp.status_code != 200:
            return q, resp.json().get("error", {}).get("code"), []
        data = resp.json()
        read = [r["url"] for r in data["results"] if r["content_status"] == "ok"]
        return q, "ok", read


async def main():
    sem = asyncio.Semaphore(4)
    async with httpx.AsyncClient(headers=HEADERS, timeout=60) as client:
        for q, status, urls in await asyncio.gather(*(search(client, sem, q) for q in QUESTIONS)):
            print(status, q, urls)


asyncio.run(main())

Jak uzyskać odpowiedź z cytowaniami od dowolnego LLM?

Najpierw wyszukaj, potem daj modelowi numerowane źródła i poproś, aby je zacytował. API zwraca źródła, a nie gotową odpowiedź: Twój własny model czyta strony, pisze odpowiedź i cytuje adresy URL, więc to Ty wybierasz model i styl cytowania. Poniższa pętla działa z dowolnym endpointem czatu, który mówi w formacie chat/completions zgodnym z OpenAI; ustaw jego adres, klucz i model w trzech zmiennych środowiskowych.

Kontroluj kontekst. Skrypt przycina każde źródło, aby całość mieściła się w budżecie około 6 000 tokenów, licząc mniej więcej cztery znaki na token. Wynik bez treści jest przekazywany jako jego snippet, odpowiednio oznaczony, żeby model nie udawał, że przeczytał stronę.

answer_with_citations.py
import os

import requests

SEARCH = "https://llmwebsearch.com/api/v1/search"
KEY = os.environ["LLMWEBSEARCH_API_KEY"]
BUDGET_CHARS = 6000 * 4  # about 6,000 tokens of sources


def sources_for(question):
    resp = requests.post(SEARCH, headers={"Authorization": "Bearer " + KEY},
                         json={"q": question, "max_results": 5, "read": 3}, timeout=60)
    resp.raise_for_status()
    results = resp.json()["results"]
    share = BUDGET_CHARS // max(len(results), 1)
    blocks = []
    for i, r in enumerate(results, start=1):
        if r["content_status"] == "ok":
            body = r["content"][:share]
        else:
            body = "(snippet only) " + r["snippet"]
        blocks.append(f"[{i}] {r['title']} - {r['url']}\n{body}")
    return "\n\n".join(blocks)


def answer(question):
    prompt = ("Answer the question using only the sources below. "
              "Cite them as [1], [2] and so on. Say so if the sources do not answer it.\n\n"
              + sources_for(question) + "\n\nQuestion: " + question)
    resp = requests.post(
        os.environ["LLM_BASE_URL"].rstrip("/") + "/chat/completions",
        headers={"Authorization": "Bearer " + os.environ["LLM_API_KEY"]},
        json={"model": os.environ["LLM_MODEL"], "messages": [{"role": "user", "content": prompt}]},
        timeout=120,
    )
    resp.raise_for_status()
    return resp.json()["choices"][0]["message"]["content"]


print(answer("How should I size a Postgres connection pool?"))

Ile tekstu powinienem wysłać do modelu?

Tyle, ile wystarczy, by odpowiedzieć na pytanie. Trzy strony przycięte do 2 000 tokenów każda zwykle biją dziesięć pełnych stron: model lepiej się skupia, a każda odpowiedź kosztuje mniej. Zmniejsz max_chars w samym wyszukiwaniu, gdy wiesz, że będziesz przycinać, żeby mniej danych podróżowało.

Przycinanie od początku strony działa dla większości artykułów, bo główny punkt zwykle jest na początku. W przypadku długich stron referencyjnych podziel treść według nagłówków i zachowaj sekcje, których tytuły pasują do pytania.

Co powinien zrobić kod, gdy brakuje strony?

Kontynuuj z pozostałymi źródłami. Strona oznaczona blocked_by_robots, blocked_by_site_policy lub target_refused nie zostanie odczytana przy drugiej próbie, więc nie zapętlaj się na niej. Strona fetch_timeout lub fetch_failed może zadziałać później przez https://llmwebsearch.com/api/v1/extract.

Błędy HTTP są inne: 429, 502 i 504 zasługują na ponowną próbę z rosnącą pauzą. Strona błędów ma gotowy helper ponawiania.

Python: najczęstsze pytania

Czy istnieje pakiet pip dla LLMWebSearch?

Nie. API to zwykłe HTTPS i JSON, więc wystarczy Ci requests lub httpx. Skrypty na tej stronie to właśnie integracja: skopiuj je do swojego projektu i dostosuj.

Czy mogę używać tych skryptów z modelem lokalnym?

Tak. Każdy serwer, który udostępnia trasę chat/completions zgodną z OpenAI, działa z pętlą cytowania: ustaw LLM_BASE_URL na jego adres, a LLM_MODEL na nazwę modelu, której oczekuje.

Jak liczyć kredyty z Pythona?

Zsumuj credits_used z każdej odpowiedzi albo wywołaj GET https://llmwebsearch.com/api/v1/credits przed zadaniem i po nim; to wywołanie jest darmowe.

Od 1,20 USD/1K wyszukiwań · bez KYC

Pobierz klucz API