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

Dokumentacja · narzędzia OpenAI

OpenAI function calling: narzędzie read_url dla Twojego modelu

Opisz jedną funkcję, read_url, i uruchom ją, gdy model o to poprosi. Model wybiera, które strony czytać; Twój kod wywołuje API i zwraca Markdown. Ten sam schemat działa z innymi modelami, które obsługują tool calling.

Ostatnia aktualizacja: · 4 min czytania

Szybka odpowiedź

Jak pozwolić modelowi OpenAI czytać strony internetowe za pomocą function calling?

Zadeklaruj funkcję read_url na liście tools, a następnie uruchom pętlę: gdy model zwróci tool call, wywołaj endpoint /read w WebReaderAPI z adresem URL i odeślij Markdown jako wiadomość tool. Każda strona kosztuje 1 kredyt, 2 z przeglądarką, od 0,07 USD/1K stron według stanu na październik 2026. Bez KYC; płatność kryptowalutą.

Jak wygląda schemat read_url?

Wystarczą dwa parametry: url do odczytania, wymagany, oraz opcjonalny max_chars, który pozwala modelowi skrócić długą stronę. Opis jest najważniejszą częścią: mówi modelowi, co zwraca narzędzie i kiedy go użyć. Trzymaj go rzeczowo i krótko.

Nazywamy narzędzie read_url, a nie web_fetch, żeby uniknąć kolizji z narzędziami, które niektóre środowiska uruchomieniowe agentów już udostępniają pod tą nazwą.

Definicja narzędzia
{
  "type": "function",
  "function": {
    "name": "read_url",
    "description": "Read a public web page and return its main content as Markdown, with its title and source URL. Use it when the user gives a link or when a page must be read to answer.",
    "parameters": {
      "type": "object",
      "properties": {
        "url": { "type": "string", "description": "The http or https address of the page." },
        "max_chars": { "type": "integer", "description": "Most characters to return, 1000 to 500000. Default 20000." }
      },
      "required": ["url"],
      "additionalProperties": false
    }
  }
}

Jak działa pętla tool calling?

Wyślij rozmowę z listą tools. Jeśli odpowiedź zawiera tool calls, uruchom każde z nich, dołącz wynik jako wiadomość z rolą tool i pasującym tool_call_id, a następnie ponownie zapytaj model. Gdy odpowiedź wraca bez tool call, jest to odpowiedź końcowa.

Ogranicz liczbę rund. Trzy lub cztery w zupełności wystarczą na pytanie o kilka stron, a limit chroni Cię przed modelem, który wciąż prosi o więcej.

Python: pełna pętla z pakietem openai
import json
import os

import requests
from openai import OpenAI

READ_URL = {
    "type": "function",
    "function": {
        "name": "read_url",
        "description": "Read a public web page and return its main content as Markdown, with its title and source URL.",
        "parameters": {
            "type": "object",
            "properties": {
                "url": {"type": "string", "description": "The http or https address of the page."},
                "max_chars": {"type": "integer", "description": "Most characters to return. Default 20000."},
            },
            "required": ["url"],
            "additionalProperties": False,
        },
    },
}


def read_url(url, max_chars=20000):
    resp = requests.get(
        "https://webreaderapi.com/api/v1/read",
        headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
        params={"url": url, "max_chars": max_chars},
        timeout=75,
    )
    body = resp.json()
    if resp.status_code != 200:
        return "Could not read the page: " + body["error"]["code"]
    return "# " + (body.get("title") or url) + "\nSource: " + body["final_url"] + "\n\n" + body["markdown"]


client = OpenAI()
model = os.environ.get("OPENAI_MODEL", "gpt-4.1-mini")
messages = [{"role": "user", "content": "What does https://example.com/blog/first-post announce? Answer in two sentences."}]

for _ in range(4):
    reply = client.chat.completions.create(model=model, messages=messages, tools=[READ_URL])
    msg = reply.choices[0].message
    if not msg.tool_calls:
        print(msg.content)
        break
    messages.append(msg)
    for call in msg.tool_calls:
        args = json.loads(call.function.arguments)
        messages.append({"role": "tool", "tool_call_id": call.id, "content": read_url(**args)})

Jak ograniczyć zużycie tokenów i koszty?

Liczą się trzy ustawienia. Trzymaj max_chars na umiarkowanym poziomie, około 8 000 do 20 000 znaków na stronę, bo każdy zwracany znak czyta model. Zachowaj domyślne main_content=true, żeby menu i stopki nigdy nie trafiały do kontekstu. I ogranicz pętlę, jak wyżej, żeby jedno pytanie nie wywołało dziesiątek odczytów.

Po naszej stronie koszt jest za stronę, nie za znak: 1 kredyt = 1 odczytana strona bez przeglądarki; 2 kredyty, gdy strona wymaga przeglądarki do wyrenderowania JavaScript. Zapytanie, które się nie powiedzie lub które zostanie odrzucone przez robots.txt witryny, nie jest obciążane opłatą. Asystent pomocy technicznej, który czyta 300 stron dziennie, zużywa około 9 000 kredytów miesięcznie, w ramach 10 000 stron (3,75 USD).

Czy schemat działa z innymi modelami?

Tak, przy drobnych zmianach w wrapperze. Większość API obsługujących tool calling przyjmuje JSON Schema dla parametrów oraz nazwę i opis narzędzia, więc read_url przenosi się między dostawcami bez zmian. Strona MCP pakuje tę samą funkcję dla klientów obsługujących Model Context Protocol, a strona LangChain opakowuje ją dla agentów LangChain i LlamaIndex.

Co model powinien zobaczyć, gdy strona jest odrzucona?

Krótkie, jasne zdanie, tak jak zwraca to powyższa pętla: „Could not read the page: blocked_by_robots”. Modele radzą sobie z tym dobrze i sięgają do innych źródeł albo informują użytkownika. Respektujemy robots.txt: nasz crawler identyfikuje się jako WebReaderAPI, przestrzega reguł napisanych dla niego lub dla wszystkich robotów i nie czyta strony, której witryna zabrania. Odrzucone strony nie są obciążane opłatą. Jeśli witryna odrzuci nasze zapytanie, zwracamy jej odpowiedź: nigdy nie rozwiązujemy CAPTCHA, nie logujemy się do kont ani nie próbujemy obejść blokady lub paywalla. Żadna z tych odmów nie zużywa kredytu.

Function calling: najczęstsze pytania

Czy potrzebne jest Responses API czy Chat Completions?

Przykład używa Chat Completions z parametrem tools. Ta sama definicja funkcji i to samo ciało read_url działają z innymi interfejsami OpenAI, które przyjmują function tools; zmienia się tylko pętla wokół nich.

Czy model może przeczytać kilka stron w jednej turze?

Tak. Odpowiedź może zawierać kilka tool calls; pętla uruchamia każde i zwraca wszystkie wyniki, zanim ponownie zapyta model. Ustaw max_chars niżej, gdy model czyta wiele stron naraz.

Czy klucz API jest widoczny dla modelu?

Nie. Klucz pozostaje w środowisku Twojego kodu. Model widzi tylko nazwę narzędzia, jego opis i tekst, który zwraca Twoja funkcja.

Ile kosztuje odrzucona strona?

Nic. 1 kredyt = 1 odczytana strona bez przeglądarki; 2 kredyty, gdy strona wymaga przeglądarki do wyrenderowania JavaScript. Zapytanie, które się nie powiedzie lub które zostanie odrzucone przez robots.txt witryny, nie jest obciążane opłatą.

Od 0,07 USD/1K stron · bez KYC

Uzyskaj klucz API