Sans KYC — pas de pièce d'identité, pas de selfie, pas de documents. Payez en crypto : BTC, USDT, USDC, ETH, SOL, LTC
Langue: Français
Obtenir une clé API

Docs · outils OpenAI

OpenAI function calling : un outil read_url pour votre modèle

Décrivez une fonction, read_url, et exécutez-la quand le modèle le demande. Le modèle choisit quelles pages lire ; votre code appelle l'API et renvoie le Markdown. Le même schéma fonctionne avec d'autres modèles qui prennent en charge le tool calling.

Dernière mise à jour: · 5 min de lecture

Réponse rapide

Comment permettre à un modèle OpenAI de lire des pages web avec le function calling ?

Déclarez une fonction read_url dans la liste tools, puis exécutez une boucle : lorsque le modèle renvoie un appel d'outil, appelez l'endpoint /read de WebReaderAPI avec l'URL et renvoyez le Markdown dans un message tool. Chaque page coûte 1 crédit, 2 avec un navigateur, à partir de 0,07 $US/1K pages en octobre 2026. Sans KYC ; payez en crypto.

À quoi ressemble le schéma read_url ?

Deux paramètres suffisent : l'url à lire, obligatoire, et un max_chars facultatif qui permet au modèle de raccourcir une page longue. La description est l'élément le plus important : elle indique au modèle ce que l'outil renvoie et quand l'utiliser. Restez factuel et bref.

Nous nommons l'outil read_url plutôt que web_fetch pour éviter un conflit avec des outils que certains environnements d'exécution d'agents fournissent déjà sous ce nom.

La définition de l'outil
{
  "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
    }
  }
}

Comment fonctionne la boucle de function calling ?

Envoyez la conversation avec la liste tools. Si la réponse contient des appels d'outils, exécutez chacun d'eux, ajoutez le résultat sous forme de message avec le rôle tool et le tool_call_id correspondant, puis interrogez à nouveau le modèle. Une réponse sans appel d'outil est la réponse finale.

Limitez le nombre de tours. Trois ou quatre suffisent pour une question portant sur quelques pages, et cette limite vous protège d'un modèle qui en redemande sans cesse.

Python : la boucle complète avec le package 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)})

Comment réduire la consommation de tokens et le coût ?

Trois réglages comptent. Gardez max_chars modeste, autour de 8 000 à 20 000 caractères par page, car chaque caractère renvoyé est lu par le modèle. Conservez l'main_content=true par défaut, pour que les menus et pieds de page n'atteignent jamais le contexte. Et limitez la boucle, comme ci-dessus, afin qu'une seule question ne déclenche pas des dizaines de lectures.

De notre côté, le coût se compte par page, pas par caractère : 1 crédit = 1 page lue sans navigateur ; 2 crédits quand la page nécessite un navigateur pour exécuter JavaScript. Une requête qui échoue, ou qu'un robots.txt de site refuse, n'est pas facturée. Un assistant de support qui lit 300 pages par jour consomme environ 9 000 crédits par mois, compris dans 10 000 pages (3,75 $US).

Le schéma fonctionne-t-il avec d'autres modèles ?

Oui, avec de petits ajustements dans le wrapper. La plupart des API de function calling acceptent un JSON Schema pour les paramètres, ainsi qu'un nom et une description pour l'outil ; read_url se transmet donc tel quel d'un fournisseur à l'autre. La page MCP prépare la même fonction pour les clients qui parlent le Model Context Protocol, et la page LangChain l'enveloppe pour les agents LangChain et LlamaIndex.

Que doit voir le modèle lorsqu'une page est refusée ?

Une phrase courte et claire, telle que la renvoie la boucle ci-dessus : « Could not read the page: blocked_by_robots ». Les modèles la gèrent bien et se rabattent sur d'autres sources ou informent l'utilisateur. Nous respectons robots.txt : notre crawler s'identifie comme WebReaderAPI, suit les règles écrites pour lui ou pour tous les robots, et ne lit pas une page qu'un site interdit. Les pages refusées ne sont pas facturées. Si un site refuse notre requête, nous renvoyons sa réponse : nous ne résolvons jamais de CAPTCHA, ne nous connectons pas à des comptes et ne cherchons pas à contourner un blocage ou un paywall. Aucun de ces refus ne consomme de crédit.

Function calling : questions fréquentes

Faut-il l'Responses API ou Chat Completions ?

L'exemple utilise Chat Completions avec le paramètre tools. La même définition de fonction et le même corps read_url fonctionnent avec les autres interfaces OpenAI qui acceptent des function tools ; seule la boucle autour d'elles change.

Le modèle peut-il lire plusieurs pages en un seul tour ?

Oui. Une réponse peut contenir plusieurs appels d'outils ; la boucle exécute chacun d'eux et renvoie tous les résultats avant d'interroger à nouveau le modèle. Réduisez max_chars lorsque le modèle lit plusieurs pages d'un coup.

La clé API est-elle exposée au modèle ?

Non. La clé reste dans l'environnement de votre code. Le modèle ne voit que le nom de l'outil, sa description et le texte que votre fonction renvoie.

Combien coûte une page refusée ?

Rien. 1 crédit = 1 page lue sans navigateur ; 2 crédits quand la page nécessite un navigateur pour exécuter JavaScript. Une requête qui échoue, ou qu'un robots.txt de site refuse, n'est pas facturée.

À partir de 0,07 $US/1K pages · sans KYC

Obtenir une clé API