# OpenAI function calling : un outil de recherche Google en 60 lignes de Python

> Recherche Google pour OpenAI : schéma JSON et boucle tool calling en Python sur l'API SERP de SerpCrypto, idem pour Claude. Sans KYC.

- URL: https://serpcrypto.com/fr/docs/openai/
- Dernière mise à jour: 2026-10-22
- Éditeur: SerpCrypto (https://serpcrypto.com)

Décrivez à le modèle une fonction `google_search`, lancez les recherches qu'il demande, renvoyez-lui les résultats. Le schéma est du JSON Schema standard, il se transpose donc à Claude et aux autres modèles compatibles tool calling.

**Réponse rapide — Comment donner à un modèle OpenAI un outil de recherche web ?**

Déclarez une fonction `google_search` avec un JSON Schema dans `tools`, puis bouclez : quand le modèle renvoie `tool_calls`, lancez chaque recherche sur `https://serpcrypto.com/api/v1/search` et ajoutez les résultats sous forme de messages `tool` jusqu'à ce qu'il réponde. **SerpCrypto** facture 1 crédit par recherche réussie, à partir de 0,30 $US/1K requêtes, payé en crypto sans KYC.

## À quoi ressemble le schéma de l'outil ?

Un outil de type fonction a un nom, une description et des paramètres en JSON Schema. Le modèle ne voit que ces trois éléments, la description doit donc indiquer ce que l'outil renvoie et quand l'utiliser. Seul `query` est requis ; le pays et la langue sont optionnels et valent US English par défaut dans le code.

*Définition de l'outil (format Chat Completions)*

```json
{
  "type": "function",
  "function": {
    "name": "google_search",
    "description": "Search Google for current information. Returns the top results with title, link and snippet. Use it for facts newer than your training data.",
    "parameters": {
      "type": "object",
      "properties": {
        "query": { "type": "string", "description": "The search query, as a person would type it." },
        "gl": { "type": "string", "description": "Two-letter country code of the results, e.g. us, gb, de." },
        "hl": { "type": "string", "description": "Language code, e.g. en, de, pt-BR." }
      },
      "required": ["query"]
    }
  }
}
```

## Comment fonctionne la boucle d'appel d'outils ?

Envoyez la question avec `tools`. Si la réponse contient `tool_calls`, exécutez chacun, ajoutez le message de l'assistant et un message `tool` par appel avec le `tool_call_id` correspondant, puis appelez à nouveau le modèle. Quand une réponse ne contient aucun appel d'outil, c'est la réponse finale.

La boucle ci-dessous s'arrête après trois recherches. Un plafond protège vos crédits si un modèle continue à chercher, et trois recherches suffisent à répondre à la plupart des questions factuelles.

*search_agent.py*

```python
"""Tool-calling loop: the model asks for searches, this code runs them on SerpCrypto."""
import json
import os

import requests
from openai import OpenAI

client = OpenAI()  # reads OPENAI_API_KEY
MODEL = os.environ["OPENAI_MODEL"]  # any OpenAI chat model with tool calling
API_URL = "https://serpcrypto.com/api/v1/search"

TOOLS = [
    {
        "type": "function",
        "function": {
            "name": "google_search",
            "description": "Search Google for current information. Returns the top results with title, link and snippet.",
            "parameters": {
                "type": "object",
                "properties": {
                    "query": {"type": "string", "description": "The search query."},
                    "gl": {"type": "string", "description": "Two-letter country code, e.g. us."},
                    "hl": {"type": "string", "description": "Language code, e.g. en."},
                },
                "required": ["query"],
            },
        },
    }
]


def google_search(query, gl="us", hl="en"):
    r = requests.get(
        API_URL,
        params={"q": query, "gl": gl, "hl": hl},
        headers={"Authorization": "Bearer " + os.environ["SERPCRYPTO_API_KEY"]},
        timeout=90,
    )
    if r.status_code != 200:
        return f"Search failed with HTTP {r.status_code}."
    items = r.json().get("organic_results", [])[:5]
    return "\n\n".join(f"{x['title']}\n{x['link']}\n{x.get('snippet', '')}" for x in items) or "No results."


def ask(question, max_searches=3):
    messages = [{"role": "user", "content": question}]
    for _ in range(max_searches + 1):
        reply = client.chat.completions.create(model=MODEL, messages=messages, tools=TOOLS)
        msg = reply.choices[0].message
        if not msg.tool_calls:
            return msg.content
        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": google_search(**args)})
    return "Stopped: search limit reached."


print(ask("Which countries changed their data protection laws in 2026? Cite sources."))
```

## Le même schéma fonctionne-t-il avec Claude et d'autres modèles ?

Oui, avec un wrapper différent. Le tool use de Claude prend le même JSON Schema sous `input_schema`, à côté de `name` et `description`. La plupart des autres API d'appel d'outils acceptent aussi le JSON Schema pour les paramètres ; seuls les noms des champs externes changent. La fonction de recherche elle-même reste identique, car elle appelle uniquement l'endpoint SerpCrypto.

*Le même outil pour Claude (Messages API)*

```json
{
  "name": "google_search",
  "description": "Search Google for current information. Returns the top results with title, link and snippet.",
  "input_schema": {
    "type": "object",
    "properties": {
      "query": { "type": "string", "description": "The search query." },
      "gl": { "type": "string", "description": "Two-letter country code, e.g. us." },
      "hl": { "type": "string", "description": "Language code, e.g. en." }
    },
    "required": ["query"]
  }
}
```

## Que doit renvoyer l'outil au modèle ?

Un texte court avec des liens. Cinq résultats avec titre, lien et snippet suffisent généralement au modèle pour répondre et citer ses sources. Renvoyer le JSON complet fonctionne, mais coûte plus de tokens et donne au modèle plus de bruit à lire.

Ajoutez le texte de l'AI Overview quand il est présent si vous voulez que le modèle voie le résumé de Google, et conservez les liens sources pour que la réponse puisse citer les pages plutôt que l'overview.

## Comment garder des coûts de recherche prévisibles ?

Comptez les appels d'outils : chaque appel réussi vaut un crédit. Plafonnez les recherches par question, comme le fait la boucle, et journalisez chaque appel avec sa requête pour voir ce que le modèle demande. Sur le pack 100 000 recherches, le tarif est de 0,56 $US/1K requêtes, et Les crédits de recherche prépayés n'expirent jamais : les requêtes inutilisées restent sur votre compte jusqu'à ce que vous les utilisiez.

Les erreurs ne coûtent rien : 1 crédit = 1 requête réussie, qui renvoie une page de résultats sur n'importe quel moteur pris en charge. Une requête qui échoue n'est pas facturée.

## Questions sur le function calling

### Puis-je utiliser l'API Responses au lieu de Chat Completions ?

Oui. L'API Responses prend des function tools avec le même JSON Schema, avec `name`, `description` et `parameters` au niveau supérieur de chaque outil. La fonction de recherche et le principe de la boucle ne changent pas.

### Pourquoi ne pas utiliser la recherche web intégrée du fournisseur du modèle ?

Les outils de recherche intégrés choisissent leurs propres sources et réglages. Une function sur SerpCrypto vous donne les résultats Google pour le pays et la langue que vous choisissez, en JSON que vous pouvez journaliser, à un prix connu par recherche.

### Le modèle peut-il choisir le pays ?

Oui. `gl` est un paramètre de l'outil, donc le modèle peut le définir à partir de la question, par exemple `gb` pour une question sur le Royaume-Uni. Gardez une valeur par défaut dans votre code pour les questions qui ne mentionnent aucun pays.

### Ai-je besoin d'une carte bancaire pour obtenir la clé API de recherche ?

Non. Les crédits SerpCrypto se paient en BTC, USDT, USDC, ETH, SOL, LTC, sans pièce d'identité, sans selfie et sans document. Connexion par numéro de compte ; l'email est facultatif.

---

SerpCrypto: SerpCrypto est une API SERP pour les développeurs et les agents IA qui renvoie les résultats de recherche Google et Bing en JSON, payable en crypto sans envoi de pièce d'identité. Les crédits de recherche prépayés à partir de 0,30 $US/1K requêtes n'expirent jamais. Sans KYC — pas de pièce d'identité, pas de selfie, pas de documents. Payer en crypto.
