Function calling / tool use : connecter un LLM à vos outils DevOps
À la fin de ce tutoriel, vous comprendrez le function calling (aussi appelé tool use), déclarerez un outil JSON Schema, gérerez la boucle modèle →
tool_calls→ exécution →tool_result, et appliquerez le pattern à un scénario DevOps (statut de pod) — sans laisser le modèle exécuter du code tout seul.Niveau : Intermédiaire · Temps estimé : 55–70 min · Versions cibles : OpenAI Chat Completions tools 2026 · Anthropic Messages
tools/tool_use· Python 3.12 · Dernière vérification : 2026-09-11← Précédent : Perplexity pour recherche tech · → Suivant : Structured outputs JSON · Hub : IA pour DevOps : parcours 2026
Prérequis
- Bases Python 3.12 et JSON
- Clé API lab OpenAI ou Anthropic (compte sandbox, budget plafonné)
- Notions Kubernetes utiles mais pas obligatoires :
kubectl get poden lecture seule - Avoir lu le hub IA pour DevOps : parcours 2026 pour le contexte série
Objectif : transformer un LLM « qui parle » en orchestrateur qui propose des appels d’outils que votre runtime exécute sous contrôle.
Ce que nous allons construire
Utilisateur ──prompt──► LLM (tools déclarés)
│ tool_calls JSON
▼
Runtime / sandbox (allowlist)
│ exécute get_pod_status(...)
▼
tool_result ──► LLM ──► réponse finale
(Schéma — alt : « Boucle function calling : LLM, runtime sandbox, tool_result ».)
Le modèle n’exécute jamais l’outil. Il émet un appel structuré (name + arguments JSON). Votre code valide, exécute (ou refuse), puis renvoie le résultat au modèle pour la suite du tour.
Étape 1 — Pourquoi le function calling change la donne DevOps
Sans tools, le modèle invente ou paraphrase. Avec function calling, vous lui donnez un catalogue d’actions : lire un statut, interroger CloudWatch, ouvrir un ticket, lancer un dry-run. C’est le cœur des agents IDE (Claude Code, Cursor, Codex) et des Actions ChatGPT.
| Approche | Ce que fait le modèle | Qui exécute |
|---|---|---|
| Chat texte seul | Texte libre | Personne |
| Function calling | Appels JSON typés | Votre runtime |
| MCP / plugins | Même idée, protocole outillé | Host MCP / plateforme |
Pour DevOps Elastic Hayway 2026, le pattern sert surtout à encadrer : allowlist, logs d’audit, human-in-the-loop sur toute mutation (kubectl apply, delete, scale).
Étape 2 — Déclarer un outil (JSON Schema)
Un outil = name + description (le modèle s’en sert pour décider) + parameters (JSON Schema des arguments).
TOOLS = [
{
"type": "function",
"function": {
"name": "get_pod_status",
"description": (
"Lit le statut d'un Pod Kubernetes (phase, ready). "
"Lecture seule ; jamais de mutation."
),
"parameters": {
"type": "object",
"properties": {
"namespace": {
"type": "string",
"description": "Namespace Kubernetes, ex. default",
},
"name": {
"type": "string",
"description": "Nom du Pod",
},
},
"required": ["namespace", "name"],
"additionalProperties": False,
},
},
}
]
Bonnes pratiques description : dire quand appeler l’outil, ce qu’il renvoie, et ce qu’il ne fait pas (pas de delete, pas de secrets).
Étape 3 — Boucle OpenAI tools (Python)
Exemple minimal avec l’API Chat Completions et le paramètre tools :
import json
import os
from openai import OpenAI
client = OpenAI(api_key=os.environ["OPENAI_API_KEY"])
def get_pod_status(namespace: str, name: str) -> dict:
# Lab : stub déterministe. En vrai : kubectl get pod -n ... -o json
return {
"namespace": namespace,
"name": name,
"phase": "Running",
"ready": "1/1",
"restarts": 0,
}
DISPATCH = {"get_pod_status": get_pod_status}
messages = [
{
"role": "system",
"content": (
"Tu es un assistant DevOps. Pour le statut d'un pod, "
"utilise get_pod_status. Ne invente pas de métriques."
),
},
{
"role": "user",
"content": "Quel est le statut du pod api-7f8 dans default ?",
},
]
resp = client.chat.completions.create(
model="gpt-4.1-mini",
messages=messages,
tools=TOOLS,
tool_choice="auto",
)
msg = resp.choices[0].message
messages.append(msg)
if msg.tool_calls:
for call in msg.tool_calls:
fn = call.function.name
args = json.loads(call.function.arguments)
if fn not in DISPATCH:
result = {"error": "tool_not_allowed"}
else:
result = DISPATCH[fn](**args)
messages.append(
{
"role": "tool",
"tool_call_id": call.id,
"content": json.dumps(result),
}
)
final = client.chat.completions.create(
model="gpt-4.1-mini",
messages=messages,
)
print(final.choices[0].message.content)
else:
print(msg.content)
Points clés : tool_choice="auto" laisse le modèle décider ; "required" force un outil ; un nom hors allowlist → erreur contrôlée, jamais d’eval sur les arguments.
Étape 4 — Même idée chez Anthropic (tool_use)
Claude Messages API utilise tools en entrée, des blocs tool_use en sortie, puis vous renvoyez des blocs tool_result :
# Pseudocode Anthropic — structure conceptuelle 2026
tools = [
{
"name": "get_pod_status",
"description": "Lit le statut d'un Pod (lecture seule).",
"input_schema": {
"type": "object",
"properties": {
"namespace": {"type": "string"},
"name": {"type": "string"},
},
"required": ["namespace", "name"],
},
}
]
# Réponse modèle : content blocks type=tool_use (id, name, input)
# Votre tour suivant : content blocks type=tool_result (tool_use_id, content)
Le vocabulaire change (input_schema vs parameters, tool_use vs tool_calls) ; le contrat reste identique : schéma → appel structuré → exécution runtime → résultat.
Étape 5 — Parallel tool calls et multi-tour
Le modèle peut demander plusieurs outils dans le même tour (ex. statut de trois pods). Exécutez-les en parallèle si indépendants, puis renvoyez tous les tool / tool_result avant le prochain appel modèle.
Multi-tour : après un premier résultat, le modèle peut enchaîner un second outil (ex. get_pod_status puis get_recent_events). Limitez la profondeur (max 3–5 tours) pour éviter les boucles coûteuses.
Étape 6 — Cas DevOps concrets
| Outil (exemple) | Lecture / écriture | HITL ? |
|---|---|---|
get_pod_status |
Lecture | Non |
query_cloudwatch_logs |
Lecture | Non (plafonner fenêtre) |
create_linear_issue |
Écriture ticket | Souvent oui |
kubectl_apply_dry_run |
Dry-run | Optionnel |
kubectl_apply |
Mutation cluster | Oui obligatoire |
Lab recommandé : stub ou cluster kind/minikube, namespace lab-*, ServiceAccount lecture seule pour les tools de type get. Jamais de kubeconfig prod dans le sandbox de l’agent.
Étape 7 — Function calling vs MCP, Actions, Skills
- Function calling : primitive API (OpenAI / Anthropic / Gemini…).
- MCP : protocole pour exposer des serveurs d’outils réutilisables — voir MCP servers : panorama DevOps.
- ChatGPT Actions : tools OpenAPI côté Custom GPT — ChatGPT Actions & outils.
- Claude Code MCP : outils dans le terminal agent — Claude Code : MCP et outils.
- Skills / workflows : recettes qui utilisent ces tools — AI Skills : concept, Agent workflows.
La leçon suivante, Structured outputs JSON, durcit la forme de la réponse finale (pas seulement des arguments d’outil). La leçon Prompt injection & sécurité couvre les attaques via contenu outil / pages web.
Étape 8 — Sécurité : allowlist, validation, secrets
- Allowlist stricte : dictionnaire
DISPATCH, refus sinon. - Valider les arguments (types, enums, regex namespace) avant exécution ; rejeter
additionalProperties. - Pas de secrets dans system prompt ni dans les logs d’arguments ; injecter tokens via env / vault au moment de l’appel HTTP.
- Sandbox : timeouts, pas de shell libre (
subprocessavec argv fixe, jamaisshell=True+ string modèle). - Audit : journaliser
tool,argsredacted,latency,user_id. - HITL pour toute mutation infra.
Checklist lab anti-dérive
- Budget API plafonné ; modèle mini pour itérer.
- Un seul outil lecture d’abord (
get_pod_statusstub). - Afficher les
tool_callsbruts avant de « faire confiance » à la réponse finale. - Tester un refus : demander une action non déclarée — le modèle ne doit pas inventer un outil.
- Couper la boucle après N tours ; afficher un message clair.
- Publish HOLD : ce draft n’est pas encore une page WordPress live.
Coût et quotas en une minute
Chaque tour avec tools = tokens input (schémas + historique) + output (tool_calls) + tour suivant. Les schémas verbeux coûtent cher : descriptions courtes, outils peu nombreux (5–15). Preferez un modèle petit pour le routing d’outils, un plus grand pour la synthèse finale si besoin.
Quiz (5 questions)
1. Qui exécute réellement l’outil en function calling ?
– A. Le GPU du fournisseur LLM
– B. Votre runtime / host
– C. Le navigateur de l’utilisateur uniquement
2. Le champ description d’un outil sert surtout à :
– A. Chiffrer les arguments
– B. Guider le modèle pour décider d’appeler (ou non)
– C. Remplacer IAM
3. tool_choice="auto" signifie :
– A. Toujours appeler le premier outil
– B. Laisser le modèle choisir outil(s) ou répondre en texte
– C. Désactiver les tools
4. Pour un kubectl apply via agent, la bonne posture est :
– A. Allowlist ouverte + auto-approve
– B. Human-in-the-loop + dry-run d’abord
– C. Coller le kubeconfig dans le prompt
5. MCP par rapport au function calling :
– A. Remplace complètement JSON Schema
– B. Expose des outils via un protocole / host réutilisable
– C. Interdit Anthropic
Réponses : 1‑B · 2‑B · 3‑B · 4‑B · 5‑B
Pour aller plus loin
- OpenAI — Function calling
- Anthropic — Tool use
- JSON Schema
- Structured outputs JSON (leçon 47)
- Prompt injection & sécurité (leçon 48)
- MCP servers : panorama DevOps
Maillage série IA Outils 2026 (F — Patterns)
| ← Précédent | Perplexity pour recherche tech |
| → Suivant | Structured outputs JSON |
| Hub | IA pour DevOps : parcours 2026 |
| Aussi | MCP · ChatGPT Actions · Claude Code MCP · AI Skills |
Conclusion
Le function calling est le contrat simple et robuste entre un LLM et votre plateforme DevOps : schémas clairs, allowlist, validation, audit, HITL sur les mutations. Maîtrisez cette boucle avant d’empiler MCP, Skills et agents multi-outils — c’est le pattern 46/50 du parcours IA Outils 2026 sur DevOps Elastic Hayway.
Publish : HOLD — attendre le feu vert Maître avant publication WordPress.
Compléments opérationnels
En DevOps, un tool n’est pas un jouet : c’est une API exécutable. Nommez-le comme une opération métier (get_pod_logs, list_alarms) plutôt que run_shell. Validez JSON côté serveur, journalisez chaque call, bornez max_steps. Reliez ai-structured-outputs, vercel-ai-sdk, mcp-servers-devops, claude-api-premiers-appels et le hub /ia/.
Testez des cas adverses : arguments hors allowlist, boucles infinies, timeouts. Documentez le mode dégradé si le LLM hallucine un tool inconnu (refus + message clair). Budgétez tokens. Formez l’équipe à lire les traces tool comme on lit CloudTrail : qui a appelé quoi, avec quels paramètres, quel résultat.
Industrialisez via un petit catalogue interne de tools approuvés, versionné avec owners — même esprit que les Skills (ai-skills-concept). Évaluez la qualité des chaînes tool+réponse comme vous évaluez un Skill (evaluer-qualite-skill. Le parcours place function calling après les bases prompts/API, avant les agents trop permissifs.
Standard de brief réutilisable
Pour ai-function-calling, adoptez un brief unique partagé par l’équipe. Il contient toujours cinq champs : objectif mesurable, contexte borné (lab/staging), liste blanche de fichiers ou ressources, interdits explicites (secrets, réseau, prod), et definition of done exécutable (commande de test ou checklist). Sans ces champs, l’outil improvisera — parfois avec élégance, souvent hors périmètre.
Stockez les briefs gagnants sous briefs/ai-function-calling/ dans un dépôt de documentation interne. Chaque brief cite le commit de référence et le modèle utilisé. Au troisième succès comparable, ouvrez une PR qui transforme le brief en rule, Skill ou slash comm
FAQ
Function calling vs texte libre ?
Les tools structurés réduisent les hallucinations d’action — à condition d’allowlist et validation serveur.
OpenAI et Anthropic ?
Même idée (tools / tool_use), schémas différents — voir aussi claude-api-premiers-appels.
Risque principal DevOps ?
Un tool shell trop large. Préférez des tools métier least privilege.
Lien MCP ?
Cousin côté agents — mcp-servers-devops, claude-code-mcp.
Structured outputs ?
Complémentaire — ai-structured-outputs.
Retour parcours IA — hub Claude, Codex, ChatGPT et Skills.