Aller au contenu principal

Web Search API : recherche web programmatique

Web Search API : recherche web programmatique

L’outil Web Search permet au modèle d’effectuer des recherches sur le web en temps réel directement depuis la Responses API. Plus besoin d’intégrer une API de recherche tierce : le modèle formule la requête, exécute la recherche et synthétise les résultats.

L’activation tient en une ligne, et c’est ce qui masque le changement de nature : votre application cesse d’être limitée à la date de coupure du modèle. Une question sur un événement d’hier, un tarif en vigueur ou une réglementation récente devient traitable, sans intégrer ni facturer un moteur de recherche tiers.

from openai import OpenAI

client = OpenAI()

response = client.responses.create(
    model="gpt-5.6-terra",
    input="Quels sont les derniers résultats de la Ligue 1 ?",
    tools=[{"type": "web_search_preview"}]
)

print(response.output_text)

Le modèle décide seul quand chercher, et ce point mérite qu’on s’y arrête : il ne cherche pas systématiquement. Sur une question qu’il estime relever de ses connaissances, il répond directement — plus vite et moins cher, mais avec le risque d’une information périmée qu’il présentera avec la même assurance. Quand la fraîcheur est critique, dites-le dans le prompt plutôt que d’espérer qu’il le devine.

Structure de la réponse

Les sources arrivent comme annotations attachées à la réponse, séparées du texte. C’est ce qui vous permet de les afficher à votre façon, de les vérifier, ou de traiter comme suspecte une réponse qui n’en comporte aucune alors que le sujet l’exigeait.

response = client.responses.create(
    model="gpt-5.6-terra",
    input="Quel est le cours actuel de l'action LVMH ?",
    tools=[{"type": "web_search_preview"}]
)

# Texte synthetise
print(response.output_text)

# Examiner les sources
for item in response.output:
    if hasattr(item, "content"):
        for block in item.content:
            if hasattr(block, "annotations"):
                for annotation in block.annotations:
                    if annotation.type == "url_citation":
                        print(f"Source : {annotation.url}")
                        print(f"Titre  : {annotation.title}")

Contexte utilisateur pour la pertinence

La localisation change davantage les résultats qu’on ne l’imagine, et pas seulement pour les recherches manifestement locales. Une question sur la fiscalité, un prix, une disponibilité ou une obligation légale n’a pas la même réponse selon le pays : sans user_location, le modèle prendra un contexte par défaut qui sera souvent américain.

response = client.responses.create(
    model="gpt-5.6-terra",
    input="Quel restaurant japonais est ouvert ce soir ?",
    tools=[{
        "type": "web_search_preview",
        "user_location": {
            "type": "approximate",
            "city": "Paris",
            "country": "FR"
        }
    }]
)

Le paramètre user_location accepte plusieurs niveaux de précision :

# Localisation approximative
"user_location": {
    "type": "approximate",
    "city": "Lyon",
    "region": "Auvergne-Rhone-Alpes",
    "country": "FR"
}

Combiner Web Search et fonctions personnalisées

La combinaison la plus productive suit toujours le même schéma : le web apporte l’information externe, vos fonctions apportent le contexte interne, et le modèle fait le rapprochement. C’est ce rapprochement qui a de la valeur — ni la recherche ni vos données prises isolément ne répondent à « ce changement nous concerne-t-il ? ».

tools = [
    {"type": "web_search_preview"},
    {
        "type": "function",
        "name": "sauvegarder_veille",
        "description": "Sauvegarder un résultat de veille dans la base de données",
        "parameters": {
            "type": "object",
            "properties": {
                "titre": {"type": "string"},
                "resume": {"type": "string"},
                "url_source": {"type": "string"},
                "categorie": {
                    "type": "string",
                    "enum": ["concurrent", "marche", "reglementation", "technologie"]
                }
            },
            "required": ["titre", "resume", "categorie"],
            "additionalProperties": False
        },
        "strict": True
    }
]

response = client.responses.create(
    model="gpt-5.6-terra",
    input="Cherche les dernières actualités sur la réglementation IA en Europe "
          "et sauvegarde les résultats importants",
    tools=tools
)

Cas d’usage en production

Veille concurrentielle automatisée

def veille_quotidienne(entreprises: list[str]):
    """Lance une veille web pour chaque concurrent."""
    resultats = []
    for entreprise in entreprises:
        response = client.responses.create(
            model="gpt-5.6-terra",
            input=f"Quelles sont les dernieres actualites concernant {entreprise} ? "
                  "Concentre-toi sur les annonces produit, levées de fonds "
                  "et partenariats des 7 derniers jours.",
            tools=[{"type": "web_search_preview"}]
        )
        resultats.append({
            "entreprise": entreprise,
            "synthese": response.output_text
        })
    return resultats

Vérification de faits

def verifier_affirmation(affirmation: str) -> dict:
    """Vérifie une affirmation en croisant plusieurs sources web."""
    response = client.responses.create(
        model="gpt-5.6-terra",
        input=f"Vérifie cette affirmation en cherchant des sources fiables : "
              f"'{affirmation}'. Indique si c'est vrai, faux ou incertain, "
              f"avec les sources qui appuient ta conclusion.",
        tools=[{"type": "web_search_preview"}]
    )

    # Extraire les citations
    sources = []
    for item in response.output:
        if hasattr(item, "content"):
            for block in item.content:
                if hasattr(block, "annotations"):
                    for ann in block.annotations:
                        if ann.type == "url_citation":
                            sources.append(ann.url)

    return {
        "analyse": response.output_text,
        "nombre_sources": len(sources),
        "sources": sources
    }

Limites à connaître

  • Le modèle peut ne pas trouver de résultats pertinents pour des sujets très niches
  • Les résultats dépendent de l’indexation web au moment de la requête
  • Le nombre de recherches par appel est limité : le modèle optimise en formulant des requêtes précises
  • Les contenus derrière un paywall ou un login ne sont pas accessibles

Points clés à retenir

  • web_search_preview s’ajoute en une ligne dans tools
  • Le modèle décide seul quand chercher sur le web
  • user_location améliore la pertinence des résultats locaux
  • Les annotations url_citation fournissent les sources
  • Combinez Web Search avec vos fonctions pour automatiser la veille