Kort antwoord
Hoe laat ik een OpenAI-model webpagina's lezen met function calling?
Declareer een read_url-functie in de tools-lijst en voer dan een loop uit: wanneer het model een tool call teruggeeft, roep je het /read-endpoint van WebReaderAPI aan met de URL en stuur je de Markdown terug als een tool-bericht. Elke pagina kost 1 credit, 2 met een browser, vanaf US$ 0,07/1K pagina's per oktober 2026. Zonder KYC; betalen met crypto.
Hoe ziet het read_url-schema eruit?
Twee parameters zijn genoeg: de url die je wilt lezen, verplicht, en een optionele max_chars waarmee het model een lange pagina kort kan houden. De description is het belangrijkste onderdeel: die vertelt het model wat de tool teruggeeft en wanneer je hem gebruikt. Houd hem feitelijk en kort.
We noemen de tool read_url in plaats van web_fetch om een botsing te voorkomen met tools die sommige agent-runtimes al onder die naam leveren.
{
"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
}
}
}Hoe werkt de tool-calling-loop?
Stuur het gesprek met de tools-lijst. Als het antwoord tool calls bevat, voer je ze allemaal uit, voeg je het resultaat toe als bericht met rol tool en de bijbehorende tool_call_id, en vraag je het model opnieuw. Komt er een antwoord terug zonder tool call, dan is dat het definitieve antwoord.
Beperk het aantal rondes. Drie of vier is ruim genoeg voor een vraag over een handvol pagina's, en de limiet beschermt je tegen een model dat blijft vragen om meer.
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)})
Hoe houd ik tokengebruik en kosten laag?
Drie instellingen zijn belangrijk. Houd max_chars bescheiden, rond 8.000 tot 20.000 tekens per pagina, want elk teken dat je teruggeeft wordt door het model gelezen. Houd de standaard main_content=true aan, zodat menu's en footers nooit in de context terechtkomen. En beperk de loop, zoals hierboven, zodat één vraag niet tientallen reads kan triggeren.
Aan onze kant gelden de kosten per pagina, niet per teken: 1 credit = 1 pagina lezen zonder browser; 2 credits wanneer de pagina een browser nodig heeft om JavaScript te renderen. Een verzoek dat mislukt, of dat de robots.txt van een site weigert, wordt niet in rekening gebracht. Een support-assistent die 300 pagina's per dag leest, gebruikt ongeveer 9.000 credits per maand, binnen 10.000 pagina's (US$ 3,75).
Werkt het schema met andere modellen?
Ja, met kleine aanpassingen in de wrapper. De meeste tool-calling-API's nemen een JSON Schema voor de parameters en een naam en description voor de tool, dus read_url gaat ongewijzigd over naar andere providers. De MCP-pagina verpakt dezelfde functie voor clients die het Model Context Protocol spreken, en de LangChain-pagina verpakt hem voor LangChain- en LlamaIndex-agents.
Wat moet het model zien wanneer een pagina wordt geweigerd?
Een korte, duidelijke zin, zoals de loop hierboven teruggeeft: "Could not read the page: blocked_by_robots". Modellen gaan daar goed mee om en vallen terug op andere bronnen of vertellen het de gebruiker. We respecteren robots.txt: onze crawler identificeert zich als WebReaderAPI, volgt de regels die voor hem of voor alle robots zijn geschreven, en leest geen pagina die een site niet toestaat. Geweigerde pagina's worden niet in rekening gebracht. Als een site ons verzoek weigert, geven we het antwoord terug: we lossen nooit CAPTCHA's op, loggen niet in op accounts en proberen nooit een blokkade of paywall te omzeilen. Geen van deze weigeringen gebruikt een credit.
Function calling: veelgestelde vragen
Heb ik hiervoor de Responses API of Chat Completions nodig?
Het voorbeeld gebruikt Chat Completions met de tools-parameter. Dezelfde functiedefinitie en dezelfde read_url-body werken met andere OpenAI-interfaces die function tools accepteren; alleen de loop eromheen verandert.
Kan het model meerdere pagina's in één beurt lezen?
Ja. Een antwoord kan meerdere tool calls bevatten; de loop voert ze allemaal uit en geeft elk resultaat terug voordat het model opnieuw wordt gevraagd. Houd max_chars lager wanneer het model veel pagina's tegelijk leest.
Wordt de API-sleutel aan het model blootgesteld?
Nee. De sleutel blijft in de omgeving van je code. Het model ziet alleen de naam van de tool, de description en de tekst die je functie teruggeeft.
Wat kost een geweigerde pagina?
Niets. 1 credit = 1 pagina lezen zonder browser; 2 credits wanneer de pagina een browser nodig heeft om JavaScript te renderen. Een verzoek dat mislukt, of dat de robots.txt van een site weigert, wordt niet in rekening gebracht.