Tool Calling (appel de fonctions)
Tool Calling (également appelé Function Calling) permet aux modèles d’aller au-delà de la génération de texte en retournant une « demande d’appel de fonction » structurée lorsque nécessaire. Votre programme exécute la logique réelle (vérifier la météo, interroger la base de données, passer commande), renvoie le résultat au modèle, et le modèle génère une réponse finale basée sur celui-ci. RouteAPI prend en charge Tool Calling sur /v1/chat/completions (format OpenAI) et /v1/messages (format Claude).
1. Aperçu de Tool Calling
Section intitulée « 1. Aperçu de Tool Calling »Qu’est-ce que Tool Calling
Section intitulée « Qu’est-ce que Tool Calling »Tool Calling est un échange multi-tours :
- Vous déclarez un ensemble d’« outils » dans la requête (chaque outil a un nom, une description et un schéma de paramètres).
- Le modèle détermine si un outil est nécessaire ; si oui, il retourne une demande d’appel avec des paramètres au lieu d’une réponse directe.
- Votre code analyse les paramètres, exécute la logique réelle et obtient le résultat.
- Vous renvoyez le résultat au modèle, qui génère une réponse en langage naturel pour l’utilisateur.
Le modèle lui-même n’exécute aucun code ; il décide uniquement « quel outil appeler » et « quels paramètres passer ». L’exécution réelle se produit toujours de votre côté, ce qui signifie que les limites de sécurité (vérifications de permissions, filtrage des paramètres) sont sous votre contrôle.
Cas d’usage
Section intitulée « Cas d’usage »| Scénario | Description |
|---|---|
| Requêtes de données en temps réel | Météo, taux de change, cours des actions, inventaire—informations absentes des données d’entraînement du modèle |
| Intégration système interne | Interroger des bases de données, appeler des API internes, lire l’état des commandes |
| Exécuter des actions | Passer des commandes, envoyer des e-mails, créer des tickets—opérations avec effets secondaires |
| Extraction structurée | Forcer le modèle à produire selon un schéma fixe, équivalent à une sortie structurée |
| Orchestration d’agents | Les frameworks d’agents utilisent Tool Calling pour piloter des tâches multi-étapes |
Modèles pris en charge
Section intitulée « Modèles pris en charge »La capacité Tool Calling dépend du modèle sélectionné. La plupart des modèles grand public (séries OpenAI GPT, Claude, Gemini, etc.) la prennent en charge, mais les détails comme le nombre maximum d’outils et la prise en charge des appels parallèles varient. L’endpoint de liste des modèles ne retourne aucun champ indiquant la capacité Tool Calling : consultez la documentation du fournisseur du modèle, ou envoyez directement une requête réelle avec tools sur le modèle cible pour le vérifier, voir Models.
2. Format de définition d’outil (OpenAI)
Section intitulée « 2. Format de définition d’outil (OpenAI) »Dans /v1/chat/completions, les outils sont déclarés via un tableau tools de niveau supérieur, où chaque outil est un objet imbriqué avec type: "function".
Structure du tableau tools
Section intitulée « Structure du tableau tools »{ "tools": [ { "type": "function", "function": { "name": "get_weather", "description": "Interroger la météo actuelle d'une ville spécifiée. Utiliser le nom complet de la ville en chinois.", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "Nom de la ville, par ex. Beijing" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"], "description": "Unité de température, par défaut celsius" } }, "required": ["city"] } } } ]}function schema
Section intitulée « function schema »| Champ | Type | Requis | Description |
|---|---|---|---|
type | string | Oui | Fixé à "function" |
function.name | string | Oui | Nom de l’outil, ne peut contenir que lettres, chiffres, underscores et tirets |
function.description | string | Recommandé | Description de l’objectif de l’outil, le modèle l’utilise pour décider d’appeler |
function.parameters | object | Non | Définition des paramètres, JSON Schema standard |
La qualité de description détermine directement si le modèle choisira correctement l’outil. Décrire clairement l’objectif, la signification de chaque paramètre, la plage de valeurs et les conditions limites est plus efficace que l’ajustement de tout paramètre d’échantillonnage.
parameters (JSON Schema)
Section intitulée « parameters (JSON Schema) »parameters utilise JSON Schema standard pour décrire la structure des paramètres :
type: Généralement"object".properties: Type, description, valeurs énumérées pour chaque paramètre.required: Liste des noms de paramètres requis.enum: Restreindre la plage de valeurs, réduit considérablement la probabilité que le modèle passe des valeurs incorrectes.
Les outils sans paramètres doivent toujours fournir un schéma vide : "parameters": { "type": "object", "properties": {} }.
3. Format de définition d’outil (Claude)
Section intitulée « 3. Format de définition d’outil (Claude) »Dans /v1/messages, les définitions d’outils sont des structures plates sans enveloppes externes type et function, et le champ de paramètre s’appelle input_schema.
Différences du tableau tools
Section intitulée « Différences du tableau tools »{ "tools": [ { "name": "get_weather", "description": "Interroger la météo actuelle d'une ville spécifiée. Utiliser le nom complet de la ville en chinois.", "input_schema": { "type": "object", "properties": { "city": { "type": "string", "description": "Nom de la ville, par ex. Beijing" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] } }, "required": ["city"] } } ]}input_schema
Section intitulée « input_schema »La structure interne de input_schema est identique à celle de parameters d’OpenAI, tous deux JSON Schema standard. La différence n’est que dans l’enveloppe externe.
Comparaison des deux formats
Section intitulée « Comparaison des deux formats »| Élément | OpenAI (/v1/chat/completions) | Claude (/v1/messages) |
|---|---|---|
| Enveloppe externe | { "type": "function", "function": {...} } | Structure plate directe, pas d’enveloppe |
| Champ nom d’outil | function.name | name |
| Champ description | function.description | description |
| Champ paramètre | function.parameters | input_schema |
| Schéma paramètre | JSON Schema standard | JSON Schema standard (identique) |
| Retour du modèle | Tableau message.tool_calls | Bloc tool_use dans content |
| Rôle de passage de résultat | Message role: "tool" indépendant | Bloc tool_result dans message user |
| Champ d’association de résultat | tool_call_id | tool_use_id |
Pour les détails complets du protocole Claude (incluant is_error, streaming input_json_delta, etc.), voir Protocole Claude Messages. Les exemples suivants sur cette page utilisent par défaut le format OpenAI.
4. Options tool_choice
Section intitulée « 4. Options tool_choice »tool_choice contrôle comment le modèle sélectionne les outils.
| Valeur | Comportement |
|---|---|
"auto" | Le modèle décide d’appeler ou non un outil et lequel. Valeur par défaut lorsque tools est présent |
"none" | Interdire l’appel de tout outil, le modèle ne produit que du texte |
"required" | Doit appeler au moins un outil, mais le modèle choisit lequel |
{ "type": "function", "function": { "name": "get_weather" } } | Forcer l’appel de l’outil spécifié |
auto (par défaut)
Section intitulée « auto (par défaut) »{ "tool_choice": "auto" }Le plus courant. Adapté aux scénarios où « les questions des utilisateurs nécessitent parfois des outils, parfois des réponses directes ».
{ "tool_choice": "none" }Désactiver temporairement les outils tout en conservant les définitions. Souvent utilisé dans la phase de clôture « laisser le modèle résumer, ne pas rappeler les outils ».
required
Section intitulée « required »{ "tool_choice": "required" }Forcer le modèle à emprunter le chemin d’outil. Adapté aux scénarios comme l’extraction structurée qui « doivent produire des résultats structurés ».
Spécifier un outil spécifique
Section intitulée « Spécifier un outil spécifique »{ "tool_choice": { "type": "function", "function": { "name": "get_weather" } }}L’équivalent au format Claude est { "type": "tool", "name": "get_weather" }, required correspond à { "type": "any" }, none correspond à { "type": "none" }.
5. Flux de Tool Calling
Section intitulée « 5. Flux de Tool Calling »Un appel d’outil complet implique au moins deux tours de requêtes.
Premier tour : le modèle retourne tool_calls
Section intitulée « Premier tour : le modèle retourne tool_calls »Envoyer une requête avec tools :
curl https://api.routeapi.ai/v1/chat/completions \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5.5", "messages": [ { "role": "user", "content": "Quel temps fait-il à Beijing maintenant ?" } ], "tools": [ { "type": "function", "function": { "name": "get_weather", "description": "Interroger la météo actuelle d une ville spécifiée.", "parameters": { "type": "object", "properties": { "city": { "type": "string" } }, "required": ["city"] } } } ] }'Lorsque le modèle détermine qu’un outil est nécessaire, finish_reason est tool_calls, message.content est null, et tool_calls contient la demande d’appel :
{ "choices": [ { "index": 0, "message": { "role": "assistant", "content": null, "tool_calls": [ { "id": "call_abc123", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\": \"Beijing\"}" } } ] }, "finish_reason": "tool_calls" } ]}Notez que arguments est une chaîne JSON, pas un objet ; vous devez le parser vous-même avec JSON.parse / json.loads. Le modèle peut occasionnellement générer du JSON invalide, donc l’analyse doit être dans un try/catch.
Exécuter l’outil
Section intitulée « Exécuter l’outil »Dispatcher par function.name vers votre logique réelle, exécuter avec les paramètres analysés :
import json
args = json.loads(tool_call["function"]["arguments"])result = get_weather(**args) # "Beijing, ensoleillé, 23 celsius"Deuxième tour : passer le résultat de l’outil
Section intitulée « Deuxième tour : passer le résultat de l’outil »Ajouter le message assistant du premier tour (avec tool_calls) tel quel à messages, puis ajouter un message role: "tool" portant le résultat. tool_call_id doit correspondre exactement à l’id du premier tour :
{ "model": "gpt-5.5", "messages": [ { "role": "user", "content": "Quel temps fait-il à Beijing maintenant ?" }, { "role": "assistant", "content": null, "tool_calls": [ { "id": "call_abc123", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\": \"Beijing\"}" } } ] }, { "role": "tool", "tool_call_id": "call_abc123", "content": "Beijing, ensoleillé, température 23 celsius, humidité 45%." } ], "tools": []}Le modèle génère la réponse finale
Section intitulée « Le modèle génère la réponse finale »La requête du deuxième tour retourne un résultat en langage naturel, finish_reason revient à stop :
{ "choices": [ { "message": { "role": "assistant", "content": "Beijing est actuellement ensoleillé avec une température de 23 celsius et une humidité de 45%, assez confortable." }, "finish_reason": "stop" } ]}6. Tool Calling multi-tours
Section intitulée « 6. Tool Calling multi-tours »Appels séquentiels de plusieurs outils
Section intitulée « Appels séquentiels de plusieurs outils »Le modèle peut nécessiter plusieurs tours d’appels d’outils pour terminer une tâche : d’abord vérifier le numéro de commande, puis utiliser le numéro de commande pour vérifier la logistique. Chaque tour suit la boucle « le modèle retourne tool_calls → exécuter → renvoyer le résultat » jusqu’à ce que finish_reason revienne à stop. Le code de production doit être écrit comme une boucle avec une limite de tours maximum pour éviter les boucles infinies :
MAX_TURNS = 5for _ in range(MAX_TURNS): resp = call_model(messages) msg = resp["choices"][0]["message"] messages.append(msg) if not msg.get("tool_calls"): break # Le modèle donne la réponse finale for tc in msg["tool_calls"]: result = dispatch(tc) # Exécuter et retourner une chaîne messages.append({ "role": "tool", "tool_call_id": tc["id"], "content": result, })Appels d’outils parallèles
Section intitulée « Appels d’outils parallèles »En un tour, le modèle peut simultanément demander plusieurs outils indépendants (par exemple, vérifier la météo de Beijing et Shanghai), résultant en un tableau tool_calls multi-éléments. Vous devez ajouter un message role: "tool" correspondant pour chaque tool_call, avec tool_call_id aligné un à un ; en manquer un causera une erreur au prochain tour.
Pour désactiver le parallélisme et forcer le modèle à appeler un seul outil à la fois, ajoutez "parallel_tool_calls": false en format OpenAI, ou ajoutez "disable_parallel_tool_use": true dans tool_choice pour le format Claude.
7. Tool Calling en streaming
Section intitulée « 7. Tool Calling en streaming »Lorsque stream: true est défini, les paramètres d’appel d’outil sont retournés incrémentalement par morceaux.
tool_calls dans la sortie en streaming
Section intitulée « tool_calls dans la sortie en streaming »Le delta.tool_calls de chaque chunk SSE contient index (identifie quel appel d’outil), et function.arguments est un fragment du JSON des paramètres :
data: {"choices":[{"delta":{"tool_calls":[{"index":0,"id":"call_abc123","type":"function","function":{"name":"get_weather","arguments":""}}]}}]}
data: {"choices":[{"delta":{"tool_calls":[{"index":0,"function":{"arguments":"{\"city\":"}}]}}]}
data: {"choices":[{"delta":{"tool_calls":[{"index":0,"function":{"arguments":"\"Beijing\"}"}}]}}]}
data: {"choices":[{"finish_reason":"tool_calls"}]}
data: [DONE]Comment traiter le delta incrémental
Section intitulée « Comment traiter le delta incrémental »Accumuler par groupes index : id et name n’apparaissent généralement que dans le premier fragment, arguments nécessite que tous les fragments soient concaténés avant l’analyse. Ne pas tenter d’analyser les états intermédiaires pendant la concaténation (c’est du JSON incomplet).
buffers = {} # index -> {"id", "name", "args"}for chunk in stream: for tc in chunk["choices"][0]["delta"].get("tool_calls", []): i = tc["index"] buf = buffers.setdefault(i, {"id": "", "name": "", "args": ""}) if tc.get("id"): buf["id"] = tc["id"] fn = tc.get("function", {}) if fn.get("name"): buf["name"] = fn["name"] if fn.get("arguments"): buf["args"] += fn["arguments"]
# Analyser après la fin du fluxfor buf in buffers.values(): args = json.loads(buf["args"])Les paramètres d’outil en streaming au format Claude sont retournés incrémentalement via le partial_json de l’événement input_json_delta, accumulés par index puis analysés ; détails dans Protocole Claude Messages.
8. État de prise en charge des modèles
Section intitulée « 8. État de prise en charge des modèles »Modèles prenant en charge Tool Calling
Section intitulée « Modèles prenant en charge Tool Calling »La plupart des modèles grand public agrégés par RouteAPI prennent en charge Tool Calling, y compris les séries OpenAI GPT, Claude, Gemini, etc. Commencez par vérifier via l’endpoint de liste des modèles que le modèle est disponible dans votre compte :
curl https://api.routeapi.ai/v1/models \ -H "Authorization: Bearer $ROUTEAPI_KEY"Cet endpoint retourne uniquement la disponibilité du modèle et les endpoints utilisables, pas la capacité Tool Calling. Pour savoir si Tool Calling est pris en charge, référez-vous à la documentation du fournisseur ou à une requête réelle avec tools.
Limitations des modèles
Section intitulée « Limitations des modèles »Différents modèles varient dans les dimensions suivantes ; vérifiez dans un environnement de test avant de passer en production :
| Dimension | Description |
|---|---|
| Nombre maximum d’outils | La limite supérieure d’outils pouvant être déclarés dans une seule requête varie selon le modèle |
| Appel parallèle | Certains modèles ne prennent pas en charge le retour de plusieurs tool_calls en un tour |
Prise en charge de tool_choice | Tous les modèles ne prennent pas en charge required / spécification d’outils spécifiques |
| Complexité des paramètres | Les JSON Schema profondément imbriqués ou très volumineux peuvent être tronqués ou ignorés par certains modèles |
| Granularité d’incrément en streaming | La fragmentation de arguments varie entre les modèles ; doit accumuler par index |
9. Exemples complets
Section intitulée « 9. Exemples complets »Exemple d’outil de requête météo (de bout en bout)
Section intitulée « Exemple d’outil de requête météo (de bout en bout) »Les trois extraits de code suivants sont fonctionnellement équivalents : définir l’outil → premier tour obtient tool_calls → exécuter → deuxième tour renvoie le résultat → obtient la réponse finale.
curl (compléter manuellement deux tours) :
# Premier tour : envoyer une requête avec des outilscurl https://api.routeapi.ai/v1/chat/completions \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5.5", "messages": [{ "role": "user", "content": "Quel temps fait-il à Beijing maintenant ?" }], "tools": [{ "type": "function", "function": { "name": "get_weather", "description": "Interroger la météo actuelle d une ville spécifiée.", "parameters": { "type": "object", "properties": { "city": { "type": "string" } }, "required": ["city"] } } }] }'
# Deuxième tour : renvoyer le résultat de l'outil (tool_call_id utilise la valeur du premier tour)curl https://api.routeapi.ai/v1/chat/completions \ -H "Authorization: Bearer $ROUTEAPI_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-5.5", "messages": [ { "role": "user", "content": "Quel temps fait-il à Beijing maintenant ?" }, { "role": "assistant", "content": null, "tool_calls": [{ "id": "call_abc123", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\": \"Beijing\"}" } }] }, { "role": "tool", "tool_call_id": "call_abc123", "content": "Beijing, ensoleillé, température 23 celsius, humidité 45%." } ] }'Python (SDK OpenAI, complète automatiquement deux tours) :
import jsonimport osfrom openai import OpenAI
client = OpenAI( api_key=os.environ["ROUTEAPI_KEY"], base_url="https://api.routeapi.ai/v1",)
tools = [ { "type": "function", "function": { "name": "get_weather", "description": "Interroger la météo actuelle d'une ville spécifiée. Utiliser le nom complet de la ville en chinois.", "parameters": { "type": "object", "properties": { "city": {"type": "string", "description": "Nom de la ville, par ex. Beijing"}, "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]}, }, "required": ["city"], }, }, }]
def get_weather(city: str, unit: str = "celsius") -> str: # Remplacer par un appel réel au service météo return f"{city}, ensoleillé, température 23 celsius, humidité 45%."
messages = [{"role": "user", "content": "Quel temps fait-il à Beijing maintenant ?"}]
# Premier tourresp = client.chat.completions.create( model="gpt-5.5", messages=messages, tools=tools)msg = resp.choices[0].message
if msg.tool_calls: # Le message assistant doit être ajouté tel quel, sinon tool_call_id ne peut pas s'aligner messages.append(msg) for tc in msg.tool_calls: args = json.loads(tc.function.arguments) result = get_weather(**args) messages.append( {"role": "tool", "tool_call_id": tc.id, "content": result} )
# Deuxième tour resp = client.chat.completions.create( model="gpt-5.5", messages=messages, tools=tools )
print(resp.choices[0].message.content)Node.js (package openai, complète automatiquement deux tours) :
import OpenAI from 'openai';
const client = new OpenAI({ apiKey: process.env.ROUTEAPI_KEY, baseURL: 'https://api.routeapi.ai/v1',});
const tools = [ { type: 'function', function: { name: 'get_weather', description: 'Interroger la météo actuelle d une ville spécifiée. Utiliser le nom complet de la ville en chinois.', parameters: { type: 'object', properties: { city: { type: 'string', description: 'Nom de la ville, par ex. Beijing' }, unit: { type: 'string', enum: ['celsius', 'fahrenheit'] }, }, required: ['city'], }, }, },];
function getWeather(city, unit = 'celsius') { // Remplacer par un appel réel au service météo return `${city}, ensoleillé, température 23 celsius, humidité 45%.`;}
const messages = [{ role: 'user', content: 'Quel temps fait-il à Beijing maintenant ?' }];
// Premier tourlet resp = await client.chat.completions.create({ model: 'gpt-5.5', messages, tools,});const msg = resp.choices[0].message;
if (msg.tool_calls) { messages.push(msg); // Ajouter le message assistant tel quel for (const tc of msg.tool_calls) { const args = JSON.parse(tc.function.arguments); const result = getWeather(args.city, args.unit); messages.push({ role: 'tool', tool_call_id: tc.id, content: result }); }
// Deuxième tour resp = await client.chat.completions.create({ model: 'gpt-5.5', messages, tools, });}
console.log(resp.choices[0].message.content);Exemple d’outil de requête de base de données
Section intitulée « Exemple d’outil de requête de base de données »Utiliser les outils comme enveloppes sécurisées pour les systèmes internes. Clé : SQL ne doit pas être généré directement par le modèle ; au lieu de cela, le modèle sélectionne les paramètres, et votre code construit des requêtes paramétrées pour éviter l’injection.
tools = [ { "type": "function", "function": { "name": "query_order", "description": "Interroger l'état et le montant de la commande par numéro de commande.", "parameters": { "type": "object", "properties": { "order_id": { "type": "string", "description": "Numéro de commande, comme ORD-20260917-001", } }, "required": ["order_id"], }, }, }]
def query_order(order_id: str) -> str: # Utiliser une requête paramétrée, ne jamais concaténer la sortie du modèle directement dans SQL row = db.execute( "SELECT status, amount FROM orders WHERE order_id = %s", (order_id,), ).fetchone() if row is None: return json.dumps({"found": False}) return json.dumps({"found": True, "status": row[0], "amount": row[1]})Les résultats d’outils sont recommandés d’être renvoyés sous forme de chaînes JSON ; les modèles peuvent analyser plus fiablement les champs structurés.
Exemple d’orchestration multi-outils
Section intitulée « Exemple d’orchestration multi-outils »Déclarer plusieurs outils simultanément ; le modèle sélectionne selon les besoins ou appelle même en parallèle. Ici, en utilisant météo + taux de change deux outils :
tools = [ { "type": "function", "function": { "name": "get_weather", "description": "Interroger la météo actuelle d'une ville spécifiée.", "parameters": { "type": "object", "properties": {"city": {"type": "string"}}, "required": ["city"], }, }, }, { "type": "function", "function": { "name": "get_exchange_rate", "description": "Interroger le taux de change entre deux devises.", "parameters": { "type": "object", "properties": { "from_currency": {"type": "string", "description": "Comme USD"}, "to_currency": {"type": "string", "description": "Comme CNY"}, }, "required": ["from_currency", "to_currency"], }, }, },]
dispatch = { "get_weather": lambda city: f"{city}, ensoleillé, 23 celsius.", "get_exchange_rate": lambda from_currency, to_currency: f"1 {from_currency} = 7.2 {to_currency}",}
messages = [{"role": "user", "content": "Quel temps fait-il à Beijing ? Aussi, dites-moi le taux de change USD vers CNY."}]
# Boucle pour gérer les appels d'outils multi-tours / parallèles, définir une limite pour éviter les boucles infiniesfor _ in range(5): resp = client.chat.completions.create( model="gpt-5.5", messages=messages, tools=tools ) msg = resp.choices[0].message messages.append(msg) if not msg.tool_calls: break # Lors d'appels parallèles, tool_calls est un tableau multi-éléments ; chacun doit être renvoyé for tc in msg.tool_calls: args = json.loads(tc.function.arguments) result = dispatch[tc.function.name](**args) messages.append( {"role": "tool", "tool_call_id": tc.id, "content": result} )
print(messages[-1]["content"])10. Gestion des erreurs
Section intitulée « 10. Gestion des erreurs »Tool Calling introduit trois points d’erreur potentiels : côté modèle, côté de votre code et côté service en amont.
Échec de validation des paramètres d’outil
Section intitulée « Échec de validation des paramètres d’outil »Le modèle peut retourner du JSON invalide, ou manquer des paramètres requis, ou passer des valeurs hors plage enum. Assurez-vous de :
- Envelopper
JSON.parse/json.loadsdans try/catch. - Après l’analyse, valider les champs requis et les plages de valeurs selon le schéma.
- Lorsque la validation échoue, renvoyer le message d’erreur comme résultat d’outil pour laisser le modèle s’auto-corriger, plutôt que de lancer directement une exception pour terminer la conversation :
try: args = json.loads(tc.function.arguments) city = args["city"] # Valider le champ requisexcept (json.JSONDecodeError, KeyError) as exc: result = f"Échec de l'analyse des paramètres : {exc}. Veuillez fournir à nouveau un paramètre city valide."else: result = get_weather(city)
messages.append({"role": "tool", "tool_call_id": tc.id, "content": result})Timeout d’exécution d’outil
Section intitulée « Timeout d’exécution d’outil »Les outils sont soutenus par de vrais services qui peuvent expirer ou être indisponibles. Définir une limite de timeout pour chaque appel d’outil ; si expiration, renvoyer le résultat comme une description d’erreur claire pour laisser le modèle basculer vers une autre stratégie :
try: result = call_service(args, timeout=5)except TimeoutError: result = "Timeout du service, données non récupérées, veuillez réessayer plus tard ou utiliser une autre méthode."Ne pas effectuer de nouvelles tentatives automatiques sur les outils avec effets secondaires (passer des commandes, envoyer des e-mails), car ils peuvent s’exécuter à répétition. La conception idempotente ou vérifier avant d’écrire est plus sûr.
L’outil retourne une erreur
Section intitulée « L’outil retourne une erreur »Les erreurs de niveau métier (commande introuvable, pas de permission) doivent également être renvoyées au modèle, plutôt que de retourner silencieusement des valeurs vides. Renvoyer des informations d’erreur structurées ; le modèle peut fournir des explications raisonnables aux utilisateurs :
messages.append({ "role": "tool", "tool_call_id": tc.id, "content": json.dumps({"error": "order_not_found", "order_id": order_id}),})Le format Claude définit correspondamment "is_error": true sur le bloc tool_result, voir Protocole Claude Messages.
Rappels de compatibilité
Section intitulée « Rappels de compatibilité »- La capacité Tool Calling, le nombre maximum d’outils, la prise en charge des appels parallèles dépendent du modèle sélectionné ; vérifiez dans l’environnement de test avant de passer en production.
argumentsest toujours une chaîne JSON, pas un objet ; doit analyser explicitement.- Dans les scénarios de streaming, doit accumuler les fragments
argumentsparindex, analyser après concaténation complète. - Les paramètres optionnels explicitement passés comme
0oufalsesont considérés comme définis par l’utilisateur, non traités comme des valeurs par défaut et écartés. - Enregistrer l’ID de requête, l’ID de modèle, le code d’état et l’utilisation de jetons pour chaque requête pour faciliter le dépannage. Détails de la structure d’erreur dans Erreurs et débogage.