Aller au contenu principal

Multi-tour avec outils

Conversations multi-tour avec function calling

Dans une conversation réelle, le modèle peut avoir besoin d’appeler des outils plusieurs fois au fil des échanges. Chaque tour peut impliquer de nouveaux appels, des résultats qui déclenchent d’autres appels, ou des demandes de précision à l’utilisateur avant d’utiliser un outil.

Le paramètre max_turns

Le paramètre max_turns limite le nombre de tours assistant/outils côté serveur dans une seule requête. Il ne concerne que les outils intégrés (web_search, code_interpreter, etc.).

response = client.responses.create(
    model="grok-3",
    input="Analyse les tendances tech 2026",
    tools=[{"type": "web_search"}],
    max_turns=5  # Maximum 5 recherches web avant de répondre
)

Point important : les invocations d’outils côté client réinitialisent le compteur. Quand vous renvoyez un function_call_output, une nouvelle allocation de max_turns commence.

Boucle multi-tour côté client

Pour gérer les conversations où le modèle appelle des outils plusieurs fois, implémentez une boucle :

import json

def multi_turn_chat(user_message, tools, max_iterations=10):
    messages = [{"role": "user", "content": user_message}]

    for i in range(max_iterations):
        response = client.chat.completions.create(
            model="grok-3",
            messages=messages,
            tools=tools
        )

        message = response.choices[0].message
        messages.append(message)

        # Si pas de tool_call, la conversation est terminée
        if not message.tool_calls:
            return message.content

        # Exécuter tous les outils demandés
        for tool_call in message.tool_calls:
            args = json.loads(tool_call.function.arguments)
            result = execute_function(tool_call.function.name, args)
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result)
            })

    return "Nombre maximum d'itérations atteint"

La variable max_iterations est un garde-fou essentiel pour éviter les boucles infinies. En production, fixez une limite raisonnable (5-10 tours).

Contexte multi-tour avec la Responses API

La Responses API offre deux mécanismes pour maintenir le contexte :

1. Stockage distant

# Premier message
r1 = client.responses.create(
    model="grok-3",
    input="Quel temps fait-il à Paris ?",
    tools=tools,
    store_messages=True
)

# Résultat de l'outil
r2 = client.responses.create(
    model="grok-3",
    input=[{
        "type": "function_call_output",
        "call_id": r1.output[0].call_id,
        "output": {temp: 18}
    }],
    previous_response_id=r1.id,
    store_messages=True
)

# Question de suivi (le contexte est conservé)
r3 = client.responses.create(
    model="grok-3",
    input="Et demain ?",
    previous_response_id=r2.id,
    tools=tools,
    store_messages=True
)

L’avantage : vous n’avez pas à gérer l’historique des messages. xAI le stocke et le récupère automatiquement via previous_response_id.

2. Contenu chiffré côté client

response = client.responses.create(
    model="grok-3",
    input="Recherche les prix des vols pour Nice",
    tools=tools,
    use_encrypted_content=True
)

Avec use_encrypted_content=True, vous recevez le raisonnement et les sorties d’outils sous forme chiffrée. Vous les renvoyez tels quels dans les requêtes suivantes, sans pouvoir les lire. C’est utile quand vous ne voulez pas que les données transitent en clair par votre serveur.

Patterns de conversation multi-tour

Pattern : recherche puis action

Tour 1 : Utilisateur → "Trouve un vol Paris-Nice pas cher"
         Modèle → tool_call: search_flights(from="CDG", to="NCE")
         Client → résultat : [{vol1}, {vol2}, {vol3}]
Tour 2 : Modèle → "J'ai trouvé 3 vols. Le moins cher est à 89€. Voulez-vous réserver ?"
         Utilisateur → "Oui, réserve le vol à 89€"
Tour 3 : Modèle → tool_call: book_flight(flight_id="FL123", passengers=1)

Pattern : agrégation de données

Tour 1 : Modèle → tool_call: get_sales(month="march")
Tour 2 : Modèle → tool_call: get_expenses(month="march")
Tour 3 : Modèle → tool_call: get_headcount(month="march")
Tour 4 : Modèle → "Voici le rapport mensuel : ventes +12%, dépenses -3%, effectif stable."

Pattern : affinement progressif

Tour 1 : Modèle → tool_call: search_products(query="chaussures running")
         Résultat → 150 produits
Tour 2 : Modèle → "J'ai trouvé 150 produits. Quelle taille et quel budget ?"
         Utilisateur → "42, max 120€"
Tour 3 : Modèle → tool_call: search_products(query="chaussures running", size=42, max_price=120)
         Résultat → 8 produits

Gestion de la mémoire

Dans les conversations longues, l’historique des messages (incluant tous les tool_calls et résultats) peut devenir très volumineux. Stratégies :

  • Résumé périodique : condensez les anciens tours en un résumé dans le system prompt
  • Fenêtre glissante : ne gardez que les N derniers tours
  • Stockage distant : utilisez store_messages=True pour déléguer à xAI

Points clés à retenir

  • max_turns limite les tours d’outils serveur — les outils client réinitialisent le compteur
  • Implémentez une boucle avec max_iterations pour éviter les boucles infinies
  • previous_response_id chaîne les conversations sans renvoyer l’historique
  • store_messages=True délègue le stockage du contexte à xAI
  • use_encrypted_content=True protège les données en transit
  • Gérez la mémoire dans les conversations longues (résumé, fenêtre glissante)