Aller au contenu principal

Architecture du function calling dans Responses API

Architecture du function calling dans Responses API

Le function calling est le mecanisme central qui permet aux modeles OpenAI d’interagir avec le monde exterieur. Dans la Responses API, ce mecanisme a ete repense pour etre plus robuste, plus previsible et nativement integre aux outils built-in comme Web Search ou Code Interpreter.

Le principe fondamental

Le modele ne fait jamais rien directement. Il emet des intentions structurees que votre code intercepte et execute. Ce decouplage est la cle de la securite et de la flexibilite du systeme.

from openai import OpenAI

client = OpenAI()

# Declarer un outil personnalise
tools = [{
    "type": "function",
    "name": "rechercher_client",
    "description": "Rechercher un client dans le CRM par nom ou email",
    "parameters": {
        "type": "object",
        "properties": {
            "terme": {
                "type": "string",
                "description": "Nom, email ou identifiant du client"
            },
            "champ": {
                "type": "string",
                "enum": ["nom", "email", "id"],
                "description": "Champ dans lequel chercher"
            }
        },
        "required": ["terme"]
    }
}]

response = client.responses.create(
    model="gpt-5.3",
    input="Trouve le client Jean Dupont",
    tools=tools
)

Anatomie de la reponse

Quand le modele decide d’appeler un outil, la reponse contient un ou plusieurs elements de type function_call dans output :

for item in response.output:
    if item.type == "function_call":
        print(f"ID appel  : {item.call_id}")
        print(f"Fonction  : {item.name}")
        print(f"Arguments : {item.arguments}")

Le call_id est essentiel : il lie l’appel a son resultat quand vous renvoyez la reponse au modele.

La boucle complete

Le function calling suit toujours le meme cycle en quatre etapes :

import json

# 1. Premier appel avec les outils declares
response = client.responses.create(
    model="gpt-5.3",
    input="Quel est le solde du client [email protected] ?",
    tools=tools
)

# 2. Detecter et executer les appels de fonction
resultats = []
for item in response.output:
    if item.type == "function_call":
        if item.name == "rechercher_client":
            args = json.loads(item.arguments)
            resultat = votre_crm.rechercher(args["terme"])
            resultats.append({
                "type": "function_call_output",
                "call_id": item.call_id,
                "output": json.dumps(resultat)
            })

# 3. Renvoyer les resultats au modele
response_finale = client.responses.create(
    model="gpt-5.3",
    input=response.output + resultats,
    tools=tools
)

# 4. Le modele formule sa reponse naturelle
print(response_finale.output_text)

Differences cles avec Chat Completions

La Responses API apporte plusieurs ameliorations architecturales.

Gestion native des outils built-in

Les outils comme web_search_preview, file_search ou code_interpreter sont declares de la meme maniere que vos fonctions personnalisees, mais executes cote serveur par OpenAI :

# Melanger outils built-in et personnalises
tools = [
    {"type": "web_search_preview"},
    {"type": "code_interpreter"},
    {
        "type": "function",
        "name": "ma_fonction",
        "description": "Ma fonction personnalisee",
        "parameters": {"type": "object", "properties": {}}
    }
]

Identifiants d’appel stables

Chaque appel de fonction recoit un call_id unique qui permet de tracer precisement quel resultat correspond a quel appel, meme en cas d’appels paralleles.

Flux simplifie

Plus besoin de gerer manuellement les roles assistant et tool dans les messages. Le champ input accepte directement la concatenation des outputs precedents avec les resultats de fonction.

Quand le modele appelle-t-il une fonction ?

Le modele decide d’appeler une fonction quand la requete de l’utilisateur necessite une information qu’il n’a pas, quand la description de la fonction correspond au besoin identifie, et quand les parametres requis peuvent etre deduits du contexte.

Vous pouvez influencer ce comportement avec le parametre tool_choice :

# Laisser le modele decider
tool_choice = "auto"

# Forcer l'appel d'une fonction specifique
tool_choice = {"type": "function", "name": "rechercher_client"}

# Interdire tout appel de fonction
tool_choice = "none"

# Exiger au moins un appel sans preciser lequel
tool_choice = "required"

Points cles a retenir

  • Le function calling est un protocole d’intention, pas d’execution
  • La boucle appel-execution-retour est le pattern fondamental
  • Les outils built-in et personnalises coexistent dans le meme tableau tools
  • Le call_id assure la tracabilite de chaque appel
  • tool_choice permet de controler finement le comportement du modele