Combiner les outils dans un même appel
Combiner les outils dans un meme appel
La puissance reelle de la Responses API emerge quand vous combinez plusieurs outils dans un meme appel. Le modele orchestre automatiquement Web Search, File Search, Code Interpreter et vos fonctions personnalisees pour accomplir des taches complexes.
Principe de la combinaison
Tous les outils se declarent dans le meme tableau tools. Le modele choisit dynamiquement quels outils utiliser et dans quel ordre :
from openai import OpenAI
client = OpenAI()
response = client.responses.create(
model="gpt-5.3",
input="Compare nos previsions de ventes avec les tendances du marche, "
"puis cree un graphique de la comparaison.",
tools=[
{"type": "file_search", "vector_store_ids": ["vs_previsions"]},
{"type": "web_search_preview"},
{"type": "code_interpreter"}
]
)
Le modele va :
- Chercher les previsions internes via File Search
- Chercher les tendances du marche via Web Search
- Generer un graphique comparatif via Code Interpreter
Exemple complet : assistant analytique
with open("donnees_ventes.csv", "rb") as f:
fichier = client.files.create(file=f, purpose="assistants")
tools = [
# Recherche dans les documents internes
{
"type": "file_search",
"vector_store_ids": ["vs_rapports", "vs_objectifs"],
"max_num_results": 10
},
# Recherche web pour le contexte marche
{
"type": "web_search_preview",
"search_context_size": "medium"
},
# Execution de code pour l'analyse
{"type": "code_interpreter"},
# Fonction pour sauvegarder le rapport
{
"type": "function",
"name": "sauvegarder_rapport",
"description": "Sauvegarder un rapport d'analyse dans le systeme documentaire",
"parameters": {
"type": "object",
"properties": {
"titre": {"type": "string"},
"contenu": {"type": "string"},
"categorie": {
"type": "string",
"enum": ["analyse", "prevision", "audit", "comparaison"]
},
"tags": {
"type": "array",
"items": {"type": "string"}
}
},
"required": ["titre", "contenu", "categorie", "tags"],
"additionalProperties": false
},
"strict": true
}
]
response = client.responses.create(
model="gpt-5.3",
input=[{
"role": "user",
"content": [
{"type": "text", "text": (
"A partir de ce fichier de ventes : "
"1. Analyse les tendances des 12 derniers mois "
"2. Compare avec nos objectifs annuels (cherche dans les docs) "
"3. Cherche les tendances du marche sur le web "
"4. Genere un graphique comparatif "
"5. Redige un rapport de synthese "
"6. Sauvegarde le rapport"
)},
{"type": "input_file", "file_id": fichier.id}
]
}],
tools=tools,
instructions=(
"Tu es un analyste business senior. "
"Utilise tous les outils a ta disposition pour produire "
"une analyse complete et sourcee."
)
)
Gerer la boucle multi-outils
Quand le modele utilise des fonctions personnalisees en plus des outils built-in, implementez une boucle :
import json
def boucle_multi_outils(prompt, tools, fichiers=None, max_tours=15):
"""Boucle de function calling avec support multi-outils."""
content = [{"type": "text", "text": prompt}]
if fichiers:
for fid in fichiers:
content.append({"type": "input_file", "file_id": fid})
messages = [{"role": "user", "content": content}]
for tour in range(max_tours):
response = client.responses.create(
model="gpt-5.3",
input=messages,
tools=tools,
instructions="Utilise les outils necessaires pour repondre completement."
)
# Les outils built-in (web_search, file_search, code_interpreter)
# sont executes automatiquement cote serveur.
# On ne traite que les function_call personnalises.
appels_custom = [
item for item in response.output
if item.type == "function_call"
]
if not appels_custom:
# Pas d'appel personnalise : le modele a fini
return {
"reponse": response.output_text,
"tours": tour + 1,
"tokens": response.usage.total_tokens
}
# Executer les fonctions personnalisees
resultats = []
for appel in appels_custom:
resultat = dispatcher_fonctions(appel.name, appel.arguments)
resultats.append({
"type": "function_call_output",
"call_id": appel.call_id,
"output": json.dumps(resultat)
})
# Preparer le prochain tour
messages = response.output + resultats
return {"reponse": "Limite de tours atteinte", "tours": max_tours}
Strategies d’orchestration
Guider l’ordre des outils
Le prompt systeme influence l’ordre dans lequel le modele utilise les outils :
# Strategy 1 : recherche d'abord, action ensuite
instructions_recherche_dabord = (
"Avant toute action, cherche d'abord les informations necessaires "
"dans les documents internes et sur le web. "
"Ne propose des actions qu'apres avoir rassemble toutes les donnees."
)
# Strategy 2 : analyse de donnees puis enrichissement
instructions_analyse_dabord = (
"Commence par analyser les donnees avec Code Interpreter. "
"Puis enrichis tes conclusions avec des recherches web. "
"Enfin, compare avec les documents internes."
)
# Strategy 3 : verification croisee
instructions_verification = (
"Pour chaque information importante, verifie-la dans au moins deux sources : "
"documents internes ET recherche web. Signale les contradictions."
)
Limiter les outils par etape
# Etape 1 : collecte de donnees (pas de code)
response_collecte = client.responses.create(
model="gpt-5.3",
input="Rassemble les informations sur le projet Alpha",
tools=[
{"type": "file_search", "vector_store_ids": ["vs_projets"]},
{"type": "web_search_preview"}
]
)
# Etape 2 : analyse avec les donnees collectees
response_analyse = client.responses.create(
model="gpt-5.3",
input=f"Analyse ces informations et genere des graphiques :\n"
f"{response_collecte.output_text}",
tools=[{"type": "code_interpreter"}]
)
Pattern : agent multi-competences
class AgentMultiCompetences:
def __init__(self, vector_stores: list[str], fonctions: list[dict]):
self.client = OpenAI()
self.tools = [
{"type": "file_search", "vector_store_ids": vector_stores},
{"type": "web_search_preview", "search_context_size": "medium"},
{"type": "code_interpreter"},
] + fonctions
def traiter(self, requete: str, fichiers: list[str] = None) -> dict:
return boucle_multi_outils(requete, self.tools, fichiers)
# Instancier l'agent
agent = AgentMultiCompetences(
vector_stores=["vs_docs", "vs_contrats"],
fonctions=[
{
"type": "function",
"name": "envoyer_email",
"description": "Envoyer un email de notification",
"parameters": {
"type": "object",
"properties": {
"destinataire": {"type": "string"},
"sujet": {"type": "string"},
"corps": {"type": "string"}
},
"required": ["destinataire", "sujet", "corps"],
"additionalProperties": false
},
"strict": true
},
{
"type": "function",
"name": "creer_tache",
"description": "Creer une tache dans le gestionnaire de projet",
"parameters": {
"type": "object",
"properties": {
"titre": {"type": "string"},
"assignee": {"type": "string"},
"priorite": {"type": "string", "enum": ["basse", "moyenne", "haute"]},
"echeance": {"type": "string"}
},
"required": ["titre", "assignee", "priorite"],
"additionalProperties": false
},
"strict": true
}
]
)
# L'agent peut maintenant :
# - Chercher dans les documents
# - Chercher sur le web
# - Analyser des donnees
# - Envoyer des emails
# - Creer des taches
resultat = agent.traiter(
"Analyse les ventes du Q1, compare avec les objectifs, "
"et cree une tache pour le directeur commercial si on est en retard."
)
Points cles a retenir
- Tous les outils coexistent dans le meme tableau
tools - Les outils built-in s’executent cote serveur, les fonctions personnalisees cote client
- Le modele orchestre automatiquement l’ordre des appels
- Guidez la strategie d’orchestration via le prompt systeme
- Implementez une boucle pour gerer les appels de fonctions personnalisees